summaryrefslogtreecommitdiff
path: root/dist/main.js
blob: 471e8447b7c0c234321e84dee956d9683be679cf (plain)
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// 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, 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  noise: function noise(time) {\n    return Math.random() * Math.random() * 2 - 1;\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.chaos;\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", "noise"];\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: -3,\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: "chaos",\n    onChange: onChange,\n    min: 0,\n    max: 0.5,\n    step: 0.01,\n    defaultValue: relabi.settings.chaos,\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          chaos: 0.2\n        },\n        waves: [{\n          shape: "sine",\n          frequency: 0.5,\n          weight: 1\n        }, {\n          shape: "sine",\n          frequency: 1.0,\n          weight: 1\n        }, {\n          shape: "sine",\n          frequency: 1.5,\n          weight: 1\n        }, {\n          shape: "sine",\n          frequency: 2.0,\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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Qyx1QkFBdUI7QUFDeEQsc0NBQXNDLHVCQUF1QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0I7O0FDeE9zQztBQUN0QztBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsZ0JBQWdCLGlCQUFXO0FBQzNCO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLGdCQUFnQixpQkFBVztBQUMzQjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxxQzs7QUN4QzhDO0FBQ3VCO0FBQ087QUFDM0I7QUFDRztBQUNqQjtBQUNtQjtBQUNGO0FBQ0U7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sYUFBTSxTQUFTLGFBQU07QUFDbEM7QUFDQSxjQUFjLDZCQUFvQixDQUFDLGFBQU07QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qiw2QkFBb0IsQ0FBQyxhQUFNO0FBQ25ELDJCQUEyQiwrQkFBZTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIseUJBQWtCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixjQUFJO0FBQ3hCLHFCQUFxQixjQUFJO0FBQ3pCO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGNBQUk7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFVO0FBQy9CO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtQkFBVTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixpQ0FBZ0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGlCQUFPO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksaUJBQVc7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGlCQUFXO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLElBQUksU0FBUztBQUNiLEdBQUcsYUFBTTtBQUNULFVBQVU7QUFDVixJQUFJLFNBQVM7QUFDYixHQUFHLGFBQU07QUFDVCxrQzs7QUMvVndEO0FBQ2U7QUFDTjtBQUNEO0FBQ2pCO0FBQ1k7QUFDeEI7QUFDRDtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNPLHNCQUFzQiw2REFBYTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQsTUFBTTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQzNKbUM7QUFDYztBQUNvQjtBQUNPO0FBQzdCO0FBQ087QUFDaUI7QUFDbkI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTywwQkFBMEIsc0RBQU07QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Qzs7QUMxT3dCO0FBQ0k7QUFDWTtBQUNFO0FBQ0E7QUFDRztBQUNGO0FBQ0E7QUFDQztBQUNJO0FBQ2Y7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QUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCx3QkFBd0IseUJBQXlCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7O0FDck1tQztBQUNxQjtBQUNnQjtBQUN0QjtBQUNSO0FBQ1Y7QUFDMEI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELGdCQUFnQjtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBGQUEwRixRQUFRO0FBQ2xHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxRQUFRO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNVN3QztBQUMwQjtBQUNMO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLCtEQUFlO0FBQ3pDO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQSw2Q0FBNkMsU0FBSTtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNuS2dEO0FBQ2dCO0FBQ1M7QUFDZDtBQUNvQjtBQUN2QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sb0NBQW9DO0FBQzlDLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLHlEQUFTO0FBQ25DO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFNBQUk7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0Qiw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxTQUFJO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQ2haNEM7QUFDRjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsbUJBQW1CO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxVQUFVLGlDQUFnQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEM7O0FDcEs4QjtBQUN3QjtBQUNPO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTyxzQkFBc0Isb0RBQUk7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQ2xFZ0Q7QUFDNkI7QUFDbEI7QUFDN0I7QUFDVTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLHlEQUFTO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUN0UHVCO0FBQ0E7QUFDRztBQUNDO0FBQ0M7QUFDNUIsaUM7O0FDTCtDO0FBQzJCO0FBQ1Y7QUFDWDtBQUNFO0FBQ1Y7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUJBQVMsU0FBUyw2REFBYTtBQUM1QztBQUNBLGlEQUFpRCxtQkFBUztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtB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O0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDaExrQztBQUMrQjtBQUNsQjtBQUNBO0FBQ2E7QUFDSTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNPLHVCQUF1Qiw2REFBYTtBQUMzQztB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNPO0FBQ1A7QUFDQSxPQUFPLFNBQVM7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCLFFBQVE7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQzs7QUMvSEE7O0FBRUE7QUFDZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQzs7QUNyREE7QUFDQTtB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QixpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHdCQUF3QjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtB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O0FBQ3ZFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsMkJBQWM7QUFDMUM7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLDJCQUFjO0FBQzFDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0IsMkJBQWM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLGNBQWEsR0FBRzs7QUFFMUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FB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SUFBSSxDQUFDeUIsU0FBUyxHQUFHLEVBQUU7RUFDNUIxQixRQUFRLENBQUNDLElBQUksQ0FBQzZDLFdBQVcsQ0FBQ3ZCLFNBQVMsQ0FBQztFQUNwQyxJQUFNaUosSUFBSSxHQUFHeUcsNEJBQVUsQ0FBQzFQLFNBQVMsQ0FBQztFQUNsQ2lKLElBQUksQ0FBQzJHLE1BQU0sZUFBQ3RELG1CQUFBLENBQUMwQyxHQUFHLE1BQUUsQ0FBQyxDQUFDO0FBQ3RCLENBQUMsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS92ZXJzaW9uLmpzPzMzODMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWJvcnQtZXJyb3IuanM/NzM4MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcz83ODdiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zLmpzP2YwZmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zLmpzP2FkM2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9nbG9iYWxzLmpzPzc0ZjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2lzLWNvbnN0cnVjdGlibGUuanM/NTI4MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc3BsaXQtaW1wb3J0LXN0YXRlbWVudHMuanM/Nzg5MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtYXVkaW8td29ya2xldC1tb2R1bGUuanM/NzQ4NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LXZhbHVlLWZvci1rZXkuanM/NWQ3NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvcGljay1lbGVtZW50LWZyb20tc2V0LmpzPzU2MGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcz9hNTJiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUuanM/MDI3YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZS5qcz8yZjk0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2F1ZGlvLXdvcmtsZXQtbm9kZS5qcz8xYjhmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS5qcz9hZTVkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeS5qcz83YTU2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanM/MzM5ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanM/MTBjOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtc2lsZW50LWNvbm5lY3Rpb24uanM/YzljOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUuanM/ZGE2ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hbmFseXNlci1ub2RlLWNvbnN0cnVjdG9yLmpzPzA4NTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQuanM/NDk2NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hbmFseXNlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/NzMxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcy1zdXBwb3J0LmpzPzM3ZmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaW5kZXgtc2l6ZS1lcnJvci5qcz9iY2NlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZC5qcz8yM2I1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci5qcz81MjdhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvY29uc3RhbnRzLmpzPzYyZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlLmpzPzExZDQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzPzc1NjkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/NjRkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUuanM/ZjJmZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9iaXF1YWQtZmlsdGVyLW5vZGUuanM/YTIyMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9jb25zdGFudC1zb3VyY2Utbm9kZS5qcz8yNDFhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2dhaW4tbm9kZS5qcz9hZTExIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL29zY2lsbGF0b3Itbm9kZS5qcz80MDljIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL3N0ZXJlby1wYW5uZXItbm9kZS5qcz9mZDc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucy5qcz8yYTc5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanM/NGRhYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVhY3RpdmF0ZS1hY3RpdmUtYXVkaW8tbm9kZS1pbnB1dC1jb25uZWN0aW9ucy5qcz9jOTMxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoLmpzPzllOWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2lzLXZhbGlkLWxhdGVuY3ktaGludC5qcz84MDAyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/OTViNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzPzA1MzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tZGVzdGluYXRpb24tbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzgyYjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tbGlzdGVuZXItZmFjdG9yeS5qcz9kMDczIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2F1ZGlvLW5vZGUuanM/YjQ1ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uLmpzP2U4YzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2luc2VydC1lbGVtZW50LWluLXNldC5qcz8wZTI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanM/M2UyMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvYWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcz8xNmI1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyLmpzPzEzNjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUuanM/MmZlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLmpzPzNjNTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcz9lODYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWxldGUtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUuanM/OWIxOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcz8yMTk1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kaXNjb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLWZyb20tbmF0aXZlLWF1ZGlvLW5vZGUuanM/ZjcyNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1ub2RlLmpzPzMwNGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tcGFyYW0uanM/OTRkOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtcGFydC1vZi1hLWN5Y2xlLmpzPzNjY2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2lzLXBhc3NpdmUtYXVkaW8tbm9kZS5qcz9hYTM1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2Qtc3VwcG9ydC5qcz9lMzQxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy92aXNpdC1lYWNoLWF1ZGlvLW5vZGUtb25jZS5qcz8wMmJiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLmpzPzkyMWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC5qcz9kZWYwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLW5vZGUtY29uc3RydWN0b3IuanM/OWZlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1wYXJhbS1mYWN0b3J5LmpzPzkyZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tcGFyYW0tcmVuZGVyZXIuanM/MDkwOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L3JlYWQtb25seS1tYXAuanM/OWM4NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3IuanM/NTEyYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY29weS1mcm9tLWNoYW5uZWwuanM/ZDAwZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY29weS10by1jaGFubmVsLmpzP2NmZWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2NyZWF0ZS1uZXN0ZWQtYXJyYXlzLmpzP2YwMTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci5qcz9lMTJhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLXdvcmtsZXQtbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzNmMTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzP2IxMzQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYmlxdWFkLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzPzI1NjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYmlxdWFkLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/ODI3YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jYWNoZS10ZXN0LXJlc3VsdC5qcz9mYzUxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtY29uc3RydWN0b3IuanM/ZWQwMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jaGFubmVsLW1lcmdlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/ZTA4NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jaGFubmVsLXNwbGl0dGVyLW5vZGUtY29uc3RydWN0b3IuanM/NTRiYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jaGFubmVsLXNwbGl0dGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz9lYjAwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Nvbm5lY3QtYXVkaW8tcGFyYW0uanM/NTcyOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanM/MTI0MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb25uZWN0ZWQtbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzPzY0NjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtY29uc3RydWN0b3IuanM/NGJkMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb25zdGFudC1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzMxNDQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29udmVydC1udW1iZXItdG8tdW5zaWduZWQtbG9uZy5qcz8wOWJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NvbnZvbHZlci1ub2RlLWNvbnN0cnVjdG9yLmpzPzA1ZTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29udm9sdmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz81YTk3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NyZWF0ZS1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzPzUzMmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGF0YS1jbG9uZS1lcnJvci5qcz8xOTViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZXRhY2gtYXJyYXktYnVmZmVyLmpzPzlmN2UiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVjb2RlLWF1ZGlvLWRhdGEuanM/MjY5ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZWNyZW1lbnQtY3ljbGUtY291bnRlci5qcz8xZjRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlbGF5LW5vZGUtY29uc3RydWN0b3IuanM/MTEzYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZWxheS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/MWU3NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcz9lMjE0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlbGV0ZS11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZS5qcz8xZDQ0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2RlbGF5LW5vZGUuanM/NmU5NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZXRlY3QtY3ljbGVzLmpzPzdhYjIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGlzY29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzLmpzPzNkNDMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWNvbnN0cnVjdG9yLmpzPzgyZjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/YmE5MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9lbmNvZGluZy1lcnJvci5qcz9iNjdiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2V2YWx1YXRlLXNvdXJjZS5qcz8zNWY3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2V2ZW50LXRhcmdldC1jb25zdHJ1Y3Rvci5qcz80MjI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2V4cG9zZS1jdXJyZW50LWZyYW1lLWFuZC1jdXJyZW50LXRpbWUuanM/NjNmNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9mZXRjaC1zb3VyY2UuanM/ZTlkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nYWluLW5vZGUtY29uc3RydWN0b3IuanM/YzdkZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nYWluLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz83N2VkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcz82MDRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC1hdWRpby1ub2RlLXJlbmRlcmVyLmpzP2RhNTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzPzAzNjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LWF1ZGlvLXBhcmFtLXJlbmRlcmVyLmpzPzBmZTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/OTIzMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yLmpzP2UwOTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LW5hdGl2ZS1jb250ZXh0LmpzPzRlYWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LW9yLWNyZWF0ZS1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzP2RhOWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2Rlcy5qcz9kY2U4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2ludmFsaWQtYWNjZXNzLWVycm9yLmpzPzM2MWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtaWlyLWZpbHRlci1ub2RlLWdldC1mcmVxdWVuY3ktcmVzcG9uc2UtbWV0aG9kLmpzPzg3NDQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaWlyLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzPzA1NmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2ZpbHRlci1idWZmZXIuanM/ZTQxYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz8zNzM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2luY3JlbWVudC1jeWNsZS1jb3VudGVyLWZhY3RvcnkuanM/ZTMyNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tY29udGV4dC5qcz81YTI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLWFueS1hdWRpby1ub2RlLmpzPzA3ODgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLXBhcmFtLmpzPzdlNzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtYW55LW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz9kZjI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1jb250ZXh0LmpzPzIyNmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLW5vZGUuanM/NjNiOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tcGFyYW0uanM/MTUxZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1uYXRpdmUtY29udGV4dC5qcz81Y2U2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/NWFkNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1zZWN1cmUtY29udGV4dC5qcz84NmY1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanM/NzM3MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvci5qcz8zMDc1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcz9hYTRiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcz9iYTU4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21pbmltYWwtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz9lZGQzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21pbmltYWwtYmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzP2RlNjIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0LmpzP2U1MzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWluaW1hbC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/NTAzNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9tb25pdG9yLWNvbm5lY3Rpb25zLmpzP2ZjNzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24uanM/OGVmNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMuanM/Y2U3NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC1zdXBwb3J0LmpzPzEwMWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2QuanM/ZjU3NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYW5hbHlzZXItbm9kZS1mYWN0b3J5LmpzP2IzNDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci5qcz84OGY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUuanM/NjNmMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLmpzP2Y4MDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLmpzPzI1MTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMuanM/OTI0ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnkuanM/M2Y5MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz8yN2UyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLmpzP2RlZGMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvci5qcz9lMTZlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWNsb25hYmlsaXR5LW9mLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzPzZjMmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWN0b3J5LmpzPzI4ZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2NvbXB1dGUtYnVmZmVyLXNpemUuanM/ZDExNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY2xvbmUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanM/OGI1MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXByb21pc2UuanM/MTJkNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLmpzPzNhOWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWtlci1mYWN0b3J5LmpzPzBjMDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWJpcXVhZC1maWx0ZXItbm9kZS5qcz9hOWRmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLW1lcmdlci1ub2RlLWZhY3RvcnkuanM/MjU2ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1jaGFubmVsLXNwbGl0dGVyLW5vZGUuanM/M2JhZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtY2hhbm5lbC1zcGxpdHRlci1ub2RlLmpzPzg5YmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWNvbnN0YW50LXNvdXJjZS1ub2RlLWZhY3RvcnkuanM/NWEwMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zLmpzPzUwMWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWNvbnN0YW50LXNvdXJjZS1ub2RlLWZha2VyLWZhY3RvcnkuanM/ZTBjYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtY29udm9sdmVyLW5vZGUtZmFjdG9yeS5qcz9hMTRkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1kZWxheS1ub2RlLmpzPzA1MTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWR5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1mYWN0b3J5LmpzPzQ4OTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWdhaW4tbm9kZS5qcz9mN2YwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFjdG9yeS5qcz9mM2UxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcz9mOGFkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLmpzPzA3MDkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLmpzP2QxY2EiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS5qcz9lY2M0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtZmFjdG9yeS5qcz8zNjMzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/NzJmNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtb3NjaWxsYXRvci1ub2RlLWZhY3RvcnkuanM/OTdlZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtcGFubmVyLW5vZGUtZmFjdG9yeS5qcz9lY2ZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzPzBkYWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXBlcmlvZGljLXdhdmUtZmFjdG9yeS5qcz85YmIxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1zY3JpcHQtcHJvY2Vzc29yLW5vZGUuanM/YjE1MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZhY3RvcnkuanM/NThmNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanM/MGRlMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWN0b3J5LmpzPzg1OTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcz8zMzQ4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25vdC1zdXBwb3J0ZWQtZXJyb3IuanM/MTM2MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/MzBkMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtY29uc3RydWN0b3IuanM/OWM1YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz83MzJhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3Bhbm5lci1ub2RlLWNvbnN0cnVjdG9yLmpzPzY4NGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz8xODI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3BlcmlvZGljLXdhdmUtY29uc3RydWN0b3IuanM/YzEwMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9yZW5kZXItYXV0b21hdGlvbi5qcz8xOGViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3JlbmRlci1pbnB1dHMtb2YtYXVkaW8tbm9kZS5qcz8zYjg1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3JlbmRlci1pbnB1dHMtb2YtYXVkaW8tcGFyYW0uanM/NzRmOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9yZW5kZXItbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz8xM2E4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3NldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcz9mMjgwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3NldC1hdWRpby1ub2RlLXRhaWwtdGltZS5qcz9lMzAwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3N0YXJ0LXJlbmRlcmluZy5qcz83MTMwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3N0ZXJlby1wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz84ZWMxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3N0ZXJlby1wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzdiNDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvdGVzdC1hdWRpby1idWZmZXItY29uc3RydWN0b3Itc3VwcG9ydC5qcz80YmIwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3Rlc3QtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcG9zdC1tZXNzYWdlLXN1cHBvcnQuanM/ZmJjYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy90ZXN0LW9mZmxpbmUtYXVkaW8tY29udGV4dC1jdXJyZW50LXRpbWUtc3VwcG9ydC5qcz9jZWE0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3Vua25vd24tZXJyb3IuanM/YzFkMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93YXZlLXNoYXBlci1ub2RlLWNvbnN0cnVjdG9yLmpzPzE0MmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd2F2ZS1zaGFwZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzI4M2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd2luZG93LmpzP2FiM2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMuanM/M2UzZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLmpzPzFhZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci5qcz83MGQ1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dyYXAtY2hhbm5lbC1tZXJnZXItbm9kZS5qcz84NzU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtZmlyc3Qtc2FtcGxlLmpzPzg5NWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2lzLWRjLWN1cnZlLmpzP2Q0ZTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL292ZXJ3cml0ZS1hY2Nlc3NvcnMuanM/MWIyNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2FuaXRpemUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanM/ODA1OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2FuaXRpemUtY2hhbm5lbC1zcGxpdHRlci1vcHRpb25zLmpzPzQ5MDciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Nhbml0aXplLXBlcmlvZGljLXdhdmUtb3B0aW9ucy5qcz9mNmRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zZXQtdmFsdWUtYXQtdGltZS11bnRpbC1wb3NzaWJsZS5qcz9hOWMyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydC5qcz82NzJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLXN1cHBvcnQuanM/OGRkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci1zdXBwb3J0LmpzP2Y2MTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLXN1cHBvcnQuanM/ZTE2ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydC5qcz9lNTZmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLXN1cHBvcnQuanM/NzRmNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy1jbG9uYWJpbGl0eS5qcz82N2MyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLmpzPzFmMTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLmpzP2VkMjIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtZXZlbnQtbGlzdGVuZXIuanM/ZTQ5ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L21vZHVsZS5qcz83OGRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRGVidWcuanM/YTM3NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL1R5cGVDaGVjay5qcz84NjcxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvQXVkaW9Db250ZXh0LmpzPzkxYWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcz85YWI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RpY2tlci5qcz9hNDU4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2suanM/YmY2YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0RlZmF1bHRzLmpzPzViNzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvVG9uZS5qcz9hZmFmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvTWF0aC5qcz9mNGNmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvVGltZWxpbmUuanM/ZTUyNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0NvbnRleHRJbml0aWFsaXphdGlvbi5qcz8wMTMxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRW1pdHRlci5qcz8xNWVkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvQmFzZUNvbnRleHQuanM/MWQyMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0NvbnRleHQuanM/YTI4MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0R1bW15Q29udGV4dC5qcz80YzlmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvSW50ZXJmYWNlLmpzPzA2ZTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXIuanM/MTQ5YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L09mZmxpbmVDb250ZXh0LmpzP2FiMTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvR2xvYmFsLmpzPzU4M2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9Db252ZXJzaW9ucy5qcz80NmY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvVGltZUJhc2UuanM/YjY3NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL1RpbWUuanM/NDE0MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL0ZyZXF1ZW5jeS5qcz80NWM2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvVHJhbnNwb3J0VGltZS5qcz9kNTBhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0LmpzP2Q2ODMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lLmpzP2YxYjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9QYXJhbS5qcz8xZjc0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZS5qcz9iNjRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvR2Fpbi5qcz9iMjMxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvT25lU2hvdFNvdXJjZS5qcz80Nzc4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvVG9uZUNvbnN0YW50U291cmNlLmpzP2Y0YmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TaWduYWwuanM/ZGRlYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UaWNrUGFyYW0uanM/NWNlMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UaWNrU2lnbmFsLmpzPzcyMTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVGlja1NvdXJjZS5qcz84MmM3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL0Nsb2NrLmpzPzEwYTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9EZWxheS5qcz9iYjNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvT2ZmbGluZS5qcz9lOTQyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVycy5qcz80OWQ1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvTWlkaS5qcz9jOGZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvVGlja3MuanM/ZTZjZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0RyYXcuanM/NTQzYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0ludGVydmFsVGltZWxpbmUuanM/MDg5YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9pbmRleC5qcz9jZDM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWUuanM/YTA5OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0Rlc3RpbmF0aW9uLmpzPzFiY2UiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9UaW1lbGluZVZhbHVlLmpzP2IwMzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVHJhbnNwb3J0RXZlbnQuanM/M2YxOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UcmFuc3BvcnRSZXBlYXRFdmVudC5qcz85OGRkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RyYW5zcG9ydC5qcz80YzRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvU291cmNlLmpzPzUwOWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9idWZmZXIvVG9uZUJ1ZmZlclNvdXJjZS5qcz8yYjNhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvTm9pc2UuanM/ZDMwNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL1VzZXJNZWRpYS5qcz9jNzNmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9Pc2NpbGxhdG9ySW50ZXJmYWNlLmpzP2Q5ZGMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL1RvbmVPc2NpbGxhdG9yTm9kZS5qcz9mYmJmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9Pc2NpbGxhdG9yLmpzPzRkZDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TaWduYWxPcGVyYXRvci5qcz85ZTg4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvV2F2ZVNoYXBlci5qcz9hM2NkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvQXVkaW9Ub0dhaW4uanM/YWRhZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL011bHRpcGx5LmpzPzUwNzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL0FNT3NjaWxsYXRvci5qcz81ODI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9GTU9zY2lsbGF0b3IuanM/NWExOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvUHVsc2VPc2NpbGxhdG9yLmpzPzQyOTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL0ZhdE9zY2lsbGF0b3IuanM/YjhkZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvUFdNT3NjaWxsYXRvci5qcz9lZmRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvci5qcz83ZDc5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvQWRkLmpzPzQyODEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TY2FsZS5qcz9lZDZlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvWmVyby5qcz9lZGI1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9MRk8uanM/ZjMzYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0RlY29yYXRvci5qcz85NmZiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvYnVmZmVyL1BsYXllci5qcz83NzgwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvYnVmZmVyL1BsYXllcnMuanM/NDc0OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL2J1ZmZlci9HcmFpblBsYXllci5qcz8wYTFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvaW5kZXguanM/ZjQyMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL0Ficy5qcz9iYjkyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvR2FpblRvQXVkaW8uanM/MjI2YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL05lZ2F0ZS5qcz8wYTIxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvU3VidHJhY3QuanM/YjY3ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL0dyZWF0ZXJUaGFuWmVyby5qcz82MjI3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvR3JlYXRlclRoYW4uanM/YmQzMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1Bvdy5qcz9hODQwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvU2NhbGVFeHAuanM/NDY3NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1N5bmNlZFNpZ25hbC5qcz85NTcyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvaW5kZXguanM/MDM1NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlLmpzPzIzZjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvSW5zdHJ1bWVudC5qcz9lOTMxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L01vbm9waG9uaWMuanM/NzRlZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlLmpzP2YyMTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvU3ludGguanM/ZTVlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9Nb2R1bGF0aW9uU3ludGguanM/M2MyOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9BTVN5bnRoLmpzP2JhMDciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvQmlxdWFkRmlsdGVyLmpzPzY0NmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyLmpzPzEzMTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9lbnZlbG9wZS9GcmVxdWVuY3lFbnZlbG9wZS5qcz84NzA4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L01vbm9TeW50aC5qcz8yZGVlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L0R1b1N5bnRoLmpzPzc4N2YiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvRk1TeW50aC5qcz9iOWM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L01ldGFsU3ludGguanM/OTMyZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9NZW1icmFuZVN5bnRoLmpzPzk1NDEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTm9pc2VTeW50aC5qcz8zYzhlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3dvcmtsZXQvV29ya2xldEdsb2JhbFNjb3BlLmpzPzhhNjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvd29ya2xldC9Ub25lQXVkaW9Xb3JrbGV0LmpzP2UwOGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvd29ya2xldC9Ub25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLndvcmtsZXQuanM/NTFmMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS93b3JrbGV0L1NpbmdsZUlPUHJvY2Vzc29yLndvcmtsZXQuanM/NTY4YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS93b3JrbGV0L0RlbGF5TGluZS53b3JrbGV0LmpzP2Q1MDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvRmVlZGJhY2tDb21iRmlsdGVyLndvcmtsZXQuanM/MDg4YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9GZWVkYmFja0NvbWJGaWx0ZXIuanM/YTUxZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9PbmVQb2xlRmlsdGVyLmpzP2E3OGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvTG93cGFzc0NvbWJGaWx0ZXIuanM/MjhlMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9QbHVja1N5bnRoLmpzPzA2Y2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvUG9seVN5bnRoLmpzPzU4ODMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvU2FtcGxlci5qcz8zMTk1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L2luZGV4LmpzP2M2MTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L1RvbmVFdmVudC5qcz9lNTMxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9Mb29wLmpzP2RiZGIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L1BhcnQuanM/OGQzOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvUGF0dGVybkdlbmVyYXRvci5qcz85Y2RmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9QYXR0ZXJuLmpzP2M0NjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L1NlcXVlbmNlLmpzPzhmOTMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L2luZGV4LmpzPzQwNGIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZS5qcz8yYzg2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvRWZmZWN0LmpzP2QxMjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9MRk9FZmZlY3QuanM/NGIzOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0F1dG9GaWx0ZXIuanM/MDk3NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvUGFubmVyLmpzP2IxZWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9BdXRvUGFubmVyLmpzPzJhNDciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9Gb2xsb3dlci5qcz80NmI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQXV0b1dhaC5qcz9jOWNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQml0Q3J1c2hlci53b3JrbGV0LmpzP2RiODUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9CaXRDcnVzaGVyLmpzP2E0OWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9DaGVieXNoZXYuanM/YjE4NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvU3BsaXQuanM/OTliOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvTWVyZ2UuanM/ZDA1YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1N0ZXJlb0VmZmVjdC5qcz9mMDZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvU3RlcmVvRmVlZGJhY2tFZmZlY3QuanM/MTFlMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0Nob3J1cy5qcz83NDFjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvRGlzdG9ydGlvbi5qcz84MDQ4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvRmVlZGJhY2tFZmZlY3QuanM/YTcxOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0ZlZWRiYWNrRGVsYXkuanM/OGJmMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9QaGFzZVNoaWZ0QWxscGFzcy5qcz84ZDUxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvRnJlcXVlbmN5U2hpZnRlci5qcz84YTYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvRnJlZXZlcmIuanM/ZTg5NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0pDUmV2ZXJiLmpzPzE1ZGMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9TdGVyZW9YRmVlZGJhY2tFZmZlY3QuanM/ODk4NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1BpbmdQb25nRGVsYXkuanM/ZGUyNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1BpdGNoU2hpZnQuanM/ODZhNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1BoYXNlci5qcz82YjcwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvUmV2ZXJiLmpzPzBkODEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL01pZFNpZGVTcGxpdC5qcz9mZTNkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlTWVyZ2UuanM/NmZiMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L01pZFNpZGVFZmZlY3QuanM/ZWZmNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1N0ZXJlb1dpZGVuZXIuanM/MGRiMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1RyZW1vbG8uanM/MGUxZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1ZpYnJhdG8uanM/MGMxZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L2luZGV4LmpzP2VjNGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9BbmFseXNlci5qcz9lZGFjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvYW5hbHlzaXMvTWV0ZXJCYXNlLmpzPzQ3NmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9NZXRlci5qcz9kZjQxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvYW5hbHlzaXMvRkZULmpzPzY1ZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9EQ01ldGVyLmpzPzdiOTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9XYXZlZm9ybS5qcz85OWQzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9Tb2xvLmpzPzFiYmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1BhblZvbC5qcz8xYWY4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9DaGFubmVsLmpzP2QzNzAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL01vbm8uanM/OWZhOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvTXVsdGliYW5kU3BsaXQuanM/MzQ1MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0xpc3RlbmVyLmpzPzIwMzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1Bhbm5lcjNELmpzP2M5ZGQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1JlY29yZGVyLmpzP2FkN2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9keW5hbWljcy9Db21wcmVzc29yLmpzPzZkYjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9keW5hbWljcy9HYXRlLmpzPzhiZjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9keW5hbWljcy9MaW1pdGVyLmpzPzE1YzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9keW5hbWljcy9NaWRTaWRlQ29tcHJlc3Nvci5qcz9kYjU5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZHluYW1pY3MvTXVsdGliYW5kQ29tcHJlc3Nvci5qcz9mZGJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0VRMy5qcz8yZjczIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0NvbnZvbHZlci5qcz9lYTE1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvaW5kZXguanM/MWQ3NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY2xhc3Nlcy5qcz9kM2M3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbmRleC5qcz81ZTU0Iiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9saWIvdXRpbC5qcz9mMWVkIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9yZWxhYmkvY2FudmFzLmpzP2RjOWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2xpYi9vdXRwdXQuanM/M2ZlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3NhbXBsZXIuanM/NTk2YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL2luc3RydW1lbnRzLmpzP2Y5YTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3JlbGFiaS9pbmRleC5qcz8wMmZhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90eXBlb2YuanM/ZjhkZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9QcmltaXRpdmUuanM/OTc2ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9Qcm9wZXJ0eUtleS5qcz9hMmZiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eS5qcz9kNzFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hcnJheUxpa2VUb0FycmF5LmpzPzIyMmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2FycmF5V2l0aG91dEhvbGVzLmpzP2M0N2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2l0ZXJhYmxlVG9BcnJheS5qcz9kMWIxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qcz82YzIyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9ub25JdGVyYWJsZVNwcmVhZC5qcz8wYWQ4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b0NvbnN1bWFibGVBcnJheS5qcz9mN2EzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hcnJheVdpdGhIb2xlcy5qcz8yYmU0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qcz84MmRmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9ub25JdGVyYWJsZVJlc3QuanM/NGViYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheS5qcz9mY2QwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL3dhcm5pbmcuanM/MmIwNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9pc0VxdWFsLmpzPzU5ZmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaG9va3MvdXNlRXZlbnQuanM/OTgxMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9Eb20vY2FuVXNlRG9tLmpzPzMwZDkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaG9va3MvdXNlTGF5b3V0RWZmZWN0LmpzPzRjZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaG9va3MvdXNlU3RhdGUuanM/NzY2ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9ob29rcy91c2VNZXJnZWRTdGF0ZS5qcz9lOWMxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzLmpzPzMzMTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2UuanM/ZDIxNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXMuanM/OTQyOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMi5qcz9iYjc1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL0tleUNvZGUuanM/ZTA4OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL2NvbnRleHQuanM/OTNkNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL3V0aWwuanM/OWVmOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL0hhbmRsZXMvSGFuZGxlLmpzPzk5ZGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9IYW5kbGVzL2luZGV4LmpzP2IwMTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9ob29rcy91c2VEcmFnLmpzPzFmM2UiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9UcmFja3MvVHJhY2suanM/MzQ4NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL1RyYWNrcy9pbmRleC5qcz9iZmU5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvTWFya3MvTWFyay5qcz9jNGIwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvTWFya3MvaW5kZXguanM/OGM1MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL1N0ZXBzL0RvdC5qcz80NTQyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvU3RlcHMvaW5kZXguanM/Yzg1NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL2hvb2tzL3VzZU9mZnNldC5qcz9kMmU0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvU2xpZGVyLmpzPzNiM2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9pbmRleC5qcz9iMjI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy10b29sdGlwL2Fzc2V0cy9ib290c3RyYXAuY3NzPzBjODgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaG9va3MvdXNlTWVtby5qcz82MmJiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL3JlZi5qcz83M2U1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3BvcnRhbC9lcy9Db250ZXh0LmpzP2Q4MTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvcG9ydGFsL2VzL3VzZURvbS5qcz9mOGI5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL0RvbS9jb250YWlucy5qcz85Nzg2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL0RvbS9keW5hbWljQ1NTLmpzPzA1NGQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvZ2V0U2Nyb2xsQmFyU2l6ZS5qcz9hYjFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3BvcnRhbC9lcy91dGlsLmpzPzk0OWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvcG9ydGFsL2VzL3VzZVNjcm9sbExvY2tlci5qcz9hODcxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3BvcnRhbC9lcy9tb2NrLmpzPzQ5NjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvcG9ydGFsL2VzL1BvcnRhbC5qcz81NWM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3BvcnRhbC9lcy9pbmRleC5qcz82ZDNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL0NoaWxkcmVuL3RvQXJyYXkuanM/NjY2ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9Eb20vZmluZERPTU5vZGUuanM/OWJlNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmVzaXplLW9ic2VydmVyLXBvbHlmaWxsL2Rpc3QvUmVzaXplT2JzZXJ2ZXIuZXMuanM/NmRkOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtcmVzaXplLW9ic2VydmVyL2VzL3V0aWxzL29ic2VydmVyVXRpbC5qcz80NzEyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVjay5qcz82OTU0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzcy5qcz85Mjk3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zZXRQcm90b3R5cGVPZi5qcz80MzUxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0cy5qcz85OGExIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZi5qcz8zMTY2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QuanM/ZGRjYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkLmpzPzQyY2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4uanM/MGQ0NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlU3VwZXIuanM/M2Q5MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtcmVzaXplLW9ic2VydmVyL2VzL1NpbmdsZU9ic2VydmVyL0RvbVdyYXBwZXIuanM/ODE3MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtcmVzaXplLW9ic2VydmVyL2VzL0NvbGxlY3Rpb24uanM/Y2YzZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtcmVzaXplLW9ic2VydmVyL2VzL1NpbmdsZU9ic2VydmVyL2luZGV4LmpzPzUyZTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXJlc2l6ZS1vYnNlcnZlci9lcy9pbmRleC5qcz9iNzZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2hvb2tzL3VzZUlkLmpzPzU3NjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaXNNb2JpbGUuanM/ZTU5ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL2NvbnRleHQuanM/YzU1MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL2hvb2tzL3VzZUFjdGlvbi5qcz9hMDY5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL0RvbS9pc1Zpc2libGUuanM/YzdmYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL3V0aWwuanM/MTIzMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL2hvb2tzL3VzZUFsaWduLmpzPzk0NGMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9ob29rcy91c2VXYXRjaC5qcz9hMzBmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvY29udGV4dC5qcz84OGE3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvRG9tV3JhcHBlci5qcz84YmZiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvaW50ZXJmYWNlLmpzPzRkMjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy91dGlsL21vdGlvbi5qcz84ZmEwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvaG9va3MvdXNlRG9tTW90aW9uRXZlbnRzLmpzP2VmZTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9ob29rcy91c2VJc29tb3JwaGljTGF5b3V0RWZmZWN0LmpzP2ZiZGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvcmFmLmpzP2MyMDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9ob29rcy91c2VOZXh0RnJhbWUuanM/MDkxNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2hvb2tzL3VzZVN0ZXBRdWV1ZS5qcz8xNTViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvaG9va3MvdXNlU3RhdHVzLmpzP2VlYWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9DU1NNb3Rpb24uanM/N2IyMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL3V0aWwvZGlmZi5qcz80YjM1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvQ1NTTW90aW9uTGlzdC5qcz85Y2E2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvaW5kZXguanM/ZjE3NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL1BvcHVwL0Fycm93LmpzPzdjM2YiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9Qb3B1cC9NYXNrLmpzPzEwNTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9Qb3B1cC9Qb3B1cENvbnRlbnQuanM/NTBhYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL1BvcHVwL2luZGV4LmpzPzgwYzAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9UcmlnZ2VyV3JhcHBlci5qcz82NDBlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvaW5kZXguanM/YmY2YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdG9vbHRpcC9lcy9wbGFjZW1lbnRzLmpzP2VlMmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXRvb2x0aXAvZXMvUG9wdXAuanM/NWMwOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdG9vbHRpcC9lcy9Ub29sdGlwLmpzP2M3ZDkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXRvb2x0aXAvZXMvaW5kZXguanM/MzhiMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvdWkvVG9vbHRpcFNsaWRlci50c3g/MmFkNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2Fzc2V0cy9pbmRleC5jc3M/ZmQxZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvdWkvQ29udHJvbHMuanN4P2U5MTMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3VpL0FwcC5qc3g/NDQyYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvaW5kZXguanN4P2VkMTIiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHZlcnNpb24gPSBcIjE0LjcuNzdcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZlcnNpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFib3J0RXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnQWJvcnRFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWJvcnQtZXJyb3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKGluc2VydEVsZW1lbnRJblNldCkgPT4ge1xuICAgIHJldHVybiAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGlucHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQoYWN0aXZlSW5wdXRzW2lucHV0XSwgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZUNvbm5lY3Rpb25zU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgYXVkaW9Ob2RlUmVuZGVyZXIsIG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhY3RpdmVJbnB1dHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgYWN0aXZlSW5wdXRzLnB1c2gobmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb05vZGVDb25uZWN0aW9uc1N0b3JlLnNldChhdWRpb05vZGUsIHtcbiAgICAgICAgICAgIGFjdGl2ZUlucHV0cyxcbiAgICAgICAgICAgIG91dHB1dHM6IG5ldyBTZXQoKSxcbiAgICAgICAgICAgIHBhc3NpdmVJbnB1dHM6IG5ldyBXZWFrTWFwKCksXG4gICAgICAgICAgICByZW5kZXJlcjogYXVkaW9Ob2RlUmVuZGVyZXJcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gKGF1ZGlvUGFyYW1Db25uZWN0aW9uc1N0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb1BhcmFtLCBhdWRpb1BhcmFtUmVuZGVyZXIpID0+IHtcbiAgICAgICAgYXVkaW9QYXJhbUNvbm5lY3Rpb25zU3RvcmUuc2V0KGF1ZGlvUGFyYW0sIHsgYWN0aXZlSW5wdXRzOiBuZXcgU2V0KCksIHBhc3NpdmVJbnB1dHM6IG5ldyBXZWFrTWFwKCksIHJlbmRlcmVyOiBhdWRpb1BhcmFtUmVuZGVyZXIgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IEFDVElWRV9BVURJT19OT0RFX1NUT1JFID0gbmV3IFdlYWtTZXQoKTtcbmV4cG9ydCBjb25zdCBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBBVURJT19OT0RFX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQVVESU9fUEFSQU1fU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IENPTlRFWFRfU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IEVWRU5UX0xJU1RFTkVSUyA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQ1lDTEVfQ09VTlRFUlMgPSBuZXcgV2Vha01hcCgpO1xuLy8gVGhpcyBjbHVua3kgbmFtZSBpcyBib3Jyb3dlZCBmcm9tIHRoZSBzcGVjLiA6LSlcbmV4cG9ydCBjb25zdCBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IE5PREVfVE9fUFJPQ0VTU09SX01BUFMgPSBuZXcgV2Vha01hcCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2xvYmFscy5qcy5tYXAiLCJjb25zdCBoYW5kbGVyID0ge1xuICAgIGNvbnN0cnVjdCgpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXI7XG4gICAgfVxufTtcbmV4cG9ydCBjb25zdCBpc0NvbnN0cnVjdGlibGUgPSAoY29uc3RydWN0aWJsZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KGNvbnN0cnVjdGlibGUsIGhhbmRsZXIpO1xuICAgICAgICBuZXcgcHJveHkoKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtY29uc3RydWN0aWJsZS5qcy5tYXAiLCIvKlxuICogVGhpcyBtYXNzaXZlIHJlZ2V4IHRyaWVzIHRvIGNvdmVyIGFsbCB0aGUgZm9sbG93aW5nIGNhc2VzLlxuICpcbiAqIGltcG9ydCAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgeyBuYW1lZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgeyBuYW1lZEltcG9ydCBhcyByZW5hbWVuZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgKiBhcyBuYW1lc3BhY2VJbXBvcnQgZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCB7IG5hbWVkSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCB7IG5hbWVkSW1wb3J0IGFzIHJlbmFtZW5kSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCAqIGFzIG5hbWVzcGFjZUltcG9ydCBmcm9tICcuL3BhdGgnO1xuICovXG5jb25zdCBJTVBPUlRfU1RBVEVNRU5UX1JFR0VYID0gL15pbXBvcnQoPzooPzpbXFxzXStbXFx3XSt8KD86W1xcc10rW1xcd10rW1xcc10qLCk/W1xcc10qXFx7W1xcc10qW1xcd10rKD86W1xcc10rYXNbXFxzXStbXFx3XSspPyg/OltcXHNdKixbXFxzXSpbXFx3XSsoPzpbXFxzXSthc1tcXHNdK1tcXHddKyk/KSpbXFxzXSp9fCg/OltcXHNdK1tcXHddK1tcXHNdKiwpP1tcXHNdKlxcKltcXHNdK2FzW1xcc10rW1xcd10rKVtcXHNdK2Zyb20pPyg/OltcXHNdKikoXCIoW15cIlxcXFxdfFxcXFwuKStcInwnKFteJ1xcXFxdfFxcXFwuKSsnKSg/OltcXHNdKik7Py87IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG5leHBvcnQgY29uc3Qgc3BsaXRJbXBvcnRTdGF0ZW1lbnRzID0gKHNvdXJjZSwgdXJsKSA9PiB7XG4gICAgY29uc3QgaW1wb3J0U3RhdGVtZW50cyA9IFtdO1xuICAgIGxldCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyA9IHNvdXJjZS5yZXBsYWNlKC9eW1xcc10rLywgJycpO1xuICAgIGxldCByZXN1bHQgPSBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cy5tYXRjaChJTVBPUlRfU1RBVEVNRU5UX1JFR0VYKTtcbiAgICB3aGlsZSAocmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHVucmVzb2x2ZWRVcmwgPSByZXN1bHRbMV0uc2xpY2UoMSwgLTEpO1xuICAgICAgICBjb25zdCBpbXBvcnRTdGF0ZW1lbnRXaXRoUmVzb2x2ZWRVcmwgPSByZXN1bHRbMF1cbiAgICAgICAgICAgIC5yZXBsYWNlKC8oW1xcc10rKT87PyQvLCAnJylcbiAgICAgICAgICAgIC5yZXBsYWNlKHVucmVzb2x2ZWRVcmwsIG5ldyBVUkwodW5yZXNvbHZlZFVybCwgdXJsKS50b1N0cmluZygpKTtcbiAgICAgICAgaW1wb3J0U3RhdGVtZW50cy5wdXNoKGltcG9ydFN0YXRlbWVudFdpdGhSZXNvbHZlZFVybCk7XG4gICAgICAgIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMuc2xpY2UocmVzdWx0WzBdLmxlbmd0aCkucmVwbGFjZSgvXltcXHNdKy8sICcnKTtcbiAgICAgICAgcmVzdWx0ID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMubWF0Y2goSU1QT1JUX1NUQVRFTUVOVF9SRUdFWCk7XG4gICAgfVxuICAgIHJldHVybiBbaW1wb3J0U3RhdGVtZW50cy5qb2luKCc7JyksIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzXTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zcGxpdC1pbXBvcnQtc3RhdGVtZW50cy5qcy5tYXAiLCJpbXBvcnQgeyBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGlzQ29uc3RydWN0aWJsZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtY29uc3RydWN0aWJsZSc7XG5pbXBvcnQgeyBzcGxpdEltcG9ydFN0YXRlbWVudHMgfSBmcm9tICcuLi9oZWxwZXJzL3NwbGl0LWltcG9ydC1zdGF0ZW1lbnRzJztcbmNvbnN0IHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzID0gKHBhcmFtZXRlckRlc2NyaXB0b3JzKSA9PiB7XG4gICAgaWYgKHBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkocGFyYW1ldGVyRGVzY3JpcHRvcnMpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBwYXJhbWV0ZXJEZXNjcmlwdG9ycyBwcm9wZXJ0eSBvZiBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBpcyBub3QgYW4gYXJyYXkuJyk7XG4gICAgfVxufTtcbmNvbnN0IHZlcmlmeVByb2Nlc3NvckN0b3IgPSAocHJvY2Vzc29yQ3RvcikgPT4ge1xuICAgIGlmICghaXNDb25zdHJ1Y3RpYmxlKHByb2Nlc3NvckN0b3IpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBzaG91bGQgYmUgYSBjb25zdHJ1Y3Rvci4nKTtcbiAgICB9XG4gICAgaWYgKHByb2Nlc3NvckN0b3IucHJvdG90eXBlID09PSBudWxsIHx8IHR5cGVvZiBwcm9jZXNzb3JDdG9yLnByb3RvdHlwZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGdpdmVuIHZhbHVlIGZvciBwcm9jZXNzb3JDdG9yIHNob3VsZCBoYXZlIGEgcHJvdG90eXBlLicpO1xuICAgIH1cbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGV2YWx1YXRlU291cmNlLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZmV0Y2hTb3VyY2UsIGdldE5hdGl2ZUNvbnRleHQsIGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG9uZ29pbmdSZXF1ZXN0cywgcmVzb2x2ZWRSZXF1ZXN0cywgdGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCwgd2luZG93KSA9PiB7XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICByZXR1cm4gKGNvbnRleHQsIG1vZHVsZVVSTCwgb3B0aW9ucyA9IHsgY3JlZGVudGlhbHM6ICdvbWl0JyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPSByZXNvbHZlZFJlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgIT09IHVuZGVmaW5lZCAmJiByZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0Lmhhcyhtb2R1bGVVUkwpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID0gb25nb2luZ1JlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdCA9IG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dC5nZXQobW9kdWxlVVJMKTtcbiAgICAgICAgICAgIGlmIChwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VPZk9uZ29pbmdSZXF1ZXN0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAvLyBCdWcgIzU5OiBTYWZhcmkgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBhdWRpb1dvcmtsZXQgcHJvcGVydHkuXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuYXRpdmVDb250ZXh0LmF1ZGlvV29ya2xldCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IGZldGNoU291cmNlKG1vZHVsZVVSTClcbiAgICAgICAgICAgICAgICAudGhlbigoW3NvdXJjZSwgYWJzb2x1dGVVcmxdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgW2ltcG9ydFN0YXRlbWVudHMsIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzXSA9IHNwbGl0SW1wb3J0U3RhdGVtZW50cyhzb3VyY2UsIGFic29sdXRlVXJsKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93OlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiAkeyBpbXBvcnRTdGF0ZW1lbnRzIH07XG4gICAgICAgICAgICAgICAgICogKChhLCBiKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgIChhW2JdID0gYVtiXSB8fCBbIF0pLnB1c2goXG4gICAgICAgICAgICAgICAgICogICAgICAgICAoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLCBnbG9iYWwsIHJlZ2lzdGVyUHJvY2Vzc29yLCBzYW1wbGVSYXRlLCBzZWxmLCB3aW5kb3cpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAkeyBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyB9XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9XG4gICAgICAgICAgICAgICAgICogICAgICk7XG4gICAgICAgICAgICAgICAgICogfSkod2luZG93LCAnX0FXR1MnKTtcbiAgICAgICAgICAgICAgICAgKiBgYGBcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4gICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFNvdXJjZSA9IGAke2ltcG9ydFN0YXRlbWVudHN9OygoYSxiKT0+eyhhW2JdPWFbYl18fFtdKS5wdXNoKChBdWRpb1dvcmtsZXRQcm9jZXNzb3IsZ2xvYmFsLHJlZ2lzdGVyUHJvY2Vzc29yLHNhbXBsZVJhdGUsc2VsZix3aW5kb3cpPT57JHtzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c31cbn0pfSkod2luZG93LCdfQVdHUycpYDtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBFdmFsdWF0aW5nIHRoZSBnaXZlbiBzb3VyY2UgY29kZSBpcyBhIHBvc3NpYmxlIHNlY3VyaXR5IHByb2JsZW0uXG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2YWx1YXRlU291cmNlKHdyYXBwZWRTb3VyY2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZhbHVhdGVBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSA9IHdpbmRvdy5fQVdHUy5wb3AoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZhbHVhdGVBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShuYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lLCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsICgpID0+IGV2YWx1YXRlQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUoY2xhc3MgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHtcbiAgICAgICAgICAgICAgICB9LCB1bmRlZmluZWQsIChuYW1lLCBwcm9jZXNzb3JDdG9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID0gTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlQcm9jZXNzb3JDdG9yKHByb2Nlc3NvckN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UGFyYW1ldGVyRGVzY3JpcHRvcnMocHJvY2Vzc29yQ3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAuc2V0KG5hbWUsIHByb2Nlc3NvckN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UHJvY2Vzc29yQ3Rvcihwcm9jZXNzb3JDdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzKHByb2Nlc3NvckN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLnNldChuYXRpdmVDb250ZXh0LCBuZXcgTWFwKFtbbmFtZSwgcHJvY2Vzc29yQ3Rvcl1dKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgOiBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgZmV0Y2hTb3VyY2UobW9kdWxlVVJMKSxcbiAgICAgICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQsIHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQpKVxuICAgICAgICAgICAgXSkudGhlbigoW1tzb3VyY2UsIGFic29sdXRlVXJsXSwgaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2VdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gaW5kZXggKyAxO1xuICAgICAgICAgICAgICAgIGluZGV4ID0gY3VycmVudEluZGV4O1xuICAgICAgICAgICAgICAgIGNvbnN0IFtpbXBvcnRTdGF0ZW1lbnRzLCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c10gPSBzcGxpdEltcG9ydFN0YXRlbWVudHMoc291cmNlLCBhYnNvbHV0ZVVybCk7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93LlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiBjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgX19idWZmZXJzID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UgPSAoKHBvc3RNZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgcmV0dXJuIChtZXNzYWdlLCB0cmFuc2ZlcmFibGVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkVHJhbnNmZXJhYmxlcyA9ICh0cmFuc2ZlcmFibGVzKVxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgPyB0cmFuc2ZlcmFibGVzLmZpbHRlcigodHJhbnNmZXJhYmxlKSA9PiAhdGhpcy5fX2J1ZmZlcnMuaGFzKHRyYW5zZmVyYWJsZSkpXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgICAgICA6IHRyYW5zZmVyYWJsZXM7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHBvc3RNZXNzYWdlLmNhbGwodGhpcy5wb3J0LCBtZXNzYWdlLCBmaWx0ZXJlZFRyYW5zZmVyYWJsZXMpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgfSkodGhpcy5wb3J0LnBvc3RNZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgfVxuICAgICAgICAgICAgICAgICAqIH1cbiAgICAgICAgICAgICAgICAgKiBgYGBcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkQXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgPyAnQXVkaW9Xb3JrbGV0UHJvY2Vzc29yJ1xuICAgICAgICAgICAgICAgICAgICA6ICdjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7X19iPW5ldyBXZWFrU2V0KCk7Y29uc3RydWN0b3IoKXtzdXBlcigpOyhwPT5wLnBvc3RNZXNzYWdlPShxPT4obSx0KT0+cS5jYWxsKHAsbSx0P3QuZmlsdGVyKHU9PiF0aGlzLl9fYi5oYXModSkpOnQpKShwLnBvc3RNZXNzYWdlKSkodGhpcy5wb3J0KX19JztcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTcwOiBDaHJvbWUgYW5kIEVkZ2UgZG8gY2FsbCBwcm9jZXNzKCkgd2l0aCBhbiBhcnJheSB3aXRoIGVtcHR5IGNoYW5uZWxEYXRhIGZvciBlYWNoIGlucHV0IGlmIG5vIGlucHV0IGlzIGNvbm5lY3RlZC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTc5OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRvIHRyYW5zZmVyIGFueSBidWZmZXIgd2hpY2ggaGFzIGJlZW4gcGFzc2VkIHRvIHRoZSBwcm9jZXNzKCkgbWV0aG9kIGFzIGFuIGFyZ3VtZW50LlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogQnVnICMxOTA6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIGVycm9yIHdoZW4gbG9hZGluZyBhbiB1bnBhcnNhYmxlIG1vZHVsZS5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93OlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiBgJHsgaW1wb3J0U3RhdGVtZW50cyB9O1xuICAgICAgICAgICAgICAgICAqICgoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLCByZWdpc3RlclByb2Nlc3NvcikgPT4geyR7IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzIH1cbiAgICAgICAgICAgICAgICAgKiB9KShcbiAgICAgICAgICAgICAgICAgKiAgICAgJHvCoHBhdGNoZWRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgfSxcbiAgICAgICAgICAgICAgICAgKiAgICAgKG5hbWUsIHByb2Nlc3NvckN0b3IpID0+IHJlZ2lzdGVyUHJvY2Vzc29yKG5hbWUsIGNsYXNzIGV4dGVuZHMgcHJvY2Vzc29yQ3RvciB7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIF9fY29sbGVjdEJ1ZmZlcnMgPSAoYXJyYXkpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICBhcnJheS5mb3JFYWNoKChlbGVtZW50KSA9PiB0aGlzLl9fYnVmZmVycy5hZGQoZWxlbWVudC5idWZmZXIpKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHByb2Nlc3MgKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIGlucHV0cy5mb3JFYWNoKHRoaXMuX19jb2xsZWN0QnVmZmVycyk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgb3V0cHV0cy5mb3JFYWNoKHRoaXMuX19jb2xsZWN0QnVmZmVycyk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgdGhpcy5fX2NvbGxlY3RCdWZmZXJzKE9iamVjdC52YWx1ZXMocGFyYW1ldGVycykpO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnByb2Nlc3MoXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIChpbnB1dHMubWFwKChpbnB1dCkgPT4gaW5wdXQuc29tZSgoY2hhbm5lbERhdGEpID0+IGNoYW5uZWxEYXRhLmxlbmd0aCA9PT0gMCkpID8gWyBdIDogaW5wdXQpLFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBvdXRwdXRzLFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICB9KVxuICAgICAgICAgICAgICAgICAqICk7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiByZWdpc3RlclByb2Nlc3NvcihgX19zYWMke2N1cnJlbnRJbmRleH1gLCBjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvcntcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICBwcm9jZXNzICgpIHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgKiAgICAgfVxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogfSlgXG4gICAgICAgICAgICAgICAgICogYGBgXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyRGVmaW5pdGlvbiA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlID8gJycgOiAnX19jID0gKGEpID0+IGEuZm9yRWFjaChlPT50aGlzLl9fYi5hZGQoZS5idWZmZXIpKTsnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclJlZ2lzdHJhdGlvbiA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgID8gJydcbiAgICAgICAgICAgICAgICAgICAgOiAnaS5mb3JFYWNoKHRoaXMuX19jKTtvLmZvckVhY2godGhpcy5fX2MpO3RoaXMuX19jKE9iamVjdC52YWx1ZXMocCkpOyc7XG4gICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFNvdXJjZSA9IGAke2ltcG9ydFN0YXRlbWVudHN9OygoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLHJlZ2lzdGVyUHJvY2Vzc29yKT0+eyR7c291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHN9XG59KSgke3BhdGNoZWRBdWRpb1dvcmtsZXRQcm9jZXNzb3J9LChuLHApPT5yZWdpc3RlclByb2Nlc3NvcihuLGNsYXNzIGV4dGVuZHMgcHske21lbWJlckRlZmluaXRpb259cHJvY2VzcyhpLG8scCl7JHtidWZmZXJSZWdpc3RyYXRpb259cmV0dXJuIHN1cGVyLnByb2Nlc3MoaS5tYXAoaj0+ai5zb21lKGs9PmsubGVuZ3RoPT09MCk/W106aiksbyxwKX19KSk7cmVnaXN0ZXJQcm9jZXNzb3IoJ19fc2FjJHtjdXJyZW50SW5kZXh9JyxjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3Nvcntwcm9jZXNzKCl7cmV0dXJuICExfX0pYDtcbiAgICAgICAgICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3dyYXBwZWRTb3VyY2VdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04JyB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb250ZXh0LmF1ZGlvV29ya2xldFxuICAgICAgICAgICAgICAgICAgICAuYWRkTW9kdWxlKHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE4NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCBhbGxvdyB0byBjcmVhdGUgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBvbiBhIGNsb3NlZCBBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LmF1ZGlvV29ya2xldC5hZGRNb2R1bGUodXJsLCBvcHRpb25zKS50aGVuKCgpID0+IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE5MDogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBsb2FkaW5nIGFuIHVucGFyc2FibGUgbW9kdWxlLlxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBgX19zYWMke2N1cnJlbnRJbmRleH1gKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAob25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9uZ29pbmdSZXF1ZXN0cy5zZXQoY29udGV4dCwgbmV3IE1hcChbW21vZHVsZVVSTCwgcHJvbWlzZV1dKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQuc2V0KG1vZHVsZVVSTCwgcHJvbWlzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvbWlzZVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPSByZXNvbHZlZFJlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkUmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWRSZXF1ZXN0cy5zZXQoY29udGV4dCwgbmV3IFNldChbbW9kdWxlVVJMXSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQuYWRkKG1vZHVsZVVSTCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgICAgICAuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID0gb25nb2luZ1JlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0LmRlbGV0ZShtb2R1bGVVUkwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8td29ya2xldC1tb2R1bGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGdldFZhbHVlRm9yS2V5ID0gKG1hcCwga2V5KSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBtYXAuZ2V0KGtleSk7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIHZhbHVlIHdpdGggdGhlIGdpdmVuIGtleSBjb3VsZCBub3QgYmUgZm91bmQuJyk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtdmFsdWUtZm9yLWtleS5qcy5tYXAiLCJleHBvcnQgY29uc3QgcGlja0VsZW1lbnRGcm9tU2V0ID0gKHNldCwgcHJlZGljYXRlKSA9PiB7XG4gICAgY29uc3QgbWF0Y2hpbmdFbGVtZW50cyA9IEFycmF5LmZyb20oc2V0KS5maWx0ZXIocHJlZGljYXRlKTtcbiAgICBpZiAobWF0Y2hpbmdFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdNb3JlIHRoYW4gb25lIGVsZW1lbnQgd2FzIGZvdW5kLicpO1xuICAgIH1cbiAgICBpZiAobWF0Y2hpbmdFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ05vIGVsZW1lbnQgd2FzIGZvdW5kLicpO1xuICAgIH1cbiAgICBjb25zdCBbbWF0Y2hpbmdFbGVtZW50XSA9IG1hdGNoaW5nRWxlbWVudHM7XG4gICAgc2V0LmRlbGV0ZShtYXRjaGluZ0VsZW1lbnQpO1xuICAgIHJldHVybiBtYXRjaGluZ0VsZW1lbnQ7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGljay1lbGVtZW50LWZyb20tc2V0LmpzLm1hcCIsImltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5pbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5leHBvcnQgY29uc3QgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gZ2V0VmFsdWVGb3JLZXkocGFzc2l2ZUlucHV0cywgc291cmNlKTtcbiAgICBjb25zdCBtYXRjaGluZ0Nvbm5lY3Rpb24gPSBwaWNrRWxlbWVudEZyb21TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQgJiYgcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gaW5wdXQpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuZGVsZXRlKHNvdXJjZSk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGluZ0Nvbm5lY3Rpb247XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEVWRU5UX0xJU1RFTkVSUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShFVkVOVF9MSVNURU5FUlMsIGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFDVElWRV9BVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICBpZiAoQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgQXVkaW9Ob2RlIGlzIGFscmVhZHkgc3RvcmVkLicpO1xuICAgIH1cbiAgICBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5hZGQoYXVkaW9Ob2RlKTtcbiAgICBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSkuZm9yRWFjaCgoZXZlbnRMaXN0ZW5lcikgPT4gZXZlbnRMaXN0ZW5lcih0cnVlKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNBdWRpb1dvcmtsZXROb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAncG9ydCcgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLXdvcmtsZXQtbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIGlmICghQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgQXVkaW9Ob2RlIGlzIG5vdCBzdG9yZWQuJyk7XG4gICAgfVxuICAgIEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmRlbGV0ZShhdWRpb05vZGUpO1xuICAgIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoYXVkaW9Ob2RlKS5mb3JFYWNoKChldmVudExpc3RlbmVyKSA9PiBldmVudExpc3RlbmVyKGZhbHNlKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG4vLyBTZXQgdGhlIGludGVybmFsU3RhdGUgb2YgdGhlIGF1ZGlvTm9kZSB0byAncGFzc2l2ZScgaWYgaXQgaXMgbm90IGFuIEF1ZGlvV29ya2xldE5vZGUgYW5kIGlmIGl0IGhhcyBubyAnYWN0aXZlJyBpbnB1dCBjb25uZWN0aW9ucy5cbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeSA9IChhdWRpb05vZGUsIGFjdGl2ZUlucHV0cykgPT4ge1xuICAgIGlmICghaXNBdWRpb1dvcmtsZXROb2RlKGF1ZGlvTm9kZSkgJiYgYWN0aXZlSW5wdXRzLmV2ZXJ5KChjb25uZWN0aW9ucykgPT4gY29ubmVjdGlvbnMuc2l6ZSA9PT0gMCkpIHtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZShhdWRpb05vZGUpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeS5qcy5tYXAiLCJpbXBvcnQgeyBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBZGRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAoYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRBdWRpb05vZGVUYWlsVGltZSwgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBpbnNlcnRFbGVtZW50SW5TZXQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc1BhcnRPZkFDeWNsZSwgaXNQYXNzaXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgdGFpbFRpbWVUaW1lb3V0SWRzID0gbmV3IFdlYWtNYXAoKTtcbiAgICByZXR1cm4gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQsIGlzT2ZmbGluZSkgPT4ge1xuICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShzb3VyY2UpO1xuICAgICAgICBjb25zdCBldmVudExpc3RlbmVyID0gKGlzQWN0aXZlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNQYXNzaXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBpbnB1dCwgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdGFpbFRpbWUgPSBnZXRBdWRpb05vZGVUYWlsVGltZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgaWYgKHRhaWxUaW1lID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5KGRlc3RpbmF0aW9uLCBhY3RpdmVJbnB1dHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YWlsVGltZVRpbWVvdXRJZCA9IHRhaWxUaW1lVGltZW91dElkcy5nZXQoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGFpbFRpbWVUaW1lb3V0SWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRhaWxUaW1lVGltZW91dElkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0YWlsVGltZVRpbWVvdXRJZHMuc2V0KGRlc3RpbmF0aW9uLCBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgdGFpbFRpbWUgKiAxMDAwKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoaW5zZXJ0RWxlbWVudEluU2V0KG91dHB1dHMsIFtkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dF0sIChvdXRwdXRDb25uZWN0aW9uKSA9PiBvdXRwdXRDb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQgJiYgb3V0cHV0Q29ubmVjdGlvblsyXSA9PT0gaW5wdXQsIHRydWUpKSB7XG4gICAgICAgICAgICBldmVudExpc3RlbmVycy5hZGQoZXZlbnRMaXN0ZW5lcik7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIGlucHV0LCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChpbnNlcnRFbGVtZW50SW5TZXQpID0+IHtcbiAgICByZXR1cm4gKHBhc3NpdmVJbnB1dHMsIGlucHV0LCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gcGFzc2l2ZUlucHV0cy5nZXQoc291cmNlKTtcbiAgICAgICAgaWYgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBhc3NpdmVJbnB1dHMuc2V0KHNvdXJjZSwgbmV3IFNldChbW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdXSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQgJiYgcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gaW5wdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFNpbGVudENvbm5lY3Rpb24gPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdCA9ICgpID0+IHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIGRpc2Nvbm5lY3QpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmRpc2Nvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB9O1xuICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1zaWxlbnQtY29ubmVjdGlvbi5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSAoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBhdWRpb1dvcmtsZXROb2RlKSA9PiB7XG4gICAgICAgIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVDb250ZXh0KS5hZGQoYXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZmZ0U2l6ZTogMjA0OCxcbiAgICBtYXhEZWNpYmVsczogLTMwLFxuICAgIG1pbkRlY2liZWxzOiAtMTAwLFxuICAgIHNtb290aGluZ1RpbWVDb25zdGFudDogMC44XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvbk5vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBbmFseXNlck5vZGUgZXh0ZW5kcyBhdWRpb25Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgYW5hbHlzZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQW5hbHlzZXJOb2RlLCBhbmFseXNlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUgPSBuYXRpdmVBbmFseXNlck5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZmdFNpemUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGZmdFNpemUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZyZXF1ZW5jeUJpbkNvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4RGVjaWJlbHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzO1xuICAgICAgICB9XG4gICAgICAgIHNldCBtYXhEZWNpYmVscyh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxMTg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiBtYXhEZWNpYmVscyBpcyBub3QgbW9yZSB0aGFuIG1pbkRlY2liZWxzLlxuICAgICAgICAgICAgY29uc3QgbWF4RGVjaWJlbHMgPSB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHM7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICghKHZhbHVlID4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyA9IG1heERlY2liZWxzO1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1pbkRlY2liZWxzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscztcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWluRGVjaWJlbHModmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgICAgIGNvbnN0IG1pbkRlY2liZWxzID0gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAoISh0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPiB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHMgPSBtaW5EZWNpYmVscztcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBzbW9vdGhpbmdUaW1lQ29uc3RhbnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLnNtb290aGluZ1RpbWVDb25zdGFudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgc21vb3RoaW5nVGltZUNvbnN0YW50KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0Qnl0ZUZyZXF1ZW5jeURhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRCeXRlRnJlcXVlbmN5RGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGbG9hdEZyZXF1ZW5jeURhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdEZyZXF1ZW5jeURhdGEoYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIGdldEZsb2F0VGltZURvbWFpbkRhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5hbHlzZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNPd25lZEJ5Q29udGV4dCA9IChuYXRpdmVBdWRpb05vZGUsIG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlLmNvbnRleHQgPT09IG5hdGl2ZUNvbnRleHQ7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtb3duZWQtYnktY29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQW5hbHlzZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQW5hbHlzZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBbmFseXNlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBbmFseXNlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBbmFseXNlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBbmFseXNlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBmZnRTaXplOiBuYXRpdmVBbmFseXNlck5vZGUuZmZ0U2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF4RGVjaWJlbHM6IG5hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyxcbiAgICAgICAgICAgICAgICAgICAgbWluRGVjaWJlbHM6IG5hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscyxcbiAgICAgICAgICAgICAgICAgICAgc21vb3RoaW5nVGltZUNvbnN0YW50OiBuYXRpdmVBbmFseXNlck5vZGUuc21vb3RoaW5nVGltZUNvbnN0YW50XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBbmFseXNlck5vZGUgPSBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBbmFseXNlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSA9IHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBbmFseXNlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5hbHlzZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQgPSAobmF0aXZlQXVkaW9CdWZmZXIpID0+IHtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKG5ldyBGbG9hdDMyQXJyYXkoMSksIDAsIC0xKTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW5kZXhTaXplRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnSW5kZXhTaXplRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LXNpemUtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW5kZXhTaXplRXJyb3IgfSBmcm9tICcuLi9mYWN0b3JpZXMvaW5kZXgtc2l6ZS1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgPSAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSA9ICgoZ2V0Q2hhbm5lbERhdGEpID0+IHtcbiAgICAgICAgcmV0dXJuIChjaGFubmVsKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsRGF0YS5jYWxsKGF1ZGlvQnVmZmVyLCBjaGFubmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBudW1iZXJPZkNoYW5uZWxzOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSAoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCB0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpID0+IHtcbiAgICBsZXQgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG51bGw7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvQnVmZmVyIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9ID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoMSwgMSwgNDQxMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjOTk6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBOb3RTdXBwb3J0ZWRFcnJvciB3aGVuIHRoZSBudW1iZXJPZkNoYW5uZWxzIGlzIHplcm8uIEJ1dCBpdCBvbmx5IGRvZXMgaXQgd2hlbiB1c2luZyB0aGVcbiAgICAgICAgICAgICAqIGZhY3RvcnkgZnVuY3Rpb24uIEJ1dCBzaW5jZSBGaXJlZm94IGFsc28gc3VwcG9ydHMgdGhlIGNvbnN0cnVjdG9yIGV2ZXJ5dGhpbmcgc2hvdWxkIGJlIGZpbmUuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIGNhY2hlVGVzdFJlc3VsdCh0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQsIHRlc3ROYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydClcbiAgICAgICAgICAgICAgICA/IG5ldyBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0pXG4gICAgICAgICAgICAgICAgOiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgLy8gQnVnICM5OTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gdGhlIG51bWJlck9mQ2hhbm5lbHMgaXMgemVyby5cbiAgICAgICAgICAgIGlmIChhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTAwOiBTYWZhcmkgZG9lcyB0aHJvdyBhIHdyb25nIGVycm9yIHdoZW4gY2FsbGluZyBnZXRDaGFubmVsRGF0YSgpIHdpdGggYW4gb3V0LW9mLWJvdW5kcyB2YWx1ZS5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNTc6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdGhlIGJ1ZmZlck9mZnNldCB0byBiZSBvdXQtb2YtYm91bmRzLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIFRoaXMgZG9lcyB2aW9sYXRlIGFsbCBnb29kIHByYXRpY2VzIGJ1dCBpdCBpcyBuZWNlc3NhcnkgdG8gYWxsb3cgdGhpcyBBdWRpb0J1ZmZlciB0byBiZSB1c2VkIHdpdGggbmF0aXZlXG4gICAgICAgICAgICAgKiAoT2ZmbGluZSlBdWRpb0NvbnRleHRzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGljIFtTeW1ib2wuaGFzSW5zdGFuY2VdKGluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gKChpbnN0YW5jZSAhPT0gbnVsbCAmJiB0eXBlb2YgaW5zdGFuY2UgPT09ICdvYmplY3QnICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnN0YW5jZSkgPT09IEF1ZGlvQnVmZmVyLnByb3RvdHlwZSkgfHxcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmhhcyhpbnN0YW5jZSkpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUID0gLTMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcbmV4cG9ydCBjb25zdCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCA9IC1NT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50cy5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzQWN0aXZlQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4gQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hY3RpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgYnVmZmVyOiBudWxsLFxuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgbG9vcDogZmFsc2UsXG4gICAgbG9vcEVuZDogMCxcbiAgICBsb29wU3RhcnQ6IDAsXG4gICAgcGxheWJhY2tSYXRlOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0J1ZmZlclNvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyID0gYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXI7XG4gICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJTZXQgPSBtZXJnZWRPcHRpb25zLmJ1ZmZlciAhPT0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBudWxsO1xuICAgICAgICAgICAgLy8gQnVnICM3MzogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHNldCBidWZmZXIodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSB2YWx1ZTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzI6IE9ubHkgQ2hyb21lICYgRWRnZSBkbyBub3QgYWxsb3cgdG8gcmVhc3NpZ24gdGhlIGJ1ZmZlciB5ZXQuXG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJTZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJTZXQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wO1xuICAgICAgICB9XG4gICAgICAgIHNldCBsb29wKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wRW5kO1xuICAgICAgICB9XG4gICAgICAgIHNldCBsb29wRW5kKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BTdGFydDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbG9vcFN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcFN0YXJ0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25lbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwLCBvZmZzZXQgPSAwLCBkdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KHdoZW4sIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIuc3RhcnQgPSBkdXJhdGlvbiA9PT0gdW5kZWZpbmVkID8gW3doZW4sIG9mZnNldF0gOiBbd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLnN0b3AgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgICBsZXQgc3RvcCA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgICAgIGxvb3A6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wLFxuICAgICAgICAgICAgICAgICAgICBsb29wRW5kOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcFN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KC4uLnN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHN0b3AgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3Aoc3RvcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wbGF5YmFja1JhdGUsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGxheWJhY2tSYXRlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNldCBzdGFydCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHN0b3AodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdG9wID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0F1ZGlvQnVmZmVyU291cmNlTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BsYXliYWNrUmF0ZScgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNCaXF1YWRGaWx0ZXJOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnZnJlcXVlbmN5JyBpbiBhdWRpb05vZGUgJiYgJ2dhaW4nIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQ29uc3RhbnRTb3VyY2VOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnb2Zmc2V0JyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQtc291cmNlLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzR2Fpbk5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICEoJ2ZyZXF1ZW5jeScgaW4gYXVkaW9Ob2RlKSAmJiAnZ2FpbicgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdhaW4tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNPc2NpbGxhdG9yTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ2RldHVuZScgaW4gYXVkaW9Ob2RlICYmICdmcmVxdWVuY3knIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vc2NpbGxhdG9yLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzU3RlcmVvUGFubmVyTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BhbicgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0ZXJlby1wYW5uZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFLCBhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IChhdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFLCBhdWRpb1BhcmFtKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGlzQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgaXNCaXF1YWRGaWx0ZXJOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2JpcXVhZC1maWx0ZXItbm9kZSc7XG5pbXBvcnQgeyBpc0NvbnN0YW50U291cmNlTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9jb25zdGFudC1zb3VyY2Utbm9kZSc7XG5pbXBvcnQgeyBpc0dhaW5Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2dhaW4tbm9kZSc7XG5pbXBvcnQgeyBpc09zY2lsbGF0b3JOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL29zY2lsbGF0b3Itbm9kZSc7XG5pbXBvcnQgeyBpc1N0ZXJlb1Bhbm5lck5vZGUgfSBmcm9tICcuLi9ndWFyZHMvc3RlcmVvLXBhbm5lci1ub2RlJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4vc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZSwgdHJhY2UpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICBhY3RpdmVJbnB1dHMuZm9yRWFjaCgoY29ubmVjdGlvbnMpID0+IGNvbm5lY3Rpb25zLmZvckVhY2goKFtzb3VyY2VdKSA9PiB7XG4gICAgICAgIGlmICghdHJhY2UuaW5jbHVkZXMoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoc291cmNlLCBbLi4udHJhY2UsIGF1ZGlvTm9kZV0pO1xuICAgICAgICB9XG4gICAgfSkpO1xuICAgIGNvbnN0IGF1ZGlvUGFyYW1zID0gaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICA/IFtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgYXVkaW9Ob2RlLnBsYXliYWNrUmF0ZVxuICAgICAgICBdXG4gICAgICAgIDogaXNBdWRpb1dvcmtsZXROb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgID8gQXJyYXkuZnJvbShhdWRpb05vZGUucGFyYW1ldGVycy52YWx1ZXMoKSlcbiAgICAgICAgICAgIDogaXNCaXF1YWRGaWx0ZXJOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUuUSwgYXVkaW9Ob2RlLmRldHVuZSwgYXVkaW9Ob2RlLmZyZXF1ZW5jeSwgYXVkaW9Ob2RlLmdhaW5dXG4gICAgICAgICAgICAgICAgOiBpc0NvbnN0YW50U291cmNlTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5vZmZzZXRdXG4gICAgICAgICAgICAgICAgICAgIDogaXNHYWluTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUuZ2Fpbl1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogaXNPc2NpbGxhdG9yTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLmRldHVuZSwgYXVkaW9Ob2RlLmZyZXF1ZW5jeV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGlzU3RlcmVvUGFubmVyTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5wYW5dXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogW107XG4gICAgZm9yIChjb25zdCBhdWRpb1BhcmFtIG9mIGF1ZGlvUGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgaWYgKGF1ZGlvUGFyYW1Db25uZWN0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBhdWRpb1BhcmFtQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzLmZvckVhY2goKFtzb3VyY2VdKSA9PiBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyhzb3VyY2UsIHRyYWNlKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZShhdWRpb05vZGUpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zIH0gZnJvbSAnLi9kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBkZWFjdGl2YXRlQXVkaW9HcmFwaCA9IChjb250ZXh0KSA9PiB7XG4gICAgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoY29udGV4dC5kZXN0aW5hdGlvbiwgW10pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlYWN0aXZhdGUtYXVkaW8tZ3JhcGguanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzVmFsaWRMYXRlbmN5SGludCA9IChsYXRlbmN5SGludCkgPT4ge1xuICAgIHJldHVybiAobGF0ZW5jeUhpbnQgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICB0eXBlb2YgbGF0ZW5jeUhpbnQgPT09ICdudW1iZXInIHx8XG4gICAgICAgICh0eXBlb2YgbGF0ZW5jeUhpbnQgPT09ICdzdHJpbmcnICYmIChsYXRlbmN5SGludCA9PT0gJ2JhbGFuY2VkJyB8fCBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJykpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy12YWxpZC1sYXRlbmN5LWhpbnQuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgaXNWYWxpZExhdGVuY3lIaW50IH0gZnJvbSAnLi4vaGVscGVycy9pcy12YWxpZC1sYXRlbmN5LWhpbnQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVVbmtub3duRXJyb3IsIG1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9Db250ZXh0IGV4dGVuZHMgYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTIgU2FmYXJpIGRvZXMgdGhyb3cgYSBTeW50YXhFcnJvciBpZiB0aGUgc2FtcGxlUmF0ZSBpcyBub3Qgc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIgJiYgZXJyLm1lc3NhZ2UgPT09ICdzYW1wbGVSYXRlIGlzIG5vdCBpbiByYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxMzEgU2FmYXJpIHJldHVybnMgbnVsbCB3aGVuIHRoZXJlIGFyZSBmb3VyIG90aGVyIEF1ZGlvQ29udGV4dHMgcnVubmluZyBhbHJlYWR5LlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVVua25vd25FcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM1MSBPbmx5IENocm9tZSBhbmQgRWRnZSB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gbGF0ZW5jeUhpbnQgaXMgaW52YWxpZC5cbiAgICAgICAgICAgIGlmICghaXNWYWxpZExhdGVuY3lIaW50KG9wdGlvbnMubGF0ZW5jeUhpbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHByb3ZpZGVkIHZhbHVlICcke29wdGlvbnMubGF0ZW5jeUhpbnR9JyBpcyBub3QgYSB2YWxpZCBlbnVtIHZhbHVlIG9mIHR5cGUgQXVkaW9Db250ZXh0TGF0ZW5jeUNhdGVnb3J5LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxNTAgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgc2V0dGluZyB0aGUgc2FtcGxlUmF0ZS5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNhbXBsZVJhdGUgIT09IHVuZGVmaW5lZCAmJiBuYXRpdmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSAhPT0gb3B0aW9ucy5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvQ29udGV4dCwgMik7XG4gICAgICAgICAgICBjb25zdCB7IGxhdGVuY3lIaW50IH0gPSBvcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgeyBzYW1wbGVSYXRlIH0gPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBAdG9kbyBUaGUgdmFsdWVzIGZvciAnYmFsYW5jZWQnLCAnaW50ZXJhY3RpdmUnIGFuZCAncGxheWJhY2snIGFyZSBqdXN0IGNvcGllZCBmcm9tIENocm9tZSdzIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgdGhpcy5fYmFzZUxhdGVuY3kgPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3kgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgICAgID8gbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5XG4gICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdiYWxhbmNlZCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gNTEyIC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAyNTYgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDEwMjQgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogLypcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBAdG9kbyBUaGUgbWluICgyNTYpIGFuZCBtYXggKDE2Mzg0KSB2YWx1ZXMgYXJlIHRha2VuIGZyb20gdGhlIGFsbG93ZWQgYnVmZmVyU2l6ZSB2YWx1ZXMgb2YgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFNjcmlwdFByb2Nlc3Nvck5vZGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWF0aC5tYXgoMiwgTWF0aC5taW4oMTI4LCBNYXRoLnJvdW5kKChsYXRlbmN5SGludCAqIHNhbXBsZVJhdGUpIC8gMTI4KSkpICogMTI4KSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQgPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBCdWcgIzE4ODogU2FmYXJpIHdpbGwgc2V0IHRoZSBjb250ZXh0J3Mgc3RhdGUgdG8gJ2ludGVycnVwdGVkJyBpbiBjYXNlIHRoZSB1c2VyIHN3aXRjaGVzIHRhYnMuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWUgPSAxZS0zNztcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5jb25uZWN0KHRoaXMuX25hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICMzNDogQ2hyb21lIGFuZCBFZGdlIHByZXRlbmQgdG8gYmUgcnVubmluZyByaWdodCBhd2F5LCBidXQgZmlyZSBhbiBvbnN0YXRlY2hhbmdlIGV2ZW50IHdoZW4gdGhlIHN0YXRlIGFjdHVhbGx5IGNoYW5nZXNcbiAgICAgICAgICAgICAqIHRvICdydW5uaW5nJy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAnc3VzcGVuZGVkJztcbiAgICAgICAgICAgICAgICBjb25zdCByZXZva2VTdGF0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgYmFzZUxhdGVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUxhdGVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlICE9PSBudWxsID8gdGhpcy5fc3RhdGUgOiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzM1OiBGaXJlZm94IGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBBdWRpb0NvbnRleHQgd2FzIGNsb3NlZCBiZWZvcmUuXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzM0OiBJZiB0aGUgc3RhdGUgd2FzIHNldCB0byBzdXNwZW5kZWQgYmVmb3JlIGl0IHNob3VsZCBiZSByZXZva2VkIG5vdy5cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUdhaW5Ob2RlICE9PSBudWxsICYmIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKG1lZGlhRWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1lZGlhRWxlbWVudCB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2UobWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1lZGlhU3RyZWFtIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tTb3VyY2UobWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtZWRpYVN0cmVhbVRyYWNrIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VtZSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlUHJvbWlzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJlc29sdmVQcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzdW1lKCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnJlc3VtZSgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU1OiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIGluc3RlYWQgb2YgYW4gSW52YWxpZFN0YXRlRXJyb3IuXG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NjogU2FmYXJpIGludm9rZXMgdGhlIGNhdGNoIGhhbmRsZXIgYnV0IHdpdGhvdXQgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkIHx8IGVyci5jb2RlID09PSAxNSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBzdXNwZW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdXNwZW5kKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgY2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlcihyZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gaXNPZmZsaW5lO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzUyOiBDaHJvbWUsIEVkZ2UgJiBTYWZhcmkgZG8gbm90IHRocm93IGFuIGV4Y2VwdGlvbiBhdCBhbGwuXG4gICAgICAgICAgICAvLyBCdWcgIzU0OiBGaXJlZm94IGRvZXMgdGhyb3cgYW4gSW5kZXhTaXplRXJyb3IuXG4gICAgICAgICAgICBpZiAodGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZG9lcyBub3QgaW5pdGlhbGl6ZSB0aGUgbWF4Q2hhbm5lbENvdW50IHByb3BlcnR5IGNvcnJlY3RseS5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzUzOiBObyBicm93c2VyIGRvZXMgdGhyb3cgYW4gZXhjZXB0aW9uIHlldC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9pc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtYXhDaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyID0gKHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgIGNvbnN0IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0xpc3RlbmVyRmFjdG9yeSA9IChjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZ2V0Rmlyc3RTYW1wbGUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChjb250ZXh0LCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUxpc3RlbmVyID0gbmF0aXZlQ29udGV4dC5saXN0ZW5lcjtcbiAgICAgICAgLy8gQnVnICMxMTc6IE9ubHkgQ2hyb21lICYgRWRnZSBzdXBwb3J0IHRoZSBuZXcgaW50ZXJmYWNlIGFscmVhZHkuXG4gICAgICAgIGNvbnN0IGNyZWF0ZUZha2VBdWRpb1BhcmFtcyA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoMSk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgbGV0IGlzU2NyaXB0UHJvY2Vzc29yTm9kZUNyZWF0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBsYXN0T3JpZW50YXRpb24gPSBbMCwgMCwgLTEsIDAsIDEsIDBdO1xuICAgICAgICAgICAgbGV0IGxhc3RQb3NpdGlvbiA9IFswLCAwLCAwXTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzU2NyaXB0UHJvY2Vzc29yTm9kZUNyZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpc1NjcmlwdFByb2Nlc3Nvck5vZGVDcmVhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCAyNTYsIDksIDApO1xuICAgICAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoeyBpbnB1dEJ1ZmZlciB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMyksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDUpXG4gICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0T3JpZW50YXRpb24oLi4ub3JpZW50YXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNiksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA3KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDgpXG4gICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdG9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RQb3NpdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVMaXN0ZW5lci5zZXRQb3NpdGlvbiguLi5wb3NpdG9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTZXRPcmllbnRhdGlvbiA9IChpbmRleCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbltpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0T3JpZW50YXRpb24oLi4ubGFzdE9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTZXRQb3NpdGlvbiA9IChpbmRleCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbltpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0UG9zaXRpb24oLi4ubGFzdFBvc2l0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVGYWtlQXVkaW9QYXJhbSA9IChpbnB1dCwgaW5pdGlhbFZhbHVlLCBzZXRWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGluaXRpYWxWYWx1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhpcyBzaG91bGQgYmUgc3RvcHBlZCB3aGVuIHRoZSBjb250ZXh0IGlzIGNsb3NlZC5cbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwgJ2RlZmF1bHRWYWx1ZScsIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICM2MiAmICM3NDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgQ29uc3RhbnRTb3VyY2VOb2RlcyBhbmQgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kXG4gICAgICAgICAgICAgICAgICogbWluVmFsdWUgZm9yIEdhaW5Ob2Rlcy5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBhdWRpb1BhcmFtID0gY3JlYXRlQXVkaW9QYXJhbSh7IGNvbnRleHQgfSwgaXNPZmZsaW5lLCBjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhhdWRpb1BhcmFtLCAndmFsdWUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChhdWRpb1BhcmFtKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQuY2FsbChhdWRpb1BhcmFtLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlICE9PSA5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxMTc6IFVzaW5nIHNldE9yaWVudGF0aW9uKCkgYW5kIHNldFBvc2l0aW9uKCkgZG9lc24ndCB3b3JrIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFZhbHVlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSA9ICgoY2FuY2VsQW5kSG9sZEF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjYW5jZWxBbmRIb2xkQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMgPSAoKGNhbmNlbFNjaGVkdWxlZFZhbHVlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSA9ICgoZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSA9ICgobGluZWFyUmFtcFRvVmFsdWVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUgPSAoKHNldFRhcmdldEF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRUYXJnZXRBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUgPSAoKHNldFZhbHVlQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHNldFZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSA9ICgoc2V0VmFsdWVDdXJ2ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRWYWx1ZUN1cnZlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmb3J3YXJkWDogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMCwgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oMCkpLFxuICAgICAgICAgICAgICAgIGZvcndhcmRZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgxLCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbigxKSksXG4gICAgICAgICAgICAgICAgZm9yd2FyZFo6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDIsIC0xLCBjcmVhdGVTZXRPcmllbnRhdGlvbigyKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25YOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg2LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigwKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg3LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigxKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25aOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg4LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigyKSksXG4gICAgICAgICAgICAgICAgdXBYOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgzLCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbigzKSksXG4gICAgICAgICAgICAgICAgdXBZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg0LCAxLCBjcmVhdGVTZXRPcmllbnRhdGlvbig0KSksXG4gICAgICAgICAgICAgICAgdXBaOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg1LCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbig1KSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgZm9yd2FyZFgsIGZvcndhcmRZLCBmb3J3YXJkWiwgcG9zaXRpb25YLCBwb3NpdGlvblksIHBvc2l0aW9uWiwgdXBYLCB1cFksIHVwWiB9ID0gbmF0aXZlTGlzdGVuZXIuZm9yd2FyZFggPT09IHVuZGVmaW5lZCA/IGNyZWF0ZUZha2VBdWRpb1BhcmFtcygpIDogbmF0aXZlTGlzdGVuZXI7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBnZXQgZm9yd2FyZFgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcndhcmRYO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBmb3J3YXJkWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZFk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGZvcndhcmRaKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3J3YXJkWjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25YKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25ZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgdXBYKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1cFg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHVwWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXBZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB1cFooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVwWjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWxpc3RlbmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZU9yQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAnY29udGV4dCcgaW4gYXVkaW9Ob2RlT3JBdWRpb1BhcmFtO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGUgfSBmcm9tICcuL2F1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiA9IChvdXRwdXRDb25uZWN0aW9uKSA9PiB7XG4gICAgcmV0dXJuIGlzQXVkaW9Ob2RlKG91dHB1dENvbm5lY3Rpb25bMF0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGluc2VydEVsZW1lbnRJblNldCA9IChzZXQsIGVsZW1lbnQsIHByZWRpY2F0ZSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgIGZvciAoY29uc3QgbG1udCBvZiBzZXQpIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZShsbW50KSkge1xuICAgICAgICAgICAgaWYgKGlnbm9yZUR1cGxpY2F0ZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignVGhlIHNldCBjb250YWlucyBhdCBsZWFzdCBvbmUgc2ltaWxhciBlbGVtZW50LicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldC5hZGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5zZXJ0LWVsZW1lbnQtaW4tc2V0LmpzLm1hcCIsImltcG9ydCB7IGluc2VydEVsZW1lbnRJblNldCB9IGZyb20gJy4vaW5zZXJ0LWVsZW1lbnQtaW4tc2V0JztcbmV4cG9ydCBjb25zdCBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgaW5zZXJ0RWxlbWVudEluU2V0KGFjdGl2ZUlucHV0cywgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5leHBvcnQgY29uc3QgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChwYXNzaXZlSW5wdXRzLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPSBwYXNzaXZlSW5wdXRzLmdldChzb3VyY2UpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuc2V0KHNvdXJjZSwgbmV3IFNldChbW291dHB1dCwgZXZlbnRMaXN0ZW5lcl1dKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNOYXRpdmVBdWRpb05vZGVGYWtlciA9IChuYXRpdmVBdWRpb05vZGVPck5hdGl2ZUF1ZGlvTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuICdpbnB1dHMnIGluIG5hdGl2ZUF1ZGlvTm9kZU9yTmF0aXZlQXVkaW9Ob2RlRmFrZXI7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXIuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5leHBvcnQgY29uc3QgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlID0gKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSkpIHtcbiAgICAgICAgY29uc3QgZmFrZU5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUuaW5wdXRzW2lucHV0XTtcbiAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QoZmFrZU5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIDApO1xuICAgICAgICByZXR1cm4gW2Zha2VOYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCAwXTtcbiAgICB9XG4gICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgIHJldHVybiBbbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXRdO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IChhY3RpdmVJbnB1dENvbm5lY3Rpb25zLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIGZvciAoY29uc3QgYWN0aXZlSW5wdXRDb25uZWN0aW9uIG9mIGFjdGl2ZUlucHV0Q29ubmVjdGlvbnMpIHtcbiAgICAgICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSB7XG4gICAgICAgICAgICBhY3RpdmVJbnB1dENvbm5lY3Rpb25zLmRlbGV0ZShhY3RpdmVJbnB1dENvbm5lY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuIGFjdGl2ZUlucHV0Q29ubmVjdGlvbjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24uanMubWFwIiwiaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KSA9PiB7XG4gICAgcmV0dXJuIHBpY2tFbGVtZW50RnJvbVNldChhY3RpdmVJbnB1dHMsIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUgPSAoYXVkaW9Ob2RlLCBldmVudExpc3RlbmVyKSA9PiB7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSk7XG4gICAgaWYgKCFldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnRMaXN0ZW5lcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBleHBlY3RlZCBldmVudCBsaXN0ZW5lci4nKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5pbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5leHBvcnQgY29uc3QgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gZ2V0VmFsdWVGb3JLZXkocGFzc2l2ZUlucHV0cywgc291cmNlKTtcbiAgICBjb25zdCBtYXRjaGluZ0Nvbm5lY3Rpb24gPSBwaWNrRWxlbWVudEZyb21TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuZGVsZXRlKHNvdXJjZSk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGluZ0Nvbm5lY3Rpb247XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmV4cG9ydCBjb25zdCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSA9IChuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUpKSB7XG4gICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLmlucHV0c1tpbnB1dF0sIG91dHB1dCwgMCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldE5hdGl2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoQVVESU9fTk9ERV9TVE9SRSwgYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fUEFSQU1fU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0TmF0aXZlQXVkaW9QYXJhbSA9IChhdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX1BBUkFNX1NUT1JFLCBhdWRpb1BhcmFtKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IENZQ0xFX0NPVU5URVJTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgaXNQYXJ0T2ZBQ3ljbGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIENZQ0xFX0NPVU5URVJTLmhhcyhhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXBhcnQtb2YtYS1jeWNsZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzUGFzc2l2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gIUFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXBhc3NpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2RTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIFRoaXMgYnVnIGV4aXN0ZWQgaW4gU2FmYXJpIHVwIHVudGlsIHYxNC4wLjIuIFNpbmNlIEF1ZGlvV29ya2xldHMgd2VyZSBub3Qgc3VwcG9ydGVkIGluIFNhZmFyaSB1bnRpbCB2MTQuMSB0aGUgcHJlc2VuY2Ugb2YgdGhlXG4gICAgICAgICAqIGNvbnN0cnVjdG9yIGZvciBhbiBBdWRpb1dvcmtsZXROb2RlIGNhbiBiZSB1c2VkIGhlcmUgdG8gc2tpcCB0aGUgdGVzdC5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhbmFseXplciA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoMjU2LCAxLCAxKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxuICAgICAgICAgICAgY29uc3QgZHVtbXkgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgLy8gQnVnICM5NTogU2FmYXJpIGRvZXMgbm90IHBsYXkgb25lIHNhbXBsZSBidWZmZXJzLlxuICAgICAgICAgICAgY29uc3Qgb25lcyA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMiwgNDQxMDApO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBvbmVzLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAgICAgY2hhbm5lbERhdGFbMF0gPSAxO1xuICAgICAgICAgICAgY2hhbm5lbERhdGFbMV0gPSAxO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICAgICAgc291cmNlLmJ1ZmZlciA9IG9uZXM7XG4gICAgICAgICAgICBzb3VyY2UubG9vcCA9IHRydWU7XG4gICAgICAgICAgICBzb3VyY2UuY29ubmVjdChhbmFseXplcikuY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgc291cmNlLmNvbm5lY3QoZHVtbXkpO1xuICAgICAgICAgICAgc291cmNlLmRpc2Nvbm5lY3QoZHVtbXkpO1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICBhbmFseXplci5vbmF1ZGlvcHJvY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNobm5sRHQgPSBldmVudC5pbnB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5wcm90b3R5cGUuc29tZS5jYWxsKGNobm5sRHQsIChzYW1wbGUpID0+IHNhbXBsZSA9PT0gMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGFuYWx5emVyLm9uYXVkaW9wcm9jZXNzID0gbnVsbDsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNjb25uZWN0KGFuYWx5emVyKTtcbiAgICAgICAgICAgICAgICBhbmFseXplci5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc291cmNlLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2Qtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZSA9IChjeWNsZXMsIHZpc2l0b3IpID0+IHtcbiAgICBjb25zdCBjb3VudHMgPSBuZXcgTWFwKCk7XG4gICAgZm9yIChjb25zdCBjeWNsZSBvZiBjeWNsZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBhdWRpb05vZGUgb2YgY3ljbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gY291bnRzLmdldChhdWRpb05vZGUpO1xuICAgICAgICAgICAgY291bnRzLnNldChhdWRpb05vZGUsIGNvdW50ID09PSB1bmRlZmluZWQgPyAxIDogY291bnQgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb3VudHMuZm9yRWFjaCgoY291bnQsIGF1ZGlvTm9kZSkgPT4gdmlzaXRvcihhdWRpb05vZGUsIGNvdW50KSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dmlzaXQtZWFjaC1hdWRpby1ub2RlLW9uY2UuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzTmF0aXZlQXVkaW9Ob2RlID0gKG5hdGl2ZUF1ZGlvTm9kZU9yQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAnY29udGV4dCcgaW4gbmF0aXZlQXVkaW9Ob2RlT3JBdWRpb1BhcmFtO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCB3cmFwQXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZCA9IChuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdCA9ICgoY29ubmVjdCkgPT4ge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6aW52YWxpZC12b2lkIG5vLWluZmVycmFibGUtdHlwZXNcbiAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSA/IGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpIDogY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0KTtcbiAgICAgICAgICAgIC8vIFNhdmUgdGhlIG5ldyBjb25uZWN0aW9uIG9ubHkgaWYgdGhlIGNhbGxzIHRvIGNvbm5lY3QgYWJvdmUgZGlkbid0IHRocm93IGFuIGVycm9yLlxuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID0gY29ubmVjdGlvbnMuZ2V0KGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIGlmIChjb25uZWN0aW9uc1RvRGVzdGluYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnNldChkZXN0aW5hdGlvbiwgW3sgaW5wdXQsIG91dHB1dCB9XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmV2ZXJ5KChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLmlucHV0ICE9PSBpbnB1dCB8fCBjb25uZWN0aW9uLm91dHB1dCAhPT0gb3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24ucHVzaCh7IGlucHV0LCBvdXRwdXQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0LmJpbmQobmF0aXZlQXVkaW9Ob2RlKSk7XG4gICAgbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QgPSAoKGRpc2Nvbm5lY3QpID0+IHtcbiAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgICAgICAgICBkaXNjb25uZWN0LmFwcGx5KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuY2xlYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2Rlc3RpbmF0aW9uLCBjb25uZWN0aW9uc1RvRGVzdGluYXRpb25dIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQ29ubmVjdGlvbnMgPSBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZmlsdGVyKChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLm91dHB1dCAhPT0gZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJlZENvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnNldChkZXN0aW5hdGlvbiwgZmlsdGVyZWRDb25uZWN0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25uZWN0aW9ucy5oYXMoZGVzdGluYXRpb25Pck91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID0gY29ubmVjdGlvbnMuZ2V0KGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQ29ubmVjdGlvbnMgPSBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZmlsdGVyKChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLm91dHB1dCAhPT0gb3V0cHV0ICYmIChjb25uZWN0aW9uLmlucHV0ICE9PSBpbnB1dCB8fCBpbnB1dCA9PT0gdW5kZWZpbmVkKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRDb25uZWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5zZXQoZGVzdGluYXRpb25Pck91dHB1dCwgZmlsdGVyZWRDb25uZWN0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtkZXN0aW5hdGlvbiwgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uXSBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5mb3JFYWNoKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KGRlc3RpbmF0aW9uLCBjb25uZWN0aW9uLm91dHB1dCwgY29ubmVjdGlvbi5pbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgY29ubmVjdGlvbi5vdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX1NUT1JFLCBFVkVOVF9MSVNURU5FUlMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvYWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGlzY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS1mcm9tLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuLi9oZWxwZXJzL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNQYXJ0T2ZBQ3ljbGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXBhcnQtb2YtYS1jeWNsZSc7XG5pbXBvcnQgeyBpc1Bhc3NpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXBhc3NpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5JztcbmltcG9ydCB7IHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZSB9IGZyb20gJy4uL2hlbHBlcnMvdmlzaXQtZWFjaC1hdWRpby1ub2RlLW9uY2UnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZCc7XG5jb25zdCBhZGRDb25uZWN0aW9uVG9BdWRpb1BhcmFtT2ZBdWRpb0NvbnRleHQgPSAoc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpc09mZmxpbmUpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lciA9IChpc0FjdGl2ZSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pO1xuICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgaWYgKGluc2VydEVsZW1lbnRJblNldChvdXRwdXRzLCBbZGVzdGluYXRpb24sIG91dHB1dF0sIChvdXRwdXRDb25uZWN0aW9uKSA9PiBvdXRwdXRDb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIHRydWUpKSB7XG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLmFkZChldmVudExpc3RlbmVyKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgW291dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbmNvbnN0IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9Ob2RlID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgIGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbihhY3RpdmVJbnB1dHNbaW5wdXRdLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgIHJldHVybiBbcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsyXSwgZmFsc2VdO1xuICAgIH1cbiAgICByZXR1cm4gW2FjdGl2ZUlucHV0Q29ubmVjdGlvblsyXSwgdHJ1ZV07XG59O1xuY29uc3QgZGVsZXRlSW5wdXRDb25uZWN0aW9uT2ZBdWRpb1BhcmFtID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzLCBwYXNzaXZlSW5wdXRzIH0gPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgIGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbihhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICBpZiAoYWN0aXZlSW5wdXRDb25uZWN0aW9uID09PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICAgICAgcmV0dXJuIFtwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzFdLCBmYWxzZV07XG4gICAgfVxuICAgIHJldHVybiBbYWN0aXZlSW5wdXRDb25uZWN0aW9uWzJdLCB0cnVlXTtcbn07XG5jb25zdCBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZSA9IChzb3VyY2UsIGlzT2ZmbGluZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCBbbGlzdGVuZXIsIGlzQWN0aXZlXSA9IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9Ob2RlKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpO1xuICAgIGlmIChsaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUoc291cmNlLCBsaXN0ZW5lcik7XG4gICAgICAgIGlmIChpc0FjdGl2ZSAmJiAhaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKSwgZ2V0TmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICB9XG59O1xuY29uc3QgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbiwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgW2xpc3RlbmVyLCBpc0FjdGl2ZV0gPSBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvUGFyYW0oc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0KTtcbiAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlKHNvdXJjZSwgbGlzdGVuZXIpO1xuICAgICAgICBpZiAoaXNBY3RpdmUgJiYgIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSkuZGlzY29ubmVjdChnZXROYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKSwgb3V0cHV0KTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5jb25zdCBkZWxldGVBbnlDb25uZWN0aW9uID0gKHNvdXJjZSwgaXNPZmZsaW5lKSA9PiB7XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZGVzdGluYXRpb25zID0gW107XG4gICAgZm9yIChjb25zdCBvdXRwdXRDb25uZWN0aW9uIG9mIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cykge1xuICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvUGFyYW0oc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGRlc3RpbmF0aW9ucy5wdXNoKG91dHB1dENvbm5lY3Rpb25bMF0pO1xuICAgIH1cbiAgICBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMuY2xlYXIoKTtcbiAgICByZXR1cm4gZGVzdGluYXRpb25zO1xufTtcbmNvbnN0IGRlbGV0ZUNvbm5lY3Rpb25BdE91dHB1dCA9IChzb3VyY2UsIGlzT2ZmbGluZSwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZGVzdGluYXRpb25zID0gW107XG4gICAgZm9yIChjb25zdCBvdXRwdXRDb25uZWN0aW9uIG9mIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cykge1xuICAgICAgICBpZiAob3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUoc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlc3RpbmF0aW9ucy5wdXNoKG91dHB1dENvbm5lY3Rpb25bMF0pO1xuICAgICAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmRlbGV0ZShvdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzdGluYXRpb25zO1xufTtcbmNvbnN0IGRlbGV0ZUNvbm5lY3Rpb25Ub0Rlc3RpbmF0aW9uID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2UgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cylcbiAgICAgICAgLmZpbHRlcigob3V0cHV0Q29ubmVjdGlvbikgPT4gb3V0cHV0Q29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiZcbiAgICAgICAgKG91dHB1dCA9PT0gdW5kZWZpbmVkIHx8IG91dHB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkgJiZcbiAgICAgICAgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgb3V0cHV0Q29ubmVjdGlvblsyXSA9PT0gaW5wdXQpKVxuICAgICAgICAubWFwKChvdXRwdXRDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0Q29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9Ob2RlKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmRlbGV0ZShvdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIG91dHB1dENvbm5lY3Rpb25bMF07XG4gICAgfSk7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZUNvbnN0cnVjdG9yID0gKGFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBhZGRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGVjcmVtZW50Q3ljbGVDb3VudGVyLCBkZXRlY3RDeWNsZXMsIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVBdWRpb1BhcmFtLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb05vZGUgZXh0ZW5kcyBldmVudFRhcmdldENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgaXNBY3RpdmUsIG5hdGl2ZUF1ZGlvTm9kZSwgYXVkaW9Ob2RlUmVuZGVyZXIpIHtcbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZSA9IG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxMjogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgdG8gZGlzY29ubmVjdCBhIHNwZWNpZmljIGRlc3RpbmF0aW9uLlxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpICYmXG4gICAgICAgICAgICAgICAgdHJ1ZSAhPT1cbiAgICAgICAgICAgICAgICAgICAgY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9KSkge1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kKG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBBVURJT19OT0RFX1NUT1JFLnNldCh0aGlzLCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgRVZFTlRfTElTVEVORVJTLnNldCh0aGlzLCBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgaWYgKGNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnICYmIGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnModGhpcywgYXVkaW9Ob2RlUmVuZGVyZXIsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgfVxuICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmludmFsaWQtdm9pZFxuICAgICAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXQgPSAwLCBpbnB1dCA9IDApIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTc0OiBTYWZhcmkgZG9lcyBleHBvc2UgYSB3cm9uZyBudW1iZXJPZk91dHB1dHMgZm9yIE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVzLlxuICAgICAgICAgICAgaWYgKG91dHB1dCA8IDAgfHwgb3V0cHV0ID49IHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQodGhpcy5fY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pIHx8IGlzTmF0aXZlQXVkaW9QYXJhbShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSh0aGlzLl9uYXRpdmVBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNQYXNzaXZlID0gaXNQYXNzaXZlQXVkaW9Ob2RlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lIHx8IGlzUGFzc2l2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QoLi4uY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcgJiYgIWlzUGFzc2l2ZSAmJiBpc1Bhc3NpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM0MTogU2FmYXJpIGRvZXMgbm90IHRocm93IHRoZSBjb3JyZWN0IGV4Y2VwdGlvbiBzbyBmYXIuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaXNOZXdDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBhZGRDb25uZWN0aW9uVG9BdWRpb05vZGUodGhpcywgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNjQ6IE9ubHkgRmlyZWZveCBkZXRlY3RzIGN5Y2xlcyBzbyBmYXIuXG4gICAgICAgICAgICAgICAgaWYgKGlzTmV3Q29ubmVjdGlvblRvQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN5Y2xlcyA9IGRldGVjdEN5Y2xlcyhbdGhpc10sIGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZShjeWNsZXMsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlcihpc09mZmxpbmUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjNzMsICMxNDcgJiAjMTUzOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCB0byBjb25uZWN0IGFuIGlucHV0IHNpZ25hbCB0byB0aGUgcGxheWJhY2tSYXRlIEF1ZGlvUGFyYW0gb2YgYW5cbiAgICAgICAgICAgICAqIEF1ZGlvQnVmZmVyU291cmNlTm9kZS4gVGhpcyBjYW4ndCBiZSBlYXNpbHkgZGV0ZWN0ZWQgYW5kIHRoYXQncyB3aHkgdGhlIG91dGRhdGVkIG5hbWUgcHJvcGVydHkgaXMgdXNlZCBoZXJlIHRvIGlkZW50aWZ5XG4gICAgICAgICAgICAgKiBTYWZhcmkuIEluIGFkZGl0aW9uIHRvIHRoYXQgdGhlIG1heFZhbHVlIHByb3BlcnR5IGlzIHVzZWQgdG8gb25seSBkZXRlY3QgdGhlIGFmZmVjdGVkIHZlcnNpb25zIGJlbG93IHYxNC4wLjIuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1BhcmFtLm5hbWUgPT09ICdwbGF5YmFja1JhdGUnICYmIG5hdGl2ZUF1ZGlvUGFyYW0ubWF4VmFsdWUgPT09IDEwMjQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUgfHwgaXNQYXNzaXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTg6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaXNOZXdDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gYWRkQ29ubmVjdGlvblRvQXVkaW9QYXJhbU9mQXVkaW9Db250ZXh0KHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzE2NDogT25seSBGaXJlZm94IGRldGVjdHMgY3ljbGVzIHNvIGZhci5cbiAgICAgICAgICAgIGlmIChpc05ld0Nvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjeWNsZXMgPSBkZXRlY3RDeWNsZXMoW3RoaXNdLCBkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZShjeWNsZXMsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlcihpc09mZmxpbmUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpIHtcbiAgICAgICAgICAgIGxldCBkZXN0aW5hdGlvbnM7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dCh0aGlzLl9jb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbnMgPSBkZWxldGVBbnlDb25uZWN0aW9uKHRoaXMsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA8IDAgfHwgZGVzdGluYXRpb25Pck91dHB1dCA+PSB0aGlzLm51bWJlck9mT3V0cHV0cykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbnMgPSBkZWxldGVDb25uZWN0aW9uQXRPdXRwdXQodGhpcywgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChvdXRwdXQgIT09IHVuZGVmaW5lZCAmJiAob3V0cHV0IDwgMCB8fCBvdXRwdXQgPj0gdGhpcy5udW1iZXJPZk91dHB1dHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZShkZXN0aW5hdGlvbk9yT3V0cHV0KSAmJiBpbnB1dCAhPT0gdW5kZWZpbmVkICYmIChpbnB1dCA8IDAgfHwgaW5wdXQgPj0gZGVzdGluYXRpb25Pck91dHB1dC5udW1iZXJPZklucHV0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25zID0gZGVsZXRlQ29ubmVjdGlvblRvRGVzdGluYXRpb24odGhpcywgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzE2NDogT25seSBGaXJlZm94IGRldGVjdHMgY3ljbGVzIHNvIGZhci5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZGVzdGluYXRpb24gb2YgZGVzdGluYXRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3ljbGVzID0gZGV0ZWN0Q3ljbGVzKFt0aGlzXSwgZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UoY3ljbGVzLCBkZWNyZW1lbnRDeWNsZUNvdW50ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IEF1dG9tYXRpb25FdmVudExpc3QgfSBmcm9tICdhdXRvbWF0aW9uLWV2ZW50cyc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9QYXJhbUZhY3RvcnkgPSAoYWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zLCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIGF1ZGlvUGFyYW1TdG9yZSwgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyLCBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50LCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIGlzQXVkaW9QYXJhbU9mT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSwgbWF4VmFsdWUgPSBudWxsLCBtaW5WYWx1ZSA9IG51bGwpID0+IHtcbiAgICAgICAgLy8gQnVnICMxOTYgT25seSBTYWZhcmkgc2V0cyB0aGUgZGVmYXVsdFZhbHVlIHRvIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlO1xuICAgICAgICBjb25zdCBhdXRvbWF0aW9uRXZlbnRMaXN0ID0gbmV3IEF1dG9tYXRpb25FdmVudExpc3QoZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbVJlbmRlcmVyID0gaXNBdWRpb1BhcmFtT2ZPZmZsaW5lQXVkaW9Db250ZXh0ID8gY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyKGF1dG9tYXRpb25FdmVudExpc3QpIDogbnVsbDtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbSA9IHtcbiAgICAgICAgICAgIGdldCBkZWZhdWx0VmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1heFZhbHVlID09PSBudWxsID8gbmF0aXZlQXVkaW9QYXJhbS5tYXhWYWx1ZSA6IG1heFZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBtaW5WYWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWluVmFsdWUgPT09IG51bGwgPyBuYXRpdmVBdWRpb1BhcmFtLm1pblZhbHVlIDogbWluVmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0udmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzk4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCB5ZXQgdHJlYXQgdGhlIHZhbHVlIHNldHRlciBsaWtlIGEgY2FsbCB0byBzZXRWYWx1ZUF0VGltZSgpLlxuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYW5jZWxBbmRIb2xkQXRUaW1lKGNhbmNlbFRpbWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzI4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCB5ZXQgaW1wbGVtZW50IGNhbmNlbEFuZEhvbGRBdFRpbWUoKS5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJldmlvdXNMYXN0RXZlbnQgPSBBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudExhc3RFdmVudCA9IEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNMYXN0RXZlbnQgIT09IGN1cnJlbnRMYXN0RXZlbnQgJiYgY3VycmVudExhc3RFdmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5lbmRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ2xpbmVhclJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5lbmRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5zdGFydFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnc2V0VmFsdWVDdXJ2ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZXMsIGN1cnJlbnRMYXN0RXZlbnQuc3RhcnRUaW1lLCBjdXJyZW50TGFzdEV2ZW50LmR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY2FuY2VsVGltZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY2FuY2VsVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTg3OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICghTnVtYmVyLmlzRmluaXRlKGVuZFRpbWUpIHx8IGVuZFRpbWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTQ6IEZpcmVmb3ggZG9lcyBub3QgaW1wbGljaXRseSBjYWxsIHNldFZhbHVlQXRUaW1lKCkgaWYgdGhlcmUgaXMgbm8gcHJldmlvdXMgZXZlbnQuXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50KGRlZmF1bHRWYWx1ZSwgY3VycmVudFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZShkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgZW5kVGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTk1OiBGaXJlZm94IGRvZXMgbm90IGltcGxpY2l0bHkgY2FsbCBzZXRWYWx1ZUF0VGltZSgpIGlmIHRoZXJlIGlzIG5vIHByZXZpb3VzIGV2ZW50LlxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KHZhbHVlLCBlbmRUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQodGFyZ2V0LCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgc3RhcnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAxODM6IFNhZmFyaSBvbmx5IGFjY2VwdHMgYSBGbG9hdDMyQXJyYXkuXG4gICAgICAgICAgICAgICAgY29uc3QgY29udmVydGVkVmFsdWVzID0gdmFsdWVzIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gdmFsdWVzIDogbmV3IEZsb2F0MzJBcnJheSh2YWx1ZXMpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICMxNTI6IFNhZmFyaSBkb2VzIG5vdCBjb3JyZWN0bHkgaW50ZXJwb2xhdGUgdGhlIHZhbHVlcyBvZiB0aGUgY3VydmUuXG4gICAgICAgICAgICAgICAgICogQHRvZG8gVW5mb3J0dW5hdGVseSB0aGVyZSBpcyBubyB3YXkgdG8gdGVzdCBmb3IgdGhpcyBiZWhhdmlvciBpbiBhIHN5bmNocm9ub3VzIGZhc2hpb24gd2hpY2ggaXMgd2h5IHRlc3RpbmcgZm9yIHRoZVxuICAgICAgICAgICAgICAgICAqIGV4aXN0ZW5jZSBvZiB0aGUgd2Via2l0QXVkaW9Db250ZXh0IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGhlcmUuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBzdGFydFRpbWUgKyBkdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2FtcGxlUmF0ZSA9IGF1ZGlvTm9kZS5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0U2FtcGxlID0gTWF0aC5jZWlsKHN0YXJ0VGltZSAqIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXN0U2FtcGxlID0gTWF0aC5mbG9vcihlbmRUaW1lICogc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mSW50ZXJwb2xhdGVkVmFsdWVzID0gbGFzdFNhbXBsZSAtIGZpcnN0U2FtcGxlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnBvbGF0ZWRWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KG51bWJlck9mSW50ZXJwb2xhdGVkVmFsdWVzKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkludGVycG9sYXRlZFZhbHVlczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aGVvcmV0aWNJbmRleCA9ICgoY29udmVydGVkVmFsdWVzLmxlbmd0aCAtIDEpIC8gZHVyYXRpb24pICogKChmaXJzdFNhbXBsZSArIGkpIC8gc2FtcGxlUmF0ZSAtIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb3dlckluZGV4ID0gTWF0aC5mbG9vcih0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cHBlckluZGV4ID0gTWF0aC5jZWlsKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRlZFZhbHVlc1tpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGNvbnZlcnRlZFZhbHVlc1tsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgxIC0gKHRoZW9yZXRpY0luZGV4IC0gbG93ZXJJbmRleCkpICogY29udmVydGVkVmFsdWVzW2xvd2VySW5kZXhdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIC0gKHVwcGVySW5kZXggLSB0aGVvcmV0aWNJbmRleCkpICogY29udmVydGVkVmFsdWVzW3VwcGVySW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoaW50ZXJwb2xhdGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZShpbnRlcnBvbGF0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lT2ZMYXN0U2FtcGxlID0gbGFzdFNhbXBsZSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aW1lT2ZMYXN0U2FtcGxlIDwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKGF1ZGlvUGFyYW0sIGludGVycG9sYXRlZFZhbHVlc1tpbnRlcnBvbGF0ZWRWYWx1ZXMubGVuZ3RoIC0gMV0sIHRpbWVPZkxhc3RTYW1wbGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZShhdWRpb1BhcmFtLCBjb252ZXJ0ZWRWYWx1ZXNbY29udmVydGVkVmFsdWVzLmxlbmd0aCAtIDFdLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoY29udmVydGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZShjb252ZXJ0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXVkaW9QYXJhbVN0b3JlLnNldChhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICAgICAgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLnNldChhdWRpb1BhcmFtLCBhdWRpb05vZGUpO1xuICAgICAgICBhZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSwgYXVkaW9QYXJhbVJlbmRlcmVyKTtcbiAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1wYXJhbS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIgPSAoYXV0b21hdGlvbkV2ZW50TGlzdCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIHJlcGxheShhdWRpb1BhcmFtKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF1dG9tYXRpb25FdmVudCBvZiBhdXRvbWF0aW9uRXZlbnRMaXN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBlbmRUaW1lLCB2YWx1ZSB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2xpbmVhclJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGVuZFRpbWUsIHZhbHVlIH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFRhcmdldCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBzdGFydFRpbWUsIHRhcmdldCwgdGltZUNvbnN0YW50IH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHN0YXJ0VGltZSwgdmFsdWUgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZUN1cnZlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGR1cmF0aW9uLCBzdGFydFRpbWUsIHZhbHVlcyB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGFwcGx5IGFuIHVua25vd24gYXV0b21hdGlvbi5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1wYXJhbS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY2xhc3MgUmVhZE9ubHlNYXAge1xuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgdGhpcy5fbWFwID0gbmV3IE1hcChwYXJhbWV0ZXJzKTtcbiAgICB9XG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuc2l6ZTtcbiAgICB9XG4gICAgZW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5lbnRyaWVzKCk7XG4gICAgfVxuICAgIGZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcgPSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwga2V5LCB0aGlzKSk7XG4gICAgfVxuICAgIGdldChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZ2V0KG5hbWUpO1xuICAgIH1cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyhuYW1lKTtcbiAgICB9XG4gICAga2V5cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5rZXlzKCk7XG4gICAgfVxuICAgIHZhbHVlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC52YWx1ZXMoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZWFkLW9ubHktbWFwLmpzLm1hcCIsImltcG9ydCB7IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgUmVhZE9ubHlNYXAgfSBmcm9tICcuLi9yZWFkLW9ubHktbWFwJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgLy8gQnVnICM2MTogVGhlIGNoYW5uZWxDb3VudE1vZGUgc2hvdWxkIGJlICdtYXgnIGFjY29yZGluZyB0byB0aGUgc3BlYyBidXQgaXMgc2V0IHRvICdleHBsaWNpdCcgdG8gYWNoaWV2ZSBjb25zaXN0ZW50IGJlaGF2aW9yLlxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIG51bWJlck9mSW5wdXRzOiAxLFxuICAgIG51bWJlck9mT3V0cHV0czogMSxcbiAgICBwYXJhbWV0ZXJEYXRhOiB7fSxcbiAgICBwcm9jZXNzb3JPcHRpb25zOiB7fVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSAoYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvciwgc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucywgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHksIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvV29ya2xldE5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMoeyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfSk7XG4gICAgICAgICAgICAvLyBCdWcgIzE5MTogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIG9wdGlvbnMgYXJlbid0IGNsb25hYmxlLlxuICAgICAgICAgICAgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHkobWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPSBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgcHJvY2Vzc29yQ29uc3RydWN0b3IgPSBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPT09IG51bGwgfHwgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAuZ2V0KG5hbWUpO1xuICAgICAgICAgICAgLy8gQnVnICMxODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgYWxsb3cgdG8gY3JlYXRlIGFuIEF1ZGlvV29ya2xldE5vZGUgb24gYSBjbG9zZWQgQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGlzT2ZmbGluZSB8fCBuYXRpdmVDb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJ1xuICAgICAgICAgICAgICAgID8gbmF0aXZlQ29udGV4dFxuICAgICAgICAgICAgICAgIDogKF9hID0gZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlKG5hdGl2ZUNvbnRleHRPckJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGlzT2ZmbGluZSA/IG51bGwgOiBjb250ZXh0LmJhc2VMYXRlbmN5LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hbWUsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyKG5hbWUsIG1lcmdlZE9wdGlvbnMsIHByb2Nlc3NvckNvbnN0cnVjdG9yKSA6IG51bGwpKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBAdG9kbyBBZGQgYSBtZWNoYW5pc20gdG8gc3dpdGNoIGFuIEF1ZGlvV29ya2xldE5vZGUgdG8gcGFzc2l2ZSBvbmNlIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gb2YgdGhlIEF1ZGlvV29ya2xldFByb2Nlc3NvclxuICAgICAgICAgICAgICogcmV0dXJucyBmYWxzZS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBbXTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycy5mb3JFYWNoKChuYXRpdmVBdWRpb1BhcmFtLCBubSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvUGFyYW0gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgICAgICAgICAgICAgcGFyYW1ldGVycy5wdXNoKFtubSwgYXVkaW9QYXJhbV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fcGFyYW1ldGVycyA9IG5ldyBSZWFkT25seU1hcChwYXJhbWV0ZXJzKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzg2ICYgIzg3OiBJbnZva2luZyB0aGUgcmVuZGVyZXIgb2YgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBtaWdodCBiZSBuZWNlc3NhcnkgaWYgaXQgaGFzIG5vIGRpcmVjdCBvciBpbmRpcmVjdCBjb25uZWN0aW9uIHRvXG4gICAgICAgICAgICAgKiB0aGUgZGVzdGluYXRpb24uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICBhZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShuYXRpdmVDb250ZXh0LCB0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyh0aGlzKTtcbiAgICAgICAgICAgIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25wcm9jZXNzb3JlcnJvcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbnByb2Nlc3NvcmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbnByb2Nlc3NvcmVycm9yKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25Qcm9jZXNzb3JFcnJvciA9IHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgICAgIHRoaXMuX29ucHJvY2Vzc29yZXJyb3IgPVxuICAgICAgICAgICAgICAgIG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3IgIT09IG51bGwgJiYgbmF0aXZlT25Qcm9jZXNzb3JFcnJvciA9PT0gd3JhcHBlZExpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgOiBuYXRpdmVPblByb2Nlc3NvckVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwYXJhbWV0ZXJzKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3BhcmFtZXRlcnMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtZXRlcnM7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvcnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wb3J0O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGZ1bmN0aW9uIGNvcHlGcm9tQ2hhbm5lbChhdWRpb0J1ZmZlciwgXG4vLyBAdG9kbyBUaGVyZSBpcyBjdXJyZW50bHkgbm8gd2F5IHRvIGRlZmluZSBzb21ldGhpbmcgbGlrZSB7IFsga2V5OiBudW1iZXIgfCBzdHJpbmcgXTogRmxvYXQzMkFycmF5IH1cbnBhcmVudCwga2V5LCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpIHtcbiAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICBpZiAocGFyZW50W2tleV0uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcGFyZW50W2tleV0gPSBuZXcgRmxvYXQzMkFycmF5KDEyOCk7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsKHBhcmVudFtrZXldLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpLlxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKTtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHBhcmVudFtrZXldID0gY2hhbm5lbERhdGEuc2xpY2UoYnVmZmVyT2Zmc2V0LCBidWZmZXJPZmZzZXQgKyAxMjgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2xpY2VkSW5wdXQgPSBuZXcgRmxvYXQzMkFycmF5KGNoYW5uZWxEYXRhLmJ1ZmZlciwgYnVmZmVyT2Zmc2V0ICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULCAxMjgpO1xuICAgICAgICAgICAgcGFyZW50W2tleV0uc2V0KHNsaWNlZElucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvcHktZnJvbS1jaGFubmVsLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjb3B5VG9DaGFubmVsID0gKGF1ZGlvQnVmZmVyLCBwYXJlbnQsIGtleSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKHBhcmVudFtrZXldLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weVRvQ2hhbm5lbCgpLlxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpLnNldChwYXJlbnRba2V5XSwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb3B5LXRvLWNoYW5uZWwuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5lc3RlZEFycmF5cyA9ICh4LCB5KSA9PiB7XG4gICAgY29uc3QgYXJyYXlzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB4OyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgYXJyYXkgPSBbXTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdHlwZW9mIHkgPT09ICdudW1iZXInID8geSA6IHlbaV07XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgIGFycmF5LnB1c2gobmV3IEZsb2F0MzJBcnJheSgxMjgpKTtcbiAgICAgICAgfVxuICAgICAgICBhcnJheXMucHVzaChhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhcnJheXM7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLW5lc3RlZC1hcnJheXMuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9UT19QUk9DRVNTT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkpID0+IHtcbiAgICBjb25zdCBub2RlVG9Qcm9jZXNzb3JNYXAgPSBnZXRWYWx1ZUZvcktleShOT0RFX1RPX1BST0NFU1NPUl9NQVBTLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkobm9kZVRvUHJvY2Vzc29yTWFwLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgY29weUZyb21DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LWZyb20tY2hhbm5lbCc7XG5pbXBvcnQgeyBjb3B5VG9DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LXRvLWNoYW5uZWwnO1xuaW1wb3J0IHsgY3JlYXRlTmVzdGVkQXJyYXlzIH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGUtbmVzdGVkLWFycmF5cyc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8td29ya2xldC1wcm9jZXNzb3InO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5jb25zdCBwcm9jZXNzQnVmZmVyID0gYXN5bmMgKHByb3h5LCByZW5kZXJlZEJ1ZmZlciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucywgb3V0cHV0Q2hhbm5lbENvdW50LCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUpID0+IHtcbiAgICAvLyBDZWlsIHRoZSBsZW5ndGggdG8gdGhlIG5leHQgZnVsbCByZW5kZXIgcXVhbnR1bS5cbiAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgIGNvbnN0IGxlbmd0aCA9IHJlbmRlcmVkQnVmZmVyID09PSBudWxsID8gTWF0aC5jZWlsKHByb3h5LmNvbnRleHQubGVuZ3RoIC8gMTI4KSAqIDEyOCA6IHJlbmRlcmVkQnVmZmVyLmxlbmd0aDtcbiAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBvcHRpb25zLmNoYW5uZWxDb3VudCAqIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgY29uc3QgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9IG91dHB1dENoYW5uZWxDb3VudC5yZWR1Y2UoKHN1bSwgdmFsdWUpID0+IHN1bSArIHZhbHVlLCAwKTtcbiAgICBjb25zdCBwcm9jZXNzZWRCdWZmZXIgPSBudW1iZXJPZk91dHB1dENoYW5uZWxzID09PSAwXG4gICAgICAgID8gbnVsbFxuICAgICAgICA6IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKG51bWJlck9mT3V0cHV0Q2hhbm5lbHMsIGxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHByb2Nlc3NvciBjb25zdHJ1Y3Rvci4nKTtcbiAgICB9XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhwcm94eSk7XG4gICAgY29uc3QgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gYXdhaXQgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5KTtcbiAgICBjb25zdCBpbnB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZklucHV0cywgb3B0aW9ucy5jaGFubmVsQ291bnQpO1xuICAgIGNvbnN0IG91dHB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZk91dHB1dHMsIG91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgY29uc3QgcGFyYW1ldGVycyA9IEFycmF5LmZyb20ocHJveHkucGFyYW1ldGVycy5rZXlzKCkpLnJlZHVjZSgocHJtdHJzLCBuYW1lKSA9PiAoeyAuLi5wcm10cnMsIFtuYW1lXTogbmV3IEZsb2F0MzJBcnJheSgxMjgpIH0pLCB7fSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMTI4KSB7XG4gICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mSW5wdXRzID4gMCAmJiByZW5kZXJlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKHJlbmRlcmVkQnVmZmVyLCBpbnB1dHNbal0sIGssIGssIGkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCAmJiByZW5kZXJlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMuZm9yRWFjaCgoeyBuYW1lIH0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKHJlbmRlcmVkQnVmZmVyLCBwYXJhbWV0ZXJzLCBuYW1lLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCwgaSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgICAgICAgICAgaWYgKG91dHB1dHNbal1ba10uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRzW2pdW2tdID0gbmV3IEZsb2F0MzJBcnJheSgxMjgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcG90ZW50aWFsbHlFbXB0eUlucHV0cyA9IGlucHV0cy5tYXAoKGlucHV0LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb05vZGVDb25uZWN0aW9ucy5hY3RpdmVJbnB1dHNbaW5kZXhdLnNpemUgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZVNvdXJjZUZsYWcgPSBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShpIC8gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUsICgpID0+IGF1ZGlvV29ya2xldFByb2Nlc3Nvci5wcm9jZXNzKHBvdGVudGlhbGx5RW1wdHlJbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpKTtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlUb0NoYW5uZWwocHJvY2Vzc2VkQnVmZmVyLCBvdXRwdXRzW2pdLCBrLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaywgaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbal07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhY3RpdmVTb3VyY2VGbGFnKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBwcm94eS5kaXNwYXRjaEV2ZW50KG5ldyBFcnJvckV2ZW50KCdwcm9jZXNzb3JlcnJvcicsIHtcbiAgICAgICAgICAgICAgICBjb2xubzogZXJyb3IuY29sbm8sXG4gICAgICAgICAgICAgICAgZmlsZW5hbWU6IGVycm9yLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIGxpbmVubzogZXJyb3IubGluZW5vLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzZWRCdWZmZXI7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKG5hbWUsIG9wdGlvbnMsIHByb2Nlc3NvckNvbnN0cnVjdG9yKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBwcm9jZXNzZWRCdWZmZXJQcm9taXNlID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICBsZXQgbmF0aXZlT3V0cHV0Tm9kZXMgPSBudWxsO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbENvdW50ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudClcbiAgICAgICAgICAgICAgICA/IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50XG4gICAgICAgICAgICAgICAgOiBBcnJheS5mcm9tKG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNjE6IE9ubHkgQ2hyb21lLCBFZGdlICYgRmlyZWZveCBoYXZlIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBdWRpb1dvcmtsZXROb2RlIHlldC5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZk91dHB1dENoYW5uZWxzID0gb3V0cHV0Q2hhbm5lbENvdW50LnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtICsgdmFsdWUsIDApO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm94eS5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IG91dHB1dENoYW5uZWxDb3VudFtpXVxuICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jb25uZWN0ID0gY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcyk7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdCA9IGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZU91dHB1dE5vZGVzID0gW291dHB1dENoYW5uZWxTcGxpdHRlck5vZGUsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcywgb3V0cHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU91dHB1dE5vZGVzID09PSBudWxsID8gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA6IG5hdGl2ZU91dHB1dE5vZGVzWzJdKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPdXRwdXROb2RlcyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHByb2Nlc3NvciBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZ2V0cyBub3QgaW5pdGlhbGl6ZWQgY29ycmVjdGx5LlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBwcm94eS5jaGFubmVsQ291bnQgKiBwcm94eS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZQYXJhbWV0ZXJzID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZCA/IDAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mQ2hhbm5lbHMgPSBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlckJ1ZmZlciA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihudW1iZXJPZkNoYW5uZWxzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENlaWwgdGhlIGxlbmd0aCB0byB0aGUgbmV4dCBmdWxsIHJlbmRlciBxdWFudHVtLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguY2VpbChwcm94eS5jb250ZXh0Lmxlbmd0aCAvIDEyOCkgKiAxMjgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnYWluTm9kZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGVzLnB1c2goY3JlYXRlTmF0aXZlR2Fpbk5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluOiAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZXMgPSBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKHByb3h5LnBhcmFtZXRlcnMudmFsdWVzKCkpLm1hcChhc3luYyAoYXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBhdWRpb1BhcmFtLnZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogTWF0aC5tYXgoMSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhaW5Ob2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgaiwgaSAqIG9wdGlvbnMuY2hhbm5lbENvdW50ICsgaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGNvbnN0YW50U291cmNlTm9kZV0gb2YgY29uc3RhbnRTb3VyY2VOb2Rlcy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCAwLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGdhaW5Ob2Rlcy5tYXAoKGdhaW5Ob2RlKSA9PiByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIGdhaW5Ob2RlKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRCdWZmZXJQcm9taXNlID0gcHJvY2Vzc0J1ZmZlcihwcm94eSwgbnVtYmVyT2ZDaGFubmVscyA9PT0gMCA/IG51bGwgOiBhd2FpdCByZW5kZXJCdWZmZXIoKSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucywgb3V0cHV0Q2hhbm5lbENvdW50LCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBwcm9jZXNzZWRCdWZmZXIgPSBhd2FpdCBwcm9jZXNzZWRCdWZmZXJQcm9taXNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCBbb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSwgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLCBvdXRwdXRHYWluTm9kZV0gPSBuYXRpdmVPdXRwdXROb2RlcztcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBwcm9jZXNzZWRCdWZmZXI7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBpIDwgcHJveHkubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3V0cHV0Q2hhbm5lbENvdW50W2ldOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0R2Fpbk5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbbm0sIGF1ZGlvUGFyYW1dIG9mIHByb3h5LnBhcmFtZXRlcnMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFRoZSBkZWZpbml0aW9uIHRoYXQgVHlwZVNjcmlwdCB1c2VzIG9mIHRoZSBBdWRpb1BhcmFtTWFwIGlzIGxhY2tpbmcgbWFueSBtZXRob2RzLlxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBhcmFtZXRlcnMuZ2V0KG5tKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbbm0sIGF1ZGlvUGFyYW1dIG9mIHByb3h5LnBhcmFtZXRlcnMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIFxuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzLmdldChubSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb1dvcmtsZXROb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZU9yR2Fpbk5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGFkZEF1ZGlvV29ya2xldE1vZHVsZSwgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yLCBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciwgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciwgZGVjb2RlQXVkaW9EYXRhLCBkZWxheU5vZGVDb25zdHJ1Y3RvciwgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yLCBnYWluTm9kZUNvbnN0cnVjdG9yLCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IsIHBhbm5lck5vZGVDb25zdHJ1Y3RvciwgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IsIHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3Rvciwgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBCYXNlQXVkaW9Db250ZXh0IGV4dGVuZHMgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKF9uYXRpdmVDb250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICBzdXBlcihfbmF0aXZlQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0ID0gX25hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9hdWRpb1dvcmtsZXQgPVxuICAgICAgICAgICAgICAgIGFkZEF1ZGlvV29ya2xldE1vZHVsZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWRkTW9kdWxlOiAobW9kdWxlVVJMLCBvcHRpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZEF1ZGlvV29ya2xldE1vZHVsZSh0aGlzLCBtb2R1bGVVUkwsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGdldCBhdWRpb1dvcmtsZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXVkaW9Xb3JrbGV0O1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhbmFseXNlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVCaXF1YWRGaWx0ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQnVmZmVyU291cmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDaGFubmVsTWVyZ2VyKG51bWJlck9mSW5wdXRzID0gNikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbnVtYmVyT2ZJbnB1dHMgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG51bWJlck9mT3V0cHV0cyA9IDYpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbnVtYmVyT2ZPdXRwdXRzIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVEZWxheShtYXhEZWxheVRpbWUgPSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGRlbGF5Tm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbWF4RGVsYXlUaW1lIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGdhaW5Ob2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlSUlSRmlsdGVyKGZlZWRmb3J3YXJkLCBmZWVkYmFjaykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IodGhpcywgeyBmZWVkYmFjaywgZmVlZGZvcndhcmQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlT3NjaWxsYXRvcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVQYW5uZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHBhbm5lck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMgPSB7IGRpc2FibGVOb3JtYWxpemF0aW9uOiBmYWxzZSB9KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yKHRoaXMsIHsgLi4uY29uc3RyYWludHMsIGltYWcsIHJlYWwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlU3RlcmVvUGFubmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlV2F2ZVNoYXBlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBkZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhLCBzdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBkZWNvZGVBdWRpb0RhdGEodGhpcy5fbmF0aXZlQ29udGV4dCwgYXVkaW9EYXRhKS50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3VjY2Vzc0NhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGVycm9yQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgUTogMSxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRldHVuZTogMCxcbiAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICBnYWluOiAwLFxuICAgIHR5cGU6ICdsb3dwYXNzJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEJpcXVhZEZpbHRlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGJpcXVhZEZpbHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzgwOiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fUSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLlEsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9kZXR1bmUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUsIDEyMDAgKiBNYXRoLmxvZzIoTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQpLCAtMTIwMCAqIE1hdGgubG9nMihNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCkpO1xuICAgICAgICAgICAgLy8gQnVnICM3NzogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlIGZvciBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSwgY29udGV4dC5zYW1wbGVSYXRlIC8gMiwgMCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc5OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9nYWluID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2FpbiwgNDAgKiBNYXRoLmxvZzEwKE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUKSwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkZXR1bmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV0dW5lO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBnYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dhaW47XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IFEoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fUTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHR5cGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUJpcXVhZEZpbHRlck5vZGUudHlwZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxODk6IFNhZmFyaSBkb2VzIHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM2ODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBwYXJhbWV0ZXJzIGRpZmZlciBpbiB0aGVpciBsZW5ndGguXG4gICAgICAgICAgICBpZiAoZnJlcXVlbmN5SHoubGVuZ3RoICE9PSBtYWdSZXNwb25zZS5sZW5ndGggfHwgbWFnUmVzcG9uc2UubGVuZ3RoICE9PSBwaGFzZVJlc3BvbnNlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUJpcXVhZEZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgUTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRldHVuZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGZyZXF1ZW5jeTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3kudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2Fpbi52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS50eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuUSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRldHVuZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuUSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ2FjaGVUZXN0UmVzdWx0ID0gKG9uZ29pbmdUZXN0cywgdGVzdFJlc3VsdHMpID0+IHtcbiAgICByZXR1cm4gKHRlc3RlciwgdGVzdCkgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZWRUZXN0UmVzdWx0ID0gdGVzdFJlc3VsdHMuZ2V0KHRlc3Rlcik7XG4gICAgICAgIGlmIChjYWNoZWRUZXN0UmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRUZXN0UmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uZ29pbmdUZXN0ID0gb25nb2luZ1Rlc3RzLmdldCh0ZXN0ZXIpO1xuICAgICAgICBpZiAob25nb2luZ1Rlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG9uZ29pbmdUZXN0O1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQgPSB0ZXN0KCk7XG4gICAgICAgICAgICBpZiAoc3luY2hyb25vdXNUZXN0UmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIG9uZ29pbmdUZXN0cy5zZXQodGVzdGVyLCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBzeW5jaHJvbm91c1Rlc3RSZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoZmluYWxUZXN0UmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG9uZ29pbmdUZXN0cy5kZWxldGUodGVzdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGVzdFJlc3VsdHMuc2V0KHRlc3RlciwgZmluYWxUZXN0UmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmFsVGVzdFJlc3VsdDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIHN5bmNocm9ub3VzVGVzdFJlc3VsdCk7XG4gICAgICAgICAgICByZXR1cm4gc3luY2hyb25vdXNUZXN0UmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2FjaGUtdGVzdC1yZXN1bHQuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBudW1iZXJPZklucHV0czogNlxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENoYW5uZWxNZXJnZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlcik7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtbWVyZ2VyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBuYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiA2LFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgIG51bWJlck9mT3V0cHV0czogNlxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ2hhbm5lbFNwbGl0dGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH0pO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlcigpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtc3BsaXR0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mT3V0cHV0c1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLXNwbGl0dGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ29ubmVjdEF1ZGlvUGFyYW0gPSAocmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIHJldHVybiByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0oYXVkaW9QYXJhbSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dEF1ZGlvTm9kZSA9IG91dHB1dEF1ZGlvTm9kZXNbb3V0cHV0XTtcbiAgICAgICAgaWYgKG91dHB1dEF1ZGlvTm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgMCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgMCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDIsIDQ0MTAwKTtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCA9IHRydWU7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0ZWQtbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIG9mZnNldDogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5LCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ29uc3RhbnRTb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSgpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSBjb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlcjtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzYyICYgIzc0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBDb25zdGFudFNvdXJjZU5vZGVzIGFuZCBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWVcbiAgICAgICAgICAgICAqIGZvciBHYWluTm9kZXMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuX29mZnNldCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9mZnNldCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25lbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RhcnQod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlci5zdGFydCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyLnN0b3AgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBzdGFydCA9IG51bGw7XG4gICAgICAgIGxldCBzdG9wID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAgICAgICAgICAgKiBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdGFydChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdG9wKHN0b3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub2Zmc2V0LCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9mZnNldCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gcmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgPSAodW5pdDMyQXJyYXkpID0+IHtcbiAgICByZXR1cm4gKHZhbHVlKSA9PiB7XG4gICAgICAgIHVuaXQzMkFycmF5WzBdID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB1bml0MzJBcnJheVswXTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZlcnQtbnVtYmVyLXRvLXVuc2lnbmVkLWxvbmcuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGJ1ZmZlcjogbnVsbCxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGlzYWJsZU5vcm1hbGl6YXRpb246IGZhbHNlXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENvbnZvbHZlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb252b2x2ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnZvbHZlck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNvbnZvbHZlck5vZGUsIGNvbnZvbHZlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZSA9IG5hdGl2ZUNvbnZvbHZlck5vZGU7XG4gICAgICAgICAgICBpZiAobWVyZ2VkT3B0aW9ucy5idWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCBtZXJnZWRPcHRpb25zLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0J1ZmZlck51bGxpZmllZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHNldCBidWZmZXIodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID0gdmFsdWU7XG4gICAgICAgICAgICAvLyBCdWcgIzExNTogU2FmYXJpIGRvZXMgbm90IGFsbG93IHRvIHNldCB0aGUgYnVmZmVyIHRvIG51bGwuXG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgJiYgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID09PSBudWxsID8gMCA6IHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgbm9ybWFsaXplKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplO1xuICAgICAgICB9XG4gICAgICAgIHNldCBub3JtYWxpemUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZvbHZlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVDb252b2x2ZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVDb252b2x2ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUNvbnZvbHZlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVDb252b2x2ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQ29udm9sdmVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUNvbnZvbHZlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVDb252b2x2ZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZU5vcm1hbGl6YXRpb246ICFuYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZUNvbnZvbHZlck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnZvbHZlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb252b2x2ZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlID0gcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbnZvbHZlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udm9sdmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE0MywgIzE0NCAmICMxNDY6IFNhZmFyaSB0aHJvd3MgYSBTeW50YXhFcnJvciB3aGVuIG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCBvciBzYW1wbGVSYXRlIGFyZSBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKGVyci5uYW1lID09PSAnU3ludGF4RXJyb3InKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZURhdGFDbG9uZUVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0RhdGFDbG9uZUVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhLWNsb25lLWVycm9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBkZXRhY2hBcnJheUJ1ZmZlciA9IChhcnJheUJ1ZmZlcikgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgY29uc3QgY2xvc2VBbmRSZXNvbHZlID0gKCkgPT4ge1xuICAgICAgICAgICAgcG9ydDIub25tZXNzYWdlID0gbnVsbDtcbiAgICAgICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9O1xuICAgICAgICBwb3J0Mi5vbm1lc3NhZ2UgPSAoKSA9PiBjbG9zZUFuZFJlc29sdmUoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGFycmF5QnVmZmVyLCBbYXJyYXlCdWZmZXJdKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgY2xvc2VBbmRSZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZXRhY2gtYXJyYXktYnVmZmVyLmpzLm1hcCIsImltcG9ydCB7IGRldGFjaEFycmF5QnVmZmVyIH0gZnJvbSAnLi4vaGVscGVycy9kZXRhY2gtYXJyYXktYnVmZmVyJztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGVjb2RlQXVkaW9EYXRhID0gKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlRGF0YUNsb25lRXJyb3IsIGNyZWF0ZUVuY29kaW5nRXJyb3IsIGRldGFjaGVkQXJyYXlCdWZmZXJzLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUNvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgdGVzdFByb21pc2VTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKSA9PiB7XG4gICAgcmV0dXJuIChhbnlDb250ZXh0LCBhdWRpb0RhdGEpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGlzTmF0aXZlQ29udGV4dChhbnlDb250ZXh0KSA/IGFueUNvbnRleHQgOiBnZXROYXRpdmVDb250ZXh0KGFueUNvbnRleHQpO1xuICAgICAgICAvLyBCdWcgIzQzOiBPbmx5IENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhIERhdGFDbG9uZUVycm9yLlxuICAgICAgICBpZiAoZGV0YWNoZWRBcnJheUJ1ZmZlcnMuaGFzKGF1ZGlvRGF0YSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVyciA9IGNyZWF0ZURhdGFDbG9uZUVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgYXVkaW9EYXRhIHBhcmFtZXRlciBtYXliZSBvZiBhIHR5cGUgd2hpY2ggY2FuJ3QgYmUgYWRkZWQgdG8gYSBXZWFrU2V0LlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGV0YWNoZWRBcnJheUJ1ZmZlcnMuYWRkKGF1ZGlvRGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIGlmIChjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKS50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTMzOiBTYWZhcmkgZG9lcyBuZXV0ZXIgdGhlIEFycmF5QnVmZmVyLlxuICAgICAgICAgICAgICAgIGRldGFjaEFycmF5QnVmZmVyKGF1ZGlvRGF0YSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCByZXR1cm4gYSBQcm9taXNlIHlldC5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBsZXRlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTMzOiBTYWZhcmkgZG9lcyBuZXV0ZXIgdGhlIEFycmF5QnVmZmVyLlxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGRldGFjaEFycmF5QnVmZmVyKGF1ZGlvRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZmFpbCA9IChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICBjb21wbGV0ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMjY6IFNhZmFyaSB0aHJvd3MgYSBzeW5jaHJvbm91cyBlcnJvci5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOiBTYWZhcmkgcmVxdWlyZXMgYSBzdWNjZXNzQ2FsbGJhY2suXG4gICAgICAgICAgICAgICAgbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhLCAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMDogU2FmYXJpIGRvZXMgdGhyb3cgYSB3cm9uZyBlcnJvciB3aGVuIGNhbGxpbmcgZ2V0Q2hhbm5lbERhdGEoKSB3aXRoIGFuIG91dC1vZi1ib3VuZHMgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGUoKS50aGVuKCgpID0+IHJlc29sdmUoYXVkaW9CdWZmZXIpKTtcbiAgICAgICAgICAgICAgICB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDogU2FmYXJpIHJldHVybnMgbnVsbCBpbnN0ZWFkIG9mIGFuIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGNyZWF0ZUVuY29kaW5nRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBmYWlsKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVjb2RlLWF1ZGlvLWRhdGEuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlciA9IChjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGN5Y2xlQ291bnRlcnMsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGdldE5hdGl2ZUNvbnRleHQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgY291bnQpID0+IHtcbiAgICAgICAgY29uc3QgY3ljbGVDb3VudGVyID0gY3ljbGVDb3VudGVycy5nZXQoYXVkaW9Ob2RlKTtcbiAgICAgICAgaWYgKGN5Y2xlQ291bnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIGV4cGVjdGVkIGN5Y2xlIGNvdW50LicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGF1ZGlvTm9kZS5jb250ZXh0KTtcbiAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAoY3ljbGVDb3VudGVyID09PSBjb3VudCkge1xuICAgICAgICAgICAgY3ljbGVDb3VudGVycy5kZWxldGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmIGlzQWN0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBvdXRwdXQgb2Ygb3V0cHV0cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0WzFdLCBvdXRwdXRbMl0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtLCBvdXRwdXRbMV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY3ljbGVDb3VudGVycy5zZXQoYXVkaW9Ob2RlLCBjeWNsZUNvdW50ZXIgLSBjb3VudCk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlY3JlbWVudC1jeWNsZS1jb3VudGVyLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRlbGF5VGltZTogMCxcbiAgICBtYXhEZWxheVRpbWU6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgRGVsYXlOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVsYXlOb2RlID0gY3JlYXRlTmF0aXZlRGVsYXlOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZGVsYXlOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIobWVyZ2VkT3B0aW9ucy5tYXhEZWxheVRpbWUpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlRGVsYXlOb2RlLCBkZWxheU5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9kZWxheVRpbWUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCBtZXJnZWRPcHRpb25zLm1heERlbGF5VGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRlbGF5VGltZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWxheVRpbWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGF5LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKG1heERlbGF5VGltZSkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVEZWxheU5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVEZWxheU5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZURlbGF5Tm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZURlbGF5Tm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRlbGF5VGltZTogbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF4RGVsYXlUaW1lXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVEZWxheU5vZGUgPSBjcmVhdGVOYXRpdmVEZWxheU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZURlbGF5Tm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRlbGF5VGltZSwgbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZWxheVRpbWUsIG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZURlbGF5Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlRGVsYXlOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEZWxheU5vZGUgPSByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVEZWxheU5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRGVsYXlOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAocGlja0VsZW1lbnRGcm9tU2V0KSA9PiB7XG4gICAgcmV0dXJuIChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgICAgICByZXR1cm4gcGlja0VsZW1lbnRGcm9tU2V0KGFjdGl2ZUlucHV0c1tpbnB1dF0sIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSA9IChnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGF1ZGlvV29ya2xldE5vZGUpID0+IHtcbiAgICAgICAgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKG5hdGl2ZUNvbnRleHQpLmRlbGV0ZShhdWRpb1dvcmtsZXROb2RlKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNEZWxheU5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdkZWxheVRpbWUnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNEZWxheU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvZGVsYXktbm9kZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGV0ZWN0Q3ljbGVzID0gKGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldFZhbHVlRm9yS2V5KSA9PiB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGRldGVjdEN5Y2xlcyhjaGFpbiwgbmV4dExpbmspIHtcbiAgICAgICAgY29uc3QgYXVkaW9Ob2RlID0gaXNBdWRpb05vZGUobmV4dExpbmspID8gbmV4dExpbmsgOiBnZXRWYWx1ZUZvcktleShhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIG5leHRMaW5rKTtcbiAgICAgICAgaWYgKGlzRGVsYXlOb2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhaW5bMF0gPT09IGF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuIFtjaGFpbl07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYWluLmluY2x1ZGVzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKG91dHB1dHMpXG4gICAgICAgICAgICAubWFwKChvdXRwdXRDb25uZWN0aW9uKSA9PiBkZXRlY3RDeWNsZXMoWy4uLmNoYWluLCBhdWRpb05vZGVdLCBvdXRwdXRDb25uZWN0aW9uWzBdKSlcbiAgICAgICAgICAgIC5yZWR1Y2UoKG1lcmdlZEN5Y2xlcywgbmVzdGVkQ3ljbGVzKSA9PiBtZXJnZWRDeWNsZXMuY29uY2F0KG5lc3RlZEN5Y2xlcyksIFtdKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRldGVjdC1jeWNsZXMuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUnO1xuY29uc3QgZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleCA9IChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2Rlcywgb3V0cHV0KSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0QXVkaW9Ob2RlID0gb3V0cHV0QXVkaW9Ob2Rlc1tvdXRwdXRdO1xuICAgIGlmIChvdXRwdXRBdWRpb05vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2RlO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVEaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbk9yT3V0cHV0ID0gdW5kZWZpbmVkLCBvdXRwdXQgPSB1bmRlZmluZWQsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2Rlcy5mb3JFYWNoKChvdXRwdXRBdWRpb05vZGUpID0+IG91dHB1dEF1ZGlvTm9kZS5kaXNjb25uZWN0KCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbk9yT3V0cHV0KS5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2Rlcy5mb3JFYWNoKChvdXRwdXRBdWRpb05vZGUpID0+IG91dHB1dEF1ZGlvTm9kZS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbnB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgMCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZXMuZm9yRWFjaCgob3V0cHV0QXVkaW9Ob2RlKSA9PiBvdXRwdXRBdWRpb05vZGUuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCAwKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpc2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cy5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgYXR0YWNrOiAwLjAwMyxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAga25lZTogMzAsXG4gICAgcmF0aW86IDEyLFxuICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgdGhyZXNob2xkOiAtMjRcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIER5bmFtaWNzQ29tcHJlc3Nvck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9hdHRhY2sgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5hdHRhY2spO1xuICAgICAgICAgICAgdGhpcy5fa25lZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgICAgICAgICB0aGlzLl9yYXRpbyA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvKTtcbiAgICAgICAgICAgIHRoaXMuX3JlbGVhc2UgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlKTtcbiAgICAgICAgICAgIHRoaXMuX3RocmVzaG9sZCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZCk7XG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAwLjAwNik7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGF0dGFjaygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hdHRhY2s7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDg6IFNhZmFyaSBhbGxvd3MgYSBjaGFubmVsQ291bnQgb2YgdGhyZWUgYW5kIGFib3ZlIHdoaWNoIGlzIHdoeSB0aGUgZ2V0dGVyIGFuZCBzZXR0ZXIgbmVlZHMgdG8gYmUgb3ZlcndyaXR0ZW4gaGVyZS5cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0NoYW5uZWxDb3VudCA9IHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IDIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IHByZXZpb3VzQ2hhbm5lbENvdW50O1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDk6IE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IGRpc2FsbG93IGEgY2hhbm5lbENvdW50TW9kZSBvZiAnbWF4JyB5ZXQgd2hpY2ggaXMgd2h5IHRoZSBnZXR0ZXIgYW5kIHNldHRlciBuZWVkcyB0byBiZVxuICAgICAgICAgKiBvdmVyd3JpdHRlbiBoZXJlLlxuICAgICAgICAgKi9cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0NoYW5uZWxDb3VudCA9IHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHByZXZpb3VzQ2hhbm5lbENvdW50O1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGtuZWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fa25lZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmF0aW8oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmF0aW87XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTExOiBTYWZhcmkgcmV0dXJucyBhbiBBdWRpb1BhcmFtIGluc3RlYWQgb2YgYSBudW1iZXIuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVkdWN0aW9uLnZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbi52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmVsZWFzZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWxlYXNlO1xuICAgICAgICB9XG4gICAgICAgIGdldCB0aHJlc2hvbGQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGhyZXNob2xkO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlXG4gICAgICAgICAgICAgKiBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBrbmVlOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJhdGlvOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZDogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5hdHRhY2ssIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmtuZWUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUua25lZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yYXRpbywgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpbyk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yZWxlYXNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkudGhyZXNob2xkLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5hdHRhY2ssIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5rbmVlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnJhdGlvLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yZWxlYXNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnRocmVzaG9sZCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRW5jb2RpbmdFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdFbmNvZGluZ0Vycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lbmNvZGluZy1lcnJvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRXZhbHVhdGVTb3VyY2UgPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChzb3VyY2UpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZCA9IHdpbmRvdy5kb2N1bWVudC5oZWFkO1xuICAgICAgICBpZiAoaGVhZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzY3JpcHQgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgICAvLyBAdG9kbyBTYWZhcmkgZG9lc24ndCBsaWtlIFVSTHMgd2l0aCBhIHR5cGUgb2YgJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9dXRmLTgnLlxuICAgICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtzb3VyY2VdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JyB9KTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyID0gd2luZG93Lm9uZXJyb3I7XG4gICAgICAgICAgICBjb25zdCByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgd2luZG93Lm9uZXJyb3IgPSBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyO1xuICAgICAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB3aW5kb3cub25lcnJvciA9IChtZXNzYWdlLCBzcmMsIGxpbmVubywgY29sbm8sIGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRWRnZSB0aGlua3MgdGhlIHNvdXJjZSBpcyB0aGUgb25lIG9mIHRoZSBodG1sIGRvY3VtZW50LlxuICAgICAgICAgICAgICAgIGlmIChzcmMgPT09IHVybCB8fCAoc3JjID09PSB3aW5kb3cubG9jYXRpb24uaHJlZiAmJiBsaW5lbm8gPT09IDEgJiYgY29sbm8gPT09IDEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUVycm9yRXZlbnRMaXN0ZW5lckFuZFJldm9rZVVybCgpO1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbE9uRXJyb3JIYW5kbGVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyKG1lc3NhZ2UsIHNyYywgbGluZW5vLCBjb2xubywgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzY3JpcHQub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE4MiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgYSBTeW50YXhFcnJvciBpbnN0ZWFkIG9mIGEgRE9NRXhjZXB0aW9uLlxuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0Lm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0LnNyYyA9IHVybDtcbiAgICAgICAgICAgIHNjcmlwdC50eXBlID0gJ21vZHVsZSc7XG4gICAgICAgICAgICBoZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmFsdWF0ZS1zb3VyY2UuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV2ZW50VGFyZ2V0Q29uc3RydWN0b3IgPSAod3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgRXZlbnRUYXJnZXQge1xuICAgICAgICBjb25zdHJ1Y3RvcihfbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0ID0gX25hdGl2ZUV2ZW50VGFyZ2V0O1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgfVxuICAgICAgICBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPSB0aGlzLl9saXN0ZW5lcnMuZ2V0KGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICBpZiAod3JhcHBlZEV2ZW50TGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnNldChsaXN0ZW5lciwgd3JhcHBlZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgd3JhcHBlZEV2ZW50TGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRpc3BhdGNoRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9IGxpc3RlbmVyID09PSBudWxsID8gdW5kZWZpbmVkIDogdGhpcy5fbGlzdGVuZXJzLmdldChsaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIHdyYXBwZWRFdmVudExpc3RlbmVyID09PSB1bmRlZmluZWQgPyBudWxsIDogd3JhcHBlZEV2ZW50TGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC10YXJnZXQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lID0gKHdpbmRvdykgPT4ge1xuICAgIHJldHVybiAoY3VycmVudFRpbWUsIHNhbXBsZVJhdGUsIGZuKSA9PiB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdywge1xuICAgICAgICAgICAgY3VycmVudEZyYW1lOiB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoY3VycmVudFRpbWUgKiBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY3VycmVudFRpbWU6IHtcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBmbigpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKHdpbmRvdyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuY3VycmVudEZyYW1lO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuY3VycmVudFRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV4cG9zZS1jdXJyZW50LWZyYW1lLWFuZC1jdXJyZW50LXRpbWUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUZldGNoU291cmNlID0gKGNyZWF0ZUFib3J0RXJyb3IpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKHVybCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFthd2FpdCByZXNwb25zZS50ZXh0KCksIHJlc3BvbnNlLnVybF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfSAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRocm93IGNyZWF0ZUFib3J0RXJyb3IoKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZldGNoLXNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZ2FpbjogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVHYWluTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVHYWluTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEdhaW5Ob2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlR2Fpbk5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlR2Fpbk5vZGUsIGdhaW5Ob2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM3NDogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2dhaW4gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlR2Fpbk5vZGUuZ2FpbiwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZ2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nYWluO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVHYWluTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVHYWluTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUdhaW5Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVHYWluTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlR2Fpbk5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUdhaW5Ob2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlR2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IG5hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUdhaW5Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmdhaW4sIG5hdGl2ZUdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlR2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVHYWluTm9kZSA9IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVHYWluTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVHYWluTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IChhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIGdldFZhbHVlRm9yS2V5KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlKSA9PiBnZXRWYWx1ZUZvcktleShhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIgPSAoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9ucyA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIGlmIChhdWRpb05vZGVDb25uZWN0aW9ucy5yZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSByZW5kZXJlciBvZiB0aGUgZ2l2ZW4gQXVkaW9Ob2RlIGluIHRoZSBhdWRpbyBncmFwaC4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXVkaW9Ob2RlQ29ubmVjdGlvbnMucmVuZGVyZXI7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tbm9kZS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSAoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlKSA9PiB7IHZhciBfYTsgcmV0dXJuIChfYSA9IGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUuZ2V0KGF1ZGlvTm9kZSkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IDA7IH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRBdWRpb1BhcmFtUmVuZGVyZXIgPSAoZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgaWYgKGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5yZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSByZW5kZXJlciBvZiB0aGUgZ2l2ZW4gQXVkaW9QYXJhbSBpbiB0aGUgYXVkaW8gZ3JhcGguJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5yZW5kZXJlcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1wYXJhbS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnSW52YWxpZFN0YXRlRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludmFsaWQtc3RhdGUtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdldE5hdGl2ZUNvbnRleHQgPSAoY29udGV4dFN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChjb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBjb250ZXh0U3RvcmUuZ2V0KGNvbnRleHQpO1xuICAgICAgICBpZiAobmF0aXZlQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAobmF0aXZlQ29udGV4dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBsZXQgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgIGlmIChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNDE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNyZWF0aW5nIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aCBsZXNzIHRoYW4gNDQxMDAgSHouXG4gICAgICAgIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLnNldChuYXRpdmVDb250ZXh0LCBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9ICh1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9IHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAodW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNvbnRleHQgaGFzIG5vIHNldCBvZiBBdWRpb1dvcmtsZXROb2Rlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2Rlcy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0ludmFsaWRBY2Nlc3NFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW52YWxpZC1hY2Nlc3MtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2ludmFsaWQtYWNjZXNzLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwSUlSRmlsdGVyTm9kZUdldEZyZXF1ZW5jeVJlc3BvbnNlTWV0aG9kID0gKG5hdGl2ZUlJUkZpbHRlck5vZGUpID0+IHtcbiAgICBuYXRpdmVJSVJGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlID0gKChnZXRGcmVxdWVuY3lSZXNwb25zZSkgPT4ge1xuICAgICAgICByZXR1cm4gKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGZyZXF1ZW5jeUh6Lmxlbmd0aCAhPT0gbWFnUmVzcG9uc2UubGVuZ3RoIHx8IG1hZ1Jlc3BvbnNlLmxlbmd0aCAhPT0gcGhhc2VSZXNwb25zZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZXRGcmVxdWVuY3lSZXNwb25zZS5jYWxsKG5hdGl2ZUlJUkZpbHRlck5vZGUsIGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSk7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgd3JhcElJUkZpbHRlck5vZGVHZXRGcmVxdWVuY3lSZXNwb25zZU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2Vycydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlSUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlLCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgSUlSRmlsdGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIGlzT2ZmbGluZSA/IG51bGwgOiBjb250ZXh0LmJhc2VMYXRlbmN5LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlpckZpbHRlck5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyKG1lcmdlZE9wdGlvbnMuZmVlZGJhY2ssIG1lcmdlZE9wdGlvbnMuZmVlZGZvcndhcmQpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUlJUkZpbHRlck5vZGUsIGlpckZpbHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzIzICYgIzI0OiBGaXJlZm94RGV2ZWxvcGVyIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvci5cbiAgICAgICAgICAgIC8vIEB0b2RvIFdyaXRlIGEgdGVzdCB3aGljaCBhbGxvd3Mgb3RoZXIgYnJvd3NlcnMgdG8gcmVtYWluIHVucGF0Y2hlZC5cbiAgICAgICAgICAgIHdyYXBJSVJGaWx0ZXJOb2RlR2V0RnJlcXVlbmN5UmVzcG9uc2VNZXRob2QobmF0aXZlSUlSRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiBhcyBzaGFtZWxlc3NseSBpbnNwaXJlZCBieSBzb3VyY2UgY29kZSBvZlxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuLy8ge0BsaW5rIGh0dHBzOi8vY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMuZ2l0LysvbWFzdGVyL3RoaXJkX3BhcnR5L1dlYktpdC9Tb3VyY2UvcGxhdGZvcm0vYXVkaW8vSUlSRmlsdGVyLmNwcHxDaHJvbWl1bSdzIElJUkZpbHRlcn0uXG5leHBvcnQgY29uc3QgZmlsdGVyQnVmZmVyID0gKGZlZWRiYWNrLCBmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmQsIGZlZWRmb3J3YXJkTGVuZ3RoLCBtaW5MZW5ndGgsIHhCdWZmZXIsIHlCdWZmZXIsIGJ1ZmZlckluZGV4LCBidWZmZXJMZW5ndGgsIGlucHV0LCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aDtcbiAgICBsZXQgaSA9IGJ1ZmZlckluZGV4O1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7IGogKz0gMSkge1xuICAgICAgICBsZXQgeSA9IGZlZWRmb3J3YXJkWzBdICogaW5wdXRbal07XG4gICAgICAgIGZvciAobGV0IGsgPSAxOyBrIDwgbWluTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHggPSAoaSAtIGspICYgKGJ1ZmZlckxlbmd0aCAtIDEpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgICAgIHkgKz0gZmVlZGZvcndhcmRba10gKiB4QnVmZmVyW3hdO1xuICAgICAgICAgICAgeSAtPSBmZWVkYmFja1trXSAqIHlCdWZmZXJbeF07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgayA9IG1pbkxlbmd0aDsgayA8IGZlZWRmb3J3YXJkTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIHkgKz0gZmVlZGZvcndhcmRba10gKiB4QnVmZmVyWyhpIC0gaykgJiAoYnVmZmVyTGVuZ3RoIC0gMSldOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBrID0gbWluTGVuZ3RoOyBrIDwgZmVlZGJhY2tMZW5ndGg7IGsgKz0gMSkge1xuICAgICAgICAgICAgeSAtPSBmZWVkYmFja1trXSAqIHlCdWZmZXJbKGkgLSBrKSAmIChidWZmZXJMZW5ndGggLSAxKV07IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYml0d2lzZVxuICAgICAgICB9XG4gICAgICAgIHhCdWZmZXJbaV0gPSBpbnB1dFtqXTtcbiAgICAgICAgeUJ1ZmZlcltpXSA9IHk7XG4gICAgICAgIGkgPSAoaSArIDEpICYgKGJ1ZmZlckxlbmd0aCAtIDEpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgb3V0cHV0W2pdID0geTtcbiAgICB9XG4gICAgcmV0dXJuIGk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsdGVyLWJ1ZmZlci5qcy5tYXAiLCJpbXBvcnQgeyBmaWx0ZXJCdWZmZXIgfSBmcm9tICcuLi9oZWxwZXJzL2ZpbHRlci1idWZmZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5jb25zdCBmaWx0ZXJGdWxsQnVmZmVyID0gKHJlbmRlcmVkQnVmZmVyLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBmZWVkYmFjaywgZmVlZGZvcndhcmQpID0+IHtcbiAgICBjb25zdCBjb252ZXJ0ZWRGZWVkYmFjayA9IGZlZWRiYWNrIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGJhY2sgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRiYWNrKTtcbiAgICBjb25zdCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCA9IGZlZWRmb3J3YXJkIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGZvcndhcmQgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRmb3J3YXJkKTtcbiAgICBjb25zdCBmZWVkYmFja0xlbmd0aCA9IGNvbnZlcnRlZEZlZWRiYWNrLmxlbmd0aDtcbiAgICBjb25zdCBmZWVkZm9yd2FyZExlbmd0aCA9IGNvbnZlcnRlZEZlZWRmb3J3YXJkLmxlbmd0aDtcbiAgICBjb25zdCBtaW5MZW5ndGggPSBNYXRoLm1pbihmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmRMZW5ndGgpO1xuICAgIGlmIChjb252ZXJ0ZWRGZWVkYmFja1swXSAhPT0gMSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZlZWRiYWNrTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRmb3J3YXJkW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmVlZGZvcndhcmRMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29udmVydGVkRmVlZGJhY2tbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgYnVmZmVyTGVuZ3RoID0gMzI7XG4gICAgY29uc3QgeEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICBjb25zdCB5QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuICAgIGNvbnN0IGZpbHRlcmVkQnVmZmVyID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIocmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVscywgcmVuZGVyZWRCdWZmZXIubGVuZ3RoLCByZW5kZXJlZEJ1ZmZlci5zYW1wbGVSYXRlKTtcbiAgICBjb25zdCBudW1iZXJPZkNoYW5uZWxzID0gcmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mQ2hhbm5lbHM7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHJlbmRlcmVkQnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBmaWx0ZXJlZEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgeEJ1ZmZlci5maWxsKDApO1xuICAgICAgICB5QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgIGZpbHRlckJ1ZmZlcihjb252ZXJ0ZWRGZWVkYmFjaywgZmVlZGJhY2tMZW5ndGgsIGNvbnZlcnRlZEZlZWRmb3J3YXJkLCBmZWVkZm9yd2FyZExlbmd0aCwgbWluTGVuZ3RoLCB4QnVmZmVyLCB5QnVmZmVyLCAwLCBidWZmZXJMZW5ndGgsIGlucHV0LCBvdXRwdXQpO1xuICAgIH1cbiAgICByZXR1cm4gZmlsdGVyZWRCdWZmZXI7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGZlZWRiYWNrLCBmZWVkZm9yd2FyZCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgZmlsdGVyZWRCdWZmZXJQcm9taXNlID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVJSVJGaWx0ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlSUlSRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUlJUkZpbHRlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICM5OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBJSVJGaWx0ZXJOb2Rlcy5cbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUlJUkZpbHRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZUlJUkZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBkZWZpbmVzIHRoZSBwYXJhbWV0ZXJzIG9mIGNyZWF0ZUlJUkZpbHRlcigpIGFzIGFycmF5cyBvZiBudW1iZXJzLlxuICAgICAgICAgICAgICAgIG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUlJUkZpbHRlcihmZWVkZm9yd2FyZCwgZmVlZGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPT09IG51bGwgPyBuYXRpdmVJSVJGaWx0ZXJOb2RlIDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGdldHMgbm90IGluaXRpYWxpemVkIGNvcnJlY3RseS5cbiAgICAgICAgICAgICAgICAgICAgcHJveHkuY29udGV4dC5kZXN0aW5hdGlvbi5jaGFubmVsQ291bnQsIFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgICAgICAgICBwcm94eS5jb250ZXh0Lmxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyZWRCdWZmZXJQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWRCdWZmZXIgPSBhd2FpdCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJGdWxsQnVmZmVyKHJlbmRlcmVkQnVmZmVyLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBmZWVkYmFjaywgZmVlZGZvcndhcmQpO1xuICAgICAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZEJ1ZmZlciA9IGF3YWl0IGZpbHRlcmVkQnVmZmVyUHJvbWlzZTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gZmlsdGVyZWRCdWZmZXI7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlSUlSRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1paXItZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24gfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tbm9kZS1vdXRwdXQtY29ubmVjdGlvbic7XG5leHBvcnQgY29uc3QgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyRmFjdG9yeSA9IChjeWNsZUNvdW50ZXJzLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9QYXJhbSwgaXNBY3RpdmVBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKGlzT2ZmbGluZSkgPT4ge1xuICAgICAgICByZXR1cm4gKGF1ZGlvTm9kZSwgY291bnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGN5Y2xlQ291bnRlciA9IGN5Y2xlQ291bnRlcnMuZ2V0KGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoY3ljbGVDb3VudGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiBpc0FjdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0WzFdLCBvdXRwdXRbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSwgb3V0cHV0WzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjeWNsZUNvdW50ZXJzLnNldChhdWRpb05vZGUsIGNvdW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuc2V0KGF1ZGlvTm9kZSwgY3ljbGVDb3VudGVyICsgY291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5jcmVtZW50LWN5Y2xlLWNvdW50ZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQgPSAoY29udGV4dFN0b3JlLCBpc05hdGl2ZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGNvbnRleHRTdG9yZS5nZXQoYW55dGhpbmcpO1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgfHwgaXNOYXRpdmVBdWRpb0NvbnRleHQoYW55dGhpbmcpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYW55LWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55QXVkaW9Ob2RlID0gKGF1ZGlvTm9kZVN0b3JlLCBpc05hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IGF1ZGlvTm9kZVN0b3JlLmhhcyhhbnl0aGluZykgfHwgaXNOYXRpdmVBdWRpb05vZGUoYW55dGhpbmcpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc0FueUF1ZGlvUGFyYW0gPSAoYXVkaW9QYXJhbVN0b3JlLCBpc05hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiBhdWRpb1BhcmFtU3RvcmUuaGFzKGFueXRoaW5nKSB8fCBpc05hdGl2ZUF1ZGlvUGFyYW0oYW55dGhpbmcpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1wYXJhbS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGNvbnRleHRTdG9yZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gY29udGV4dFN0b3JlLmdldChhbnl0aGluZyk7XG4gICAgICAgIHJldHVybiBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgfHwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGFueXRoaW5nKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQXVkaW9Db250ZXh0ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUF1ZGlvTm9kZSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiB3aW5kb3cgIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvdy5BdWRpb05vZGUgPT09ICdmdW5jdGlvbicgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiB3aW5kb3cuQXVkaW9Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQXVkaW9QYXJhbSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiB3aW5kb3cgIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvdy5BdWRpb1BhcmFtID09PSAnZnVuY3Rpb24nICYmIGFueXRoaW5nIGluc3RhbmNlb2Ygd2luZG93LkF1ZGlvUGFyYW07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtYXVkaW8tcGFyYW0uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQ29udGV4dCA9IChpc05hdGl2ZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVBdWRpb0NvbnRleHQoYW55dGhpbmcpIHx8IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChhbnl0aGluZyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBhbnl0aGluZyBpbnN0YW5jZW9mIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzU2VjdXJlQ29udGV4dCA9ICh3aW5kb3cpID0+IHdpbmRvdyAhPT0gbnVsbCAmJiB3aW5kb3cuaXNTZWN1cmVDb250ZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtc2VjdXJlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgLy8gQnVnICMxNzE6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSwgbnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1lZGlhRWxlbWVudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUubWVkaWFFbGVtZW50O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2Vycydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICAvLyBCdWcgIzE3MzogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0cmVhbSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLnN0cmVhbTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTcyOiBTYWZhcmkgYWxsb3dzIHRvIGNyZWF0ZSBhIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSwgbnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtZWRpYVN0cmVhbSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZS5tZWRpYVN0cmVhbTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIG51bGwpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgaXNWYWxpZExhdGVuY3lIaW50IH0gZnJvbSAnLi4vaGVscGVycy9pcy12YWxpZC1sYXRlbmN5LWhpbnQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWluaW1hbEF1ZGlvQ29udGV4dCBleHRlbmRzIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE5MiBTYWZhcmkgZG9lcyB0aHJvdyBhIFN5bnRheEVycm9yIGlmIHRoZSBzYW1wbGVSYXRlIGlzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMiAmJiBlcnIubWVzc2FnZSA9PT0gJ3NhbXBsZVJhdGUgaXMgbm90IGluIHJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzEzMSBTYWZhcmkgcmV0dXJucyBudWxsIHdoZW4gdGhlcmUgYXJlIGZvdXIgb3RoZXIgQXVkaW9Db250ZXh0cyBydW5uaW5nIGFscmVhZHkuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlVW5rbm93bkVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzUxIE9ubHkgQ2hyb21lIGFuZCBFZGdlIHRocm93IGFuIGVycm9yIGlmIHRoZSBnaXZlbiBsYXRlbmN5SGludCBpcyBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTGF0ZW5jeUhpbnQob3B0aW9ucy5sYXRlbmN5SGludCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgcHJvdmlkZWQgdmFsdWUgJyR7b3B0aW9ucy5sYXRlbmN5SGludH0nIGlzIG5vdCBhIHZhbGlkIGVudW0gdmFsdWUgb2YgdHlwZSBBdWRpb0NvbnRleHRMYXRlbmN5Q2F0ZWdvcnkuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzE1MCBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBzZXR0aW5nIHRoZSBzYW1wbGVSYXRlLlxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2FtcGxlUmF0ZSAhPT0gdW5kZWZpbmVkICYmIG5hdGl2ZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlICE9PSBvcHRpb25zLnNhbXBsZVJhdGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlQXVkaW9Db250ZXh0LCAyKTtcbiAgICAgICAgICAgIGNvbnN0IHsgbGF0ZW5jeUhpbnQgfSA9IG9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCB7IHNhbXBsZVJhdGUgfSA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEB0b2RvIFRoZSB2YWx1ZXMgZm9yICdiYWxhbmNlZCcsICdpbnRlcmFjdGl2ZScgYW5kICdwbGF5YmFjaycgYXJlIGp1c3QgY29waWVkIGZyb20gQ2hyb21lJ3MgaW1wbGVtZW50YXRpb24uXG4gICAgICAgICAgICB0aGlzLl9iYXNlTGF0ZW5jeSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIG5hdGl2ZUF1ZGlvQ29udGV4dC5iYXNlTGF0ZW5jeSA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICAgICAgPyBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3lcbiAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2JhbGFuY2VkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyA1MTIgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAnaW50ZXJhY3RpdmUnIHx8IGxhdGVuY3lIaW50ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDI1NiAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAncGxheWJhY2snXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMTAyNCAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAvKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIEB0b2RvIFRoZSBtaW4gKDI1NikgYW5kIG1heCAoMTYzODQpIHZhbHVlcyBhcmUgdGFrZW4gZnJvbSB0aGUgYWxsb3dlZCBidWZmZXJTaXplIHZhbHVlcyBvZiBhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogU2NyaXB0UHJvY2Vzc29yTm9kZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChNYXRoLm1heCgyLCBNYXRoLm1pbigxMjgsIE1hdGgucm91bmQoKGxhdGVuY3lIaW50ICogc2FtcGxlUmF0ZSkgLyAxMjgpKSkgKiAxMjgpIC8gc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg4OiBTYWZhcmkgd2lsbCBzZXQgdGhlIGNvbnRleHQncyBzdGF0ZSB0byAnaW50ZXJydXB0ZWQnIGluIGNhc2UgdGhlIHVzZXIgc3dpdGNoZXMgdGFicy5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZ2Fpbi52YWx1ZSA9IDFlLTM3O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmNvbm5lY3QodGhpcy5fbmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzM0OiBDaHJvbWUgYW5kIEVkZ2UgcHJldGVuZCB0byBiZSBydW5uaW5nIHJpZ2h0IGF3YXksIGJ1dCBmaXJlIGFuIG9uc3RhdGVjaGFuZ2UgZXZlbnQgd2hlbiB0aGUgc3RhdGUgYWN0dWFsbHkgY2hhbmdlc1xuICAgICAgICAgICAgICogdG8gJ3J1bm5pbmcnLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9ICdzdXNwZW5kZWQnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJldm9rZVN0YXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBiYXNlTGF0ZW5jeSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9iYXNlTGF0ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgIT09IG51bGwgPyB0aGlzLl9zdGF0ZSA6IHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBjbG9zZSgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMzU6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIEF1ZGlvQ29udGV4dCB3YXMgY2xvc2VkIGJlZm9yZS5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMzQ6IElmIHRoZSBzdGF0ZSB3YXMgc2V0IHRvIHN1c3BlbmRlZCBiZWZvcmUgaXQgc2hvdWxkIGJlIHJldm9rZWQgbm93LlxuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlR2Fpbk5vZGUgIT09IG51bGwgJiYgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVhY3RpdmF0ZUF1ZGlvR3JhcGgodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bWUoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZVByb21pc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VtZSgpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZXN1bWUoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NTogQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciBpbnN0ZWFkIG9mIGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCB8fCBlcnIuY29kZSA9PT0gMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc3VzcGVuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3VzcGVuZCgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbmltYWwtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBDT05URVhUX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0xpc3RlbmVyLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUsIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxCYXNlQXVkaW9Db250ZXh0IGV4dGVuZHMgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKF9uYXRpdmVDb250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICBzdXBlcihfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0ID0gX25hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICBDT05URVhUX1NUT1JFLnNldCh0aGlzLCBfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KF9uYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUuc2V0KF9uYXRpdmVDb250ZXh0LCBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fZGVzdGluYXRpb24gPSBuZXcgYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3Rvcih0aGlzLCBudW1iZXJPZkNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVyID0gY3JlYXRlQXVkaW9MaXN0ZW5lcih0aGlzLCBfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLl9vbnN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY3VycmVudFRpbWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZGVzdGluYXRpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVzdGluYXRpb247XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxpc3RlbmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xpc3RlbmVyO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbnN0YXRlY2hhbmdlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uc3RhdGVjaGFuZ2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uc3RhdGVjaGFuZ2UodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSB3cmFwcGVkTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPblN0YXRlQ2hhbmdlID0gdGhpcy5fbmF0aXZlQ29udGV4dC5vbnN0YXRlY2hhbmdlO1xuICAgICAgICAgICAgdGhpcy5fb25zdGF0ZWNoYW5nZSA9IG5hdGl2ZU9uU3RhdGVDaGFuZ2UgIT09IG51bGwgJiYgbmF0aXZlT25TdGF0ZUNoYW5nZSA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPblN0YXRlQ2hhbmdlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udGV4dC5zdGF0ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaW1hbC1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RQcm9taXNlU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgLy8gVGhpcyAxMiBudW1iZXJzIHJlcHJlc2VudCB0aGUgNDggYnl0ZXMgb2YgYW4gZW1wdHkgV0FWRSBmaWxlIHdpdGggYSBzaW5nbGUgc2FtcGxlLlxuICAgIGNvbnN0IHVpbnQzMkFycmF5ID0gbmV3IFVpbnQzMkFycmF5KFsxMTc5MDExNDEwLCA0MCwgMTE2MzI4MDcyNywgNTQ0NTAxMDk0LCAxNiwgMTMxMDczLCA0NDEwMCwgMTc2NDAwLCAxMDQ4NTgwLCAxNjM1MDE3MDYwLCA0LCAwXSk7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gQnVnICMxOiBTYWZhcmkgcmVxdWlyZXMgYSBzdWNjZXNzQ2FsbGJhY2suXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuYXRpdmVDb250ZXh0LmRlY29kZUF1ZGlvRGF0YSh1aW50MzJBcnJheS5idWZmZXIsICgpID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgc3VjY2VzcyBjYWxsYmFjay5cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwcm9taXNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBwcm9taXNlLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSByZWplY3RlZCBlcnJvcnMuXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1wcm9taXNlLXN1cHBvcnQuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbnVtYmVyT2ZDaGFubmVsczogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHN0YXJ0UmVuZGVyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0IGV4dGVuZHMgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0gPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vICMyMSBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyBhbmQgdGhlcmVmb3JlIHdvdWxkIGZpcmUgdGhlIHN0YXRlY2hhbmdlIGV2ZW50IGJlZm9yZSB0aGUgcHJvbWlzZSBjYW4gYmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsYXlTdGF0ZUNoYW5nZUV2ZW50O1xuICAgICAgICAgICAgICAgIH0pKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgPT09IG51bGwgPyB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXRlIDogdGhpcy5fc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRSZW5kZXJpbmcoKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM5ICYgIzU5OiBJdCBpcyB0aGVvcmV0aWNhbGx5IHBvc3NpYmxlIHRoYXQgc3RhcnRSZW5kZXJpbmcoKSB3aWxsIGZpcnN0IHJlbmRlciBhIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LiBUaGVyZWZvcmVcbiAgICAgICAgICAgICAqIHRoZSBzdGF0ZSBvZiB0aGUgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCBtaWdodCBubyB0cmFuc2l0aW9uIHRvIHJ1bm5pbmcgaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAncnVubmluZyc7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnRSZW5kZXJpbmcodGhpcy5kZXN0aW5hdGlvbiwgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaW1hbC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1vbml0b3JDb25uZWN0aW9ucyA9IChpbnNlcnRFbGVtZW50SW5TZXQsIGlzTmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb05vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpID0+IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgU2V0KCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0ID0gKChjb25uZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6aW52YWxpZC12b2lkIG5vLWluZmVycmFibGUtdHlwZXNcbiAgICAgICAgICAgIHJldHVybiAoZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdhc0Rpc2Nvbm5lY3RlZCA9IGNvbm5lY3Rpb25zLnNpemUgPT09IDA7XG4gICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGNvbm5lY3Rpb25zLCBbZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXRdLCAoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgY29ubmVjdGlvblsxXSA9PT0gb3V0cHV0ICYmIGNvbm5lY3Rpb25bMl0gPT09IGlucHV0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdhc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hlbkNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZXN0aW5hdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb24sIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGNvbm5lY3Rpb25zLCBbZGVzdGluYXRpb24sIG91dHB1dF0sIChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBjb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIHRydWUpO1xuICAgICAgICAgICAgICAgIGlmICh3YXNEaXNjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hlbkNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShuYXRpdmVBdWRpb05vZGUuY29ubmVjdCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0ID0gKChkaXNjb25uZWN0KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB3YXNDb25uZWN0ZWQgPSBjb25uZWN0aW9ucy5zaXplID4gMDtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuYXBwbHkobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDEgYXJndW1lbnQgeWV0LlxuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvblsxXSA9PT0gZGVzdGluYXRpb25Pck91dHB1dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDIgYXJndW1lbnRzIHlldC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb25Pck91dHB1dCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvdXRwdXQgPT09IHVuZGVmaW5lZCB8fCBjb25uZWN0aW9uWzFdID09PSBvdXRwdXQpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgY29ubmVjdGlvblsyXSA9PT0gaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlzRGlzY29ubmVjdGVkID0gY29ubmVjdGlvbnMuc2l6ZSA9PT0gMDtcbiAgICAgICAgICAgICAgICBpZiAod2FzQ29ubmVjdGVkICYmIGlzRGlzY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHdoZW5EaXNjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb05vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tb25pdG9yLWNvbm5lY3Rpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCBvcHRpb24pID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnNbb3B0aW9uXTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbmF0aXZlQXVkaW9Ob2RlW29wdGlvbl0pIHtcbiAgICAgICAgbmF0aXZlQXVkaW9Ob2RlW29wdGlvbl0gPSB2YWx1ZTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuZXhwb3J0IGNvbnN0IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zKSA9PiB7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgJ2NoYW5uZWxDb3VudCcpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsICdjaGFubmVsQ291bnRNb2RlJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQgPSAobmF0aXZlQW5hbHlzZXJOb2RlKSA9PiB7XG4gICAgcmV0dXJuIHR5cGVvZiBuYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSA9PT0gJ2Z1bmN0aW9uJztcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kID0gKG5hdGl2ZUFuYWx5c2VyTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhID0gKGFycmF5KSA9PiB7XG4gICAgICAgIGNvbnN0IGJ5dGVUaW1lRG9tYWluRGF0YSA9IG5ldyBVaW50OEFycmF5KGFycmF5Lmxlbmd0aCk7XG4gICAgICAgIG5hdGl2ZUFuYWx5c2VyTm9kZS5nZXRCeXRlVGltZURvbWFpbkRhdGEoYnl0ZVRpbWVEb21haW5EYXRhKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5tYXgoYnl0ZVRpbWVEb21haW5EYXRhLmxlbmd0aCwgbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBhcnJheVtpXSA9IChieXRlVGltZURvbWFpbkRhdGFbaV0gLSAxMjgpICogMC4wMDc4MTI1O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGVGYWN0b3J5ID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgICAgICAvLyBCdWcgIzM3OiBGaXJlZm94IGRvZXMgbm90IGNyZWF0ZSBhbiBBbmFseXNlck5vZGUgd2l0aCB0aGUgZGVmYXVsdCBwcm9wZXJ0aWVzLlxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgaWYgKCEob3B0aW9ucy5tYXhEZWNpYmVscyA+IG9wdGlvbnMubWluRGVjaWJlbHMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdmZnRTaXplJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdtYXhEZWNpYmVscycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnbWluRGVjaWJlbHMnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucywgJ3Ntb290aGluZ1RpbWVDb25zdGFudCcpO1xuICAgICAgICAvLyBCdWcgIzM2OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBnZXRGbG9hdFRpbWVEb21haW5EYXRhKCkgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQsICgpID0+IHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydChuYXRpdmVBbmFseXNlck5vZGUpKSkge1xuICAgICAgICAgICAgd3JhcEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2QobmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlQW5hbHlzZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWFuYWx5c2VyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAod2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb0J1ZmZlcicpKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuQXVkaW9CdWZmZXI7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1idWZmZXItY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSA9IChuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsIGF1ZGlvUGFyYW0pID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnNbYXVkaW9QYXJhbV07XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG5hdGl2ZUF1ZGlvTm9kZVthdWRpb1BhcmFtXS52YWx1ZSkge1xuICAgICAgICBuYXRpdmVBdWRpb05vZGVbYXVkaW9QYXJhbV0udmFsdWUgPSB2YWx1ZTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMgPSAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0ID0gKChzdGFydCkgPT4ge1xuICAgICAgICBsZXQgaXNTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pID0+IHtcbiAgICAgICAgICAgIGlmIChpc1NjaGVkdWxlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICBpc1NjaGVkdWxlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyA9IChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUpID0+IHtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RhcnQgPSAoKHN0YXJ0KSA9PiB7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAoKHR5cGVvZiBkdXJhdGlvbiA9PT0gJ251bWJlcicgJiYgZHVyYXRpb24gPCAwKSB8fCBvZmZzZXQgPCAwIHx8IHdoZW4gPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgcGFyYW1ldGVycyBjYW4ndCBiZSBuZWdhdGl2ZS5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgPSAobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0b3AgPSAoKHN0b3ApID0+IHtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCkgPT4ge1xuICAgICAgICAgICAgaWYgKHdoZW4gPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgcGFyYW1ldGVyIGNhbid0IGJlIG5lZ2F0aXZlLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGxpbmcsIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyLCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAncGxheWJhY2tSYXRlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdidWZmZXInKTtcbiAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wRW5kJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wU3RhcnQnKTtcbiAgICAgICAgLy8gQnVnICM2OTogU2FmYXJpIGRvZXMgYWxsb3cgY2FsbHMgdG8gc3RhcnQoKSBvZiBhbiBhbHJlYWR5IHNjaGVkdWxlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE1NCAmICMxNTU6IFNhZmFyaSBkb2VzIG5vdCBoYW5kbGUgb2Zmc2V0cyB3aGljaCBhcmUgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1wbGluZyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTYyOiBTYWZhcmkgZG9lcyB0aHJvdyBhbiBlcnJvciB3aGVuIHN0b3AoKSBpcyBjYWxsZWQgb24gYW4gQXVkaW9CdWZmZXJTb3VyY2VOb2RlIHdoaWNoIGhhcyBubyBidWZmZXIgYXNzaWduZWQgdG8gaXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTk6IFNhZmFyaSBkb2VzIG5vdCBpZ25vcmUgY2FsbHMgdG8gc3RvcCgpIG9mIGFuIGFscmVhZHkgc3RvcHBlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoJ0F1ZGlvQ29udGV4dCcpKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuQXVkaW9Db250ZXh0O1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCd3ZWJraXRBdWRpb0NvbnRleHQnKSA/IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQgOiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uO1xuICAgICAgICAvLyBCdWcgIzEzMjogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50LlxuICAgICAgICBpZiAobmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ICE9PSBjaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY5OiBTYWZhcmkgdGhyb3dzIGFuIGVycm9yIG9uIGVhY2ggYXR0ZW1wdCB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzgzOiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnRNb2RlLlxuICAgICAgICBpZiAoaXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ICYmIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgIT09ICdleHBsaWNpdCcpIHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZG9lcyBub3QgaW5pdGlhbGl6ZSB0aGUgbWF4Q2hhbm5lbENvdW50IHByb3BlcnR5IGNvcnJlY3RseS5cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLCAnbWF4Q2hhbm5lbENvdW50Jywge1xuICAgICAgICAgICAgICAgIHZhbHVlOiBjaGFubmVsQ291bnRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTY4OiBObyBicm93c2VyIGRvZXMgeWV0IGhhdmUgYW4gQXVkaW9EZXN0aW5hdGlvbk5vZGUgd2l0aCBhbiBvdXRwdXQuXG4gICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICB9KTtcbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKGdhaW5Ob2RlLCAnY2hhbm5lbENvdW50JywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoZ2Fpbk5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKGdhaW5Ob2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY5OiBTYWZhcmkgdGhyb3dzIGFuIGVycm9yIG9uIGVhY2ggYXR0ZW1wdCB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChnYWluTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgc2V0LmNhbGwoZ2Fpbk5vZGUsIHZhbHVlKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKGdhaW5Ob2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChnYWluTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2Fpbk5vZGUsICdtYXhDaGFubmVsQ291bnQnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQHRvZG8gVGhpcyBzaG91bGQgYmUgZGlzY29ubmVjdGVkIHdoZW4gdGhlIGNvbnRleHQgaXMgY2xvc2VkLlxuICAgICAgICBnYWluTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgcmV0dXJuIGdhaW5Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb1dvcmtsZXROb2RlJykgPyB3aW5kb3cuQXVkaW9Xb3JrbGV0Tm9kZSA6IG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdENsb25hYmlsaXR5T2ZBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyA9IChhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgYXJlIG5vdCBjbG9uYWJsZS5cbiAgICAgICAgcG9ydDEucG9zdE1lc3NhZ2UoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1jbG9uYWJpbGl0eS1vZi1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyB0ZXN0Q2xvbmFiaWxpdHlPZkF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWNsb25hYmlsaXR5LW9mLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFjdG9yeSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmFtZSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihuYXRpdmVDb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICAgICAgbGV0IG9ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIHtcbiAgICAgICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgICAgICogQnVnICM2MTogT3ZlcndyaXRpbmcgdGhlIHByb3BlcnR5IGFjY2Vzc29ycyBmb3IgY2hhbm5lbENvdW50IGFuZCBjaGFubmVsQ291bnRNb2RlIGlzIG5lY2Vzc2FyeSBhcyBsb25nIGFzIHNvbWVcbiAgICAgICAgICAgICAgICAgICAgICogYnJvd3NlcnMgaGF2ZSBubyBuYXRpdmUgaW1wbGVtZW50YXRpb24gdG8gYWNoaWV2ZSBhIGNvbnNpc3RlbnQgYmVoYXZpb3IuXG4gICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE1NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCB5ZXQgZmlyZSBhbiBFcnJvckV2ZW50LlxuICAgICAgICAgICAgICAgICAgICBvbnByb2Nlc3NvcmVycm9yOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IG9ucHJvY2Vzc29yZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ucHJvY2Vzc29yZXJyb3IgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbnByb2Nlc3NvcmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUuYWRkRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIgPSAoKGFkZEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ3Byb2Nlc3NvcmVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSB0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2YgYXJnc1sxXSA9PT0gJ29iamVjdCcgJiYgYXJnc1sxXSAhPT0gbnVsbCAmJiB0eXBlb2YgYXJnc1sxXS5oYW5kbGVFdmVudCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdLmhhbmRsZUV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IHBhdGNoZWRFdmVudExpc3RlbmVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gZmlyZSBhbiBldmVudCBvZiB0eXBlIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGV2ZW50LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB7IHZhbHVlOiAncHJvY2Vzc29yZXJyb3InIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lcihuZXcgRXJyb3JFdmVudChhcmdzWzBdLCB7IC4uLmV2ZW50IH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLnNldCh1bnBhdGNoZWRFdmVudExpc3RlbmVyLCBhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gZmlyZSBhbiBldmVudCBvZiB0eXBlIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lci5jYWxsKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsICdlcnJvcicsIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZEV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9ICgocmVtb3ZlRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAncHJvY2Vzc29yZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5kZWxldGUoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3ODogQ2hyb21lIGFuZCBFZGdlIGRvIGZpcmUgYW4gZXZlbnQgb2YgdHlwZSBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAnZXJyb3InLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZW1vdmVFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgaW52b2tlIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gaWYgdGhlIGNvcnJlc3BvbmRpbmcgQXVkaW9Xb3JrbGV0Tm9kZSBpcyB1bmNvbm5lY3RlZCBidXRcbiAgICAgICAgICAgICAgICAgKiBoYXMgYW4gb3V0cHV0LlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mT3V0cHV0cyAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBnYWluOiAwXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiBuYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiBuYXRpdmVHYWluTm9kZS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBEaXNjb25uZWN0IHRoZSBjb25uZWN0aW9uIHdoZW4gdGhlIHByb2Nlc3MoKSBmdW5jdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSByZXR1cm5zIGZhbHNlLlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzYwOiBDaHJvbWUgJiBFZGdlIHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIGluc3RlYWQgb2YgYSBOb3RTdXBwb3J0ZWRFcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDExKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzYxOiBPbmx5IENocm9tZSAmIEVkZ2UgaGF2ZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB5ZXQuXG4gICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHRlc3RDbG9uYWJpbGl0eU9mQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY29tcHV0ZUJ1ZmZlclNpemUgPSAoYmFzZUxhdGVuY3ksIHNhbXBsZVJhdGUpID0+IHtcbiAgICBpZiAoYmFzZUxhdGVuY3kgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDUxMjtcbiAgICB9XG4gICAgcmV0dXJuIE1hdGgubWF4KDUxMiwgTWF0aC5taW4oMTYzODQsIE1hdGgucG93KDIsIE1hdGgucm91bmQoTWF0aC5sb2cyKGJhc2VMYXRlbmN5ICogc2FtcGxlUmF0ZSkpKSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbXB1dGUtYnVmZmVyLXNpemUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIHBvcnQxLm9ubWVzc2FnZSA9ICh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9O1xuICAgICAgICBwb3J0MS5vbm1lc3NhZ2VlcnJvciA9ICh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgICAgICAgICByZWplY3QoZGF0YSk7XG4gICAgICAgIH07XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgYXJlIG5vdCBjbG9uYWJsZS5cbiAgICAgICAgcG9ydDIucG9zdE1lc3NhZ2UoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsb25lLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzLm1hcCIsImltcG9ydCB7IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgfSBmcm9tICcuL2Nsb25lLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlID0gYXN5bmMgKHByb2Nlc3NvckNvbnN0cnVjdG9yLCBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IGNsb25lZEF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gYXdhaXQgY2xvbmVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyhhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgcmV0dXJuIG5ldyBwcm9jZXNzb3JDb25zdHJ1Y3RvcihjbG9uZWRBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXByb21pc2UuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9UT19QUk9DRVNTT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSB9IGZyb20gJy4vY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXByb21pc2UnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvciA9IChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBsZXQgbm9kZVRvUHJvY2Vzc29yTWFwID0gTk9ERV9UT19QUk9DRVNTT1JfTUFQUy5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgaWYgKG5vZGVUb1Byb2Nlc3Nvck1hcCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG5vZGVUb1Byb2Nlc3Nvck1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIE5PREVfVE9fUFJPQ0VTU09SX01BUFMuc2V0KG5hdGl2ZUNvbnRleHQsIG5vZGVUb1Byb2Nlc3Nvck1hcCk7XG4gICAgfVxuICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgPSBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlKHByb2Nlc3NvckNvbnN0cnVjdG9yLCBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgbm9kZVRvUHJvY2Vzc29yTWFwLnNldChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlKTtcbiAgICByZXR1cm4gYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGNvbXB1dGVCdWZmZXJTaXplIH0gZnJvbSAnLi4vaGVscGVycy9jb21wdXRlLWJ1ZmZlci1zaXplJztcbmltcG9ydCB7IGNvcHlGcm9tQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS1mcm9tLWNoYW5uZWwnO1xuaW1wb3J0IHsgY29weVRvQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS10by1jaGFubmVsJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvciB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yJztcbmltcG9ydCB7IGNyZWF0ZU5lc3RlZEFycmF5cyB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLW5lc3RlZC1hcnJheXMnO1xuaW1wb3J0IHsgUmVhZE9ubHlNYXAgfSBmcm9tICcuLi9yZWFkLW9ubHktbWFwJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXJGYWN0b3J5ID0gKGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMgPT09IDAgJiYgb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbENvdW50ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudClcbiAgICAgICAgICAgID8gb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnRcbiAgICAgICAgICAgIDogQXJyYXkuZnJvbShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgIC8vIEB0b2RvIENoZWNrIGlmIGFueSBvZiB0aGUgY2hhbm5lbENvdW50IHZhbHVlcyBpcyBncmVhdGVyIHRoYW4gdGhlIGltcGxlbWVudGF0aW9uJ3MgbWF4aW11bSBudW1iZXIgb2YgY2hhbm5lbHMuXG4gICAgICAgIGlmIChvdXRwdXRDaGFubmVsQ291bnQuc29tZSgoY2hhbm5lbENvdW50KSA9PiBjaGFubmVsQ291bnQgPCAxKSkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3V0cHV0Q2hhbm5lbENvdW50Lmxlbmd0aCAhPT0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSAhPT0gJ2V4cGxpY2l0Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBvcHRpb25zLmNoYW5uZWxDb3VudCAqIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgIGNvbnN0IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPSBvdXRwdXRDaGFubmVsQ291bnQucmVkdWNlKChzdW0sIHZhbHVlKSA9PiBzdW0gKyB2YWx1ZSwgMCk7XG4gICAgICAgIGNvbnN0IG51bWJlck9mUGFyYW1ldGVycyA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzID09PSB1bmRlZmluZWQgPyAwIDogcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICBpZiAobnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzID4gNiB8fCBudW1iZXJPZk91dHB1dENoYW5uZWxzID4gNikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXNzYWdlQ2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjb25zdCBnYWluTm9kZXMgPSBbXTtcbiAgICAgICAgY29uc3QgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2RlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgZ2Fpbk5vZGVzLnB1c2goY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZXMgPSBbXTtcbiAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgeyBkZWZhdWx0VmFsdWUsIG1heFZhbHVlLCBtaW5WYWx1ZSwgbmFtZSB9IG9mIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy5wYXJhbWV0ZXJEYXRhW25hbWVdICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3B0aW9ucy5wYXJhbWV0ZXJEYXRhW25hbWVdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAoZGVmYXVsdFZhbHVlID09PSB1bmRlZmluZWQgPyAwIDogZGVmYXVsdFZhbHVlKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBtYXhWYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAobWF4VmFsdWUgPT09IHVuZGVmaW5lZCA/IE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIDogbWF4VmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIG1pblZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IChtaW5WYWx1ZSA9PT0gdW5kZWZpbmVkID8gTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQgOiBtaW5WYWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZXMucHVzaChjb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycylcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlclNpemUgPSBjb21wdXRlQnVmZmVyU2l6ZShiYXNlTGF0ZW5jeSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgYnVmZmVyU2l6ZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzLCBcbiAgICAgICAgLy8gQnVnICM4NzogT25seSBGaXJlZm94IHdpbGwgZmlyZSBhbiBBdWRpb1Byb2Nlc3NpbmdFdmVudCBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgb3V0cHV0LlxuICAgICAgICBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSk7XG4gICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyksXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogb3V0cHV0Q2hhbm5lbENvdW50W2ldXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGdhaW5Ob2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0pO1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGosIGkgKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlck1hcCA9IG5ldyBSZWFkT25seU1hcChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IFtdXG4gICAgICAgICAgICA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLm1hcCgoeyBuYW1lIH0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY29uc3RhbnRTb3VyY2VOb2Rlc1tpbmRleF07XG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgpO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25hbWUsIGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXRdO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICBpbnB1dENoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgIGxldCBjaGFubmVsSW50ZXJwcmV0YXRpb24gPSBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgbGV0IG9ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAvLyBCdWcgIzg3OiBFeHBvc2UgYXQgbGVhc3Qgb25lIG91dHB1dCB0byBtYWtlIHRoaXMgbm9kZSBjb25uZWN0YWJsZS5cbiAgICAgICAgY29uc3Qgb3V0cHV0QXVkaW9Ob2RlcyA9IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAwID8gW3NjcmlwdFByb2Nlc3Nvck5vZGVdIDogb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzO1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyU2l6ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KF8pIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZShfKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBnYWluTm9kZSBvZiBnYWluTm9kZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGVzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb25wcm9jZXNzb3JlcnJvcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb25wcm9jZXNzb3JlcnJvcih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb25wcm9jZXNzb3JlcnJvciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwYXJhbWV0ZXJzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJhbWV0ZXJNYXA7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvcnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VDaGFubmVsLnBvcnQyO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29ubmVjdDogY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dEF1ZGlvTm9kZXMpLFxuICAgICAgICAgICAgZGlzY29ubmVjdDogZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dEF1ZGlvTm9kZXMpLFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLmFkZEV2ZW50TGlzdGVuZXIgPSAoKGFkZEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAnbWVzc2FnZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHR5cGVvZiBhcmdzWzFdID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIGFyZ3NbMV0gPT09ICdvYmplY3QnICYmIGFyZ3NbMV0gIT09IG51bGwgJiYgdHlwZW9mIGFyZ3NbMV0uaGFuZGxlRXZlbnQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV0uaGFuZGxlRXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1bnBhdGNoZWRFdmVudExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHBhdGNoZWRFdmVudExpc3RlbmVycy5nZXQoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUobmF0aXZlQ29udGV4dC5jdXJyZW50VGltZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiB1bnBhdGNoZWRFdmVudExpc3RlbmVyKGV2ZW50KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuc2V0KHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIsIGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhZGRFdmVudExpc3RlbmVyLmNhbGwobWVzc2FnZUNoYW5uZWwucG9ydDEsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobWVzc2FnZUNoYW5uZWwucG9ydDEuYWRkRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSAoKHJlbW92ZUV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAnbWVzc2FnZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmRlbGV0ZShhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKG1lc3NhZ2VDaGFubmVsLnBvcnQxLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIpO1xuICAgICAgICBsZXQgb25tZXNzYWdlID0gbnVsbDtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1lc3NhZ2VDaGFubmVsLnBvcnQxLCAnb25tZXNzYWdlJywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiBvbm1lc3NhZ2UsXG4gICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbm1lc3NhZ2UgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbm1lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNoYW5uZWwucG9ydDEuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9ubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcHJvY2Vzc29yQ29uc3RydWN0b3IucHJvdG90eXBlLnBvcnQgPSBtZXNzYWdlQ2hhbm5lbC5wb3J0MTtcbiAgICAgICAgbGV0IGF1ZGlvV29ya2xldFByb2Nlc3NvciA9IG51bGw7XG4gICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgPSBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3IobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCBwcm9jZXNzb3JDb25zdHJ1Y3Rvciwgb3B0aW9ucyk7XG4gICAgICAgIGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UudGhlbigoZFdya2x0UHJjc3NyKSA9PiAoYXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gZFdya2x0UHJjc3NyKSk7XG4gICAgICAgIGNvbnN0IGlucHV0cyA9IGNyZWF0ZU5lc3RlZEFycmF5cyhvcHRpb25zLm51bWJlck9mSW5wdXRzLCBvcHRpb25zLmNoYW5uZWxDb3VudCk7XG4gICAgICAgIGNvbnN0IG91dHB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZk91dHB1dHMsIG91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IFtdXG4gICAgICAgICAgICA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLnJlZHVjZSgocHJtdHJzLCB7IG5hbWUgfSkgPT4gKHsgLi4ucHJtdHJzLCBbbmFtZV06IG5ldyBGbG9hdDMyQXJyYXkoMTI4KSB9KSwge30pO1xuICAgICAgICBsZXQgaXNBY3RpdmUgPSB0cnVlO1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0T3V0cHV0c0dyYXBoID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID4gMCkge1xuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdChvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSA9IG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG91dHB1dENoYW5uZWxDb3VudFtpXTsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYWN0aXZlSW5wdXRJbmRleGVzID0gbmV3IE1hcCgpO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICh7IGlucHV0QnVmZmVyLCBvdXRwdXRCdWZmZXIgfSkgPT4ge1xuICAgICAgICAgICAgaWYgKGF1ZGlvV29ya2xldFByb2Nlc3NvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUlucHV0cyA9IGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlclNpemU7IGkgKz0gMTI4KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5RnJvbUNoYW5uZWwoaW5wdXRCdWZmZXIsIGlucHV0c1tqXSwgaywgaywgaSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmZvckVhY2goKHsgbmFtZSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChpbnB1dEJ1ZmZlciwgcGFyYW1ldGVycywgbmFtZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgsIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRwdXRzW2pdW2tdLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0c1tqXVtrXSA9IG5ldyBGbG9hdDMyQXJyYXkoMTI4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvdGVudGlhbGx5RW1wdHlJbnB1dHMgPSBpbnB1dHMubWFwKChpbnB1dCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVJbnB1dCA9IGFjdGl2ZUlucHV0c1tpbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZUlucHV0LnNpemUgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5zZXQoaW5kZXgsIGJ1ZmZlclNpemUgLyAxMjgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gYWN0aXZlSW5wdXRJbmRleGVzLmdldChpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZXZlcnkoKGNoYW5uZWxEYXRhKSA9PiBjaGFubmVsRGF0YS5ldmVyeSgoc2FtcGxlKSA9PiBzYW1wbGUgPT09IDApKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5kZWxldGUoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlSW5wdXRJbmRleGVzLnNldChpbmRleCwgY291bnQgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZVNvdXJjZUZsYWcgPSBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShuYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lICsgaSAvIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiBhdWRpb1dvcmtsZXRQcm9jZXNzb3IucHJvY2Vzcyhwb3RlbnRpYWxseUVtcHR5SW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZSA9IGFjdGl2ZVNvdXJjZUZsYWc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5VG9DaGFubmVsKG91dHB1dEJ1ZmZlciwgb3V0cHV0c1tqXSwgaywgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGssIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIuZGlzcGF0Y2hFdmVudChuZXcgRXJyb3JFdmVudCgncHJvY2Vzc29yZXJyb3InLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbm86IGVycm9yLmNvbG5vLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBlcnJvci5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lbm86IGVycm9yLmxpbmVubyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluTm9kZXNbal0uZGlzY29ubmVjdChpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2pdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5kaXNjb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGssIGogKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGspO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY29uc3RhbnRTb3VyY2VOb2Rlc1tqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5kaXNjb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RPdXRwdXRzR3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgLy8gQnVnICM4NzogT25seSBGaXJlZm94IHdpbGwgZmlyZSBhbiBBdWRpb1Byb2Nlc3NpbmdFdmVudCBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgb3V0cHV0LlxuICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjb25uZWN0RmFrZUdyYXBoID0gKCkgPT4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0RmFrZUdyYXBoID0gKCkgPT4ge1xuICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSA9IG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvdXRwdXRDaGFubmVsQ291bnRbaV07IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KG91dHB1dENoYW5uZWxNZXJnZXJOb2RlLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaiwgaik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdEZha2VHcmFwaCgpO1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RPdXRwdXRzR3JhcGgoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIGNvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ1EnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ2RldHVuZScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAnZnJlcXVlbmN5Jyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdnYWluJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICd0eXBlJyk7XG4gICAgcmV0dXJuIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWJpcXVhZC1maWx0ZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGVGYWN0b3J5ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCB3cmFwQ2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIob3B0aW9ucy5udW1iZXJPZklucHV0cyk7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMjA6IFNhZmFyaSByZXF1aXJlcyBhIGNvbm5lY3Rpb24gb2YgYW55IGtpbmQgdG8gdHJlYXQgdGhlIGlucHV0IHNpZ25hbCBjb3JyZWN0bHkuXG4gICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGUgZXhpc3RlbmNlIG9mXG4gICAgICAgICAqIHRoZSB3ZWJraXRBdWRpb0NvbnRleHQgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgaGVyZS5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgd3JhcENoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNoYW5uZWwtbWVyZ2VyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IChjaGFubmVsU3BsaXR0ZXJOb2RlKSA9PiB7XG4gICAgY29uc3QgY2hhbm5lbENvdW50ID0gY2hhbm5lbFNwbGl0dGVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgLy8gQnVnICM5NzogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudCB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBpdHMgaW5pdGlhbCB2YWx1ZS5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxDb3VudCcsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiBjaGFubmVsQ291bnQsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IGNoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBCdWcgIzMwOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGNoYW5nZSB0aGUgY2hhbm5lbENvdW50TW9kZSB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBleHBsaWNpdC5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG4gICAgICAgIGdldDogKCkgPT4gJ2V4cGxpY2l0JyxcbiAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gJ2V4cGxpY2l0Jykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBCdWcgIzMyOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGNoYW5nZSB0aGUgY2hhbm5lbEludGVycHJldGF0aW9uIHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIGRpc2NyZXRlLlxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsU3BsaXR0ZXJOb2RlLCAnY2hhbm5lbEludGVycHJldGF0aW9uJywge1xuICAgICAgICBnZXQ6ICgpID0+ICdkaXNjcmV0ZScsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09ICdkaXNjcmV0ZScpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1jaGFubmVsLXNwbGl0dGVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcENoYW5uZWxTcGxpdHRlck5vZGUgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtY2hhbm5lbC1zcGxpdHRlci1ub2RlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIob3B0aW9ucy5udW1iZXJPZk91dHB1dHMpO1xuICAgIC8vIEJ1ZyAjOTY6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxDb3VudC5cbiAgICAvLyBCdWcgIzI5OiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnRNb2RlLlxuICAgIC8vIEJ1ZyAjMzE6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxJbnRlcnByZXRhdGlvbi5cbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIG9wdGlvbnMpO1xuICAgIC8vIEJ1ZyAjMjksICMzMCwgIzMxLCAjMzIsICM5NiAmICM5NzogT25seSBDaHJvbWUsIEVkZ2UgJiBGaXJlZm94IHBhcnRpYWxseSBzdXBwb3J0IHRoZSBzcGVjIHlldC5cbiAgICB3cmFwQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICByZXR1cm4gbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY2hhbm5lbC1zcGxpdHRlci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNjI6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IENvbnN0YW50U291cmNlTm9kZXMuXG4gICAgICAgIGlmIChuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgb3B0aW9ucywgJ29mZnNldCcpO1xuICAgICAgICAvLyBCdWcgIzQ0OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IE9ubHkgRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNzU6IFNhZmFyaSB3aWxsIG5vdCBmaXJlIGFuIGVuZGVkIGV2ZW50IGlmIHRoZSBDb25zdGFudFNvdXJjZU5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpbnRlcmNlcHRDb25uZWN0aW9ucyA9IChvcmlnaW5hbCwgaW50ZXJjZXB0b3IpID0+IHtcbiAgICBvcmlnaW5hbC5jb25uZWN0ID0gaW50ZXJjZXB0b3IuY29ubmVjdC5iaW5kKGludGVyY2VwdG9yKTtcbiAgICBvcmlnaW5hbC5kaXNjb25uZWN0ID0gaW50ZXJjZXB0b3IuZGlzY29ubmVjdC5iaW5kKGludGVyY2VwdG9yKTtcbiAgICByZXR1cm4gb3JpZ2luYWw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJjZXB0LWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgb2Zmc2V0LCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAyLCA0NDEwMCk7XG4gICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IG9mZnNldCB9KTtcbiAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAvLyBCdWcgIzk1OiBTYWZhcmkgZG9lcyBub3QgcGxheSBvciBsb29wIG9uZSBzYW1wbGUgYnVmZmVycy5cbiAgICAgICAgY2hhbm5lbERhdGFbMF0gPSAxO1xuICAgICAgICBjaGFubmVsRGF0YVsxXSA9IDE7XG4gICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBhdWRpb0J1ZmZlcjtcbiAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AgPSB0cnVlO1xuICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb2Zmc2V0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3RhcnQod2hlbiA9IDApIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQuY2FsbChhdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0b3Aod2hlbiA9IDApIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcC5jYWxsKGF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIGF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIGdhaW5Ob2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ29udm9sdmVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIFRoZSBub3JtYWxpemUgcHJvcGVydHkgbmVlZHMgdG8gYmUgc2V0IGJlZm9yZSBzZXR0aW5nIHRoZSBidWZmZXIuXG4gICAgICAgIGlmIChvcHRpb25zLmRpc2FibGVOb3JtYWxpemF0aW9uID09PSBuYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZSkge1xuICAgICAgICAgICAgbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemUgPSAhb3B0aW9ucy5kaXNhYmxlTm9ybWFsaXphdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQ29udm9sdmVyTm9kZSwgb3B0aW9ucywgJ2J1ZmZlcicpO1xuICAgICAgICAvLyBCdWcgIzExMzogU2FmYXJpIGRvZXMgYWxsb3cgdG8gc2V0IHRoZSBjaGFubmVsQ291bnQgdG8gYSB2YWx1ZSBsYXJnZXIgdGhhbiAyLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnQgPiAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVDb252b2x2ZXJOb2RlLCAnY2hhbm5lbENvdW50JywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlID4gMikge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMxMTQ6IFNhZmFyaSBhbGxvd3MgdG8gc2V0IHRoZSBjaGFubmVsQ291bnRNb2RlIHRvICdtYXgnLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlQ29udm9sdmVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlLCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmF0aXZlQ29udm9sdmVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jb252b2x2ZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVEZWxheU5vZGUgPSAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlRGVsYXkob3B0aW9ucy5tYXhEZWxheVRpbWUpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlRGVsYXlOb2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRGVsYXlOb2RlLCBvcHRpb25zLCAnZGVsYXlUaW1lJyk7XG4gICAgcmV0dXJuIG5hdGl2ZURlbGF5Tm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtZGVsYXktbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkgPSAoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIEJ1ZyAjMTA4OiBTYWZhcmkgYWxsb3dzIGEgY2hhbm5lbENvdW50IG9mIHRocmVlIGFuZCBhYm92ZS5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50ID4gMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzEwOTogT25seSBDaHJvbWUgYW5kIEZpcmVmb3ggZGlzYWxsb3cgYSBjaGFubmVsQ291bnRNb2RlIG9mICdtYXgnLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ2F0dGFjaycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ2tuZWUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdyYXRpbycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ3JlbGVhc2UnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICd0aHJlc2hvbGQnKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlR2Fpbk5vZGUsIG9wdGlvbnMpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVHYWluTm9kZSwgb3B0aW9ucywgJ2dhaW4nKTtcbiAgICByZXR1cm4gbmF0aXZlR2Fpbk5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWdhaW4tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgb3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBCdWcgIzk6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IElJUkZpbHRlck5vZGVzLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBkZWZpbmVzIHRoZSBwYXJhbWV0ZXJzIG9mIGNyZWF0ZUlJUkZpbHRlcigpIGFzIGFycmF5cyBvZiBudW1iZXJzLlxuICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIob3B0aW9ucy5mZWVkZm9yd2FyZCwgb3B0aW9ucy5mZWVkYmFjayk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlSUlSRmlsdGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVJSVJGaWx0ZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGNvbXB1dGVCdWZmZXJTaXplIH0gZnJvbSAnLi4vaGVscGVycy9jb21wdXRlLWJ1ZmZlci1zaXplJztcbmltcG9ydCB7IGZpbHRlckJ1ZmZlciB9IGZyb20gJy4uL2hlbHBlcnMvZmlsdGVyLWJ1ZmZlcic7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmZ1bmN0aW9uIGRpdmlkZShhLCBiKSB7XG4gICAgY29uc3QgZGVub21pbmF0b3IgPSBiWzBdICogYlswXSArIGJbMV0gKiBiWzFdO1xuICAgIHJldHVybiBbKGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0pIC8gZGVub21pbmF0b3IsIChhWzFdICogYlswXSAtIGFbMF0gKiBiWzFdKSAvIGRlbm9taW5hdG9yXTtcbn1cbmZ1bmN0aW9uIG11bHRpcGx5KGEsIGIpIHtcbiAgICByZXR1cm4gW2FbMF0gKiBiWzBdIC0gYVsxXSAqIGJbMV0sIGFbMF0gKiBiWzFdICsgYVsxXSAqIGJbMF1dO1xufVxuZnVuY3Rpb24gZXZhbHVhdGVQb2x5bm9taWFsKGNvZWZmaWNpZW50LCB6KSB7XG4gICAgbGV0IHJlc3VsdCA9IFswLCAwXTtcbiAgICBmb3IgKGxldCBpID0gY29lZmZpY2llbnQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcbiAgICAgICAgcmVzdWx0ID0gbXVsdGlwbHkocmVzdWx0LCB6KTtcbiAgICAgICAgcmVzdWx0WzBdICs9IGNvZWZmaWNpZW50W2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlckZhY3RvcnkgPSAoY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCB7IGNoYW5uZWxDb3VudCwgY2hhbm5lbENvdW50TW9kZSwgY2hhbm5lbEludGVycHJldGF0aW9uLCBmZWVkYmFjaywgZmVlZGZvcndhcmQgfSkgPT4ge1xuICAgICAgICBjb25zdCBidWZmZXJTaXplID0gY29tcHV0ZUJ1ZmZlclNpemUoYmFzZUxhdGVuY3ksIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZEZlZWRiYWNrID0gZmVlZGJhY2sgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBmZWVkYmFjayA6IG5ldyBGbG9hdDY0QXJyYXkoZmVlZGJhY2spO1xuICAgICAgICBjb25zdCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCA9IGZlZWRmb3J3YXJkIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGZvcndhcmQgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRmb3J3YXJkKTtcbiAgICAgICAgY29uc3QgZmVlZGJhY2tMZW5ndGggPSBjb252ZXJ0ZWRGZWVkYmFjay5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGZlZWRmb3J3YXJkTGVuZ3RoID0gY29udmVydGVkRmVlZGZvcndhcmQubGVuZ3RoO1xuICAgICAgICBjb25zdCBtaW5MZW5ndGggPSBNYXRoLm1pbihmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmRMZW5ndGgpO1xuICAgICAgICBpZiAoZmVlZGJhY2tMZW5ndGggPT09IDAgfHwgZmVlZGJhY2tMZW5ndGggPiAyMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udmVydGVkRmVlZGJhY2tbMF0gPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZlZWRmb3J3YXJkTGVuZ3RoID09PSAwIHx8IGZlZWRmb3J3YXJkTGVuZ3RoID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbnZlcnRlZEZlZWRmb3J3YXJkWzBdID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb252ZXJ0ZWRGZWVkYmFja1swXSAhPT0gMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmZWVkZm9yd2FyZExlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29udmVydGVkRmVlZGZvcndhcmRbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZlZWRiYWNrTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb252ZXJ0ZWRGZWVkYmFja1tpXSAvPSBjb252ZXJ0ZWRGZWVkYmFja1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCBidWZmZXJTaXplLCBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudCk7XG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSBjaGFubmVsQ291bnRNb2RlO1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IGNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgY29uc3QgYnVmZmVyTGVuZ3RoID0gMzI7XG4gICAgICAgIGNvbnN0IGJ1ZmZlckluZGV4ZXMgPSBbXTtcbiAgICAgICAgY29uc3QgeEJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgY29uc3QgeUJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFubmVsQ291bnQ7IGkgKz0gMSkge1xuICAgICAgICAgICAgYnVmZmVySW5kZXhlcy5wdXNoKDApO1xuICAgICAgICAgICAgY29uc3QgeEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICAgICAgICAgIGNvbnN0IHlCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgICAgICAgICB4QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgICAgICB5QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgICAgICB4QnVmZmVycy5wdXNoKHhCdWZmZXIpO1xuICAgICAgICAgICAgeUJ1ZmZlcnMucHVzaCh5QnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXRCdWZmZXIgPSBldmVudC5pbnB1dEJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dEJ1ZmZlciA9IGV2ZW50Lm91dHB1dEJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IG51bWJlck9mQ2hhbm5lbHMgPSBpbnB1dEJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNoYW5uZWxzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dCA9IGlucHV0QnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgICAgICAgICBidWZmZXJJbmRleGVzW2ldID0gZmlsdGVyQnVmZmVyKGNvbnZlcnRlZEZlZWRiYWNrLCBmZWVkYmFja0xlbmd0aCwgY29udmVydGVkRmVlZGZvcndhcmQsIGZlZWRmb3J3YXJkTGVuZ3RoLCBtaW5MZW5ndGgsIHhCdWZmZXJzW2ldLCB5QnVmZmVyc1tpXSwgYnVmZmVySW5kZXhlc1tpXSwgYnVmZmVyTGVuZ3RoLCBpbnB1dCwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbnlxdWlzdCA9IG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXJTaXplO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtzY3JpcHRQcm9jZXNzb3JOb2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRGlzc2FsbG93IGFkZGluZyBhbiBhdWRpb3Byb2Nlc3MgbGlzdGVuZXIuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmIChmcmVxdWVuY3lIei5sZW5ndGggIT09IG1hZ1Jlc3BvbnNlLmxlbmd0aCB8fCBtYWdSZXNwb25zZS5sZW5ndGggIT09IHBoYXNlUmVzcG9uc2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBsZW5ndGggPSBmcmVxdWVuY3lIei5sZW5ndGg7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYSA9IC1NYXRoLlBJICogKGZyZXF1ZW5jeUh6W2ldIC8gbnlxdWlzdCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHogPSBbTWF0aC5jb3Mob21lZ2EpLCBNYXRoLnNpbihvbWVnYSldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmF0b3IgPSBldmFsdWF0ZVBvbHlub21pYWwoY29udmVydGVkRmVlZGZvcndhcmQsIHopO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZW5vbWluYXRvciA9IGV2YWx1YXRlUG9seW5vbWlhbChjb252ZXJ0ZWRGZWVkYmFjaywgeik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZGl2aWRlKG51bWVyYXRvciwgZGVub21pbmF0b3IpO1xuICAgICAgICAgICAgICAgICAgICBtYWdSZXNwb25zZVtpXSA9IE1hdGguc3FydChyZXNwb25zZVswXSAqIHJlc3BvbnNlWzBdICsgcmVzcG9uc2VbMV0gKiByZXNwb25zZVsxXSk7XG4gICAgICAgICAgICAgICAgICAgIHBoYXNlUmVzcG9uc2VbaV0gPSBNYXRoLmF0YW4yKHJlc3BvbnNlWzFdLCByZXNwb25zZVswXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIsIHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgPSAobmF0aXZlQXVkaW9Db250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2Uob3B0aW9ucy5tZWRpYUVsZW1lbnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgb3B0aW9ucyk7XG4gICAgLy8gQnVnICMxNzQ6IFNhZmFyaSBkb2VzIGV4cG9zZSBhIHdyb25nIG51bWJlck9mT3V0cHV0cy5cbiAgICBpZiAobmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZS5udW1iZXJPZk91dHB1dHMgPT09IDEpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsICdudW1iZXJPZk91dHB1dHMnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IChuYXRpdmVBdWRpb0NvbnRleHQsIHsgbWVkaWFTdHJlYW0gfSkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvU3RyZWFtVHJhY2tzID0gbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKTtcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTUxOiBTYWZhcmkgZG9lcyBub3QgdXNlIHRoZSBhdWRpbyB0cmFjayBhcyBpbnB1dCBhbnltb3JlIGlmIGl0IGdldHMgcmVtb3ZlZCBmcm9tIHRoZSBtZWRpYVN0cmVhbSBhZnRlciBjb25zdHJ1Y3Rpb24uXG4gICAgICogQnVnICMxNTk6IFNhZmFyaSBwaWNrcyB0aGUgZmlyc3QgYXVkaW8gdHJhY2sgaWYgdGhlIE1lZGlhU3RyZWFtIGhhcyBtb3JlIHRoYW4gb25lIGF1ZGlvIHRyYWNrLlxuICAgICAqL1xuICAgIGF1ZGlvU3RyZWFtVHJhY2tzLnNvcnQoKGEsIGIpID0+IChhLmlkIDwgYi5pZCA/IC0xIDogYS5pZCA+IGIuaWQgPyAxIDogMCkpO1xuICAgIGNvbnN0IGZpbHRlcmVkQXVkaW9TdHJlYW1UcmFja3MgPSBhdWRpb1N0cmVhbVRyYWNrcy5zbGljZSgwLCAxKTtcbiAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShuZXcgTWVkaWFTdHJlYW0oZmlsdGVyZWRBdWRpb1N0cmVhbVRyYWNrcykpO1xuICAgIC8qXG4gICAgICogQnVnICMxNTEgJiAjMTU5OiBUaGUgZ2l2ZW4gbWVkaWFTdHJlYW0gZ2V0cyByZWNvbnN0cnVjdGVkIGJlZm9yZSBpdCBnZXRzIHBhc3NlZCB0byB0aGUgbmF0aXZlIG5vZGUgd2hpY2ggaXMgd2h5IHRoZSBhY2Nlc3NvciBuZWVkc1xuICAgICAqIHRvIGJlIG92ZXJ3cml0dGVuIGFzIGl0IHdvdWxkIG90aGVyd2lzZSBleHBvc2UgdGhlIHJlY29uc3RydWN0ZWQgdmVyc2lvbi5cbiAgICAgKi9cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsICdtZWRpYVN0cmVhbScsIHsgdmFsdWU6IG1lZGlhU3RyZWFtIH0pO1xuICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlRmFjdG9yeSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb0NvbnRleHQsIHsgbWVkaWFTdHJlYW1UcmFjayB9KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTIxOiBPbmx5IEZpcmVmb3ggZG9lcyB5ZXQgc3VwcG9ydCB0aGUgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZS5cbiAgICAgICAgaWYgKHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1UcmFja1NvdXJjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVRyYWNrU291cmNlKG1lZGlhU3RyZWFtVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKFttZWRpYVN0cmVhbVRyYWNrXSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgLy8gQnVnICMxMjA6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIG1lZGlhU3RyZWFtIGhhcyBubyBhdWRpbyB0cmFjay5cbiAgICAgICAgaWYgKG1lZGlhU3RyZWFtVHJhY2sua2luZCAhPT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3MjogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQXVkaW9Db250ZXh0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoJ09mZmxpbmVBdWRpb0NvbnRleHQnKSkge1xuICAgICAgICByZXR1cm4gd2luZG93Lk9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgfVxuICAgIHJldHVybiB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ3dlYmtpdE9mZmxpbmVBdWRpb0NvbnRleHQnKSA/IHdpbmRvdy53ZWJraXRPZmZsaW5lQXVkaW9Db250ZXh0IDogbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zLCAnZGV0dW5lJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ2ZyZXF1ZW5jeScpO1xuICAgICAgICBpZiAob3B0aW9ucy5wZXJpb2RpY1dhdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUuc2V0UGVyaW9kaWNXYXZlKG9wdGlvbnMucGVyaW9kaWNXYXZlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ3R5cGUnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IENocm9tZSAmIEVkZ2UgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxOTogU2FmYXJpIGRvZXMgbm90IGlnbm9yZSBjYWxscyB0byBzdG9wKCkgb2YgYW4gYWxyZWFkeSBzdG9wcGVkIEF1ZGlvQnVmZmVyU291cmNlTm9kZS5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyhuYXRpdmVPc2NpbGxhdG9yTm9kZSwgbmF0aXZlQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgT3NjaWxsYXRvck5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgbmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICByZXR1cm4gbmF0aXZlT3NjaWxsYXRvck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtb3NjaWxsYXRvci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgICAgIC8vIEJ1ZyAjMTI0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZnlpbmcgdGhlIG9yaWVudGF0aW9uIGFuZCB0aGUgcG9zaXRpb24gd2l0aCBBdWRpb1BhcmFtcy5cbiAgICAgICAgaWYgKG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblgnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblknKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblonKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblgnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblknKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblonKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdjb25lSW5uZXJBbmdsZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2NvbmVPdXRlckFuZ2xlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnY29uZU91dGVyR2FpbicpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2Rpc3RhbmNlTW9kZWwnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdtYXhEaXN0YW5jZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3Bhbm5pbmdNb2RlbCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3JlZkRpc3RhbmNlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncm9sbG9mZkZhY3RvcicpO1xuICAgICAgICByZXR1cm4gbmF0aXZlUGFubmVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1wYW5uZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlckZhY3RvcnkgPSAoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRGaXJzdFNhbXBsZSwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGNvbmVJbm5lckFuZ2xlLCBjb25lT3V0ZXJBbmdsZSwgY29uZU91dGVyR2FpbiwgZGlzdGFuY2VNb2RlbCwgbWF4RGlzdGFuY2UsIG9yaWVudGF0aW9uWCwgb3JpZW50YXRpb25ZLCBvcmllbnRhdGlvblosIHBhbm5pbmdNb2RlbCwgcG9zaXRpb25YLCBwb3NpdGlvblksIHBvc2l0aW9uWiwgcmVmRGlzdGFuY2UsIHJvbGxvZmZGYWN0b3IsIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBwYW5uZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVQYW5uZXIoKTtcbiAgICAgICAgLy8gQnVnICMxMjU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgIGlmIChhdWRpb05vZGVPcHRpb25zLmNoYW5uZWxDb3VudCA+IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMjY6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgIGlmIChhdWRpb05vZGVPcHRpb25zLmNoYW5uZWxDb3VudE1vZGUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMocGFubmVyTm9kZSwgYXVkaW9Ob2RlT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX09QVElPTlMgPSB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiA2XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCBvcmllbnRhdGlvblhHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3Qgb3JpZW50YXRpb25ZR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IG9yaWVudGF0aW9uWkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBwb3NpdGlvblhHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25ZR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uWkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCAyNTYsIDYsIDEpO1xuICAgICAgICBjb25zdCB3YXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbmV3IEZsb2F0MzJBcnJheShbMSwgMV0pLFxuICAgICAgICAgICAgb3ZlcnNhbXBsZTogJ25vbmUnXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgbGFzdE9yaWVudGF0aW9uID0gW29yaWVudGF0aW9uWCwgb3JpZW50YXRpb25ZLCBvcmllbnRhdGlvblpdO1xuICAgICAgICBsZXQgbGFzdFBvc2l0aW9uID0gW3Bvc2l0aW9uWCwgcG9zaXRpb25ZLCBwb3NpdGlvblpdO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KDEpO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICh7IGlucHV0QnVmZmVyIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW1xuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDApLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDEpLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDIpXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RPcmllbnRhdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRPcmllbnRhdGlvbiguLi5vcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHBvc2l0b24gPSBbXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMyksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNCksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNSlcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAocG9zaXRvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0UG9zaXRpb24oLi4ucG9zaXRvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb24gPSBwb3NpdG9uO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob3JpZW50YXRpb25ZR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob3JpZW50YXRpb25aR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25YR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25ZR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25aR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyNTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjY6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbmVPdXRlckFuZ2xlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjb25lT3V0ZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lT3V0ZXJHYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjb25lT3V0ZXJHYWluKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjc6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jb25lT3V0ZXJHYWluID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgZGlzdGFuY2VNb2RlbCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2lucHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBtYXhEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5tYXhEaXN0YW5jZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgbWF4RGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUubWF4RGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9yaWVudGF0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZW50YXRpb25YR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb3JpZW50YXRpb25ZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvbllHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvcmllbnRhdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWVudGF0aW9uWkdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhbm5pbmdNb2RlbCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5wYW5uaW5nTW9kZWw7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHBhbm5pbmdNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucGFubmluZ01vZGVsID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25YR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25ZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbllHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWkdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLnJlZkRpc3RhbmNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCByZWZEaXN0YW5jZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI5OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5yZWZEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3I7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHJvbGxvZmZGYWN0b3IodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEzMDogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucm9sbG9mZkZhY3RvciA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoY29uZUlubmVyQW5nbGUgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lSW5uZXJBbmdsZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVJbm5lckFuZ2xlID0gY29uZUlubmVyQW5nbGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbmVPdXRlckFuZ2xlICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyQW5nbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lT3V0ZXJBbmdsZSA9IGNvbmVPdXRlckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25lT3V0ZXJHYWluICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyR2Fpbikge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckdhaW4gPSBjb25lT3V0ZXJHYWluO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXN0YW5jZU1vZGVsICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuZGlzdGFuY2VNb2RlbCkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmRpc3RhbmNlTW9kZWwgPSBkaXN0YW5jZU1vZGVsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXhEaXN0YW5jZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm1heERpc3RhbmNlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIubWF4RGlzdGFuY2UgPSBtYXhEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZW50YXRpb25YICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25YLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25YLnZhbHVlID0gb3JpZW50YXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmllbnRhdGlvblkgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblkudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblkudmFsdWUgPSBvcmllbnRhdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yaWVudGF0aW9uWiAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWi52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWi52YWx1ZSA9IG9yaWVudGF0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFubmluZ01vZGVsICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucGFubmluZ01vZGVsKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucGFubmluZ01vZGVsID0gcGFubmluZ01vZGVsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvblggIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblgudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblgudmFsdWUgPSBwb3NpdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uWSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWS52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWS52YWx1ZSA9IHBvc2l0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb25aICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25aLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25aLnZhbHVlID0gcG9zaXRpb25aO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWZEaXN0YW5jZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnJlZkRpc3RhbmNlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucmVmRGlzdGFuY2UgPSByZWZEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm9sbG9mZkZhY3RvciAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnJvbGxvZmZGYWN0b3IpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yb2xsb2ZmRmFjdG9yID0gcm9sbG9mZkZhY3RvcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGFzdE9yaWVudGF0aW9uWzBdICE9PSAxIHx8IGxhc3RPcmllbnRhdGlvblsxXSAhPT0gMCB8fCBsYXN0T3JpZW50YXRpb25bMl0gIT09IDApIHtcbiAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0T3JpZW50YXRpb24oLi4ubGFzdE9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICB9XG4gICAgICAgIGlmIChsYXN0UG9zaXRpb25bMF0gIT09IDAgfHwgbGFzdFBvc2l0aW9uWzFdICE9PSAwIHx8IGxhc3RQb3NpdGlvblsyXSAhPT0gMCkge1xuICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRQb3NpdGlvbiguLi5sYXN0UG9zaXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChwYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgICAgICBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUoaW5wdXRHYWluTm9kZSwgd2F2ZVNoYXBlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChvcmllbnRhdGlvblhHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KG9yaWVudGF0aW9uWUdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3Qob3JpZW50YXRpb25aR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDIpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChwb3NpdGlvblhHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMyk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KHBvc2l0aW9uWUdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCA0KTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocG9zaXRpb25aR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDUpO1xuICAgICAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHBhbm5lck5vZGUpO1xuICAgICAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlKGlucHV0R2Fpbk5vZGUsIHdhdmVTaGFwZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3JpZW50YXRpb25YR2Fpbk5vZGUpO1xuICAgICAgICAgICAgb3JpZW50YXRpb25YR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG9yaWVudGF0aW9uWUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWUdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChvcmllbnRhdGlvblpHYWluTm9kZSk7XG4gICAgICAgICAgICBvcmllbnRhdGlvblpHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocG9zaXRpb25YR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpb25YR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBvc2l0aW9uWUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHBvc2l0aW9uWUdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwb3NpdGlvblpHYWluTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGlvblpHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmRpc2Nvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlUGFubmVyTm9kZUZha2VyLCBwYW5uZXJOb2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeSA9IChjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBkaXNhYmxlTm9ybWFsaXphdGlvbiwgaW1hZywgcmVhbCB9KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTgwOiBTYWZhcmkgZG9lcyBub3QgYWxsb3cgdG8gdXNlIG9yZGluYXJ5IGFycmF5cy5cbiAgICAgICAgY29uc3QgY29udmVydGVkSW1hZyA9IGltYWcgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBpbWFnIDogbmV3IEZsb2F0MzJBcnJheShpbWFnKTtcbiAgICAgICAgY29uc3QgY29udmVydGVkUmVhbCA9IHJlYWwgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyByZWFsIDogbmV3IEZsb2F0MzJBcnJheShyZWFsKTtcbiAgICAgICAgY29uc3QgbmF0aXZlUGVyaW9kaWNXYXZlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUoY29udmVydGVkUmVhbCwgY29udmVydGVkSW1hZywgeyBkaXNhYmxlTm9ybWFsaXphdGlvbiB9KTtcbiAgICAgICAgLy8gQnVnICMxODE6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbmRleFNpemVFcnJvciBzbyBmYXIgaWYgdGhlIGdpdmVuIGFycmF5cyBoYXZlIGxlc3MgdGhhbiB0d28gdmFsdWVzLlxuICAgICAgICBpZiAoQXJyYXkuZnJvbShpbWFnKS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYXRpdmVQZXJpb2RpY1dhdmU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGVyaW9kaWMtd2F2ZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlID0gKG5hdGl2ZUNvbnRleHQsIGJ1ZmZlclNpemUsIG51bWJlck9mSW5wdXRDaGFubmVscywgbnVtYmVyT2ZPdXRwdXRDaGFubmVscykgPT4ge1xuICAgIHJldHVybiBuYXRpdmVDb250ZXh0LmNyZWF0ZVNjcmlwdFByb2Nlc3NvcihidWZmZXJTaXplLCBudW1iZXJPZklucHV0Q2hhbm5lbHMsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lIGRlcHJlY2F0aW9uXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXNjcmlwdC1wcm9jZXNzb3Itbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBjaGFubmVsQ291bnRNb2RlID0gb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzEwNTogVGhlIGNoYW5uZWxDb3VudE1vZGUgb2YgJ2NsYW1wZWQtbWF4JyBzaG91bGQgYmUgc3VwcG9ydGVkLiBIb3dldmVyIGl0IGlzIG5vdCBwb3NzaWJsZSB0byB3cml0ZSBhIHBvbHlmaWxsIGZvciBTYWZhcmlcbiAgICAgICAgICogd2hpY2ggc3VwcG9ydHMgaXQgYW5kIHRoZXJlZm9yZSBpdCBjYW4ndCBiZSBzdXBwb3J0ZWQgYXQgYWxsLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudE1vZGUgPT09ICdjbGFtcGVkLW1heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBTdGVyZW9QYW5uZXJOb2RlLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIG9wdGlvbnMsICdwYW4nKTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDU6IFRoZSBjaGFubmVsQ291bnRNb2RlIG9mICdjbGFtcGVkLW1heCcgc2hvdWxkIGJlIHN1cHBvcnRlZC4gSG93ZXZlciBpdCBpcyBub3QgcG9zc2libGUgdG8gd3JpdGUgYSBwb2x5ZmlsbCBmb3IgU2FmYXJpXG4gICAgICAgICAqIHdoaWNoIHN1cHBvcnRzIGl0IGFuZCB0aGVyZWZvcmUgaXQgY2FuJ3QgYmUgc3VwcG9ydGVkIGF0IGFsbC5cbiAgICAgICAgICovXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBjaGFubmVsQ291bnRNb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgLy8gVGhlIGN1cnZlIGhhcyBhIHNpemUgb2YgMTRiaXQgcGx1cyAxIHZhbHVlIHRvIGhhdmUgYW4gZXhhY3QgcmVwcmVzZW50YXRpb24gZm9yIHplcm8uIFRoaXMgdmFsdWUgaGFzIGJlZW4gZGV0ZXJtaW5lZCBleHBlcmltZW50YWxseS5cbiAgICBjb25zdCBDVVJWRV9TSVpFID0gMTYzODU7XG4gICAgY29uc3QgRENfQ1VSVkUgPSBuZXcgRmxvYXQzMkFycmF5KFsxLCAxXSk7XG4gICAgY29uc3QgSEFMRl9QSSA9IE1hdGguUEkgLyAyO1xuICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX09QVElPTlMgPSB7IGNoYW5uZWxDb3VudDogMSwgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JywgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnIH07XG4gICAgY29uc3QgU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUyA9IHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgb3ZlcnNhbXBsZTogJ25vbmUnIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoRm9yTW9ubyA9IChuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbGVmdFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBDVVJWRV9TSVpFOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHggPSAoaSAvIChDVVJWRV9TSVpFIC0gMSkpICogSEFMRl9QSTtcbiAgICAgICAgICAgIGxlZnRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbGVmdEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBsZWZ0V2F2ZVNoYXBlck5vZGUgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLCBjdXJ2ZTogbGVmdFdhdmVTaGFwZXJDdXJ2ZSB9KSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHBhbldhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IERDX0NVUlZFIH0pKTtcbiAgICAgICAgY29uc3QgcmlnaHRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRXYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiByaWdodFdhdmVTaGFwZXJDdXJ2ZSB9KSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGxlZnRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChyaWdodEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5jb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IGxlZnRXYXZlU2hhcGVyTm9kZSA6IGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QocmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHJpZ2h0V2F2ZVNoYXBlck5vZGUgOiByaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChyaWdodEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc2Nvbm5lY3RHcmFwaCgpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHJpZ2h0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gbGVmdFdhdmVTaGFwZXJOb2RlIDogbGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcmlnaHRXYXZlU2hhcGVyTm9kZSA6IHJpZ2h0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBjb25zdCBidWlsZEludGVybmFsR3JhcGhGb3JTdGVyZW8gPSAobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgY2VudGVySW5kZXggPSBNYXRoLmZsb29yKENVUlZFX1NJWkUgLyAyKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBDVVJWRV9TSVpFOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmIChpID4gY2VudGVySW5kZXgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gKChpIC0gY2VudGVySW5kZXgpIC8gKENVUlZFX1NJWkUgLSAxIC0gY2VudGVySW5kZXgpKSAqIEhBTEZfUEk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguY29zKHgpO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAwO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gKGkgLyAoQ1VSVkVfU0laRSAtIDEgLSBjZW50ZXJJbmRleCkpICogSEFMRl9QSTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gMTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDA7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLnNpbih4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiAyXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHBhbldhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IERDX0NVUlZFIH0pKTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmNvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHBhbldhdmVTaGFwZXJOb2RlIDogcGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAwKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMSk7XG4gICAgICAgICAgICAgICAgcGFuV2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwYW5HYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoID0gKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGlmIChjaGFubmVsQ291bnQgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBidWlsZEludGVybmFsR3JhcGhGb3JNb25vKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudCA9PT0gMikge1xuICAgICAgICAgICAgcmV0dXJuIGJ1aWxkSW50ZXJuYWxHcmFwaEZvclN0ZXJlbyhuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgfTtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnRNb2RlLCBwYW4sIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBpZiAoY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5hdWRpb05vZGVPcHRpb25zLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiAyXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudE1vZGUsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IHBhbkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIGdhaW46IHBhblxuICAgICAgICB9KTtcbiAgICAgICAgbGV0IHsgY29ubmVjdEdyYXBoLCBkaXNjb25uZWN0R3JhcGggfSA9IGJ1aWxkSW50ZXJuYWxHcmFwaChuYXRpdmVDb250ZXh0LCBjaGFubmVsQ291bnQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnbWF4VmFsdWUnLCB7IGdldDogKCkgPT4gMSB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhbkdhaW5Ob2RlLmdhaW4sICdtaW5WYWx1ZScsIHsgZ2V0OiAoKSA9PiAtMSB9KTtcbiAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAoeyBjb25uZWN0R3JhcGgsIGRpc2Nvbm5lY3RHcmFwaCB9ID0gYnVpbGRJbnRlcm5hbEdyYXBoKG5hdGl2ZUNvbnRleHQsIHZhbHVlLCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09ICdjbGFtcGVkLW1heCcgfHwgdmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2lucHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcGFuKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5HYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbm5lY3RHcmFwaCgpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnksIGNoYW5uZWxNZXJnZXJOb2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBjb3JyZWN0bHkgbWFwIHRoZSB2YWx1ZXMuXG4gICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGUgZXhpc3RlbmNlIG9mXG4gICAgICAgICAqIHRoZSB3ZWJraXRBdWRpb0NvbnRleHQgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgaGVyZS4gVGVzdGluZyBmb3IgdGhlIGF1dG9tYXRpb25SYXRlIHByb3BlcnR5IGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHRoaXMgd29ya2Fyb3VuZFxuICAgICAgICAgKiBpc24ndCBuZWNlc3NhcnkgYW55bW9yZSBzaW5jZSB2MTQuMC4yIG9mIFNhZmFyaS5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcgJiZcbiAgICAgICAgICAgIG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpLmdhaW4uYXV0b21hdGlvblJhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVXYXZlU2hhcGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGN1cnZlID0gb3B0aW9ucy5jdXJ2ZSA9PT0gbnVsbCB8fCBvcHRpb25zLmN1cnZlIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gb3B0aW9ucy5jdXJ2ZSA6IG5ldyBGbG9hdDMyQXJyYXkob3B0aW9ucy5jdXJ2ZSk7XG4gICAgICAgIC8vIEJ1ZyAjMTA0OiBDaHJvbWUgYW5kIEVkZ2Ugd2lsbCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3Igd2hlbiB0aGUgY3VydmUgaGFzIGxlc3MgdGhhbiB0d28gc2FtcGxlcy5cbiAgICAgICAgaWYgKGN1cnZlICE9PSBudWxsICYmIGN1cnZlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSB2YWx1ZXMgb2YgdHlwZSBGbG9hdDMyQXJyYXkgY2FuIGJlIGFzc2lnbmVkIHRvIHRoZSBjdXJ2ZSBwcm9wZXJ0eS5cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB7IGN1cnZlIH0sICdjdXJ2ZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlV2F2ZVNoYXBlck5vZGUsIG9wdGlvbnMsICdvdmVyc2FtcGxlJyk7XG4gICAgICAgIGxldCBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVXYXZlU2hhcGVyTm9kZSwgJ2N1cnZlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlV2F2ZVNoYXBlck5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKHZhbHVlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNEQ0N1cnZlKHZhbHVlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChpc0RDQ3VydmUobmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUpKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyRmFjdG9yeSA9IChjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgY3VydmUsIG92ZXJzYW1wbGUsIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIGNvbnN0IHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLCBhdWRpb05vZGVPcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLCBhdWRpb05vZGVPcHRpb25zKTtcbiAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3QgaW52ZXJ0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IC0xIH0pO1xuICAgICAgICBjb25zdCBvdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3QgcmV2ZXJ0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IC0xIH0pO1xuICAgICAgICBsZXQgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgIGxldCBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICBsZXQgdW5tb2RpZmllZEN1cnZlID0gbnVsbDtcbiAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVubW9kaWZpZWRDdXJ2ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY3VydmUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VydmVMZW5ndGggPSB2YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZ2F0aXZlQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KGN1cnZlTGVuZ3RoICsgMiAtIChjdXJ2ZUxlbmd0aCAlIDIpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpdmVDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoY3VydmVMZW5ndGggKyAyIC0gKGN1cnZlTGVuZ3RoICUgMikpO1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZUN1cnZlWzBdID0gdmFsdWVbMF07XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlQ3VydmVbMF0gPSAtdmFsdWVbY3VydmVMZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5jZWlsKChjdXJ2ZUxlbmd0aCArIDEpIC8gMik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlckluZGV4ID0gKGN1cnZlTGVuZ3RoICsgMSkgLyAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGhlb3JldGljSW5kZXggPSAoaSAvIGxlbmd0aCkgKiBjZW50ZXJJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvd2VySW5kZXggPSBNYXRoLmZsb29yKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwcGVySW5kZXggPSBNYXRoLmNlaWwodGhlb3JldGljSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVDdXJ2ZVtpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHZhbHVlW2xvd2VySW5kZXhdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZVtsb3dlckluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIHZhbHVlW3VwcGVySW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVDdXJ2ZVtpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IC12YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSBsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IC0oKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSBsb3dlckluZGV4XSkgLVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgLSAodXBwZXJJbmRleCAtIHRoZW9yZXRpY0luZGV4KSkgKiB2YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSB1cHBlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZUN1cnZlW2xlbmd0aF0gPSBjdXJ2ZUxlbmd0aCAlIDIgPT09IDEgPyB2YWx1ZVtsZW5ndGggLSAxXSA6ICh2YWx1ZVtsZW5ndGggLSAyXSArIHZhbHVlW2xlbmd0aCAtIDFdKSAvIDI7XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSBuZWdhdGl2ZUN1cnZlO1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gcG9zaXRpdmVDdXJ2ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdW5tb2RpZmllZEN1cnZlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0RDQ3VydmUodW5tb2RpZmllZEN1cnZlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtpbnB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG92ZXJzYW1wbGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb3ZlcnNhbXBsZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoY3VydmUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgdmFsdWVzIG9mIHR5cGUgRmxvYXQzMkFycmF5IGNhbiBiZSBhc3NpZ25lZCB0byB0aGUgY3VydmUgcHJvcGVydHkuXG4gICAgICAgICAgICBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLmN1cnZlID0gY3VydmUgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBjdXJ2ZSA6IG5ldyBGbG9hdDMyQXJyYXkoY3VydmUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdmVyc2FtcGxlICE9PSBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLm92ZXJzYW1wbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlKS5jb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChpbnZlcnRHYWluTm9kZSkuY29ubmVjdChwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlKS5jb25uZWN0KHJldmVydEdhaW5Ob2RlKS5jb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChpc0RDQ3VydmUodW5tb2RpZmllZEN1cnZlKSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QobmVnYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3V0cHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGludmVydEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGludmVydEdhaW5Ob2RlLmRpc2Nvbm5lY3QocG9zaXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocmV2ZXJ0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuZGlzY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciwgb3V0cHV0R2Fpbk5vZGUpLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ05vdFN1cHBvcnRlZEVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ub3Qtc3VwcG9ydGVkLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IHRlc3RQcm9taXNlU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIG51bWJlck9mQ2hhbm5lbHM6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc3RhcnRSZW5kZXJpbmcpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgT2ZmbGluZUF1ZGlvQ29udGV4dCBleHRlbmRzIGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGEsIGIsIGMpIHtcbiAgICAgICAgICAgIGxldCBvcHRpb25zO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhID09PSAnbnVtYmVyJyAmJiBiICE9PSB1bmRlZmluZWQgJiYgYyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHsgbGVuZ3RoOiBiLCBudW1iZXJPZkNoYW5uZWxzOiBhLCBzYW1wbGVSYXRlOiBjIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gYTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGdpdmVuIHBhcmFtZXRlcnMgYXJlIG5vdCB2YWxpZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0gPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vICMyMSBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyBhbmQgdGhlcmVmb3JlIHdvdWxkIGZpcmUgdGhlIHN0YXRlY2hhbmdlIGV2ZW50IGJlZm9yZSB0aGUgcHJvbWlzZSBjYW4gYmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsYXlTdGF0ZUNoYW5nZUV2ZW50O1xuICAgICAgICAgICAgICAgIH0pKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgPT09IG51bGwgPyB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXRlIDogdGhpcy5fc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRSZW5kZXJpbmcoKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM5ICYgIzU5OiBJdCBpcyB0aGVvcmV0aWNhbGx5IHBvc3NpYmxlIHRoYXQgc3RhcnRSZW5kZXJpbmcoKSB3aWxsIGZpcnN0IHJlbmRlciBhIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LiBUaGVyZWZvcmVcbiAgICAgICAgICAgICAqIHRoZSBzdGF0ZSBvZiB0aGUgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCBtaWdodCBubyB0cmFuc2l0aW9uIHRvIHJ1bm5pbmcgaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAncnVubmluZyc7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnRSZW5kZXJpbmcodGhpcy5kZXN0aW5hdGlvbiwgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGV0dW5lOiAwLFxuICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgIHBlcmlvZGljV2F2ZTogdW5kZWZpbmVkLFxuICAgIHR5cGU6ICdzaW5lJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBPc2NpbGxhdG9yTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBvc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgY29uc3QgbnlxdWlzdCA9IGNvbnRleHQuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUsIG9zY2lsbGF0b3JOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM4MTogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZGV0dW5lID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSwgMTUzNjAwLCAtMTUzNjAwKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzY6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5LCBueXF1aXN0LCAtbnlxdWlzdCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZU9zY2lsbGF0b3JOb2RlO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gb3NjaWxsYXRvck5vZGVSZW5kZXJlcjtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsICYmIG1lcmdlZE9wdGlvbnMucGVyaW9kaWNXYXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlZE9wdGlvbnMucGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBkZXR1bmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV0dW5lO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uZW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLm9uZW5kZWQ7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbmF0aXZlT25FbmRlZCAhPT0gbnVsbCAmJiBuYXRpdmVPbkVuZGVkID09PSB3cmFwcGVkTGlzdGVuZXIgPyB2YWx1ZSA6IG5hdGl2ZU9uRW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgdHlwZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZSA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIucGVyaW9kaWNXYXZlID0gcGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5zdGFydCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5zdG9wID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHBlcmlvZGljV2F2ZSA9IG51bGw7XG4gICAgICAgIGxldCBzdGFydCA9IG51bGw7XG4gICAgICAgIGxldCBzdG9wID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlT3NjaWxsYXRvck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlT3NjaWxsYXRvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkZXR1bmU6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZnJlcXVlbmN5OiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZTogcGVyaW9kaWNXYXZlID09PSBudWxsID8gdW5kZWZpbmVkIDogcGVyaW9kaWNXYXZlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS50eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3Aoc3RvcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVPc2NpbGxhdG9yTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNldCBwZXJpb2RpY1dhdmUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUgPSByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlT3NjaWxsYXRvck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgY29uZUlubmVyQW5nbGU6IDM2MCxcbiAgICBjb25lT3V0ZXJBbmdsZTogMzYwLFxuICAgIGNvbmVPdXRlckdhaW46IDAsXG4gICAgZGlzdGFuY2VNb2RlbDogJ2ludmVyc2UnLFxuICAgIG1heERpc3RhbmNlOiAxMDAwMCxcbiAgICBvcmllbnRhdGlvblg6IDEsXG4gICAgb3JpZW50YXRpb25ZOiAwLFxuICAgIG9yaWVudGF0aW9uWjogMCxcbiAgICBwYW5uaW5nTW9kZWw6ICdlcXVhbHBvd2VyJyxcbiAgICBwb3NpdGlvblg6IDAsXG4gICAgcG9zaXRpb25ZOiAwLFxuICAgIHBvc2l0aW9uWjogMCxcbiAgICByZWZEaXN0YW5jZTogMSxcbiAgICByb2xsb2ZmRmFjdG9yOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhbm5lck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFBhbm5lck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHBhbm5lck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZVBhbm5lck5vZGUsIHBhbm5lck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlID0gbmF0aXZlUGFubmVyTm9kZTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblggPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblkgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblksIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblogPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblosIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblggPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblkgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblksIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblogPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblosIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjb25lSW5uZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lT3V0ZXJBbmdsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjb25lT3V0ZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lT3V0ZXJHYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyR2FpbjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY29uZU91dGVyR2Fpbih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJHYWluID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRpc3RhbmNlTW9kZWwoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsO1xuICAgICAgICB9XG4gICAgICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWwgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4RGlzdGFuY2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5tYXhEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWF4RGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUubWF4RGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25YKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25ZKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25aKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGFubmluZ01vZGVsKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsO1xuICAgICAgICB9XG4gICAgICAgIHNldCBwYW5uaW5nTW9kZWwodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucmVmRGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHJlZkRpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJvbGxvZmZGYWN0b3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yO1xuICAgICAgICB9XG4gICAgICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3IgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFubmVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHJlbmRlcmVkQnVmZmVyUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBuYXRpdmVQYW5uZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgY29uZUlubmVyQW5nbGU6IG5hdGl2ZVBhbm5lck5vZGUuY29uZUlubmVyQW5nbGUsXG4gICAgICAgICAgICAgICAgY29uZU91dGVyQW5nbGU6IG5hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUsXG4gICAgICAgICAgICAgICAgY29uZU91dGVyR2FpbjogbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJHYWluLFxuICAgICAgICAgICAgICAgIGRpc3RhbmNlTW9kZWw6IG5hdGl2ZVBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbCxcbiAgICAgICAgICAgICAgICBtYXhEaXN0YW5jZTogbmF0aXZlUGFubmVyTm9kZS5tYXhEaXN0YW5jZSxcbiAgICAgICAgICAgICAgICBwYW5uaW5nTW9kZWw6IG5hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsLFxuICAgICAgICAgICAgICAgIHJlZkRpc3RhbmNlOiBuYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlLFxuICAgICAgICAgICAgICAgIHJvbGxvZmZGYWN0b3I6IG5hdGl2ZVBhbm5lck5vZGUucm9sbG9mZkZhY3RvclxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVQYW5uZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZVBhbm5lck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxMjQ6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmeWluZyB0aGUgb3JpZW50YXRpb24gYW5kIHRoZSBwb3NpdGlvbiB3aXRoIEF1ZGlvUGFyYW1zLlxuICAgICAgICAgICAgaWYgKCdidWZmZXJTaXplJyBpbiBuYXRpdmVQYW5uZXJOb2RlKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5jb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25aOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWi52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25aOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWi52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUdhaW5Ob2RlID09PSBudWxsID8gbmF0aXZlUGFubmVyTm9kZSA6IG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVHYWluTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZEJ1ZmZlclByb21pc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoNiwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICAgICAgICAgIHByb3h5LmNvbnRleHQubGVuZ3RoLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDZcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3QocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICByZW5kZXJlZEJ1ZmZlclByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlcyA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5vcmllbnRhdGlvblgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkub3JpZW50YXRpb25ZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5Lm9yaWVudGF0aW9uWixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5wb3NpdGlvblgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkucG9zaXRpb25ZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5LnBvc2l0aW9uWlxuICAgICAgICAgICAgICAgICAgICAgICAgXS5tYXAoYXN5bmMgKGF1ZGlvUGFyYW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGluZGV4ID09PSAwID8gMSA6IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzW2ldLmNvbm5lY3QobmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIDAsIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXNbaV0uc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkQnVmZmVyID0gYXdhaXQgcmVuZGVyZWRCdWZmZXJQcm9taXNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVsczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxEYXRhcy5wdXNoKHJlbmRlcmVkQnVmZmVyLmdldENoYW5uZWxEYXRhKGkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RPcmllbnRhdGlvbiA9IFtjaGFubmVsRGF0YXNbMF1bMF0sIGNoYW5uZWxEYXRhc1sxXVswXSwgY2hhbm5lbERhdGFzWzJdWzBdXTtcbiAgICAgICAgICAgICAgICBsZXQgbGFzdFBvc2l0aW9uID0gW2NoYW5uZWxEYXRhc1szXVswXSwgY2hhbm5lbERhdGFzWzRdWzBdLCBjaGFubmVsRGF0YXNbNV1bMF1dO1xuICAgICAgICAgICAgICAgIGxldCBnYXRlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICAgICAgbGV0IHBhcnRpYWxQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblg6IGxhc3RPcmllbnRhdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBsYXN0T3JpZW50YXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWjogbGFzdE9yaWVudGF0aW9uWzJdLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblg6IGxhc3RQb3NpdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBsYXN0UG9zaXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogbGFzdFBvc2l0aW9uWzJdXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGdhdGVHYWluTm9kZSkuY29ubmVjdChwYXJ0aWFsUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxMjg7IGkgPCByZW5kZXJlZEJ1ZmZlci5sZW5ndGg7IGkgKz0gMTI4KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW2NoYW5uZWxEYXRhc1swXVtpXSwgY2hhbm5lbERhdGFzWzFdW2ldLCBjaGFubmVsRGF0YXNbMl1baV1dO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW2NoYW5uZWxEYXRhc1szXVtpXSwgY2hhbm5lbERhdGFzWzRdW2ldLCBjaGFubmVsRGF0YXNbNV1baV1dO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3JpZW50YXRpb24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0b24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gaSAvIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHsgLi4uY29tbW9uQXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uY29tbW9uTmF0aXZlUGFubmVyTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBsYXN0T3JpZW50YXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBsYXN0T3JpZW50YXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25aOiBsYXN0T3JpZW50YXRpb25bMl0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBsYXN0UG9zaXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBsYXN0UG9zaXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25aOiBsYXN0UG9zaXRpb25bMl1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2F0ZUdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGdhdGVHYWluTm9kZSkuY29ubmVjdChwYXJ0aWFsUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGlhbFBhbm5lck5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFuYXRpdmVQYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblksIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblopO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblksIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWik7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVQYW5uZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVQYW5uZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlUGFubmVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlUGFubmVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVPck5hdGl2ZVBhbm5lck5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBkaXNhYmxlTm9ybWFsaXphdGlvbjogZmFsc2Vcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgPSAoY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlLCBnZXROYXRpdmVDb250ZXh0LCBwZXJpb2RpY1dhdmVTdG9yZSwgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFBlcmlvZGljV2F2ZSB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyh7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9KTtcbiAgICAgICAgICAgIGNvbnN0IHBlcmlvZGljV2F2ZSA9IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIHBlcmlvZGljV2F2ZVN0b3JlLmFkZChwZXJpb2RpY1dhdmUpO1xuICAgICAgICAgICAgLy8gVGhpcyBkb2VzIHZpb2xhdGUgYWxsIGdvb2QgcHJhdGljZXMgYnV0IGl0IGlzIHVzZWQgaGVyZSB0byBzaW1wbGlmeSB0aGUgaGFuZGxpbmcgb2YgcGVyaW9kaWMgd2F2ZXMuXG4gICAgICAgICAgICByZXR1cm4gcGVyaW9kaWNXYXZlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShpbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuICgoaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlID09PSAnb2JqZWN0JyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpID09PSBQZXJpb2RpY1dhdmUucHJvdG90eXBlKSB8fFxuICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZVN0b3JlLmhhcyhpbnN0YW5jZSkpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wZXJpb2RpYy13YXZlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJBdXRvbWF0aW9uID0gKGdldEF1ZGlvUGFyYW1SZW5kZXJlciwgcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1SZW5kZXJlciA9IGdldEF1ZGlvUGFyYW1SZW5kZXJlcihhdWRpb1BhcmFtKTtcbiAgICAgICAgYXVkaW9QYXJhbVJlbmRlcmVyLnJlcGxheShuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICAgICAgcmV0dXJuIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbShhdWRpb1BhcmFtLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1hdXRvbWF0aW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSA9IChnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGlzUGFydE9mQUN5Y2xlKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChhdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9ucyA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGF1ZGlvTm9kZUNvbm5lY3Rpb25zLmFjdGl2ZUlucHV0c1xuICAgICAgICAgICAgLm1hcCgoY29ubmVjdGlvbnMsIGlucHV0KSA9PiBBcnJheS5mcm9tKGNvbm5lY3Rpb25zKS5tYXAoYXN5bmMgKFtzb3VyY2UsIG91dHB1dF0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvTm9kZVJlbmRlcmVyID0gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoc291cmNlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gYXdhaXQgYXVkaW9Ob2RlUmVuZGVyZXIucmVuZGVyKHNvdXJjZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IGF1ZGlvTm9kZS5jb250ZXh0LmRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgaWYgKCFpc1BhcnRPZkFDeWNsZShzb3VyY2UpICYmIChhdWRpb05vZGUgIT09IGRlc3RpbmF0aW9uIHx8ICFpc1BhcnRPZkFDeWNsZShhdWRpb05vZGUpKSkge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpXG4gICAgICAgICAgICAucmVkdWNlKChhbGxSZW5kZXJpbmdQcm9taXNlcywgcmVuZGVyaW5nUHJvbWlzZXMpID0+IFsuLi5hbGxSZW5kZXJpbmdQcm9taXNlcywgLi4ucmVuZGVyaW5nUHJvbWlzZXNdLCBbXSkpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0gPSAoZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucywgaXNQYXJ0T2ZBQ3ljbGUpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGF1ZGlvUGFyYW0sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGF1ZGlvUGFyYW0pO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5hY3RpdmVJbnB1dHMpLm1hcChhc3luYyAoW3NvdXJjZSwgb3V0cHV0XSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXVkaW9Ob2RlUmVuZGVyZXIgPSBnZXRBdWRpb05vZGVSZW5kZXJlcihzb3VyY2UpO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSBhd2FpdCBhdWRpb05vZGVSZW5kZXJlci5yZW5kZXIoc291cmNlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLWlucHV0cy1vZi1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIHRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHByb21pc2VzIHlldC5cbiAgICAgICAgaWYgKGNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGFkdmFuY2UgY3VycmVudFRpbWUgaWYgaXQgaXMgbm90IGFjY2Vzc2VkIHdoaWxlIHJlbmRlcmluZyB0aGUgYXVkaW8uXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlVGVzdFJlc3VsdCh0ZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCwgdGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQpKS50aGVuKChpc09mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnRlZCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgNTEyLCAwLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5vbmNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKCkgPT4gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jdXJyZW50VGltZTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbm5lY3QobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNDg6IFNhZmFyaSBkb2VzIG5vdCByZW5kZXIgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCB3aXRob3V0IGFueSBjb25uZWN0ZWQgbm9kZS5cbiAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICBnYWluOiAwXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQub25jb21wbGV0ZSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGV2ZW50LnJlbmRlcmVkQnVmZmVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBnYWluTm9kZS5jb25uZWN0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVTZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzID0gKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKSA9PiB7XG4gICAgICAgIGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZS5zZXQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlU2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSAoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlLCB0YWlsVGltZSkgPT4gYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZS5zZXQoYXVkaW9Ob2RlLCB0YWlsVGltZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzLm1hcCIsImltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlU3RhcnRSZW5kZXJpbmcgPSAoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpID0+IHtcbiAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiBnZXRBdWRpb05vZGVSZW5kZXJlcihkZXN0aW5hdGlvbilcbiAgICAgICAgLnJlbmRlcihkZXN0aW5hdGlvbiwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dClcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICM4NiAmICM4NzogSW52b2tpbmcgdGhlIHJlbmRlcmVyIG9mIGFuIEF1ZGlvV29ya2xldE5vZGUgbWlnaHQgYmUgbmVjZXNzYXJ5IGlmIGl0IGhhcyBubyBkaXJlY3Qgb3IgaW5kaXJlY3QgY29ubmVjdGlvbiB0byB0aGVcbiAgICAgICAgICogZGVzdGluYXRpb24uXG4gICAgICAgICAqL1xuICAgICAgICAudGhlbigoKSA9PiBQcm9taXNlLmFsbChBcnJheS5mcm9tKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkubWFwKChhdWRpb1dvcmtsZXROb2RlKSA9PiBnZXRBdWRpb05vZGVSZW5kZXJlcihhdWRpb1dvcmtsZXROb2RlKS5yZW5kZXIoYXVkaW9Xb3JrbGV0Tm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSlcbiAgICAgICAgLnRoZW4oKCkgPT4gcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSlcbiAgICAgICAgLnRoZW4oKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgLy8gQnVnICMxMDA6IFNhZmFyaSBkb2VzIHRocm93IGEgd3JvbmcgZXJyb3Igd2hlbiBjYWxsaW5nIGdldENoYW5uZWxEYXRhKCkgd2l0aCBhbiBvdXQtb2YtYm91bmRzIHZhbHVlLlxuICAgICAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0KGF1ZGlvQnVmZmVyKSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmFkZChhdWRpb0J1ZmZlcik7XG4gICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGFydC1yZW5kZXJpbmcuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTA1OiBUaGUgY2hhbm5lbENvdW50TW9kZSBzaG91bGQgYmUgJ2NsYW1wZWQtbWF4JyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgYnV0IGlzIHNldCB0byAnZXhwbGljaXQnIHRvIGFjaGlldmUgY29uc2lzdGVudFxuICAgICAqIGJlaGF2aW9yLlxuICAgICAqL1xuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIHBhbjogMFxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFN0ZXJlb1Bhbm5lck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIHN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9wYW4gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4pO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwYW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFuO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlU3RlcmVvUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIHBhbjogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4udmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wYW4sIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBhbiwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlU3RlcmVvUGFubmVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlU3RlcmVvUGFubmVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCIvLyBCdWcgIzMzOiBTYWZhcmkgZXhwb3NlcyBhbiBBdWRpb0J1ZmZlciBidXQgaXQgY2FuJ3QgYmUgdXNlZCBhcyBhIGNvbnN0cnVjdG9yLlxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydCA9IChuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoeyBsZW5ndGg6IDEsIHNhbXBsZVJhdGU6IDQ0MTAwIH0pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLXVudXNlZC1leHByZXNzaW9uXG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItY29uc3RydWN0b3Itc3VwcG9ydC5qcy5tYXAiLCIvLyBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gQnVnICM2MTogSWYgdGhlcmUgaXMgbm8gbmF0aXZlIEF1ZGlvV29ya2xldE5vZGUgaXQgZ2V0cyBmYWtlZCBhbmQgdGhlcmVmb3JlIGl0IGlzIG5vIHByb2JsZW0gaWYgdGhlIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoWydjbGFzcyBBIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29ye3Byb2Nlc3MoaSl7dGhpcy5wb3J0LnBvc3RNZXNzYWdlKGksW2lbMF1bMF0uYnVmZmVyXSl9fXJlZ2lzdGVyUHJvY2Vzc29yKFwiYVwiLEEpJ10sIHtcbiAgICAgICAgICAgIHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04J1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMxNDE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNyZWF0aW5nIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aCBsZXNzIHRoYW4gNDQxMDAgSHouXG4gICAgICAgIGNvbnN0IG9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEyOCwgNDQxMDApO1xuICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBsZXQgaXNFbWl0dGluZ01lc3NhZ2VFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgbGV0IGlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgb2ZmbGluZUF1ZGlvQ29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb1dvcmtsZXROb2RlID0gbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihvZmZsaW5lQXVkaW9Db250ZXh0LCAnYScsIHsgbnVtYmVyT2ZPdXRwdXRzOiAwIH0pO1xuICAgICAgICAgICAgY29uc3Qgb3NjaWxsYXRvciA9IG9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgYXVkaW9Xb3JrbGV0Tm9kZS5wb3J0Lm9ubWVzc2FnZSA9ICgpID0+IChpc0VtaXR0aW5nTWVzc2FnZUV2ZW50cyA9IHRydWUpO1xuICAgICAgICAgICAgYXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gKCkgPT4gKGlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cyA9IHRydWUpO1xuICAgICAgICAgICAgb3NjaWxsYXRvci5jb25uZWN0KGF1ZGlvV29ya2xldE5vZGUpO1xuICAgICAgICAgICAgb3NjaWxsYXRvci5zdGFydCgwKTtcbiAgICAgICAgICAgIGF3YWl0IG9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc0VtaXR0aW5nTWVzc2FnZUV2ZW50cyAmJiAhaXNFbWl0dGluZ1Byb2Nlc3NvckVycm9yRXZlbnRzO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlVGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQgPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgLy8gQnVnICM0ODogU2FmYXJpIGRvZXMgbm90IHJlbmRlciBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGhvdXQgYW55IGNvbm5lY3RlZCBub2RlLlxuICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5vbmNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3VycmVudFRpbWUgIT09IDApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LW9mZmxpbmUtYXVkaW8tY29udGV4dC1jdXJyZW50LXRpbWUtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlVW5rbm93bkVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ1Vua25vd25FcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dW5rbm93bi1lcnJvci5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBjdXJ2ZTogbnVsbCxcbiAgICBvdmVyc2FtcGxlOiAnbm9uZSdcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlV2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFdhdmVTaGFwZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHdhdmVTaGFwZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICAvLyBAdG9kbyBBZGQgYSBtZWNoYW5pc20gdG8gb25seSBzd2l0Y2ggYSBXYXZlU2hhcGVyTm9kZSB0byBhY3RpdmUgd2hpbGUgaXQgaXMgY29ubmVjdGVkLlxuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlV2F2ZVNoYXBlck5vZGUsIHdhdmVTaGFwZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNDdXJ2ZU51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVXYXZlU2hhcGVyTm9kZTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY3VydmUodmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTAzOiBTYWZhcmkgZG9lcyBub3QgYWxsb3cgdG8gc2V0IHRoZSBjdXJ2ZSB0byBudWxsLlxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNDdXJ2ZU51bGxpZmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KFswLCAwXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMDQ6IENocm9tZSBhbmQgRWRnZSB3aWxsIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG92ZXJzYW1wbGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d2F2ZS1zaGFwZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVXYXZlU2hhcGVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlV2F2ZVNoYXBlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVXYXZlU2hhcGVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGN1cnZlOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcnNhbXBsZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVXYXZlU2hhcGVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlV2F2ZVNoYXBlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVdhdmVTaGFwZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdhdmUtc2hhcGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV2luZG93ID0gKCkgPT4gKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IHdpbmRvdyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD13aW5kb3cuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyA9IChjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPSAoZGVzdGluYXRpb24sIGNoYW5uZWxOdW1iZXJBc051bWJlciwgYnVmZmVyT2Zmc2V0QXNOdW1iZXIgPSAwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgaWYgKGNoYW5uZWxOdW1iZXIgPj0gYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlckxlbmd0aCA9IGF1ZGlvQnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcik7XG4gICAgICAgICAgICBjb25zdCBkZXN0aW5hdGlvbkxlbmd0aCA9IGRlc3RpbmF0aW9uLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBidWZmZXJPZmZzZXQgPCAwID8gLWJ1ZmZlck9mZnNldCA6IDA7IGkgKyBidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlckxlbmd0aCAmJiBpIDwgZGVzdGluYXRpb25MZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uW2ldID0gY2hhbm5lbERhdGFbaSArIGJ1ZmZlck9mZnNldF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwgPSAoc291cmNlLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgIGlmIChjaGFubmVsTnVtYmVyID49IGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJMZW5ndGggPSBhdWRpb0J1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlTGVuZ3RoID0gc291cmNlLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBidWZmZXJPZmZzZXQgPCAwID8gLWJ1ZmZlck9mZnNldCA6IDA7IGkgKyBidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlckxlbmd0aCAmJiBpIDwgc291cmNlTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsRGF0YVtpICsgYnVmZmVyT2Zmc2V0XSA9IHNvdXJjZVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyA9IChjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9ICgoY29weUZyb21DaGFubmVsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhidWZmZXJPZmZzZXRBc051bWJlcik7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGlmIChidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvcHlGcm9tQ2hhbm5lbC5jYWxsKGF1ZGlvQnVmZmVyLCBkZXN0aW5hdGlvbiwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwpO1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID0gKChjb3B5VG9DaGFubmVsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKHNvdXJjZSwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3B5VG9DaGFubmVsLmNhbGwoYXVkaW9CdWZmZXIsIHNvdXJjZSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyID0gKG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG51bGxpZmllZEJ1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBudWxsaWZpZWRCdWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgJ2J1ZmZlcicsIChnZXQpID0+ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZ2V0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbGlmaWVkQnVmZmVyID8gbnVsbCA6IHZhbHVlO1xuICAgICAgICB9LCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBzZXQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHZhbHVlID09PSBudWxsID8gbnVsbGlmaWVkQnVmZmVyIDogdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXIuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBDaGFubmVsTWVyZ2VyTm9kZSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICAvLyBCdWcgIzE1OiBTYWZhcmkgZG9lcyBub3QgcmV0dXJuIHRoZSBkZWZhdWx0IHByb3BlcnRpZXMuXG4gICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuICAgICAgICAvLyBCdWcgIzE2OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBzZXR0aW5nIGEgZGlmZmVyZW50IGNoYW5uZWxDb3VudCBvciBjaGFubmVsQ291bnRNb2RlLlxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbE1lcmdlck5vZGUsICdjaGFubmVsQ291bnQnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IDEsXG4gICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxNZXJnZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIHNldDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzIwOiBTYWZhcmkgcmVxdWlyZXMgYSBjb25uZWN0aW9uIG9mIGFueSBraW5kIHRvIHRyZWF0IHRoZSBpbnB1dCBzaWduYWwgY29ycmVjdGx5LlxuICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gY2hhbm5lbE1lcmdlck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICBtb25pdG9yQ29ubmVjdGlvbnMoY2hhbm5lbE1lcmdlck5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1jaGFubmVsLW1lcmdlci1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBnZXRGaXJzdFNhbXBsZSA9IChhdWRpb0J1ZmZlciwgYnVmZmVyLCBjaGFubmVsTnVtYmVyKSA9PiB7XG4gICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgIGlmIChhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcilbMF07XG4gICAgfVxuICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbChidWZmZXIsIGNoYW5uZWxOdW1iZXIpO1xuICAgIHJldHVybiBidWZmZXJbMF07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWZpcnN0LXNhbXBsZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNEQ0N1cnZlID0gKGN1cnZlKSA9PiB7XG4gICAgaWYgKGN1cnZlID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgbGVuZ3RoID0gY3VydmUubGVuZ3RoO1xuICAgIGlmIChsZW5ndGggJSAyICE9PSAwKSB7XG4gICAgICAgIHJldHVybiBjdXJ2ZVtNYXRoLmZsb29yKGxlbmd0aCAvIDIpXSAhPT0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnZlW2xlbmd0aCAvIDIgLSAxXSArIGN1cnZlW2xlbmd0aCAvIDJdICE9PSAwO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWRjLWN1cnZlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBvdmVyd3JpdGVBY2Nlc3NvcnMgPSAob2JqZWN0LCBwcm9wZXJ0eSwgY3JlYXRlR2V0dGVyLCBjcmVhdGVTZXR0ZXIpID0+IHtcbiAgICBsZXQgcHJvdG90eXBlID0gb2JqZWN0O1xuICAgIHdoaWxlICghcHJvdG90eXBlLmhhc093blByb3BlcnR5KHByb3BlcnR5KSkge1xuICAgICAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICB9XG4gICAgY29uc3QgeyBnZXQsIHNldCB9ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm90b3R5cGUsIHByb3BlcnR5KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgeyBnZXQ6IGNyZWF0ZUdldHRlcihnZXQpLCBzZXQ6IGNyZWF0ZVNldHRlcihzZXQpIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW92ZXJ3cml0ZS1hY2Nlc3NvcnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAob3B0aW9ucykgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIG91dHB1dENoYW5uZWxDb3VudDogb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudFxuICAgICAgICAgICAgOiBvcHRpb25zLm51bWJlck9mSW5wdXRzID09PSAxICYmIG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAxXG4gICAgICAgICAgICAgICAgPyAvKlxuICAgICAgICAgICAgICAgICAgICogQnVnICM2MTogVGhpcyBzaG91bGQgYmUgdGhlIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscywgYnV0IHVuZm9ydHVuYXRlbHkgdGhhdCBpcyBhbG1vc3QgaW1wb3NzaWJsZSB0byBmYWtlLiBUaGF0J3Mgd2h5XG4gICAgICAgICAgICAgICAgICAgKiB0aGUgY2hhbm5lbENvdW50TW9kZSBpcyByZXF1aXJlZCB0byBiZSAnZXhwbGljaXQnIGFzIGxvbmcgYXMgdGhlcmUgaXMgbm90IGEgbmF0aXZlIGltcGxlbWVudGF0aW9uIGluIGV2ZXJ5IGJyb3dzZXIuIFRoYXRcbiAgICAgICAgICAgICAgICAgICAqIG1ha2VzIHN1cmUgdGhlIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyBlcXVpdmlsYW50IHRvIHRoZSBjaGFubmVsQ291bnQgd2hpY2ggbWFrZXMgaXQgbXVjaCBlYXNpZXIgdG8gY29tcHV0ZS5cbiAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBbb3B0aW9ucy5jaGFubmVsQ291bnRdXG4gICAgICAgICAgICAgICAgOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyB9LCAoKSA9PiAxKVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2FuaXRpemUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgY2hhbm5lbENvdW50OiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNhbml0aXplLWNoYW5uZWwtc3BsaXR0ZXItb3B0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zID0gKG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IGltYWcsIHJlYWwgfSA9IG9wdGlvbnM7XG4gICAgaWYgKGltYWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAocmVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnOiBbMCwgMF0sIHJlYWw6IFswLCAwXSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWc6IEFycmF5LmZyb20ocmVhbCwgKCkgPT4gMCksIHJlYWwgfTtcbiAgICB9XG4gICAgaWYgKHJlYWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnLCByZWFsOiBBcnJheS5mcm9tKGltYWcsICgpID0+IDApIH07XG4gICAgfVxuICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWcsIHJlYWwgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zYW5pdGl6ZS1wZXJpb2RpYy13YXZlLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZSA9IChhdWRpb1BhcmFtLCB2YWx1ZSwgc3RhcnRUaW1lKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZXJyLmNvZGUgIT09IDkpIHtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUoYXVkaW9QYXJhbSwgdmFsdWUsIHN0YXJ0VGltZSArIDFlLTcpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtdmFsdWUtYXQtdGltZS11bnRpbC1wb3NzaWJsZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgNDQxMDApO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlcjtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoMCwgMSk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoLTEpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiBlcnIgaW5zdGFuY2VvZiBSYW5nZUVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxLCA0NDEwMCk7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXI7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoLTEpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiBlcnIgaW5zdGFuY2VvZiBSYW5nZUVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSA9IChhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zIGFyZSBub3QgY2xvbmFibGUuXG4gICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMtY2xvbmFiaWxpdHkuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nID0gKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCA9ICgoc3RhcnQpID0+IHtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXI7XG4gICAgICAgICAgICAvLyBCdWcgIzE1NDogU2FmYXJpIGRvZXMgbm90IGNsYW1wIHRoZSBvZmZzZXQgaWYgaXQgaXMgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLlxuICAgICAgICAgICAgY29uc3QgY2xhbXBlZE9mZnNldCA9IGJ1ZmZlciA9PT0gbnVsbCA/IG9mZnNldCA6IE1hdGgubWluKGJ1ZmZlci5kdXJhdGlvbiwgb2Zmc2V0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU1OiBTYWZhcmkgZG9lcyBub3QgaGFuZGxlIHRoZSBvZmZzZXQgY29ycmVjdGx5IGlmIGl0IHdvdWxkIGNhdXNlIHRoZSBidWZmZXIgdG8gYmUgbm90IGJlIHBsYXllZCBhdCBhbGwuXG4gICAgICAgICAgICBpZiAoYnVmZmVyICE9PSBudWxsICYmIGNsYW1wZWRPZmZzZXQgPiBidWZmZXIuZHVyYXRpb24gLSAwLjUgLyBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29udGV4dC5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIDAsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIGNsYW1wZWRPZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcuanMubWFwIiwiaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzID0gKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgIGNvbnN0IGRpc2Nvbm5lY3RHYWluTm9kZSA9ICgoZGlzY29ubmVjdCkgPT4ge1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMSBhcmd1bWVudCB5ZXQuXG4gICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCBuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0R2Fpbk5vZGUpO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5kaXNjb25uZWN0KTtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0R2Fpbk5vZGUpO1xuICAgIGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wID0gKChzdG9wKSA9PiB7XG4gICAgICAgIGxldCBpc1N0b3BwZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzU3RvcHBlZCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgd2hlbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RvcC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICAgICAgaXNTdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBFdmVudExpc3RlbmVyID0gKHRhcmdldCwgZXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiAoZXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsgdmFsdWU6IHRhcmdldCB9O1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhldmVudCwge1xuICAgICAgICAgICAgY3VycmVudFRhcmdldDogZGVzY3JpcHRvcixcbiAgICAgICAgICAgIHRhcmdldDogZGVzY3JpcHRvclxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGVvZiBldmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRMaXN0ZW5lci5jYWxsKHRhcmdldCwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBldmVudExpc3RlbmVyLmhhbmRsZUV2ZW50LmNhbGwodGFyZ2V0LCBldmVudCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWV2ZW50LWxpc3RlbmVyLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCwgY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQgfSBmcm9tICdhdXRvbWF0aW9uLWV2ZW50cyc7XG5pbXBvcnQgeyBjcmVhdGVBYm9ydEVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWJvcnQtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlQWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGNyZWF0ZUFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb1dvcmtsZXRNb2R1bGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYXVkaW8td29ya2xldC1tb2R1bGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkU2lsZW50Q29ubmVjdGlvbiB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1zaWxlbnQtY29ubmVjdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVBZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBbmFseXNlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYW5hbHlzZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1idWZmZXItY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1saXN0ZW5lci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1BhcmFtRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tcGFyYW0tcmVuZGVyZXInO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby13b3JrbGV0LW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYmlxdWFkLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDYWNoZVRlc3RSZXN1bHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9jYWNoZS10ZXN0LXJlc3VsdCc7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY2hhbm5lbC1tZXJnZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLXNwbGl0dGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdC1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzJztcbmltcG9ydCB7IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb25uZWN0ZWQtbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252ZXJ0LW51bWJlci10by11bnNpZ25lZC1sb25nJztcbmltcG9ydCB7IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnZvbHZlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9jcmVhdGUtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVEYXRhQ2xvbmVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2RhdGEtY2xvbmUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlRGVjb2RlQXVkaW9EYXRhIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVjb2RlLWF1ZGlvLWRhdGEnO1xuaW1wb3J0IHsgY3JlYXRlRGVjcmVtZW50Q3ljbGVDb3VudGVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVjcmVtZW50LWN5Y2xlLWNvdW50ZXInO1xuaW1wb3J0IHsgY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxheS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVEZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZURlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVsZXRlLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZURldGVjdEN5Y2xlcyB9IGZyb20gJy4vZmFjdG9yaWVzL2RldGVjdC1jeWNsZXMnO1xuaW1wb3J0IHsgY3JlYXRlRGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2Rpc2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2R5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUVuY29kaW5nRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9lbmNvZGluZy1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVFdmFsdWF0ZVNvdXJjZSB9IGZyb20gJy4vZmFjdG9yaWVzL2V2YWx1YXRlLXNvdXJjZSc7XG5pbXBvcnQgeyBjcmVhdGVFdmVudFRhcmdldENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZXZlbnQtdGFyZ2V0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvZXhwb3NlLWN1cnJlbnQtZnJhbWUtYW5kLWN1cnJlbnQtdGltZSc7XG5pbXBvcnQgeyBjcmVhdGVGZXRjaFNvdXJjZSB9IGZyb20gJy4vZmFjdG9yaWVzL2ZldGNoLXNvdXJjZSc7XG5pbXBvcnQgeyBjcmVhdGVHYWluTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2Fpbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2Fpbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVHZXRBdWRpb05vZGVSZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1ub2RlLXJlbmRlcmVyJztcbmltcG9ydCB7IGNyZWF0ZUdldEF1ZGlvTm9kZVRhaWxUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lJztcbmltcG9ydCB7IGNyZWF0ZUdldEF1ZGlvUGFyYW1SZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1wYXJhbS1yZW5kZXJlcic7XG5pbXBvcnQgeyBjcmVhdGVHZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0TmF0aXZlQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1uYXRpdmUtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVHZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2Rlcyc7XG5pbXBvcnQgeyBjcmVhdGVJSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2lpci1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbmNyZW1lbnQtY3ljbGUtY291bnRlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUluZGV4U2l6ZUVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaW5kZXgtc2l6ZS1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbnZhbGlkLWFjY2Vzcy1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueUF1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUlzQW55QXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVDb250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc1NlY3VyZUNvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1zZWN1cmUtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc1N1cHBvcnRlZFByb21pc2UgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1zdXBwb3J0ZWQtcHJvbWlzZSc7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9taW5pbWFsLWJhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTW9uaXRvckNvbm5lY3Rpb25zIH0gZnJvbSAnLi9mYWN0b3JpZXMvbW9uaXRvci1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWFuYWx5c2VyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYmlxdWFkLWZpbHRlci1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLW1lcmdlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLXNwbGl0dGVyLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWNvbnZvbHZlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlRGVsYXlOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWRlbGF5LW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlR2Fpbk5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtZ2Fpbi1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtb3NjaWxsYXRvci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtcGFubmVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1wZXJpb2RpYy13YXZlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1zY3JpcHQtcHJvY2Vzc29yLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL25vdC1zdXBwb3J0ZWQtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVQZXJpb2RpY1dhdmVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL3BlcmlvZGljLXdhdmUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVyQXV0b21hdGlvbiB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1hdXRvbWF0aW9uJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1pbnB1dHMtb2YtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZVNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9zZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlU2V0QXVkaW9Ob2RlVGFpbFRpbWUgfSBmcm9tICcuL2ZhY3Rvcmllcy9zZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlU3RhcnRSZW5kZXJpbmcgfSBmcm9tICcuL2ZhY3Rvcmllcy9zdGFydC1yZW5kZXJpbmcnO1xuaW1wb3J0IHsgY3JlYXRlU3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9zdGVyZW8tcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc1N1YmFycmF5U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLXN1YmFycmF5LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dENsb3NlTWV0aG9kU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1jbG9zZS1tZXRob2Qtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Db250ZXh0RGVjb2RlQXVkaW9EYXRhTWV0aG9kVHlwZUVycm9yU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1kZWNvZGUtYXVkaW8tZGF0YS1tZXRob2QtdHlwZS1lcnJvci1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRPcHRpb25zU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1vcHRpb25zLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvTm9kZUNvbm5lY3RNZXRob2RTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1ub2RlLWNvbm5lY3QtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3Nvck5vT3V0cHV0c1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLW5vLW91dHB1dHMtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q2hhbm5lbE1lcmdlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1jaGFubmVsLW1lcmdlci1ub2RlLWNoYW5uZWwtY291bnQtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q29uc3RhbnRTb3VyY2VOb2RlQWNjdXJhdGVTY2hlZHVsaW5nU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29uc3RhbnQtc291cmNlLW5vZGUtYWNjdXJhdGUtc2NoZWR1bGluZy1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQnVmZmVyUmVhc3NpZ25hYmlsaXR5U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29udm9sdmVyLW5vZGUtYnVmZmVyLXJlYXNzaWduYWJpbGl0eS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29udm9sdmVyLW5vZGUtY2hhbm5lbC1jb3VudC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RJc1NlY3VyZUNvbnRleHRTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1pcy1zZWN1cmUtY29udGV4dC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZU1lZGlhU3RyZWFtV2l0aG91dEF1ZGlvVHJhY2tTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUtbWVkaWEtc3RyZWFtLXdpdGhvdXQtYXVkaW8tdHJhY2stc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3Qtb2ZmbGluZS1hdWRpby1jb250ZXh0LWN1cnJlbnQtdGltZS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RTdGVyZW9QYW5uZXJOb2RlRGVmYXVsdFZhbHVlU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3Qtc3RlcmVvLXBhbm5lci1ub2RlLWRlZmF1bHQtdmFsdWUtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVVbmtub3duRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy91bmtub3duLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZVdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy93YXZlLXNoYXBlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvd2F2ZS1zaGFwZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZVdpbmRvdyB9IGZyb20gJy4vZmFjdG9yaWVzL3dpbmRvdyc7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcyc7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMnO1xuaW1wb3J0IHsgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyJztcbmltcG9ydCB7IGNyZWF0ZVdyYXBDaGFubmVsTWVyZ2VyTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtY2hhbm5lbC1tZXJnZXItbm9kZSc7XG5pbXBvcnQgeyBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFLCBBVURJT19OT0RFX1NUT1JFLCBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSwgQVVESU9fUEFSQU1fU1RPUkUsIENPTlRFWFRfU1RPUkUsIENZQ0xFX0NPVU5URVJTIH0gZnJvbSAnLi9nbG9iYWxzJztcbmltcG9ydCB7IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2Rpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldEZpcnN0U2FtcGxlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1maXJzdC1zYW1wbGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXROYXRpdmVBdWRpb1BhcmFtIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LXZhbHVlLWZvci1rZXknO1xuaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi9oZWxwZXJzL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBpc0RDQ3VydmUgfSBmcm9tICcuL2hlbHBlcnMvaXMtZGMtY3VydmUnO1xuaW1wb3J0IHsgaXNQYXJ0T2ZBQ3ljbGUgfSBmcm9tICcuL2hlbHBlcnMvaXMtcGFydC1vZi1hLWN5Y2xlJztcbmltcG9ydCB7IGlzUGFzc2l2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9pcy1wYXNzaXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgb3ZlcndyaXRlQWNjZXNzb3JzIH0gZnJvbSAnLi9oZWxwZXJzL292ZXJ3cml0ZS1hY2Nlc3NvcnMnO1xuaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9oZWxwZXJzL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5pbXBvcnQgeyBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi9oZWxwZXJzL3Nhbml0aXplLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyB9IGZyb20gJy4vaGVscGVycy9zYW5pdGl6ZS1jaGFubmVsLXNwbGl0dGVyLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zIH0gZnJvbSAnLi9oZWxwZXJzL3Nhbml0aXplLXBlcmlvZGljLXdhdmUtb3B0aW9ucyc7XG5pbXBvcnQgeyBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUgfSBmcm9tICcuL2hlbHBlcnMvc2V0LXZhbHVlLWF0LXRpbWUtdW50aWwtcG9zc2libGUnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMtY2xvbmFiaWxpdHknO1xuaW1wb3J0IHsgdGVzdERvbUV4Y2VwdGlvbkNvbnN0cnVjdG9yU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWRvbS1leGNlcHRpb24tY29uc3RydWN0b3Itc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdFRyYW5zZmVyYWJsZXNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtdHJhbnNmZXJhYmxlcy1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzJztcbmltcG9ydCB7IHdyYXBFdmVudExpc3RlbmVyIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtZXZlbnQtbGlzdGVuZXInO1xuLypcbiAqIEB0b2RvIEV4cGxpY2l0bHkgcmVmZXJlbmNpbmcgdGhlIGJhcnJlbCBmaWxlIHNlZW1zIHRvIGJlIG5lY2Vzc2FyeSB3aGVuIGVuYWJsaW5nIHRoZVxuICogaXNvbGF0ZWRNb2R1bGVzIGNvbXBpbGVyIG9wdGlvbi5cbiAqL1xuZXhwb3J0ICogZnJvbSAnLi9pbnRlcmZhY2VzL2luZGV4JztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMvaW5kZXgnO1xuY29uc3QgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBjcmVhdGVBZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShpbnNlcnRFbGVtZW50SW5TZXQpO1xuY29uc3QgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gY3JlYXRlQWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGluc2VydEVsZW1lbnRJblNldCk7XG5jb25zdCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IGNyZWF0ZURlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBpY2tFbGVtZW50RnJvbVNldCk7XG5jb25zdCBhdWRpb05vZGVUYWlsVGltZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldEF1ZGlvTm9kZVRhaWxUaW1lID0gY3JlYXRlR2V0QXVkaW9Ob2RlVGFpbFRpbWUoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSk7XG5jb25zdCBjYWNoZVRlc3RSZXN1bHQgPSBjcmVhdGVDYWNoZVRlc3RSZXN1bHQobmV3IE1hcCgpLCBuZXcgV2Vha01hcCgpKTtcbmNvbnN0IHdpbmRvdyA9IGNyZWF0ZVdpbmRvdygpO1xuY29uc3QgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlRmFjdG9yeShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IGdldEF1ZGlvTm9kZVJlbmRlcmVyID0gY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMpO1xuY29uc3QgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUgPSBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGlzUGFydE9mQUN5Y2xlKTtcbmNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyID0gY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBnZXROYXRpdmVDb250ZXh0ID0gY3JlYXRlR2V0TmF0aXZlQ29udGV4dChDT05URVhUX1NUT1JFKTtcbmNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUgPSBuZXcgV2Vha01hcCgpO1xuY29uc3QgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciA9IGNyZWF0ZUV2ZW50VGFyZ2V0Q29uc3RydWN0b3Iod3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVBdWRpb0NvbnRleHQgPSBjcmVhdGVJc05hdGl2ZUF1ZGlvQ29udGV4dChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBpc05hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZUlzTmF0aXZlQXVkaW9Ob2RlKHdpbmRvdyk7XG5jb25zdCBpc05hdGl2ZUF1ZGlvUGFyYW0gPSBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0od2luZG93KTtcbmNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgYXVkaW9Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb05vZGVDb25zdHJ1Y3RvcihjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyhBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFKSwgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlKGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlVGFpbFRpbWUsIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgaW5zZXJ0RWxlbWVudEluU2V0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNQYXJ0T2ZBQ3ljbGUsIGlzUGFzc2l2ZUF1ZGlvTm9kZSksIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyRmFjdG9yeShDWUNMRV9DT1VOVEVSUywgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGlzQWN0aXZlQXVkaW9Ob2RlKSwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlcihjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIENZQ0xFX0NPVU5URVJTLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBnZXROYXRpdmVDb250ZXh0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSwgY3JlYXRlRGV0ZWN0Q3ljbGVzKGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldFZhbHVlRm9yS2V5KSwgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZUF1ZGlvUGFyYW0sIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKTtcbmNvbnN0IGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQW5hbHlzZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IHsgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IgYXMgQW5hbHlzZXJOb2RlIH07XG5jb25zdCBhdWRpb0J1ZmZlclN0b3JlID0gbmV3IFdlYWtTZXQoKTtcbmNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHdpbmRvdyk7XG5jb25zdCBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgPSBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcobmV3IFVpbnQzMkFycmF5KDEpKTtcbmNvbnN0IHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyA9IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzID0gY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKTtcbmNvbnN0IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0KG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IpLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmV4cG9ydCB7IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgYXMgQXVkaW9CdWZmZXIgfTtcbmNvbnN0IGFkZFNpbGVudENvbm5lY3Rpb24gPSBjcmVhdGVBZGRTaWxlbnRDb25uZWN0aW9uKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKTtcbmNvbnN0IHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSA9IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9QYXJhbShnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zLCBpc1BhcnRPZkFDeWNsZSk7XG5jb25zdCBjb25uZWN0QXVkaW9QYXJhbSA9IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtKHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSk7XG5jb25zdCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nLCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlcihvdmVyd3JpdGVBY2Nlc3NvcnMpLCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpO1xuY29uc3QgcmVuZGVyQXV0b21hdGlvbiA9IGNyZWF0ZVJlbmRlckF1dG9tYXRpb24oY3JlYXRlR2V0QXVkaW9QYXJhbVJlbmRlcmVyKGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyksIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSk7XG5jb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNyZWF0ZUF1ZGlvUGFyYW0gPSBjcmVhdGVBdWRpb1BhcmFtRmFjdG9yeShjcmVhdGVBZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUpLCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIEFVRElPX1BBUkFNX1NUT1JFLCBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIsIGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCwgY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUpO1xuY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuZXhwb3J0IHsgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIH07XG5jb25zdCBhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZUZhY3RvcnkoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG92ZXJ3cml0ZUFjY2Vzc29ycyksIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBzZXRBdWRpb05vZGVUYWlsVGltZSA9IGNyZWF0ZVNldEF1ZGlvTm9kZVRhaWxUaW1lKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpO1xuY29uc3QgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBtb25pdG9yQ29ubmVjdGlvbnMgPSBjcmVhdGVNb25pdG9yQ29ubmVjdGlvbnMoaW5zZXJ0RWxlbWVudEluU2V0LCBpc05hdGl2ZUF1ZGlvTm9kZSk7XG5jb25zdCB3cmFwQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVXcmFwQ2hhbm5lbE1lcmdlck5vZGUoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeShuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgd3JhcENoYW5uZWxNZXJnZXJOb2RlKTtcbmNvbnN0IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXJGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCk7XG5jb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciA9IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5KGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpO1xuY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyID0gY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZGVsYXlOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVEZWxheU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpO1xuY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyID0gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBkeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciA9IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBnYWluTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlR2Fpbk5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXJGYWN0b3J5KGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKTtcbmNvbnN0IHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVSZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZVRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpKTtcbmNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcik7XG5jb25zdCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVJSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGUsIGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVBdWRpb0xpc3RlbmVyID0gY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkoY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldEZpcnN0U2FtcGxlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG92ZXJ3cml0ZUFjY2Vzc29ycyk7XG5jb25zdCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvTGlzdGVuZXIsIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUgPSBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyk7XG5jb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcik7XG5jb25zdCBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlckZhY3RvcnkoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWN0b3J5KGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgb3ZlcndyaXRlQWNjZXNzb3JzKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlckZhY3RvcnkoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRGaXJzdFNhbXBsZSwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFjdG9yeShjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIpO1xuY29uc3QgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBwYW5uZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmUgPSBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmVGYWN0b3J5KGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yID0gY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IoY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlLCBnZXROYXRpdmVDb250ZXh0LCBuZXcgV2Vha1NldCgpLCBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMpO1xuY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkobmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpO1xuY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCB3YXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlV2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGlzU2VjdXJlQ29udGV4dCA9IGNyZWF0ZUlzU2VjdXJlQ29udGV4dCh3aW5kb3cpO1xuY29uc3QgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUgPSBjcmVhdGVFeHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSh3aW5kb3cpO1xuY29uc3QgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG4vLyBUaGUgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKCkgZnVuY3Rpb24gaXMgb25seSBhdmFpbGFibGUgaW4gYSBTZWN1cmVDb250ZXh0LlxuZXhwb3J0IGNvbnN0IGFkZEF1ZGlvV29ya2xldE1vZHVsZSA9IGlzU2VjdXJlQ29udGV4dFxuICAgID8gY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZUV2YWx1YXRlU291cmNlKHdpbmRvdyksIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBjcmVhdGVGZXRjaFNvdXJjZShjcmVhdGVBYm9ydEVycm9yKSwgZ2V0TmF0aXZlQ29udGV4dCwgZ2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmV3IFdlYWtNYXAoKSwgbmV3IFdlYWtNYXAoKSwgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIFxuICAgIC8vIEB0b2RvIHdpbmRvdyBpcyBndWFyYW50ZWVkIHRvIGJlIGRlZmluZWQgYmVjYXVzZSBpc1NlY3VyZUNvbnRleHQgY2hlY2tzIHRoYXQgYXMgd2VsbC5cbiAgICB3aW5kb3cpXG4gICAgOiB1bmRlZmluZWQ7XG5jb25zdCBpc05hdGl2ZUNvbnRleHQgPSBjcmVhdGVJc05hdGl2ZUNvbnRleHQoaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5leHBvcnQgY29uc3QgZGVjb2RlQXVkaW9EYXRhID0gY3JlYXRlRGVjb2RlQXVkaW9EYXRhKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlRGF0YUNsb25lRXJyb3IsIGNyZWF0ZUVuY29kaW5nRXJyb3IsIG5ldyBXZWFrU2V0KCksIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB0ZXN0UHJvbWlzZVN1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpO1xuY29uc3QgYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGFkZEF1ZGlvV29ya2xldE1vZHVsZSwgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yLCBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciwgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciwgZGVjb2RlQXVkaW9EYXRhLCBkZWxheU5vZGVDb25zdHJ1Y3RvciwgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yLCBnYWluTm9kZUNvbnN0cnVjdG9yLCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IsIHBhbm5lck5vZGVDb25zdHJ1Y3RvciwgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IsIHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3Rvciwgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3Rvcik7XG5jb25zdCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQpO1xuY29uc3QgYXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbmV4cG9ydCB7IGF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIEF1ZGlvQ29udGV4dCB9O1xuY29uc3QgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID0gY3JlYXRlR2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUpO1xuY29uc3QgYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVBZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpO1xuY29uc3QgY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IGNyZWF0ZUNvbm5lY3RNdWx0aXBsZU91dHB1dHMoY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpO1xuY29uc3QgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IGNyZWF0ZURpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMoY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSBjcmVhdGVHZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSwgZ2V0VmFsdWVGb3JLZXkpO1xuY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyRmFjdG9yeShjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZhY3RvcnkoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyID0gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY29ubmVjdE11bHRpcGxlT3V0cHV0cywgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUpO1xuY29uc3Qgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IGNyZWF0ZVNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlKTtcbi8vIFRoZSBBdWRpb1dvcmtsZXROb2RlIGNvbnN0cnVjdG9yIGlzIG9ubHkgYXZhaWxhYmxlIGluIGEgU2VjdXJlQ29udGV4dC5cbmNvbnN0IGF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9IGlzU2VjdXJlQ29udGV4dFxuICAgID8gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMsIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5LCB3cmFwRXZlbnRMaXN0ZW5lcilcbiAgICA6IHVuZGVmaW5lZDtcbmV4cG9ydCB7IGF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciBhcyBBdWRpb1dvcmtsZXROb2RlIH07XG5leHBvcnQgeyBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgYXMgQmlxdWFkRmlsdGVyTm9kZSB9O1xuZXhwb3J0IHsgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciBhcyBDaGFubmVsTWVyZ2VyTm9kZSB9O1xuZXhwb3J0IHsgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yIGFzIENoYW5uZWxTcGxpdHRlck5vZGUgfTtcbmV4cG9ydCB7IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciBhcyBDb252b2x2ZXJOb2RlIH07XG5leHBvcnQgeyBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBDb25zdGFudFNvdXJjZU5vZGUgfTtcbmV4cG9ydCB7IGRlbGF5Tm9kZUNvbnN0cnVjdG9yIGFzIERlbGF5Tm9kZSB9O1xuZXhwb3J0IHsgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yIGFzIER5bmFtaWNzQ29tcHJlc3Nvck5vZGUgfTtcbmV4cG9ydCB7IGdhaW5Ob2RlQ29uc3RydWN0b3IgYXMgR2Fpbk5vZGUgfTtcbmV4cG9ydCB7IGlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciBhcyBJSVJGaWx0ZXJOb2RlIH07XG5leHBvcnQgeyBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgfTtcbmV4cG9ydCB7IG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSB9O1xuY29uc3QgbWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5leHBvcnQgeyBtaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgTWluaW1hbEF1ZGlvQ29udGV4dCB9O1xuY29uc3QgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBzdGFydFJlbmRlcmluZyA9IGNyZWF0ZVN0YXJ0UmVuZGVyaW5nKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcywgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmNvbnN0IG1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHN0YXJ0UmVuZGVyaW5nKTtcbmV4cG9ydCB7IG1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHQgfTtcbmNvbnN0IG9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHN0YXJ0UmVuZGVyaW5nKTtcbmV4cG9ydCB7IG9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciBhcyBPZmZsaW5lQXVkaW9Db250ZXh0IH07XG5leHBvcnQgeyBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yIGFzIE9zY2lsbGF0b3JOb2RlIH07XG5leHBvcnQgeyBwYW5uZXJOb2RlQ29uc3RydWN0b3IgYXMgUGFubmVyTm9kZSB9O1xuZXhwb3J0IHsgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgYXMgUGVyaW9kaWNXYXZlIH07XG5leHBvcnQgeyBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgYXMgU3RlcmVvUGFubmVyTm9kZSB9O1xuZXhwb3J0IHsgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciBhcyBXYXZlU2hhcGVyTm9kZSB9O1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9Db250ZXh0ID0gY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQoQ09OVEVYVF9TVE9SRSwgaXNOYXRpdmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9Ob2RlID0gY3JlYXRlSXNBbnlBdWRpb05vZGUoQVVESU9fTk9ERV9TVE9SRSwgaXNOYXRpdmVBdWRpb05vZGUpO1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9QYXJhbSA9IGNyZWF0ZUlzQW55QXVkaW9QYXJhbShBVURJT19QQVJBTV9TVE9SRSwgaXNOYXRpdmVBdWRpb1BhcmFtKTtcbmV4cG9ydCBjb25zdCBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVJc0FueU9mZmxpbmVBdWRpb0NvbnRleHQoQ09OVEVYVF9TVE9SRSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmV4cG9ydCBjb25zdCBpc1N1cHBvcnRlZCA9ICgpID0+IGNyZWF0ZUlzU3VwcG9ydGVkUHJvbWlzZShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc1N1YmFycmF5U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Db250ZXh0Q2xvc2VNZXRob2RTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dERlY29kZUF1ZGlvRGF0YU1ldGhvZFR5cGVFcnJvclN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dE9wdGlvbnNTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvTm9kZUNvbm5lY3RNZXRob2RTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JOb091dHB1dHNTdXBwb3J0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENoYW5uZWxNZXJnZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q29uc3RhbnRTb3VyY2VOb2RlQWNjdXJhdGVTY2hlZHVsaW5nU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUJ1ZmZlclJlYXNzaWduYWJpbGl0eVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENvbnZvbHZlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIHRlc3REb21FeGNlcHRpb25Db25zdHJ1Y3RvclN1cHBvcnQsIGNyZWF0ZVRlc3RJc1NlY3VyZUNvbnRleHRTdXBwb3J0KHdpbmRvdyksIGNyZWF0ZVRlc3RNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZU1lZGlhU3RyZWFtV2l0aG91dEF1ZGlvVHJhY2tTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdFN0ZXJlb1Bhbm5lck5vZGVEZWZhdWx0VmFsdWVTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIHRlc3RUcmFuc2ZlcmFibGVzU3VwcG9ydCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tb2R1bGUuanMubWFwIiwiLyoqXG4gKiBBc3NlcnQgdGhhdCB0aGUgc3RhdGVtZW50IGlzIHRydWUsIG90aGVyd2lzZSBpbnZva2UgdGhlIGVycm9yLlxuICogQHBhcmFtIHN0YXRlbWVudFxuICogQHBhcmFtIGVycm9yIFRoZSBtZXNzYWdlIHdoaWNoIGlzIHBhc3NlZCBpbnRvIGFuIEVycm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoc3RhdGVtZW50LCBlcnJvcikge1xuICAgIGlmICghc3RhdGVtZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgfVxufVxuLyoqXG4gKiBNYWtlIHN1cmUgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgaXMgd2l0aGluIHRoZSByYW5nZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UmFuZ2UodmFsdWUsIGd0ZSwgbHRlID0gSW5maW5pdHkpIHtcbiAgICBpZiAoIShndGUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gbHRlKSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVmFsdWUgbXVzdCBiZSB3aXRoaW4gWyR7Z3RlfSwgJHtsdGV9XSwgZ290OiAke3ZhbHVlfWApO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBzdXJlIHRoYXQgdGhlIGdpdmVuIHZhbHVlIGlzIHdpdGhpbiB0aGUgcmFuZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydENvbnRleHRSdW5uaW5nKGNvbnRleHQpIHtcbiAgICAvLyBhZGQgYSB3YXJuaW5nIGlmIHRoZSBjb250ZXh0IGlzIG5vdCBzdGFydGVkXG4gICAgaWYgKCFjb250ZXh0LmlzT2ZmbGluZSAmJiBjb250ZXh0LnN0YXRlICE9PSBcInJ1bm5pbmdcIikge1xuICAgICAgICB3YXJuKFwiVGhlIEF1ZGlvQ29udGV4dCBpcyBcXFwic3VzcGVuZGVkXFxcIi4gSW52b2tlIFRvbmUuc3RhcnQoKSBmcm9tIGEgdXNlciBhY3Rpb24gdG8gc3RhcnQgdGhlIGF1ZGlvLlwiKTtcbiAgICB9XG59XG4vKipcbiAqIFRoZSBkZWZhdWx0IGxvZ2dlciBpcyB0aGUgY29uc29sZVxuICovXG5sZXQgZGVmYXVsdExvZ2dlciA9IGNvbnNvbGU7XG4vKipcbiAqIFNldCB0aGUgbG9nZ2luZyBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlcihsb2dnZXIpIHtcbiAgICBkZWZhdWx0TG9nZ2VyID0gbG9nZ2VyO1xufVxuLyoqXG4gKiBMb2cgYW55dGhpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyguLi5hcmdzKSB7XG4gICAgZGVmYXVsdExvZ2dlci5sb2coLi4uYXJncyk7XG59XG4vKipcbiAqIFdhcm4gYW55dGhpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdhcm4oLi4uYXJncykge1xuICAgIGRlZmF1bHRMb2dnZXIud2FybiguLi5hcmdzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlYnVnLmpzLm1hcCIsIi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIHVuZGVmaW5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNVbmRlZihhcmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gXCJ1bmRlZmluZWRcIjtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIG5vdCB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmaW5lZChhcmcpIHtcbiAgICByZXR1cm4gIWlzVW5kZWYoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGEgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09IFwiZnVuY3Rpb25cIjtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBhbiBvYmplY3QgbGl0ZXJhbCAoaS5lLiBge31gKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICAgIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZykgPT09IFwiW29iamVjdCBPYmplY3RdXCIgJiYgYXJnLmNvbnN0cnVjdG9yID09PSBPYmplY3QpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhIGJvb2xlYW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgYXJnID09PSBcImJvb2xlYW5cIik7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGFuIEFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICAgIHJldHVybiAoQXJyYXkuaXNBcnJheShhcmcpKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBpbiB0aGUgZm9ybSBvZiBhIG5vdGUgaW4gc2NpZW50aWZpYyBwaXRjaCBub3RhdGlvbi5cbiAqIGUuZy4gXCJDNFwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vdGUoYXJnKSB7XG4gICAgcmV0dXJuIGlzU3RyaW5nKGFyZykgJiYgL14oW2EtZ117MX0oPzpifCN8eHxiYik/KSgtP1swLTldKykvaS50ZXN0KGFyZyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UeXBlQ2hlY2suanMubWFwIiwiaW1wb3J0IHsgQXVkaW9Db250ZXh0IGFzIHN0ZEF1ZGlvQ29udGV4dCwgQXVkaW9Xb3JrbGV0Tm9kZSBhcyBzdGRBdWRpb1dvcmtsZXROb2RlLCBPZmZsaW5lQXVkaW9Db250ZXh0IGFzIHN0ZE9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwic3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogQ3JlYXRlIGEgbmV3IEF1ZGlvQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXVkaW9Db250ZXh0KG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IHN0ZEF1ZGlvQ29udGV4dChvcHRpb25zKTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IE9mZmxpbmVBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHQoY2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSkge1xuICAgIHJldHVybiBuZXcgc3RkT2ZmbGluZUF1ZGlvQ29udGV4dChjaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbn1cbi8qKlxuICogQSByZWZlcmVuY2UgdG8gdGhlIHdpbmRvdyBvYmplY3RcbiAqIEBoaWRkZW5cbiAqL1xuZXhwb3J0IGNvbnN0IHRoZVdpbmRvdyA9IHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IG51bGw7XG4vKipcbiAqIElmIHRoZSBicm93c2VyIGhhcyBhIHdpbmRvdyBvYmplY3Qgd2hpY2ggaGFzIGFuIEF1ZGlvQ29udGV4dFxuICogQGhpZGRlblxuICovXG5leHBvcnQgY29uc3QgaGFzQXVkaW9Db250ZXh0ID0gdGhlV2luZG93ICYmXG4gICAgKHRoZVdpbmRvdy5oYXNPd25Qcm9wZXJ0eShcIkF1ZGlvQ29udGV4dFwiKSB8fCB0aGVXaW5kb3cuaGFzT3duUHJvcGVydHkoXCJ3ZWJraXRBdWRpb0NvbnRleHRcIikpO1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUoY29udGV4dCwgbmFtZSwgb3B0aW9ucykge1xuICAgIGFzc2VydChpc0RlZmluZWQoc3RkQXVkaW9Xb3JrbGV0Tm9kZSksIFwiVGhpcyBub2RlIG9ubHkgd29ya3MgaW4gYSBzZWN1cmUgY29udGV4dCAoaHR0cHMgb3IgbG9jYWxob3N0KVwiKTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIG5ldyBzdGRBdWRpb1dvcmtsZXROb2RlKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpO1xufVxuLyoqXG4gKiBUaGlzIHByb21pc2UgcmVzb2x2ZXMgdG8gYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyBpZiB0aGVcbiAqIGZ1bmN0aW9uYWxpdHkgaXMgc3VwcG9ydGVkIHdpdGhpbiB0aGUgY3VycmVudGx5IHVzZWQgYnJvd3NlLlxuICogVGFrZW4gZnJvbSBbc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRdKGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc2d1dHRhbmRpbi9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dCNpc3N1cHBvcnRlZClcbiAqL1xuZXhwb3J0IHsgaXNTdXBwb3J0ZWQgYXMgc3VwcG9ydGVkIH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdWRpb0NvbnRleHQuanMubWFwIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxyXG4gICAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcclxuICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XHJcbiAgICB2YXIgXywgZG9uZSA9IGZhbHNlO1xyXG4gICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgY29udGV4dCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnB1c2goXyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xyXG4gICAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMucHVzaChfKTtcclxuICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgIGRvbmUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcclxuICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcclxuICAgIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRJbihzdGF0ZSwgcmVjZWl2ZXIpIHtcclxuICAgIGlmIChyZWNlaXZlciA9PT0gbnVsbCB8fCAodHlwZW9mIHJlY2VpdmVyICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZWNlaXZlciAhPT0gXCJmdW5jdGlvblwiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB1c2UgJ2luJyBvcGVyYXRvciBvbiBub24tb2JqZWN0XCIpO1xyXG4gICAgcmV0dXJuIHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgPT09IHN0YXRlIDogc3RhdGUuaGFzKHJlY2VpdmVyKTtcclxufVxyXG4iLCIvKipcbiAqIEEgY2xhc3Mgd2hpY2ggcHJvdmlkZXMgYSByZWxpYWJsZSBjYWxsYmFjayB1c2luZyBlaXRoZXJcbiAqIGEgV2ViIFdvcmtlciwgb3IgaWYgdGhhdCBpc24ndCBzdXBwb3J0ZWQsIGZhbGxzIGJhY2sgdG8gc2V0VGltZW91dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tlciB7XG4gICAgY29uc3RydWN0b3IoY2FsbGJhY2ssIHR5cGUsIHVwZGF0ZUludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl91cGRhdGVJbnRlcnZhbCA9IHVwZGF0ZUludGVydmFsO1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGNsb2NrIHNvdXJjZSBmb3IgdGhlIGZpcnN0IHRpbWVcbiAgICAgICAgdGhpcy5fY3JlYXRlQ2xvY2soKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgYSB3ZWIgd29ya2VyXG4gICAgICovXG4gICAgX2NyZWF0ZVdvcmtlcigpIHtcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtcbiAgICAgICAgICAgIC8qIGphdmFzY3JpcHQgKi8gYFxuXHRcdFx0Ly8gdGhlIGluaXRpYWwgdGltZW91dCB0aW1lXG5cdFx0XHRsZXQgdGltZW91dFRpbWUgPSAgJHsodGhpcy5fdXBkYXRlSW50ZXJ2YWwgKiAxMDAwKS50b0ZpeGVkKDEpfTtcblx0XHRcdC8vIG9ubWVzc2FnZSBjYWxsYmFja1xuXHRcdFx0c2VsZi5vbm1lc3NhZ2UgPSBmdW5jdGlvbihtc2cpe1xuXHRcdFx0XHR0aW1lb3V0VGltZSA9IHBhcnNlSW50KG1zZy5kYXRhKTtcblx0XHRcdH07XG5cdFx0XHQvLyB0aGUgdGljayBmdW5jdGlvbiB3aGljaCBwb3N0cyBhIG1lc3NhZ2Vcblx0XHRcdC8vIGFuZCBzY2hlZHVsZXMgYSBuZXcgdGlja1xuXHRcdFx0ZnVuY3Rpb24gdGljaygpe1xuXHRcdFx0XHRzZXRUaW1lb3V0KHRpY2ssIHRpbWVvdXRUaW1lKTtcblx0XHRcdFx0c2VsZi5wb3N0TWVzc2FnZSgndGljaycpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gY2FsbCB0aWNrIGluaXRpYWxseVxuXHRcdFx0dGljaygpO1xuXHRcdFx0YFxuICAgICAgICBdLCB7IHR5cGU6IFwidGV4dC9qYXZhc2NyaXB0XCIgfSk7XG4gICAgICAgIGNvbnN0IGJsb2JVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBjb25zdCB3b3JrZXIgPSBuZXcgV29ya2VyKGJsb2JVcmwpO1xuICAgICAgICB3b3JrZXIub25tZXNzYWdlID0gdGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5fd29ya2VyID0gd29ya2VyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSB0aW1lb3V0IGxvb3BcbiAgICAgKi9cbiAgICBfY3JlYXRlVGltZW91dCgpIHtcbiAgICAgICAgdGhpcy5fdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlVGltZW91dCgpO1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2soKTtcbiAgICAgICAgfSwgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHRoZSBjbG9jayBzb3VyY2UuXG4gICAgICovXG4gICAgX2NyZWF0ZUNsb2NrKCkge1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3b3JrZXJcIikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVXb3JrZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gd29ya2VycyBub3Qgc3VwcG9ydGVkLCBmYWxsYmFjayB0byB0aW1lb3V0XG4gICAgICAgICAgICAgICAgdGhpcy5fdHlwZSA9IFwidGltZW91dFwiO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJ0aW1lb3V0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVRpbWVvdXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cCB0aGUgY3VycmVudCBjbG9jayBzb3VyY2VcbiAgICAgKi9cbiAgICBfZGlzcG9zZUNsb2NrKCkge1xuICAgICAgICBpZiAodGhpcy5fdGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5fdGltZW91dCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3dvcmtlcikge1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLm9ubWVzc2FnZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHJhdGUgaW4gc2Vjb25kcyB0aGUgdGlja2VyIHdpbGwgdXBkYXRlXG4gICAgICovXG4gICAgZ2V0IHVwZGF0ZUludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlSW50ZXJ2YWw7XG4gICAgfVxuICAgIHNldCB1cGRhdGVJbnRlcnZhbChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl91cGRhdGVJbnRlcnZhbCA9IE1hdGgubWF4KGludGVydmFsLCAxMjggLyA0NDEwMCk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcIndvcmtlclwiKSB7XG4gICAgICAgICAgICB0aGlzLl93b3JrZXIucG9zdE1lc3NhZ2UoTWF0aC5tYXgoaW50ZXJ2YWwgKiAxMDAwLCAxKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIHRpY2tlciwgZWl0aGVyIGEgd29ya2VyIG9yIGEgdGltZW91dFxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9kaXNwb3NlQ2xvY2soKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5fZGlzcG9zZUNsb2NrKCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja2VyLmpzLm1hcCIsImltcG9ydCB7IGlzQW55QXVkaW9Db250ZXh0LCBpc0FueUF1ZGlvTm9kZSwgaXNBbnlBdWRpb1BhcmFtLCBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQsIH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG4vKipcbiAqIFRlc3QgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlb2YgQXVkaW9QYXJhbVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb1BhcmFtKGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvUGFyYW0oYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgYW4gaW5zdGFuY2VvZiBBdWRpb05vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9Ob2RlKGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvTm9kZShhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgaW5zdGFuY2VvZiBhbiBPZmZsaW5lQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJnKSB7XG4gICAgcmV0dXJuIGlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dChhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgYW4gaW5zdGFuY2VvZiBBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9Db250ZXh0KGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvQ29udGV4dChhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgaW5zdGFuY2VvZiBhbiBBdWRpb0J1ZmZlclxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb0J1ZmZlcihhcmcpIHtcbiAgICByZXR1cm4gYXJnIGluc3RhbmNlb2YgQXVkaW9CdWZmZXI7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BZHZhbmNlZFR5cGVDaGVjay5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvQnVmZmVyLCBpc0F1ZGlvTm9kZSwgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4vQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCwgaXNPYmplY3QsIGlzVW5kZWYgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogU29tZSBvYmplY3RzIHNob3VsZCBub3QgYmUgbWVyZ2VkXG4gKi9cbmZ1bmN0aW9uIG5vQ29weShrZXksIGFyZykge1xuICAgIHJldHVybiBrZXkgPT09IFwidmFsdWVcIiB8fCBpc0F1ZGlvUGFyYW0oYXJnKSB8fCBpc0F1ZGlvTm9kZShhcmcpIHx8IGlzQXVkaW9CdWZmZXIoYXJnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkZWVwTWVyZ2UodGFyZ2V0LCAuLi5zb3VyY2VzKSB7XG4gICAgaWYgKCFzb3VyY2VzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgaWYgKGlzT2JqZWN0KHRhcmdldCkgJiYgaXNPYmplY3Qoc291cmNlKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChub0NvcHkoa2V5LCBzb3VyY2Vba2V5XSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNPYmplY3Qoc291cmNlW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXRba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHRhcmdldCwgeyBba2V5XToge30gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZXBNZXJnZSh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHNvdXJjZVtrZXldIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gZGVlcE1lcmdlKHRhcmdldCwgLi4uc291cmNlcyk7XG59XG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdHdvIGFycmF5cyBoYXZlIHRoZSBzYW1lIHZhbHVlIGZvciBlYWNoIG9mIHRoZSBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcEVxdWFscyhhcnJheUEsIGFycmF5Qikge1xuICAgIHJldHVybiBhcnJheUEubGVuZ3RoID09PSBhcnJheUIubGVuZ3RoICYmIGFycmF5QS5ldmVyeSgoZWxlbWVudCwgaW5kZXgpID0+IGFycmF5QltpbmRleF0gPT09IGVsZW1lbnQpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGFuIGFyZ3MgYXJyYXkgaW50byBhbiBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25zRnJvbUFyZ3VtZW50cyhkZWZhdWx0cywgYXJnc0FycmF5LCBrZXlzID0gW10sIG9iaktleSkge1xuICAgIGNvbnN0IG9wdHMgPSB7fTtcbiAgICBjb25zdCBhcmdzID0gQXJyYXkuZnJvbShhcmdzQXJyYXkpO1xuICAgIC8vIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhbiBvYmplY3QgYW5kIGhhcyBhbiBvYmplY3Qga2V5XG4gICAgaWYgKGlzT2JqZWN0KGFyZ3NbMF0pICYmIG9iaktleSAmJiAhUmVmbGVjdC5oYXMoYXJnc1swXSwgb2JqS2V5KSkge1xuICAgICAgICAvLyBpZiBpdCdzIG5vdCBwYXJ0IG9mIHRoZSBkZWZhdWx0c1xuICAgICAgICBjb25zdCBwYXJ0T2ZEZWZhdWx0cyA9IE9iamVjdC5rZXlzKGFyZ3NbMF0pLnNvbWUoa2V5ID0+IFJlZmxlY3QuaGFzKGRlZmF1bHRzLCBrZXkpKTtcbiAgICAgICAgaWYgKCFwYXJ0T2ZEZWZhdWx0cykge1xuICAgICAgICAgICAgLy8gbWVyZ2UgdGhhdCBrZXlcbiAgICAgICAgICAgIGRlZXBNZXJnZShvcHRzLCB7IFtvYmpLZXldOiBhcmdzWzBdIH0pO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBvYmoga2V5IGZyb20gdGhlIGtleXNcbiAgICAgICAgICAgIGtleXMuc3BsaWNlKGtleXMuaW5kZXhPZihvYmpLZXkpLCAxKTtcbiAgICAgICAgICAgIC8vIHNoaWZ0IHRoZSBmaXJzdCBhcmd1bWVudCBvZmZcbiAgICAgICAgICAgIGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNPYmplY3QoYXJnc1swXSkpIHtcbiAgICAgICAgZGVlcE1lcmdlKG9wdHMsIGFyZ3NbMF0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaXNEZWZpbmVkKGFyZ3NbaV0pKSB7XG4gICAgICAgICAgICAgICAgb3B0c1trZXlzW2ldXSA9IGFyZ3NbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlZXBNZXJnZShkZWZhdWx0cywgb3B0cyk7XG59XG4vKipcbiAqIFJldHVybiB0aGlzIGluc3RhbmNlcyBkZWZhdWx0IHZhbHVlcyBieSBjYWxsaW5nIENvbnN0cnVjdG9yLmdldERlZmF1bHRzKClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRzRnJvbUluc3RhbmNlKGluc3RhbmNlKSB7XG4gICAgcmV0dXJuIGluc3RhbmNlLmNvbnN0cnVjdG9yLmdldERlZmF1bHRzKCk7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGZhbGxiYWNrIGlmIHRoZSBnaXZlbiBvYmplY3QgaXMgdW5kZWZpbmVkLlxuICogVGFrZSBhbiBhcnJheSBvZiBhcmd1bWVudHMgYW5kIHJldHVybiBhIGZvcm1hdHRlZCBvcHRpb25zIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRBcmcoZ2l2ZW4sIGZhbGxiYWNrKSB7XG4gICAgaWYgKGlzVW5kZWYoZ2l2ZW4pKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBnaXZlbjtcbiAgICB9XG59XG4vKipcbiAqIFJlbW92ZSBhbGwgb2YgdGhlIHByb3BlcnRpZXMgYmVsb25naW5nIHRvIG9taXQgZnJvbSBvYmouXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbWl0RnJvbU9iamVjdChvYmosIG9taXQpIHtcbiAgICBvbWl0LmZvckVhY2gocHJvcCA9PiB7XG4gICAgICAgIGlmIChSZWZsZWN0LmhhcyhvYmosIHByb3ApKSB7XG4gICAgICAgICAgICBkZWxldGUgb2JqW3Byb3BdO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG9iajtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlZmF1bHRzLmpzLm1hcCIsIi8qKlxuICogVG9uZS5qc1xuICogQGF1dGhvciBZb3RhbSBNYW5uXG4gKiBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiBAY29weXJpZ2h0IDIwMTQtMjAxOSBZb3RhbSBNYW5uXG4gKi9cbmltcG9ydCB7IHZlcnNpb24gfSBmcm9tIFwiLi4vdmVyc2lvblwiO1xuaW1wb3J0IHsgdGhlV2luZG93IH0gZnJvbSBcIi4vY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCIuL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQGNsYXNzICBUb25lIGlzIHRoZSBiYXNlIGNsYXNzIG9mIGFsbCBvdGhlciBjbGFzc2VzLlxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgY2xhc3MgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdERFQlVHR0lOR1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldCB0aGlzIGRlYnVnIGZsYWcgdG8gbG9nIGFsbCBldmVudHMgdGhhdCBoYXBwZW4gaW4gdGhpcyBjbGFzcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIFx0RElTUE9TSU5HXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBpbnN0YW5jZSB3YXMgZGlzcG9zZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3dhc0Rpc3Bvc2VkID0gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYWxsIG9mIHRoZSBkZWZhdWx0IG9wdGlvbnMgYmVsb25naW5nIHRvIHRoZSBjbGFzcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJpbnRzIHRoZSBvdXRwdXRzIHRvIHRoZSBjb25zb2xlIGxvZyBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLlxuICAgICAqIFByaW50cyB0aGUgY29udGVudHMgb25seSBpZiBlaXRoZXIgdGhlIG9iamVjdCBoYXMgYSBwcm9wZXJ0eVxuICAgICAqIGNhbGxlZCBgZGVidWdgIHNldCB0byB0cnVlLCBvciBhIHZhcmlhYmxlIGNhbGxlZCBUT05FX0RFQlVHX0NMQVNTXG4gICAgICogaXMgc2V0IHRvIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiAvLyBwcmludHMgYWxsIGxvZ3Mgb3JpZ2luYXRpbmcgZnJvbSB0aGlzIG9zY2lsbGF0b3JcbiAgICAgKiBvc2MuZGVidWcgPSB0cnVlO1xuICAgICAqIC8vIGNhbGxzIHRvIHN0YXJ0L3N0b3Agd2lsbCBwcmludCBpbiB0aGUgY29uc29sZVxuICAgICAqIG9zYy5zdGFydCgpO1xuICAgICAqL1xuICAgIGxvZyguLi5hcmdzKSB7XG4gICAgICAgIC8vIGlmIHRoZSBvYmplY3QgaXMgZWl0aGVyIHNldCB0byBkZWJ1ZyA9IHRydWVcbiAgICAgICAgLy8gb3IgaWYgdGhlcmUgaXMgYSBzdHJpbmcgb24gdGhlIFRvbmUuZ2xvYmFsLndpdGggdGhlIGNsYXNzIG5hbWVcbiAgICAgICAgaWYgKHRoaXMuZGVidWcgfHwgKHRoZVdpbmRvdyAmJiB0aGlzLnRvU3RyaW5nKCkgPT09IHRoZVdpbmRvdy5UT05FX0RFQlVHX0NMQVNTKSkge1xuICAgICAgICAgICAgbG9nKHRoaXMsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGRpc2Nvbm5lY3QgYW5kIGRpc3Bvc2UuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5fd2FzRGlzcG9zZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIGlmIHRoZSBpbnN0YW5jZSB3YXMgZGlzcG9zZWQuICdEaXNwb3NpbmcnIGFuXG4gICAgICogaW5zdGFuY2UgbWVhbnMgdGhhdCBhbGwgb2YgdGhlIFdlYiBBdWRpbyBub2RlcyB0aGF0IHdlcmVcbiAgICAgKiBjcmVhdGVkIGZvciB0aGUgaW5zdGFuY2UgYXJlIGRpc2Nvbm5lY3RlZCBhbmQgZnJlZWQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgZGlzcG9zZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93YXNEaXNwb3NlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgY2xhc3MgdG8gYSBzdHJpbmdcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvc2MudG9TdHJpbmcoKSk7XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XG4gICAgfVxufVxuLyoqXG4gKiBUaGUgdmVyc2lvbiBudW1iZXIgc2VtdmVyXG4gKi9cblRvbmUudmVyc2lvbiA9IHZlcnNpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lLmpzLm1hcCIsIi8qKlxuICogVGhlIHRocmVzaG9sZCBmb3IgY29ycmVjdG5lc3MgZm9yIG9wZXJhdG9ycy4gTGVzcyB0aGFuIG9uZSBzYW1wbGUgZXZlblxuICogYXQgdmVyeSBoaWdoIHNhbXBsaW5nIHJhdGVzIChlLmcuIGAxZS02IDwgMSAvIDE5MjAwMGApLlxuICovXG5jb25zdCBFUFNJTE9OID0gMWUtNjtcbi8qKlxuICogVGVzdCBpZiBBIGlzIGdyZWF0ZXIgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHVChhLCBiKSB7XG4gICAgcmV0dXJuIGEgPiBiICsgRVBTSUxPTjtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHVEUoYSwgYikge1xuICAgIHJldHVybiBHVChhLCBiKSB8fCBFUShhLCBiKTtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGxlc3MgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMVChhLCBiKSB7XG4gICAgcmV0dXJuIGEgKyBFUFNJTE9OIDwgYjtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGxlc3MgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFUShhLCBiKSB7XG4gICAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8IEVQU0lMT047XG59XG4vKipcbiAqIENsYW1wIHRoZSB2YWx1ZSB3aXRoaW4gdGhlIGdpdmVuIHJhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGFtcCh2YWx1ZSwgbWluLCBtYXgpIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoTWF0aC5taW4odmFsdWUsIG1heCksIG1pbik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NYXRoLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4vRGVidWdcIjtcbmltcG9ydCB7IEVRLCBHVCwgR1RFLCBMVCB9IGZyb20gXCIuL01hdGhcIjtcbi8qKlxuICogQSBUaW1lbGluZSBjbGFzcyBmb3Igc2NoZWR1bGluZyBhbmQgbWFpbnRhaW5pbmcgc3RhdGVcbiAqIGFsb25nIGEgdGltZWxpbmUuIEFsbCBldmVudHMgbXVzdCBoYXZlIGEgXCJ0aW1lXCIgcHJvcGVydHkuXG4gKiBJbnRlcm5hbGx5LCBldmVudHMgYXJlIHN0b3JlZCBpbiB0aW1lIG9yZGVyIGZvciBmYXN0XG4gKiByZXRyaWV2YWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lbGluZSBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpbWVsaW5lXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXJyYXkgb2Ygc2NoZWR1bGVkIHRpbWVsaW5lIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpbWVsaW5lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWVtb3J5XCJdKTtcbiAgICAgICAgdGhpcy5tZW1vcnkgPSBvcHRpb25zLm1lbW9yeTtcbiAgICAgICAgdGhpcy5pbmNyZWFzaW5nID0gb3B0aW9ucy5pbmNyZWFzaW5nO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtZW1vcnk6IEluZmluaXR5LFxuICAgICAgICAgICAgaW5jcmVhc2luZzogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc2VydCBhbiBldmVudCBvYmplY3Qgb250byB0aGUgdGltZWxpbmUuIEV2ZW50cyBtdXN0IGhhdmUgYSBcInRpbWVcIiBhdHRyaWJ1dGUuXG4gICAgICogQHBhcmFtIGV2ZW50ICBUaGUgZXZlbnQgb2JqZWN0IHRvIGluc2VydCBpbnRvIHRoZSB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBhZGQoZXZlbnQpIHtcbiAgICAgICAgLy8gdGhlIGV2ZW50IG5lZWRzIHRvIGhhdmUgYSB0aW1lIGF0dHJpYnV0ZVxuICAgICAgICBhc3NlcnQoUmVmbGVjdC5oYXMoZXZlbnQsIFwidGltZVwiKSwgXCJUaW1lbGluZTogZXZlbnRzIG11c3QgaGF2ZSBhIHRpbWUgYXR0cmlidXRlXCIpO1xuICAgICAgICBldmVudC50aW1lID0gZXZlbnQudGltZS52YWx1ZU9mKCk7XG4gICAgICAgIGlmICh0aGlzLmluY3JlYXNpbmcgJiYgdGhpcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RWYWx1ZSA9IHRoaXMuX3RpbWVsaW5lW3RoaXMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBhc3NlcnQoR1RFKGV2ZW50LnRpbWUsIGxhc3RWYWx1ZS50aW1lKSwgXCJUaGUgdGltZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbGFzdCBzY2hlZHVsZWQgdGltZVwiKTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnB1c2goZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2goZXZlbnQudGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoaW5kZXggKyAxLCAwLCBldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBtb3JlIHRoYW4gdGhlIG1lbW9yeSwgcmVtb3ZlIHRoZSBwcmV2aW91cyBvbmVzXG4gICAgICAgIGlmICh0aGlzLmxlbmd0aCA+IHRoaXMubWVtb3J5KSB7XG4gICAgICAgICAgICBjb25zdCBkaWZmID0gdGhpcy5sZW5ndGggLSB0aGlzLm1lbW9yeTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnNwbGljZSgwLCBkaWZmKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFuIGV2ZW50IGZyb20gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIGV2ZW50ICBUaGUgZXZlbnQgb2JqZWN0IHRvIHJlbW92ZSBmcm9tIHRoZSBsaXN0LlxuICAgICAqIEByZXR1cm5zIHtUaW1lbGluZX0gdGhpc1xuICAgICAqL1xuICAgIHJlbW92ZShldmVudCkge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3RpbWVsaW5lLmluZGV4T2YoZXZlbnQpO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG5lYXJlc3QgZXZlbnQgd2hvc2UgdGltZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXQodGltZSwgcGFyYW0gPSBcInRpbWVcIikge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lLCBwYXJhbSk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGZpcnN0IGV2ZW50IGluIHRoZSB0aW1lbGluZSB3aXRob3V0IHJlbW92aW5nIGl0XG4gICAgICogQHJldHVybnMge09iamVjdH0gVGhlIGZpcnN0IGV2ZW50IG9iamVjdFxuICAgICAqL1xuICAgIHBlZWsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVswXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBmaXJzdCBldmVudCBpbiB0aGUgdGltZWxpbmUgYW5kIHJlbW92ZSBpdFxuICAgICAqL1xuICAgIHNoaWZ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmUuc2hpZnQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBldmVudCB3aGljaCBpcyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRBZnRlcih0aW1lLCBwYXJhbSA9IFwidGltZVwiKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUsIHBhcmFtKTtcbiAgICAgICAgaWYgKGluZGV4ICsgMSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4ICsgMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGV2ZW50IGJlZm9yZSB0aGUgZXZlbnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRCZWZvcmUodGltZSkge1xuICAgICAgICBjb25zdCBsZW4gPSB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG4gICAgICAgIC8vIGlmIGl0J3MgYWZ0ZXIgdGhlIGxhc3QgaXRlbSwgcmV0dXJuIHRoZSBsYXN0IGl0ZW1cbiAgICAgICAgaWYgKGxlbiA+IDAgJiYgdGhpcy5fdGltZWxpbmVbbGVuIC0gMV0udGltZSA8IHRpbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKGluZGV4IC0gMSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgYXQgYW5kIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICBhZnRlciAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSB0aGlzLl9zZWFyY2goYWZ0ZXIpO1xuICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICBpZiAoRVEodGhpcy5fdGltZWxpbmVbaW5kZXhdLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGZpcnN0IGl0ZW0gd2l0aCB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2ldLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZSgwLCBpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyB0aGUgZmlyc3QgaXRlbSdzIHRpbWVcbiAgICAgICAgICAgIGlmIChHVEUodGhpcy5fdGltZWxpbmVbMF0udGltZSwgYWZ0ZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGV2ZW50cyBiZWZvcmUgb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBjYW5jZWwgYmVmb3JlLlxuICAgICAqL1xuICAgIGNhbmNlbEJlZm9yZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZShpbmRleCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBldmVudCBpZiB0aGVyZSBpcyBvbmUuIG51bGwgb3RoZXJ3aXNlXG4gICAgICogQHBhcmFtICBldmVudCBUaGUgZXZlbnQgdG8gZmluZCB0aGUgcHJldmlvdXMgb25lIG9mXG4gICAgICogQHJldHVybiBUaGUgZXZlbnQgcmlnaHQgYmVmb3JlIHRoZSBnaXZlbiBldmVudFxuICAgICAqL1xuICAgIHByZXZpb3VzRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl90aW1lbGluZS5pbmRleE9mKGV2ZW50KTtcbiAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4IC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb2VzIGEgYmluYXJ5IHNlYXJjaCBvbiB0aGUgdGltZWxpbmUgYXJyYXkgYW5kIHJldHVybnMgdGhlXG4gICAgICogbmVhcmVzdCBldmVudCBpbmRleCB3aG9zZSB0aW1lIGlzIGFmdGVyIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIElmIGEgdGltZSBpcyBzZWFyY2hlZCBiZWZvcmUgdGhlIGZpcnN0IGluZGV4IGluIHRoZSB0aW1lbGluZSwgLTEgaXMgcmV0dXJuZWQuXG4gICAgICogSWYgdGhlIHRpbWUgaXMgYWZ0ZXIgdGhlIGVuZCwgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGl0ZW0gaXMgcmV0dXJuZWQuXG4gICAgICovXG4gICAgX3NlYXJjaCh0aW1lLCBwYXJhbSA9IFwidGltZVwiKSB7XG4gICAgICAgIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYmVnaW5uaW5nID0gMDtcbiAgICAgICAgY29uc3QgbGVuID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuICAgICAgICBsZXQgZW5kID0gbGVuO1xuICAgICAgICBpZiAobGVuID4gMCAmJiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXVtwYXJhbV0gPD0gdGltZSkge1xuICAgICAgICAgICAgcmV0dXJuIGxlbiAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGJlZ2lubmluZyA8IGVuZCkge1xuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBtaWRwb2ludCBmb3Igcm91Z2hseSBlcXVhbCBwYXJ0aXRpb25cbiAgICAgICAgICAgIGxldCBtaWRQb2ludCA9IE1hdGguZmxvb3IoYmVnaW5uaW5nICsgKGVuZCAtIGJlZ2lubmluZykgLyAyKTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbbWlkUG9pbnRdO1xuICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fdGltZWxpbmVbbWlkUG9pbnQgKyAxXTtcbiAgICAgICAgICAgIGlmIChFUShldmVudFtwYXJhbV0sIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gY2hvb3NlIHRoZSBsYXN0IG9uZSB0aGF0IGhhcyB0aGUgc2FtZSB0aW1lXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IG1pZFBvaW50OyBpIDwgdGhpcy5fdGltZWxpbmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVzdEV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChFUSh0ZXN0RXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWlkUG9pbnQgPSBpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pZFBvaW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoTFQoZXZlbnRbcGFyYW1dLCB0aW1lKSAmJiBHVChuZXh0RXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKEdUKGV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBzZWFyY2ggbG93ZXJcbiAgICAgICAgICAgICAgICBlbmQgPSBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIHNlYXJjaCB1cHBlclxuICAgICAgICAgICAgICAgIGJlZ2lubmluZyA9IG1pZFBvaW50ICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGl0ZXJhdG9yLiBBcHBsaWVzIGV4dHJhIHNhZmV0eSBjaGVja3MgZm9yXG4gICAgICogcmVtb3ZpbmcgaXRlbXMgZnJvbSB0aGUgYXJyYXkuXG4gICAgICovXG4gICAgX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgPSAwLCB1cHBlckJvdW5kID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5zbGljZShsb3dlckJvdW5kLCB1cHBlckJvdW5kICsgMSkuZm9yRWFjaChjYWxsYmFjayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IG9yIGJlZm9yZSB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQmVmb3JlKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgY29uc3QgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKHVwcGVyQm91bmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCAwLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hBZnRlcih0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBiZXR3ZWVuIHRoZSBzdGFydFRpbWUgYW5kIGVuZFRpbWUuXG4gICAgICogVGhlIHRpbWVyYW5nZSBpcyBpbmNsdXNpdmUgb2YgdGhlIHN0YXJ0VGltZSwgYnV0IGV4Y2x1c2l2ZSBvZiB0aGUgZW5kVGltZS5cbiAgICAgKiByYW5nZSA9IFtzdGFydFRpbWUsIGVuZFRpbWUpLlxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGVuZFRpbWUgVGhlIGVuZCBvZiB0aGUgdGVzdCBpbnRlcnZhbC5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEJldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBjYWxsYmFjaykge1xuICAgICAgICBsZXQgbG93ZXJCb3VuZCA9IHRoaXMuX3NlYXJjaChzdGFydFRpbWUpO1xuICAgICAgICBsZXQgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaChlbmRUaW1lKTtcbiAgICAgICAgaWYgKGxvd2VyQm91bmQgIT09IC0xICYmIHVwcGVyQm91bmQgIT09IC0xKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fdGltZWxpbmVbbG93ZXJCb3VuZF0udGltZSAhPT0gc3RhcnRUaW1lKSB7XG4gICAgICAgICAgICAgICAgbG93ZXJCb3VuZCArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXhjbHVzaXZlIG9mIHRoZSBlbmQgdGltZVxuICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lW3VwcGVyQm91bmRdLnRpbWUgPT09IGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICB1cHBlckJvdW5kIC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChsb3dlckJvdW5kID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgMCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCBvciBhZnRlciB0aGUgZ2l2ZW4gdGltZS4gU2ltaWxhciB0b1xuICAgICAqIGZvckVhY2hBZnRlciwgYnV0IGluY2x1ZGVzIHRoZSBpdGVtKHMpIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hGcm9tKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIC8vIHdvcmsgYmFja3dhcmRzIHVudGlsIHRoZSBldmVudCB0aW1lIGlzIGxlc3MgdGhhbiB0aW1lXG4gICAgICAgIHdoaWxlIChsb3dlckJvdW5kID49IDAgJiYgdGhpcy5fdGltZWxpbmVbbG93ZXJCb3VuZF0udGltZSA+PSB0aW1lKSB7XG4gICAgICAgICAgICBsb3dlckJvdW5kLS07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEF0VGltZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmICh1cHBlckJvdW5kICE9PSAtMSAmJiBFUSh0aGlzLl90aW1lbGluZVt1cHBlckJvdW5kXS50aW1lLCB0aW1lKSkge1xuICAgICAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB1cHBlckJvdW5kO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHVwcGVyQm91bmQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2ldLnRpbWUsIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvd2VyQm91bmQgPSBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICAgICAgfSwgbG93ZXJCb3VuZCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZWxpbmUuanMubWFwIiwiLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBJTklUSUFMSVpJTkcgTkVXIENPTlRFWFRcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBBcnJheSBvZiBjYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkXG4gKi9cbmNvbnN0IG5vdGlmeU5ld0NvbnRleHQgPSBbXTtcbi8qKlxuICogVXNlZCBpbnRlcm5hbGx5IHRvIHNldHVwIGEgbmV3IENvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQ29udGV4dEluaXQoY2IpIHtcbiAgICBub3RpZnlOZXdDb250ZXh0LnB1c2goY2IpO1xufVxuLyoqXG4gKiBJbnZva2UgYW55IGNsYXNzZXMgd2hpY2ggbmVlZCB0byBhbHNvIGJlIGluaXRpYWxpemVkIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdGlhbGl6ZUNvbnRleHQoY3R4KSB7XG4gICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICBub3RpZnlOZXdDb250ZXh0LmZvckVhY2goY2IgPT4gY2IoY3R4KSk7XG59XG4vKipcbiAqIEFycmF5IG9mIGNhbGxiYWNrcyB0byBpbnZva2Ugd2hlbiBhIG5ldyBjb250ZXh0IGlzIGNyZWF0ZWRcbiAqL1xuY29uc3Qgbm90aWZ5Q2xvc2VDb250ZXh0ID0gW107XG4vKipcbiAqIFVzZWQgaW50ZXJuYWxseSB0byB0ZWFyIGRvd24gYSBDb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkNvbnRleHRDbG9zZShjYikge1xuICAgIG5vdGlmeUNsb3NlQ29udGV4dC5wdXNoKGNiKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZUNvbnRleHQoY3R4KSB7XG4gICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICBub3RpZnlDbG9zZUNvbnRleHQuZm9yRWFjaChjYiA9PiBjYihjdHgpKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnRleHRJbml0aWFsaXphdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzVW5kZWYgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogRW1pdHRlciBnaXZlcyBjbGFzc2VzIHdoaWNoIGV4dGVuZCBpdFxuICogdGhlIGFiaWxpdHkgdG8gbGlzdGVuIGZvciBhbmQgZW1pdCBldmVudHMuXG4gKiBJbnNwaXJhdGlvbiBhbmQgcmVmZXJlbmNlIGZyb20gSmVyb21lIEV0aWVubmUncyBbTWljcm9FdmVudF0oaHR0cHM6Ly9naXRodWIuY29tL2plcm9tZWV0aWVubmUvbWljcm9ldmVudC5qcykuXG4gKiBNSVQgKGMpIDIwMTEgSmVyb21lIEV0aWVubmUuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgRW1pdHRlciBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVtaXR0ZXJcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIGNhbGxiYWNrIHRvIGEgc3BlY2lmaWMgZXZlbnQuXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiBmb3IuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gICAgICovXG4gICAgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIHNwbGl0IHRoZSBldmVudFxuICAgICAgICBjb25zdCBldmVudHMgPSBldmVudC5zcGxpdCgvXFxXKy8pO1xuICAgICAgICBldmVudHMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fZXZlbnRzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF0aGlzLl9ldmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudE5hbWVdID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9ldmVudHNbZXZlbnROYW1lXS5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCaW5kIGEgY2FsbGJhY2sgd2hpY2ggaXMgb25seSBpbnZva2VkIG9uY2VcbiAgICAgKiBAcGFyYW0gIGV2ZW50ICAgICBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIGZvci5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWRcbiAgICAgKi9cbiAgICBvbmNlKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICBjb25zdCBib3VuZENhbGxiYWNrID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgIGNhbGxiYWNrKC4uLmFyZ3MpO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBldmVudFxuICAgICAgICAgICAgdGhpcy5vZmYoZXZlbnQsIGJvdW5kQ2FsbGJhY2spO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9uKGV2ZW50LCBib3VuZENhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGUgZXZlbnQgbGlzdGVuZXIuXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIGV2ZW50IHRvIHN0b3AgbGlzdGVuaW5nIHRvLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB3aGljaCB3YXMgYm91bmQgdG8gdGhlIGV2ZW50IHdpdGggRW1pdHRlci5vbi5cbiAgICAgKiAgICAgICAgICAgICAgICAgICBJZiBubyBjYWxsYmFjayBpcyBnaXZlbiwgYWxsIGNhbGxiYWNrcyBldmVudHMgYXJlIHJlbW92ZWQuXG4gICAgICovXG4gICAgb2ZmKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICBjb25zdCBldmVudHMgPSBldmVudC5zcGxpdCgvXFxXKy8pO1xuICAgICAgICBldmVudHMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fZXZlbnRzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNVbmRlZihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50XSA9IFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnRMaXN0ID0gdGhpcy5fZXZlbnRzW2V2ZW50XTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGV2ZW50TGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50TGlzdFtpXSA9PT0gY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSBhbGwgb2YgdGhlIGNhbGxiYWNrcyBib3VuZCB0byB0aGUgZXZlbnRcbiAgICAgKiB3aXRoIGFueSBhcmd1bWVudHMgcGFzc2VkIGluLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cbiAgICAgKiBAcGFyYW0gYXJncyBUaGUgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGZ1bmN0aW9ucyBsaXN0ZW5pbmcuXG4gICAgICovXG4gICAgZW1pdChldmVudCwgLi4uYXJncykge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50TGlzdCA9IHRoaXMuX2V2ZW50c1tldmVudF0uc2xpY2UoMCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGV2ZW50TGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBldmVudExpc3RbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgRW1pdHRlciBmdW5jdGlvbnMgKG9uL29mZi9lbWl0KSB0byB0aGUgb2JqZWN0XG4gICAgICovXG4gICAgc3RhdGljIG1peGluKGNvbnN0cikge1xuICAgICAgICAvLyBpbnN0YW5jZS5fZXZlbnRzID0ge307XG4gICAgICAgIFtcIm9uXCIsIFwib25jZVwiLCBcIm9mZlwiLCBcImVtaXRcIl0uZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihFbWl0dGVyLnByb3RvdHlwZSwgbmFtZSk7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RyLnByb3RvdHlwZSwgbmFtZSwgcHJvcGVydHkpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RW1pdHRlci5qcy5tYXAiLCJpbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuZXhwb3J0IGNsYXNzIEJhc2VDb250ZXh0IGV4dGVuZHMgRW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgfVxuICAgIC8qXG4gICAgICogVGhpcyBpcyBhIHBsYWNlaG9sZGVyIHNvIHRoYXQgSlNPTi5zdHJpbmdpZnkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3JcbiAgICAgKiBUaGlzIG1hdGNoZXMgd2hhdCBKU09OLnN0cmluZ2lmeShhdWRpb0NvbnRleHQpIHJldHVybnMgb24gYSBuYXRpdmVcbiAgICAgKiBhdWRpb0NvbnRleHQgaW5zdGFuY2UuXG4gICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QmFzZUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUaWNrZXIgfSBmcm9tIFwiLi4vY2xvY2svVGlja2VyXCI7XG5pbXBvcnQgeyBpc0F1ZGlvQ29udGV4dCB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0NvbnRleHQsIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUsIH0gZnJvbSBcIi4vQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBjbG9zZUNvbnRleHQsIGluaXRpYWxpemVDb250ZXh0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG5pbXBvcnQgeyBCYXNlQ29udGV4dCB9IGZyb20gXCIuL0Jhc2VDb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dC5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250ZXh0IGV4dGVuZHMgQmFzZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbnRleHRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBvZiB0aGUgY29uc3RhbnRzIEF1ZGlvQnVmZmVyU291cmNlTm9kZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbnN0YW50cyA9IG5ldyBNYXAoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgc2V0VGltZW91dCBldmVudHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lb3V0cyA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVvdXQgaWQgY291bnRlclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dElkcyA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcml2YXRlIGluZGljYXRvciBpZiB0aGUgY29udGV4dCBoYXMgYmVlbiBpbml0aWFsaXplZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgY29udGV4dCBpcyBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IG9yIGFuIEF1ZGlvQ29udGV4dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pc09mZmxpbmUgPSBmYWxzZTtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBBVURJTyBXT1JLTEVUXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1hcHMgYSBtb2R1bGUgbmFtZSB0byBwcm9taXNlIG9mIHRoZSBhZGRNb2R1bGUgbWV0aG9kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl93b3JrbGV0TW9kdWxlcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbnRleHQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXG4gICAgICAgICAgICBcImNvbnRleHRcIixcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChvcHRpb25zLmNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbnRleHQgPSBvcHRpb25zLmNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gY3JlYXRlQXVkaW9Db250ZXh0KHtcbiAgICAgICAgICAgICAgICBsYXRlbmN5SGludDogb3B0aW9ucy5sYXRlbmN5SGludCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RpY2tlciA9IG5ldyBUaWNrZXIodGhpcy5lbWl0LmJpbmQodGhpcywgXCJ0aWNrXCIpLCBvcHRpb25zLmNsb2NrU291cmNlLCBvcHRpb25zLnVwZGF0ZUludGVydmFsKTtcbiAgICAgICAgdGhpcy5vbihcInRpY2tcIiwgdGhpcy5fdGltZW91dExvb3AuYmluZCh0aGlzKSk7XG4gICAgICAgIC8vIGZ3ZCBldmVudHMgZnJvbSB0aGUgY29udGV4dFxuICAgICAgICB0aGlzLl9jb250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGF0ZWNoYW5nZVwiLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fc2V0TGF0ZW5jeUhpbnQob3B0aW9ucy5sYXRlbmN5SGludCk7XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gb3B0aW9ucy5sb29rQWhlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNsb2NrU291cmNlOiBcIndvcmtlclwiLFxuICAgICAgICAgICAgbGF0ZW5jeUhpbnQ6IFwiaW50ZXJhY3RpdmVcIixcbiAgICAgICAgICAgIGxvb2tBaGVhZDogMC4xLFxuICAgICAgICAgICAgdXBkYXRlSW50ZXJ2YWw6IDAuMDUsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmlzaCBzZXR0aW5nIHVwIHRoZSBjb250ZXh0LiAqKllvdSB1c3VhbGx5IGRvIG5vdCBuZWVkIHRvIGRvIHRoaXMgbWFudWFsbHkuKipcbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAvLyBhZGQgYW55IGFkZGl0aW9uYWwgbW9kdWxlc1xuICAgICAgICAgICAgaW5pdGlhbGl6ZUNvbnRleHQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQkFTRSBBVURJTyBDT05URVhUIE1FVEhPRFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgIH1cbiAgICBjcmVhdGVPc2NpbGxhdG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlclNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJpcXVhZEZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxNZXJnZXIobnVtYmVyT2ZJbnB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ2hhbm5lbE1lcmdlcihudW1iZXJPZklucHV0cyk7XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxTcGxpdHRlcihudW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG51bWJlck9mT3V0cHV0cyk7XG4gICAgfVxuICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuICAgIH1cbiAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgIH1cbiAgICBjcmVhdGVEZWxheShtYXhEZWxheVRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlRGVsYXkobWF4RGVsYXlUaW1lKTtcbiAgICB9XG4gICAgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKTtcbiAgICB9XG4gICAgY3JlYXRlR2FpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIH1cbiAgICBjcmVhdGVJSVJGaWx0ZXIoZmVlZEZvcndhcmQsIGZlZWRiYWNrKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlSUlSRmlsdGVyKGZlZWRGb3J3YXJkLCBmZWVkYmFjayk7XG4gICAgfVxuICAgIGNyZWF0ZVBhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnLCBjb25zdHJhaW50cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMpO1xuICAgIH1cbiAgICBjcmVhdGVTdGVyZW9QYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgIH1cbiAgICBjcmVhdGVXYXZlU2hhcGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnQoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCksIFwiTm90IGF2YWlsYWJsZSBpZiBPZmZsaW5lQXVkaW9Db250ZXh0XCIpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKGVsZW1lbnQpIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShlbGVtZW50KTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKTtcbiAgICB9XG4gICAgZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IHNhbXBsZVJhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0ZW5lclxuICAgICAqL1xuICAgIGdldCBsaXN0ZW5lcigpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9saXN0ZW5lcjtcbiAgICB9XG4gICAgc2V0IGxpc3RlbmVyKGwpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgbGlzdGVuZXIgY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVyID0gbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlcmUgaXMgb25seSBvbmUgVHJhbnNwb3J0IHBlciBDb250ZXh0LiBJdCBpcyBjcmVhdGVkIG9uIGluaXRpYWxpemF0aW9uLlxuICAgICAqL1xuICAgIGdldCB0cmFuc3BvcnQoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0O1xuICAgIH1cbiAgICBzZXQgdHJhbnNwb3J0KHQpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgdHJhbnNwb3J0IGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl90cmFuc3BvcnQgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIHRoZSBEcmF3IG9iamVjdCBmb3IgdGhlIGNvbnRleHQgd2hpY2ggaXMgdXNlZnVsIGZvciBzeW5jaHJvbml6aW5nIHRoZSBkcmF3IGZyYW1lIHdpdGggdGhlIFRvbmUuanMgY2xvY2suXG4gICAgICovXG4gICAgZ2V0IGRyYXcoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZHJhdztcbiAgICB9XG4gICAgc2V0IGRyYXcoZCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIkRyYXcgY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2RyYXcgPSBkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgQ29udGV4dCdzIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICovXG4gICAgZ2V0IGRlc3RpbmF0aW9uKCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3RpbmF0aW9uO1xuICAgIH1cbiAgICBzZXQgZGVzdGluYXRpb24oZCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIlRoZSBkZXN0aW5hdGlvbiBjYW5ub3QgYmUgc2V0IGFmdGVyIGluaXRpYWxpemF0aW9uLlwiKTtcbiAgICAgICAgdGhpcy5fZGVzdGluYXRpb24gPSBkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gYXVkaW8gd29ya2xldCBub2RlIGZyb20gYSBuYW1lIGFuZCBvcHRpb25zLiBUaGUgbW9kdWxlXG4gICAgICogbXVzdCBmaXJzdCBiZSBsb2FkZWQgdXNpbmcgW1thZGRBdWRpb1dvcmtsZXRNb2R1bGVdXS5cbiAgICAgKi9cbiAgICBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKG5hbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUodGhpcy5yYXdDb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIEF1ZGlvV29ya2xldFByb2Nlc3NvciBtb2R1bGVcbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIG1vZHVsZVxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBtb2R1bGVcbiAgICAgKi9cbiAgICBhZGRBdWRpb1dvcmtsZXRNb2R1bGUodXJsLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKHRoaXMucmF3Q29udGV4dC5hdWRpb1dvcmtsZXQpLCBcIkF1ZGlvV29ya2xldE5vZGUgaXMgb25seSBhdmFpbGFibGUgaW4gYSBzZWN1cmUgY29udGV4dCAoaHR0cHMgb3IgbG9jYWxob3N0KVwiKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fd29ya2xldE1vZHVsZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd29ya2xldE1vZHVsZXMuc2V0KG5hbWUsIHRoaXMucmF3Q29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeWllbGQgdGhpcy5fd29ya2xldE1vZHVsZXMuZ2V0KG5hbWUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIHdvcmtsZXRzIGhhdmUgYmVlbiBsb2FkZWQgb24gdGhpcyBjb250ZXh0XG4gICAgICovXG4gICAgd29ya2xldHNBcmVSZWFkeSgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0TW9kdWxlcy5mb3JFYWNoKChwcm9taXNlKSA9PiBwcm9taXNlcy5wdXNoKHByb21pc2UpKTtcbiAgICAgICAgICAgIHlpZWxkIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gVElDS0VSXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBIb3cgb2Z0ZW4gdGhlIGludGVydmFsIGNhbGxiYWNrIGlzIGludm9rZWQuXG4gICAgICogVGhpcyBudW1iZXIgY29ycmVzcG9uZHMgdG8gaG93IHJlc3BvbnNpdmUgdGhlIHNjaGVkdWxpbmdcbiAgICAgKiBjYW4gYmUuIGNvbnRleHQudXBkYXRlSW50ZXJ2YWwgKyBjb250ZXh0Lmxvb2tBaGVhZCBnaXZlcyB5b3UgdGhlXG4gICAgICogdG90YWwgbGF0ZW5jeSBiZXR3ZWVuIHNjaGVkdWxpbmcgYW4gZXZlbnQgYW5kIGhlYXJpbmcgaXQuXG4gICAgICovXG4gICAgZ2V0IHVwZGF0ZUludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsO1xuICAgIH1cbiAgICBzZXQgdXBkYXRlSW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsID0gaW50ZXJ2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdoYXQgdGhlIHNvdXJjZSBvZiB0aGUgY2xvY2sgaXMsIGVpdGhlciBcIndvcmtlclwiIChkZWZhdWx0KSxcbiAgICAgKiBcInRpbWVvdXRcIiwgb3IgXCJvZmZsaW5lXCIgKG5vbmUpLlxuICAgICAqL1xuICAgIGdldCBjbG9ja1NvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tlci50eXBlO1xuICAgIH1cbiAgICBzZXQgY2xvY2tTb3VyY2UodHlwZSkge1xuICAgICAgICB0aGlzLl90aWNrZXIudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHBsYXliYWNrLCB3aGljaCBhZmZlY3RzIHRyYWRlb2ZmcyBiZXR3ZWVuIGF1ZGlvXG4gICAgICogb3V0cHV0IGxhdGVuY3kgYW5kIHJlc3BvbnNpdmVuZXNzLlxuICAgICAqIEluIGFkZGl0aW9uIHRvIHNldHRpbmcgdGhlIHZhbHVlIGluIHNlY29uZHMsIHRoZSBsYXRlbmN5SGludCBhbHNvXG4gICAgICogYWNjZXB0cyB0aGUgc3RyaW5ncyBcImludGVyYWN0aXZlXCIgKHByaW9yaXRpemVzIGxvdyBsYXRlbmN5KSxcbiAgICAgKiBcInBsYXliYWNrXCIgKHByaW9yaXRpemVzIHN1c3RhaW5lZCBwbGF5YmFjayksIFwiYmFsYW5jZWRcIiAoYmFsYW5jZXNcbiAgICAgKiBsYXRlbmN5IGFuZCBwZXJmb3JtYW5jZSkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBwcmlvcml0aXplIHN1c3RhaW5lZCBwbGF5YmFja1xuICAgICAqIGNvbnN0IGNvbnRleHQgPSBuZXcgVG9uZS5Db250ZXh0KHsgbGF0ZW5jeUhpbnQ6IFwicGxheWJhY2tcIiB9KTtcbiAgICAgKiAvLyBzZXQgdGhpcyBjb250ZXh0IGFzIHRoZSBnbG9iYWwgQ29udGV4dFxuICAgICAqIFRvbmUuc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgKiAvLyB0aGUgZ2xvYmFsIGNvbnRleHQgaXMgZ2V0dGFibGUgd2l0aCBUb25lLmdldENvbnRleHQoKVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuZ2V0Q29udGV4dCgpLmxhdGVuY3lIaW50KTtcbiAgICAgKi9cbiAgICBnZXQgbGF0ZW5jeUhpbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sYXRlbmN5SGludDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBsb29rQWhlYWQgYW5kIHVwZGF0ZUludGVydmFsIGJhc2VkIG9uIHRoZSBsYXRlbmN5SGludFxuICAgICAqL1xuICAgIF9zZXRMYXRlbmN5SGludChoaW50KSB7XG4gICAgICAgIGxldCBsb29rQWhlYWRWYWx1ZSA9IDA7XG4gICAgICAgIHRoaXMuX2xhdGVuY3lIaW50ID0gaGludDtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGhpbnQpKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGhpbnQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiaW50ZXJhY3RpdmVcIjpcbiAgICAgICAgICAgICAgICAgICAgbG9va0FoZWFkVmFsdWUgPSAwLjE7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwbGF5YmFja1wiOlxuICAgICAgICAgICAgICAgICAgICBsb29rQWhlYWRWYWx1ZSA9IDAuNTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImJhbGFuY2VkXCI6XG4gICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZFZhbHVlID0gMC4yNTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb29rQWhlYWQgPSBsb29rQWhlYWRWYWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVJbnRlcnZhbCA9IGxvb2tBaGVhZFZhbHVlIC8gMjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHVud3JhcHBlZCBBdWRpb0NvbnRleHQgb3IgT2ZmbGluZUF1ZGlvQ29udGV4dFxuICAgICAqL1xuICAgIGdldCByYXdDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIHBsdXMgYSBzaG9ydCBbW2xvb2tBaGVhZF1dLlxuICAgICAqL1xuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWUgKyB0aGlzLmxvb2tBaGVhZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIHdpdGhvdXQgdGhlIFtbbG9va0FoZWFkXV0uXG4gICAgICogSW4gbW9zdCBjYXNlcyBpdCBpcyBiZXR0ZXIgdG8gdXNlIFtbbm93XV0gaW5zdGVhZCBvZiBbW2ltbWVkaWF0ZV1dIHNpbmNlXG4gICAgICogd2l0aCBbW25vd11dIHRoZSBbW2xvb2tBaGVhZF1dIGlzIGFwcGxpZWQgZXF1YWxseSB0byBfYWxsXyBjb21wb25lbnRzIGluY2x1ZGluZyBpbnRlcm5hbCBjb21wb25lbnRzLFxuICAgICAqIHRvIG1ha2luZyBzdXJlIHRoYXQgZXZlcnl0aGluZyBpcyBzY2hlZHVsZWQgaW4gc3luYy4gTWl4aW5nIFtbbm93XV0gYW5kIFtbaW1tZWRpYXRlXV1cbiAgICAgKiBjYW4gY2F1c2Ugc29tZSB0aW1pbmcgaXNzdWVzLiBJZiBubyBsb29rQWhlYWQgaXMgZGVzaXJlZCwgeW91IGNhbiBzZXQgdGhlIFtbbG9va0FoZWFkXV0gdG8gYDBgLlxuICAgICAqL1xuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgYXVkaW8gY29udGV4dCBmcm9tIGEgc3VzcGVuZGVkIHN0YXRlLiBUaGlzIGlzIHJlcXVpcmVkXG4gICAgICogdG8gaW5pdGlhbGx5IHN0YXJ0IHRoZSBBdWRpb0NvbnRleHQuIFNlZSBbW1RvbmUuc3RhcnRdXVxuICAgICAqL1xuICAgIHJlc3VtZSgpIHtcbiAgICAgICAgaWYgKGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5yZXN1bWUoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgY29udGV4dC4gT25jZSBjbG9zZWQsIHRoZSBjb250ZXh0IGNhbiBubyBsb25nZXIgYmUgdXNlZCBhbmRcbiAgICAgKiBhbnkgQXVkaW9Ob2RlcyBjcmVhdGVkIGZyb20gdGhlIGNvbnRleHQgd2lsbCBiZSBzaWxlbnQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCB0aGlzLl9jb250ZXh0LmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgICAgICBjbG9zZUNvbnRleHQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqKkludGVybmFsKiogR2VuZXJhdGUgYSBsb29wZWQgYnVmZmVyIGF0IHNvbWUgY29uc3RhbnQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0Q29uc3RhbnQodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLl9jb25zdGFudHMuaGFzKHZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb25zdGFudHMuZ2V0KHZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxMjgsIHRoaXMuX2NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICBjb25zdCBhcnIgPSBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGFycltpXSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50ID0gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgICAgIGNvbnN0YW50LmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgICAgICBjb25zdGFudC5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICAgICAgY29uc3RhbnQuYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICAgICAgY29uc3RhbnQubG9vcCA9IHRydWU7XG4gICAgICAgICAgICBjb25zdGFudC5zdGFydCgwKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50cy5zZXQodmFsLCBjb25zdGFudCk7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RhbnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuIEFsc28gY2xvc2VzIHRoZSBhdWRpbyBjb250ZXh0LlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGlja2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGltZW91dHMuZGlzcG9zZSgpO1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLl9jb25zdGFudHMpLm1hcCgodmFsKSA9PiB0aGlzLl9jb25zdGFudHNbdmFsXS5kaXNjb25uZWN0KCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUSU1FT1VUU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVGhlIHByaXZhdGUgbG9vcCB3aGljaCBrZWVwcyB0cmFjayBvZiB0aGUgY29udGV4dCBzY2hlZHVsZWQgdGltZW91dHNcbiAgICAgKiBJcyBpbnZva2VkIGZyb20gdGhlIGNsb2NrIHNvdXJjZVxuICAgICAqL1xuICAgIF90aW1lb3V0TG9vcCgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgbGV0IGZpcnN0RXZlbnQgPSB0aGlzLl90aW1lb3V0cy5wZWVrKCk7XG4gICAgICAgIHdoaWxlICh0aGlzLl90aW1lb3V0cy5sZW5ndGggJiYgZmlyc3RFdmVudCAmJiBmaXJzdEV2ZW50LnRpbWUgPD0gbm93KSB7XG4gICAgICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICBmaXJzdEV2ZW50LmNhbGxiYWNrKCk7XG4gICAgICAgICAgICAvLyBzaGlmdCB0aGUgZmlyc3QgZXZlbnQgb2ZmXG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5zaGlmdCgpO1xuICAgICAgICAgICAgLy8gZ2V0IHRoZSBuZXh0IG9uZVxuICAgICAgICAgICAgZmlyc3RFdmVudCA9IHRoaXMuX3RpbWVvdXRzLnBlZWsoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHNldFRpbWVvdXQgd2hpY2ggaXMgZ3VhcmFudGVlZCBieSB0aGUgY2xvY2sgc291cmNlLlxuICAgICAqIEFsc28gcnVucyBpbiB0aGUgb2ZmbGluZSBjb250ZXh0LlxuICAgICAqIEBwYXJhbSAgZm4gICAgICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZVxuICAgICAqIEBwYXJhbSAgdGltZW91dCAgVGhlIHRpbWVvdXQgaW4gc2Vjb25kc1xuICAgICAqIEByZXR1cm5zIElEIHRvIHVzZSB3aGVuIGludm9raW5nIENvbnRleHQuY2xlYXJUaW1lb3V0XG4gICAgICovXG4gICAgc2V0VGltZW91dChmbiwgdGltZW91dCkge1xuICAgICAgICB0aGlzLl90aW1lb3V0SWRzKys7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRzLmFkZCh7XG4gICAgICAgICAgICBjYWxsYmFjazogZm4sXG4gICAgICAgICAgICBpZDogdGhpcy5fdGltZW91dElkcyxcbiAgICAgICAgICAgIHRpbWU6IG5vdyArIHRpbWVvdXQsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZW91dElkcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGEgcHJldmlvdXNseSBzY2hlZHVsZWQgdGltZW91dCB3aXRoIFRvbmUuY29udGV4dC5zZXRUaW1lb3V0XG4gICAgICogQHBhcmFtICBpZCAgVGhlIElEIHJldHVybmVkIGZyb20gc2V0VGltZW91dFxuICAgICAqL1xuICAgIGNsZWFyVGltZW91dChpZCkge1xuICAgICAgICB0aGlzLl90aW1lb3V0cy5mb3JFYWNoKChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmlkID09PSBpZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVvdXRzLnJlbW92ZShldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXIgdGhlIGZ1bmN0aW9uIHNjaGVkdWxlZCBieSBbW3NldEludGVydmFsXV1cbiAgICAgKi9cbiAgICBjbGVhckludGVydmFsKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsZWFyVGltZW91dChpZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgYSByZXBlYXRpbmcgZXZlbnQgdG8gdGhlIGNvbnRleHQncyBjYWxsYmFjayBjbG9ja1xuICAgICAqL1xuICAgIHNldEludGVydmFsKGZuLCBpbnRlcnZhbCkge1xuICAgICAgICBjb25zdCBpZCA9ICsrdGhpcy5fdGltZW91dElkcztcbiAgICAgICAgY29uc3QgaW50ZXJ2YWxGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5hZGQoe1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBldmVudCB0byByZXBlYXQgaXRcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWxGbigpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgdGltZTogbm93ICsgaW50ZXJ2YWwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8ga2ljayBpdCBvZmZcbiAgICAgICAgaW50ZXJ2YWxGbigpO1xuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEJhc2VDb250ZXh0IH0gZnJvbSBcIi4vQmFzZUNvbnRleHRcIjtcbmV4cG9ydCBjbGFzcyBEdW1teUNvbnRleHQgZXh0ZW5kcyBCYXNlQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gMDtcbiAgICAgICAgdGhpcy5sYXRlbmN5SGludCA9IDA7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQkFTRSBBVURJTyBDT05URVhUIE1FVEhPRFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU9zY2lsbGF0b3IoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQnVmZmVyU291cmNlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUJpcXVhZEZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXIoX251bWJlck9mQ2hhbm5lbHMsIF9sZW5ndGgsIF9zYW1wbGVSYXRlKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQ2hhbm5lbE1lcmdlcihfbnVtYmVyT2ZJbnB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsU3BsaXR0ZXIoX251bWJlck9mT3V0cHV0cykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNvbnZvbHZlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVEZWxheShfbWF4RGVsYXlUaW1lKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlSUlSRmlsdGVyKF9mZWVkRm9yd2FyZCwgX2ZlZWRiYWNrKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlUGFubmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVBlcmlvZGljV2F2ZShfcmVhbCwgX2ltYWcsIF9jb25zdHJhaW50cykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVN0ZXJlb1Bhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVXYXZlU2hhcGVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKF9zdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2UoX2VsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGRlY29kZUF1ZGlvRGF0YShfYXVkaW9EYXRhKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFRPTkUgQVVESU8gQ09OVEVYVCBNRVRIT0RTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKF9uYW1lLCBfb3B0aW9ucykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCByYXdDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGFkZEF1ZGlvV29ya2xldE1vZHVsZShfdXJsLCBfbmFtZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVzdW1lKCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHNldFRpbWVvdXQoX2ZuLCBfdGltZW91dCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgY2xlYXJUaW1lb3V0KF9pZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0SW50ZXJ2YWwoX2ZuLCBfaW50ZXJ2YWwpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwoX2lkKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRDb25zdGFudChfdmFsKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgZ2V0IGxpc3RlbmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCB0cmFuc3BvcnQoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IGRyYXcoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgc2V0IGRyYXcoX2QpIHsgfVxuICAgIGdldCBkZXN0aW5hdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBzZXQgZGVzdGluYXRpb24oX2QpIHsgfVxuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RHVtbXlDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IGlzQXJyYXkgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogTWFrZSB0aGUgcHJvcGVydHkgbm90IHdyaXRhYmxlIHVzaW5nIGBkZWZpbmVQcm9wZXJ0eWAuIEludGVybmFsIHVzZSBvbmx5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZE9ubHkodGFyZ2V0LCBwcm9wZXJ0eSkge1xuICAgIGlmIChpc0FycmF5KHByb3BlcnR5KSkge1xuICAgICAgICBwcm9wZXJ0eS5mb3JFYWNoKHN0ciA9PiByZWFkT25seSh0YXJnZXQsIHN0cikpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBhbiBhdHRyaWJ1dGUgd3JpdGVhYmxlLiBJbnRlcm5hbCB1c2Ugb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRhYmxlKHRhcmdldCwgcHJvcGVydHkpIHtcbiAgICBpZiAoaXNBcnJheShwcm9wZXJ0eSkpIHtcbiAgICAgICAgcHJvcGVydHkuZm9yRWFjaChzdHIgPT4gd3JpdGFibGUodGFyZ2V0LCBzdHIpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7XG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuZXhwb3J0IGNvbnN0IG5vT3AgPSAoKSA9PiB7XG4gICAgLy8gbm8gb3BlcmF0aW9uIGhlcmUhXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW50ZXJmYWNlLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc051bWJlciwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEF1ZGlvQnVmZmVyIGxvYWRpbmcgYW5kIHN0b3JhZ2UuIFRvbmVBdWRpb0J1ZmZlciBpcyB1c2VkIGludGVybmFsbHkgYnkgYWxsXG4gKiBjbGFzc2VzIHRoYXQgbWFrZSByZXF1ZXN0cyBmb3IgYXVkaW8gZmlsZXMgc3VjaCBhcyBUb25lLlBsYXllcixcbiAqIFRvbmUuU2FtcGxlciBhbmQgVG9uZS5Db252b2x2ZXIuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgYnVmZmVyID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL0ExLm1wM1wiLCAoKSA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKFwibG9hZGVkXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZUF1ZGlvQnVmZmVyIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUF1ZGlvQnVmZmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbmxvYWQgPSBub09wO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUF1ZGlvQnVmZmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCIsIFwib25lcnJvclwiXSk7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9IG9wdGlvbnMucmV2ZXJzZTtcbiAgICAgICAgdGhpcy5vbmxvYWQgPSBvcHRpb25zLm9ubG9hZDtcbiAgICAgICAgaWYgKG9wdGlvbnMudXJsICYmIGlzQXVkaW9CdWZmZXIob3B0aW9ucy51cmwpIHx8IG9wdGlvbnMudXJsIGluc3RhbmNlb2YgVG9uZUF1ZGlvQnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLnNldChvcHRpb25zLnVybCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTdHJpbmcob3B0aW9ucy51cmwpKSB7XG4gICAgICAgICAgICAvLyBpbml0aWF0ZSB0aGUgZG93bmxvYWRcbiAgICAgICAgICAgIHRoaXMubG9hZChvcHRpb25zLnVybCkuY2F0Y2gob3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzYW1wbGUgcmF0ZSBvZiB0aGUgQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5zYW1wbGVSYXRlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGdldENvbnRleHQoKS5zYW1wbGVSYXRlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhc3MgaW4gYW4gQXVkaW9CdWZmZXIgb3IgVG9uZUF1ZGlvQnVmZmVyIHRvIHNldCB0aGUgdmFsdWUgb2YgdGhpcyBidWZmZXIuXG4gICAgICovXG4gICAgc2V0KGJ1ZmZlcikge1xuICAgICAgICBpZiAoYnVmZmVyIGluc3RhbmNlb2YgVG9uZUF1ZGlvQnVmZmVyKSB7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIGxvYWRlZCwgc2V0IGl0XG4gICAgICAgICAgICBpZiAoYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlciA9IGJ1ZmZlci5nZXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSB3aGVuIGl0J3MgbG9hZGVkLCBpbnZva2UgaXQncyBjYWxsYmFja1xuICAgICAgICAgICAgICAgIGJ1ZmZlci5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0KGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25sb2FkKHRoaXMpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmV2ZXJzZSBpdCBpbml0aWFsbHlcbiAgICAgICAgaWYgKHRoaXMuX3JldmVyc2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgc3RvcmVkIGluIHRoZSBvYmplY3QuXG4gICAgICovXG4gICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhbiBmZXRjaCByZXF1ZXN0IGZvciB0aGUgc2VsZWN0ZWQgdXJsIHRoZW4gZGVjb2RlcyB0aGUgZmlsZSBhcyBhbiBhdWRpbyBidWZmZXIuXG4gICAgICogSW52b2tlcyB0aGUgY2FsbGJhY2sgb25jZSB0aGUgYXVkaW8gYnVmZmVyIGxvYWRzLlxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuIGZpbGV0eXBlIHN1cHBvcnQgZGVwZW5kcyBvbiB0aGUgYnJvd3Nlci5cbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2l0aCB0aGlzIFRvbmVBdWRpb0J1ZmZlclxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBkb25lTG9hZGluZyA9IFRvbmVBdWRpb0J1ZmZlci5sb2FkKHVybCkudGhlbihhdWRpb0J1ZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgb25sb2FkIG1ldGhvZFxuICAgICAgICAgICAgICAgIHRoaXMub25sb2FkKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLnB1c2goZG9uZUxvYWRpbmcpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB5aWVsZCBkb25lTG9hZGluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgZG93bmxvYWRlZCBmaWxlXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLmluZGV4T2YoZG9uZUxvYWRpbmcpO1xuICAgICAgICAgICAgICAgIFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXVkaW8gYnVmZmVyIGZyb20gdGhlIGFycmF5LlxuICAgICAqIFRvIGNyZWF0ZSBhIG11bHRpY2hhbm5lbCBBdWRpb0J1ZmZlciwgcGFzcyBpbiBhIG11bHRpZGltZW5zaW9uYWwgYXJyYXkuXG4gICAgICogQHBhcmFtIGFycmF5IFRoZSBhcnJheSB0byBmaWxsIHRoZSBhdWRpbyBidWZmZXJcbiAgICAgKi9cbiAgICBmcm9tQXJyYXkoYXJyYXkpIHtcbiAgICAgICAgY29uc3QgaXNNdWx0aWRpbWVuc2lvbmFsID0gaXNBcnJheShhcnJheSkgJiYgYXJyYXlbMF0ubGVuZ3RoID4gMDtcbiAgICAgICAgY29uc3QgY2hhbm5lbHMgPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheS5sZW5ndGggOiAxO1xuICAgICAgICBjb25zdCBsZW4gPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheVswXS5sZW5ndGggOiBhcnJheS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlQnVmZmVyKGNoYW5uZWxzLCBsZW4sIGNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IG11bHRpQ2hhbm5lbEFycmF5ID0gIWlzTXVsdGlkaW1lbnNpb25hbCAmJiBjaGFubmVscyA9PT0gMSA/XG4gICAgICAgICAgICBbYXJyYXldIDogYXJyYXk7XG4gICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgY2hhbm5lbHM7IGMrKykge1xuICAgICAgICAgICAgYnVmZmVyLmNvcHlUb0NoYW5uZWwobXVsdGlDaGFubmVsQXJyYXlbY10sIGMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN1bXMgbXVsdGlwbGUgY2hhbm5lbHMgaW50byAxIGNoYW5uZWxcbiAgICAgKiBAcGFyYW0gY2hhbk51bSBPcHRpb25hbGx5IG9ubHkgY29weSBhIHNpbmdsZSBjaGFubmVsIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIHRvTW9ubyhjaGFuTnVtKSB7XG4gICAgICAgIGlmIChpc051bWJlcihjaGFuTnVtKSkge1xuICAgICAgICAgICAgdGhpcy5mcm9tQXJyYXkodGhpcy50b0FycmF5KGNoYW5OdW0pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBvdXRwdXRBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgbnVtQ2hhbm5lbHMgPSB0aGlzLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IG51bUNoYW5uZWxzOyBjaGFubmVsKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsQXJyYXkgPSB0aGlzLnRvQXJyYXkoY2hhbm5lbCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFubmVsQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0QXJyYXlbaV0gKz0gY2hhbm5lbEFycmF5W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGRpdmlkZSBieSB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzXG4gICAgICAgICAgICBvdXRwdXRBcnJheSA9IG91dHB1dEFycmF5Lm1hcChzYW1wbGUgPT4gc2FtcGxlIC8gbnVtQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5mcm9tQXJyYXkob3V0cHV0QXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ1ZmZlciBhcyBhbiBhcnJheS4gU2luZ2xlIGNoYW5uZWwgYnVmZmVycyB3aWxsIHJldHVybiBhIDEtZGltZW5zaW9uYWxcbiAgICAgKiBGbG9hdDMyQXJyYXksIGFuZCBtdWx0aWNoYW5uZWwgYnVmZmVycyB3aWxsIHJldHVybiBtdWx0aWRpbWVuc2lvbmFsIGFycmF5cy5cbiAgICAgKiBAcGFyYW0gY2hhbm5lbCBPcHRpb25hbGx5IG9ubHkgY29weSBhIHNpbmdsZSBjaGFubmVsIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIHRvQXJyYXkoY2hhbm5lbCkge1xuICAgICAgICBpZiAoaXNOdW1iZXIoY2hhbm5lbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubnVtYmVyT2ZDaGFubmVscyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9BcnJheSgwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGMrKykge1xuICAgICAgICAgICAgICAgIHJldFtjXSA9IHRoaXMuZ2V0Q2hhbm5lbERhdGEoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEZsb2F0MzJBcnJheSByZXByZXNlbnRpbmcgdGhlIFBDTSBhdWRpbyBkYXRhIGZvciB0aGUgc3BlY2lmaWMgY2hhbm5lbC5cbiAgICAgKiBAcGFyYW0gIGNoYW5uZWwgIFRoZSBjaGFubmVsIG51bWJlciB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJuIFRoZSBhdWRpbyBhcyBhIFR5cGVkQXJyYXlcbiAgICAgKi9cbiAgICBnZXRDaGFubmVsRGF0YShjaGFubmVsKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheSgwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDdXQgYSBzdWJzZWN0aW9uIG9mIHRoZSBhcnJheSBhbmQgcmV0dXJuIGEgYnVmZmVyIG9mIHRoZVxuICAgICAqIHN1YnNlY3Rpb24uIERvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYnVmZmVyXG4gICAgICogQHBhcmFtIHN0YXJ0IFRoZSB0aW1lIHRvIHN0YXJ0IHRoZSBzbGljZVxuICAgICAqIEBwYXJhbSBlbmQgVGhlIGVuZCB0aW1lIHRvIHNsaWNlLiBJZiBub25lIGlzIGdpdmVuIHdpbGwgZGVmYXVsdCB0byB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgICAgKi9cbiAgICBzbGljZShzdGFydCwgZW5kID0gdGhpcy5kdXJhdGlvbikge1xuICAgICAgICBjb25zdCBzdGFydFNhbXBsZXMgPSBNYXRoLmZsb29yKHN0YXJ0ICogdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3QgZW5kU2FtcGxlcyA9IE1hdGguZmxvb3IoZW5kICogdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgYXNzZXJ0KHN0YXJ0U2FtcGxlcyA8IGVuZFNhbXBsZXMsIFwiVGhlIHN0YXJ0IHRpbWUgbXVzdCBiZSBsZXNzIHRoYW4gdGhlIGVuZCB0aW1lXCIpO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBlbmRTYW1wbGVzIC0gc3RhcnRTYW1wbGVzO1xuICAgICAgICBjb25zdCByZXRCdWZmZXIgPSBnZXRDb250ZXh0KCkuY3JlYXRlQnVmZmVyKHRoaXMubnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCB0aGlzLnNhbXBsZVJhdGUpO1xuICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICByZXRCdWZmZXIuY29weVRvQ2hhbm5lbCh0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpLnN1YmFycmF5KHN0YXJ0U2FtcGxlcywgZW5kU2FtcGxlcyksIGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKHJldEJ1ZmZlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldmVyc2UgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBfcmV2ZXJzZSgpIHtcbiAgICAgICAgaWYgKHRoaXMubG9hZGVkKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRDaGFubmVsRGF0YShpKS5yZXZlcnNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgaXMgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxlbmd0aCA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgZ2V0IGR1cmF0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyIGluIHNhbXBsZXNcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGlzY3JldGUgYXVkaW8gY2hhbm5lbHMuIFJldHVybnMgMCBpZiBubyBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGdldCBudW1iZXJPZkNoYW5uZWxzKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgZ2V0IHJldmVyc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXZlcnNlZDtcbiAgICB9XG4gICAgc2V0IHJldmVyc2UocmV2KSB7XG4gICAgICAgIGlmICh0aGlzLl9yZXZlcnNlZCAhPT0gcmV2KSB7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlZCA9IHJldjtcbiAgICAgICAgICAgIHRoaXMuX3JldmVyc2UoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBUb25lQXVkaW9CdWZmZXIgZnJvbSB0aGUgYXJyYXkuIFRvIGNyZWF0ZSBhIG11bHRpY2hhbm5lbCBBdWRpb0J1ZmZlcixcbiAgICAgKiBwYXNzIGluIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS5cbiAgICAgKiBAcGFyYW0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwgdGhlIGF1ZGlvIGJ1ZmZlclxuICAgICAqIEByZXR1cm4gQSBUb25lQXVkaW9CdWZmZXIgY3JlYXRlZCBmcm9tIHRoZSBhcnJheVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tQXJyYXkoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIChuZXcgVG9uZUF1ZGlvQnVmZmVyKCkpLmZyb21BcnJheShhcnJheSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUb25lQXVkaW9CdWZmZXIgZnJvbSBhIFVSTCwgcmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gYSBUb25lQXVkaW9CdWZmZXJcbiAgICAgKiBAcGFyYW0gIHVybCBUaGUgdXJsIHRvIGxvYWQuXG4gICAgICogQHJldHVybiBBIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gYSBUb25lQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbVVybCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKTtcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBidWZmZXIubG9hZCh1cmwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9hZHMgYSB1cmwgdXNpbmcgZmV0Y2ggYW5kIHJldHVybnMgdGhlIEF1ZGlvQnVmZmVyLlxuICAgICAqL1xuICAgIHN0YXRpYyBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgLy8gdGVzdCBpZiB0aGUgdXJsIGNvbnRhaW5zIG11bHRpcGxlIGV4dGVuc2lvbnNcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPSB1cmwubWF0Y2goL1xcWyhbXlxcXVxcW10rXFx8LispXFxdJC8pO1xuICAgICAgICAgICAgaWYgKG1hdGNoZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb25zID0gbWF0Y2hlc1sxXS5zcGxpdChcInxcIik7XG4gICAgICAgICAgICAgICAgbGV0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbMF07XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBleHQgb2YgZXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoVG9uZUF1ZGlvQnVmZmVyLnN1cHBvcnRzVHlwZShleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24gPSBleHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShtYXRjaGVzWzBdLCBleHRlbnNpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZXJlIGlzIGEgc2xhc2ggYmV0d2VlbiB0aGUgYmFzZVVybCBhbmQgdGhlIHVybFxuICAgICAgICAgICAgY29uc3QgYmFzZVVybCA9IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsID09PSBcIlwiIHx8IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsLmVuZHNXaXRoKFwiL1wiKSA/IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsIDogVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgKyBcIi9cIjtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0geWllbGQgZmV0Y2goYmFzZVVybCArIHVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb3VsZCBub3QgbG9hZCB1cmw6ICR7dXJsfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSB5aWVsZCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXIgPSB5aWVsZCBnZXRDb250ZXh0KCkuZGVjb2RlQXVkaW9EYXRhKGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrcyBhIHVybCdzIGV4dGVuc2lvbiB0byBzZWUgaWYgdGhlIGN1cnJlbnQgYnJvd3NlciBjYW4gcGxheSB0aGF0IGZpbGUgdHlwZS5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwvZXh0ZW5zaW9uIHRvIHRlc3RcbiAgICAgKiBAcmV0dXJuIElmIHRoZSBmaWxlIGV4dGVuc2lvbiBjYW4gYmUgcGxheWVkXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5Ub25lQXVkaW9CdWZmZXIuc3VwcG9ydHNUeXBlKFwid2F2XCIpOyAvLyByZXR1cm5zIHRydWVcbiAgICAgKiBUb25lLlRvbmVBdWRpb0J1ZmZlci5zdXBwb3J0c1R5cGUoXCJwYXRoL3RvL2ZpbGUud2F2XCIpOyAvLyByZXR1cm5zIHRydWVcbiAgICAgKi9cbiAgICBzdGF0aWMgc3VwcG9ydHNUeXBlKHVybCkge1xuICAgICAgICBjb25zdCBleHRlbnNpb25zID0gdXJsLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1tleHRlbnNpb25zLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhdWRpb1wiKS5jYW5QbGF5VHlwZShcImF1ZGlvL1wiICsgZXh0ZW5zaW9uKTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlICE9PSBcIlwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgUHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIGFsbCBvZiB0aGUgYnVmZmVycyBoYXZlIGxvYWRlZFxuICAgICAqL1xuICAgIHN0YXRpYyBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAvLyB0aGlzIG1ha2VzIHN1cmUgdGhhdCB0aGUgZnVuY3Rpb24gaXMgYWx3YXlzIGFzeW5jXG4gICAgICAgICAgICB5aWVsZCBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIHdoaWxlIChUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHlpZWxkIFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU1RBVElDIE1FVEhPRFNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBBIHBhdGggd2hpY2ggaXMgcHJlZml4ZWQgYmVmb3JlIGV2ZXJ5IHVybC5cbiAqL1xuVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgPSBcIlwiO1xuLyoqXG4gKiBBbGwgb2YgdGhlIGRvd25sb2Fkc1xuICovXG5Ub25lQXVkaW9CdWZmZXIuZG93bmxvYWRzID0gW107XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9CdWZmZXIuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvQ29udGV4dFwiO1xuaW1wb3J0IHsgaXNPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL1RvbmVBdWRpb0J1ZmZlclwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dFxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBleGFtcGxlXG4gKiAvLyBnZW5lcmF0ZSBhIHNpbmdsZSBjaGFubmVsLCAwLjUgc2Vjb25kIGJ1ZmZlclxuICogY29uc3QgY29udGV4dCA9IG5ldyBUb25lLk9mZmxpbmVDb250ZXh0KDEsIDAuNSwgNDQxMDApO1xuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcih7IGNvbnRleHQgfSk7XG4gKiBjb250ZXh0LnJlbmRlcigpLnRoZW4oYnVmZmVyID0+IHtcbiAqIFx0Y29uc29sZS5sb2coYnVmZmVyLm51bWJlck9mQ2hhbm5lbHMsIGJ1ZmZlci5kdXJhdGlvbik7XG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNsYXNzIE9mZmxpbmVDb250ZXh0IGV4dGVuZHMgQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgIGNsb2NrU291cmNlOiBcIm9mZmxpbmVcIixcbiAgICAgICAgICAgIGNvbnRleHQ6IGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0pID9cbiAgICAgICAgICAgICAgICBhcmd1bWVudHNbMF0gOiBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0KGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdICogYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbMl0pLFxuICAgICAgICAgICAgbG9va0FoZWFkOiAwLFxuICAgICAgICAgICAgdXBkYXRlSW50ZXJ2YWw6IGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0pID9cbiAgICAgICAgICAgICAgICAxMjggLyBhcmd1bWVudHNbMF0uc2FtcGxlUmF0ZSA6IDEyOCAvIGFyZ3VtZW50c1syXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiT2ZmbGluZUNvbnRleHRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFuIGFydGlmaWNpYWwgY2xvY2sgc291cmNlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jdXJyZW50VGltZSA9IDA7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fZHVyYXRpb24gPSBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdKSA/XG4gICAgICAgICAgICBhcmd1bWVudHNbMF0ubGVuZ3RoIC8gYXJndW1lbnRzWzBdLnNhbXBsZVJhdGUgOiBhcmd1bWVudHNbMV07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE92ZXJyaWRlIHRoZSBub3cgbWV0aG9kIHRvIHBvaW50IHRvIHRoZSBpbnRlcm5hbCBjbG9jayB0aW1lXG4gICAgICovXG4gICAgbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNhbWUgYXMgdGhpcy5ub3coKVxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIganVzdCB0aGUgY2xvY2sgcG9ydGlvbiBvZiB0aGUgYXVkaW8gY29udGV4dC5cbiAgICAgKi9cbiAgICBfcmVuZGVyQ2xvY2soYXN5bmNocm9ub3VzKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICAgICAgd2hpbGUgKHRoaXMuX2R1cmF0aW9uIC0gdGhpcy5fY3VycmVudFRpbWUgPj0gMCkge1xuICAgICAgICAgICAgICAgIC8vIGludm9rZSBhbGwgdGhlIGNhbGxiYWNrcyBvbiB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJ0aWNrXCIpO1xuICAgICAgICAgICAgICAgIC8vIGluY3JlbWVudCB0aGUgY2xvY2sgaW4gYmxvY2stc2l6ZWQgY2h1bmtzXG4gICAgICAgICAgICAgICAgdGhpcy5fY3VycmVudFRpbWUgKz0gMTI4IC8gdGhpcy5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgIC8vIHlpZWxkIG9uY2UgYSBzZWNvbmQgb2YgYXVkaW9cbiAgICAgICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgICAgIGNvbnN0IHlpZWxkRXZlcnkgPSBNYXRoLmZsb29yKHRoaXMuc2FtcGxlUmF0ZSAvIDEyOCk7XG4gICAgICAgICAgICAgICAgaWYgKGFzeW5jaHJvbm91cyAmJiBpbmRleCAlIHlpZWxkRXZlcnkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgbmV3IFByb21pc2UoZG9uZSA9PiBzZXRUaW1lb3V0KGRvbmUsIDEpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgdGhlIG91dHB1dCBvZiB0aGUgT2ZmbGluZUNvbnRleHRcbiAgICAgKiBAcGFyYW0gYXN5bmNocm9ub3VzIElmIHRoZSBjbG9jayBzaG91bGQgYmUgcmVuZGVyZWQgYXN5bmNocm9ub3VzbHksIHdoaWNoIHdpbGwgbm90IGJsb2NrIHRoZSBtYWluIHRocmVhZCwgYnV0IGJlIHNsaWdodGx5IHNsb3dlci5cbiAgICAgKi9cbiAgICByZW5kZXIoYXN5bmNocm9ub3VzID0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgeWllbGQgdGhpcy53b3JrbGV0c0FyZVJlYWR5KCk7XG4gICAgICAgICAgICB5aWVsZCB0aGlzLl9yZW5kZXJDbG9jayhhc3luY2hyb25vdXMpO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgdGhpcy5fY29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBUb25lQXVkaW9CdWZmZXIoYnVmZmVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBjb250ZXh0XG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PZmZsaW5lQ29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4uL3ZlcnNpb25cIjtcbmltcG9ydCB7IGhhc0F1ZGlvQ29udGV4dCwgdGhlV2luZG93IH0gZnJvbSBcIi4vY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0L0NvbnRleHRcIjtcbmltcG9ydCB7IER1bW15Q29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQvRHVtbXlDb250ZXh0XCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IGlzQXVkaW9Db250ZXh0LCBpc09mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRoaXMgZHVtbXkgY29udGV4dCBpcyB1c2VkIHRvIGF2b2lkIHRocm93aW5nIGltbWVkaWF0ZSBlcnJvcnMgd2hlbiBpbXBvcnRpbmcgaW4gTm9kZS5qc1xuICovXG5jb25zdCBkdW1teUNvbnRleHQgPSBuZXcgRHVtbXlDb250ZXh0KCk7XG4vKipcbiAqIFRoZSBnbG9iYWwgYXVkaW8gY29udGV4dCB3aGljaCBpcyBnZXRhYmxlIGFuZCBhc3NpZ25hYmxlIHRocm91Z2hcbiAqIGdldENvbnRleHQgYW5kIHNldENvbnRleHRcbiAqL1xubGV0IGdsb2JhbENvbnRleHQgPSBkdW1teUNvbnRleHQ7XG4vKipcbiAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3lzdGVtLXdpZGUgW1tDb250ZXh0XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250ZXh0KCkge1xuICAgIGlmIChnbG9iYWxDb250ZXh0ID09PSBkdW1teUNvbnRleHQgJiYgaGFzQXVkaW9Db250ZXh0KSB7XG4gICAgICAgIHNldENvbnRleHQobmV3IENvbnRleHQoKSk7XG4gICAgfVxuICAgIHJldHVybiBnbG9iYWxDb250ZXh0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGRlZmF1bHQgYXVkaW8gY29udGV4dFxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldENvbnRleHQoY29udGV4dCkge1xuICAgIGlmIChpc0F1ZGlvQ29udGV4dChjb250ZXh0KSkge1xuICAgICAgICBnbG9iYWxDb250ZXh0ID0gbmV3IENvbnRleHQoY29udGV4dCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzT2ZmbGluZUF1ZGlvQ29udGV4dChjb250ZXh0KSkge1xuICAgICAgICBnbG9iYWxDb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KGNvbnRleHQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZ2xvYmFsQ29udGV4dCA9IGNvbnRleHQ7XG4gICAgfVxufVxuLyoqXG4gKiBNb3N0IGJyb3dzZXJzIHdpbGwgbm90IHBsYXkgX2FueV8gYXVkaW8gdW50aWwgYSB1c2VyXG4gKiBjbGlja3Mgc29tZXRoaW5nIChsaWtlIGEgcGxheSBidXR0b24pLiBJbnZva2UgdGhpcyBtZXRob2RcbiAqIG9uIGEgY2xpY2sgb3Iga2V5cHJlc3MgZXZlbnQgaGFuZGxlciB0byBzdGFydCB0aGUgYXVkaW8gY29udGV4dC5cbiAqIE1vcmUgYWJvdXQgdGhlIEF1dG9wbGF5IHBvbGljeVxuICogW2hlcmVdKGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3dlYi91cGRhdGVzLzIwMTcvMDkvYXV0b3BsYXktcG9saWN5LWNoYW5nZXMjd2ViYXVkaW8pXG4gKiBAZXhhbXBsZVxuICogZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJ1dHRvblwiKS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgYXN5bmMgKCkgPT4ge1xuICogXHRhd2FpdCBUb25lLnN0YXJ0KCk7XG4gKiBcdGNvbnNvbGUubG9nKFwiY29udGV4dCBzdGFydGVkXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhcnQoKSB7XG4gICAgcmV0dXJuIGdsb2JhbENvbnRleHQucmVzdW1lKCk7XG59XG4vKipcbiAqIExvZyBUb25lLmpzICsgdmVyc2lvbiBpbiB0aGUgY29uc29sZS5cbiAqL1xuaWYgKHRoZVdpbmRvdyAmJiAhdGhlV2luZG93LlRPTkVfU0lMRU5DRV9MT0dHSU5HKSB7XG4gICAgbGV0IHByZWZpeCA9IFwidlwiO1xuICAgIGlmICh2ZXJzaW9uID09PSBcImRldlwiKSB7XG4gICAgICAgIHByZWZpeCA9IFwiXCI7XG4gICAgfVxuICAgIGNvbnN0IHByaW50U3RyaW5nID0gYCAqIFRvbmUuanMgJHtwcmVmaXh9JHt2ZXJzaW9ufSAqIGA7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhgJWMke3ByaW50U3RyaW5nfWAsIFwiYmFja2dyb3VuZDogIzAwMDsgY29sb3I6ICNmZmZcIik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HbG9iYWwuanMubWFwIiwiLyoqXG4gKiBFcXVhbCBwb3dlciBnYWluIHNjYWxlLiBHb29kIGZvciBjcm9zcy1mYWRpbmcuXG4gKiBAcGFyYW0gIHBlcmNlbnQgKDAtMSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVxdWFsUG93ZXJTY2FsZShwZXJjZW50KSB7XG4gICAgY29uc3QgcGlGYWN0b3IgPSAwLjUgKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbihwZXJjZW50ICogcGlGYWN0b3IpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGRlY2liZWxzIGludG8gZ2Fpbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRiVG9HYWluKGRiKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCBkYiAvIDIwKTtcbn1cbi8qKlxuICogQ29udmVydCBnYWluIHRvIGRlY2liZWxzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2FpblRvRGIoZ2Fpbikge1xuICAgIHJldHVybiAyMCAqIChNYXRoLmxvZyhnYWluKSAvIE1hdGguTE4xMCk7XG59XG4vKipcbiAqIENvbnZlcnQgYW4gaW50ZXJ2YWwgKGluIHNlbWl0b25lcykgdG8gYSBmcmVxdWVuY3kgcmF0aW8uXG4gKiBAcGFyYW0gaW50ZXJ2YWwgdGhlIG51bWJlciBvZiBzZW1pdG9uZXMgYWJvdmUgdGhlIGJhc2Ugbm90ZVxuICogQGV4YW1wbGVcbiAqIFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKDApOyAvLyAxXG4gKiBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbygxMik7IC8vIDJcbiAqIFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKC0xMik7IC8vIDAuNVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDIsIChpbnRlcnZhbCAvIDEyKSk7XG59XG4vKipcbiAqIFRoZSBHbG9iYWwgW2NvbmNlcnQgdHVuaW5nIHBpdGNoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db25jZXJ0X3BpdGNoKSB3aGljaCBpcyB1c2VkXG4gKiB0byBnZW5lcmF0ZSBhbGwgdGhlIG90aGVyIHBpdGNoIHZhbHVlcyBmcm9tIG5vdGVzLiBBNCdzIHZhbHVlcyBpbiBIZXJ0ei5cbiAqL1xubGV0IEE0ID0gNDQwO1xuZXhwb3J0IGZ1bmN0aW9uIGdldEE0KCkge1xuICAgIHJldHVybiBBNDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXRBNChmcmVxKSB7XG4gICAgQTQgPSBmcmVxO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgZnJlcXVlbmN5IHZhbHVlIHRvIGEgTUlESSBub3RlLlxuICogQHBhcmFtIGZyZXF1ZW5jeSBUaGUgdmFsdWUgdG8gZnJlcXVlbmN5IHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAZXhhbXBsZVxuICogVG9uZS5mdG9tKDQ0MCk7IC8vIHJldHVybnMgNjlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZ0b20oZnJlcXVlbmN5KSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoZnRvbWYoZnJlcXVlbmN5KSk7XG59XG4vKipcbiAqIENvbnZlcnQgYSBmcmVxdWVuY3kgdG8gYSBmbG9hdGluZyBwb2ludCBtaWRpIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmdG9tZihmcmVxdWVuY3kpIHtcbiAgICByZXR1cm4gNjkgKyAxMiAqIE1hdGgubG9nMihmcmVxdWVuY3kgLyBBNCk7XG59XG4vKipcbiAqIENvbnZlcnQgYSBNSURJIG5vdGUgdG8gZnJlcXVlbmN5IHZhbHVlLlxuICogQHBhcmFtICBtaWRpIFRoZSBtaWRpIG51bWJlciB0byBjb252ZXJ0LlxuICogQHJldHVybiBUaGUgY29ycmVzcG9uZGluZyBmcmVxdWVuY3kgdmFsdWVcbiAqIEBleGFtcGxlXG4gKiBUb25lLm10b2YoNjkpOyAvLyA0NDBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG10b2YobWlkaSkge1xuICAgIHJldHVybiBBNCAqIE1hdGgucG93KDIsIChtaWRpIC0gNjkpIC8gMTIpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udmVyc2lvbnMuanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1N0cmluZywgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBUaW1lQmFzZSBpcyBhIGZsZXhpYmxlIGVuY29kaW5nIG9mIHRpbWUgd2hpY2ggY2FuIGJlIGV2YWx1YXRlZCB0byBhbmQgZnJvbSBhIHN0cmluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVCYXNlQ2xhc3MgZXh0ZW5kcyBUb25lIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIHRpbWUgdmFsdWUuIFVzZWQgdG8gY29tcHV0ZVxuICAgICAqIFRyYW5zcG9ydCBhbmQgY29udGV4dC1yZWxhdGl2ZSB0aW1pbmcuXG4gICAgICogQHBhcmFtICB2YWx1ZSAgVGhlIHRpbWUgdmFsdWUgYXMgYSBudW1iZXIsIHN0cmluZyBvciBvYmplY3RcbiAgICAgKiBAcGFyYW0gIHVuaXRzICBVbml0IHZhbHVlc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIHZhbHVlLCB1bml0cykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGRlZmF1bHQgdW5pdHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJzXCI7XG4gICAgICAgIHRoaXMuX3ZhbCA9IHZhbHVlO1xuICAgICAgICB0aGlzLl91bml0cyA9IHVuaXRzO1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB0aGlzLl9leHByZXNzaW9ucyA9IHRoaXMuX2dldEV4cHJlc3Npb25zKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFsbCBvZiB0aGUgdGltZSBlbmNvZGluZyBleHByZXNzaW9uc1xuICAgICAqL1xuICAgIF9nZXRFeHByZXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGh6OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeVRvVW5pdHMocGFyc2VGbG9hdCh2YWx1ZSkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KWh6JC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGk6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGlja3NUb1VuaXRzKHBhcnNlSW50KHZhbHVlLCAxMCkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKWkkL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbToge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VJbnQodmFsdWUsIDEwKSAqIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspbSQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUsIGRvdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2FsYXIgPSBkb3QgPT09IFwiLlwiID8gMS41IDogMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG51bWVyaWNWYWx1ZSA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpICogc2NhbGFyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyg0IC8gbnVtZXJpY1ZhbHVlKSAqIHNjYWxhcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKW4oXFwuPykkL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cHJlc3Npb25zW3RoaXMuZGVmYXVsdFVuaXRzXS5tZXRob2QuY2FsbCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pJC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgczoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zZWNvbmRzVG9Vbml0cyhwYXJzZUZsb2F0KHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pcyQvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNhbXBsZXM6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodmFsdWUsIDEwKSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKXNhbXBsZXMkLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyg4IC8gKE1hdGguZmxvb3IobnVtZXJpY1ZhbHVlKSAqIDMpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyl0JC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAobSwgcSwgcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAobSAmJiBtICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSAqIHBhcnNlRmxvYXQobSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChxICYmIHEgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChxKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgJiYgcyAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHMpIC8gNCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KTooXFxkKyg/OlxcLlxcZCspPyk6PyhcXGQrKD86XFwuXFxkKyk/KT8kLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VkFMVUUgT0ZcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBFdmFsdWF0ZSB0aGUgdGltZSB2YWx1ZS4gUmV0dXJucyB0aGUgdGltZSBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIHZhbHVlT2YoKSB7XG4gICAgICAgIGlmICh0aGlzLl92YWwgaW5zdGFuY2VvZiBUaW1lQmFzZUNsYXNzKSB7XG4gICAgICAgICAgICB0aGlzLmZyb21UeXBlKHRoaXMuX3ZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fdmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25vQXJnKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTdHJpbmcodGhpcy5fdmFsKSAmJiBpc1VuZGVmKHRoaXMuX3VuaXRzKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCB1bml0cyBpbiB0aGlzLl9leHByZXNzaW9ucykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9leHByZXNzaW9uc1t1bml0c10ucmVnZXhwLnRlc3QodGhpcy5fdmFsLnRyaW0oKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdW5pdHMgPSB1bml0cztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHR5cGVOYW1lIGluIHRoaXMuX3ZhbCkge1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fdmFsW3R5cGVOYW1lXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSB0aGlzLl92YWxbdHlwZU5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWUgPSAobmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5jb250ZXh0LCB0eXBlTmFtZSkpLnZhbHVlT2YoKSAqIHF1YW50aXR5O1xuICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0b3RhbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX3VuaXRzKSkge1xuICAgICAgICAgICAgY29uc3QgZXhwciA9IHRoaXMuX2V4cHJlc3Npb25zW3RoaXMuX3VuaXRzXTtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoaW5nID0gdGhpcy5fdmFsLnRvU3RyaW5nKCkudHJpbSgpLm1hdGNoKGV4cHIucmVnZXhwKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBleHByLm1ldGhvZC5hcHBseSh0aGlzLCBtYXRjaGluZy5zbGljZSgxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwci5tZXRob2QuY2FsbCh0aGlzLCB0aGlzLl92YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHRoaXMuX3ZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VU5JVCBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gMSAvIGZyZXE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gKDYwIC8gdGhpcy5fZ2V0QnBtKCkpICogYmVhdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIHNlY29uZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gKHRpY2tzICogKHRoaXMuX2JlYXRzVG9Vbml0cygxKSkgLyB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdpdGggbm8gYXJndW1lbnRzLCByZXR1cm4gJ25vdydcbiAgICAgKi9cbiAgICBfbm9BcmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ub3coKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRURU1QTyBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgYnBtXG4gICAgICovXG4gICAgX2dldEJwbSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQuYnBtLnZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWVTaWduYXR1cmVcbiAgICAgKi9cbiAgICBfZ2V0VGltZVNpZ25hdHVyZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQudGltZVNpZ25hdHVyZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBQUFEgb3IgMTkyIGlmIFRyYW5zcG9ydCBpcyBub3QgYXZhaWxhYmxlXG4gICAgICovXG4gICAgX2dldFBQUSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQuUFBRO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdENPTlZFUlNJT04gSU5URVJGQUNFXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogQ29lcmNlIGEgdGltZSB0eXBlIGludG8gdGhpcyB1bml0cyB0eXBlLlxuICAgICAqIEBwYXJhbSB0eXBlIEFueSB0aW1lIHR5cGUgdW5pdHNcbiAgICAgKi9cbiAgICBmcm9tVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3VuaXRzID0gdW5kZWZpbmVkO1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZGVmYXVsdFVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlIFwic1wiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9TZWNvbmRzKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiaVwiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9UaWNrcygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImh6XCI6XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdHlwZS50b0ZyZXF1ZW5jeSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm1pZGlcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvTWlkaSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIGluIGhlcnR6XG4gICAgICovXG4gICAgdG9GcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiAxIC8gdGhpcy50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNhbXBsZXNcbiAgICAgKi9cbiAgICB0b1NhbXBsZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcygpICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMuXG4gICAgICovXG4gICAgdG9NaWxsaXNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcygpICogMTAwMDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lQmFzZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgZnRvbSB9IGZyb20gXCIuL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBUaW1lQmFzZUNsYXNzIH0gZnJvbSBcIi4vVGltZUJhc2VcIjtcbi8qKlxuICogVGltZUNsYXNzIGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIFRpbWVDbGFzcyBjYW4gYmUgcGFzc2VkIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG4gKiBAcGFyYW0gIHZhbCAgICBUaGUgdGltZSB2YWx1ZS5cbiAqIEBwYXJhbSAgdW5pdHMgIFRoZSB1bml0cyBvZiB0aGUgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdGltZSA9IFRvbmUuVGltZShcIjRuXCIpOyAvLyBhIHF1YXJ0ZXIgbm90ZVxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVDbGFzcyBleHRlbmRzIFRpbWVCYXNlQ2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpbWVDbGFzc1wiO1xuICAgIH1cbiAgICBfZ2V0RXhwcmVzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHN1cGVyLl9nZXRFeHByZXNzaW9ucygpLCB7XG4gICAgICAgICAgICBub3c6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6IChjYXB0dXJlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub3coKSArIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgY2FwdHVyZSkudmFsdWVPZigpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXlxcKyguKykvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHF1YW50aXplOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAoY2FwdHVyZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWFudFRvID0gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIGNhcHR1cmUpLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NlY29uZHNUb1VuaXRzKHRoaXMuY29udGV4dC50cmFuc3BvcnQubmV4dFN1YmRpdmlzaW9uKHF1YW50VG8pKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL15AKC4rKS8sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUXVhbnRpemUgdGhlIHRpbWUgYnkgdGhlIGdpdmVuIHN1YmRpdmlzaW9uLiBPcHRpb25hbGx5IGFkZCBhXG4gICAgICogcGVyY2VudGFnZSB3aGljaCB3aWxsIG1vdmUgdGhlIHRpbWUgdmFsdWUgdG93YXJkcyB0aGUgaWRlYWxcbiAgICAgKiBxdWFudGl6ZWQgdmFsdWUgYnkgdGhhdCBwZXJjZW50YWdlLlxuICAgICAqIEBwYXJhbSAgc3ViZGl2ICAgIFRoZSBzdWJkaXZpc2lvbiB0byBxdWFudGl6ZSB0b1xuICAgICAqIEBwYXJhbSAgcGVyY2VudCAgTW92ZSB0aGUgdGltZSB2YWx1ZSB0b3dhcmRzIHRoZSBxdWFudGl6ZWQgdmFsdWUgYnkgYSBwZXJjZW50YWdlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5UaW1lKDIxKS5xdWFudGl6ZSgyKTsgLy8gcmV0dXJucyAyMlxuICAgICAqIFRvbmUuVGltZSgwLjYpLnF1YW50aXplKFwiNG5cIiwgMC41KTsgLy8gcmV0dXJucyAwLjU1XG4gICAgICovXG4gICAgcXVhbnRpemUoc3ViZGl2LCBwZXJjZW50ID0gMSkge1xuICAgICAgICBjb25zdCBzdWJkaXZpc2lvbiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgc3ViZGl2KS52YWx1ZU9mKCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy52YWx1ZU9mKCk7XG4gICAgICAgIGNvbnN0IG11bHRpcGxlID0gTWF0aC5yb3VuZCh2YWx1ZSAvIHN1YmRpdmlzaW9uKTtcbiAgICAgICAgY29uc3QgaWRlYWwgPSBtdWx0aXBsZSAqIHN1YmRpdmlzaW9uO1xuICAgICAgICBjb25zdCBkaWZmID0gaWRlYWwgLSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgZGlmZiAqIHBlcmNlbnQ7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIFRpbWUgdG8gTm90YXRpb24uIFRoZSBub3RhdGlvbiB2YWx1ZXMgYXJlIHdpbGwgYmUgdGhlXG4gICAgICogY2xvc2VzdCByZXByZXNlbnRhdGlvbiBiZXR3ZWVuIDFtIHRvIDEyOHRoIG5vdGUuXG4gICAgICogQHJldHVybiB7Tm90YXRpb259XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBpZiB0aGUgVHJhbnNwb3J0IGlzIGF0IDEyMGJwbTpcbiAgICAgKiBUb25lLlRpbWUoMikudG9Ob3RhdGlvbigpOyAvLyByZXR1cm5zIFwiMW1cIlxuICAgICAqL1xuICAgIHRvTm90YXRpb24oKSB7XG4gICAgICAgIGNvbnN0IHRpbWUgPSB0aGlzLnRvU2Vjb25kcygpO1xuICAgICAgICBjb25zdCB0ZXN0Tm90YXRpb25zID0gW1wiMW1cIl07XG4gICAgICAgIGZvciAobGV0IHBvd2VyID0gMTsgcG93ZXIgPCA5OyBwb3dlcisrKSB7XG4gICAgICAgICAgICBjb25zdCBzdWJkaXYgPSBNYXRoLnBvdygyLCBwb3dlcik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJuLlwiKTtcbiAgICAgICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChzdWJkaXYgKyBcIm5cIik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJ0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChcIjBcIik7XG4gICAgICAgIC8vIGZpbmQgdGhlIGNsb3NldHMgbm90YXRpb24gcmVwcmVzZW50YXRpb25cbiAgICAgICAgbGV0IGNsb3Nlc3QgPSB0ZXN0Tm90YXRpb25zWzBdO1xuICAgICAgICBsZXQgY2xvc2VzdFNlY29uZHMgPSBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGVzdE5vdGF0aW9uc1swXSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHRlc3ROb3RhdGlvbnMuZm9yRWFjaChub3RhdGlvbiA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3RhdGlvblNlY29uZHMgPSBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgbm90YXRpb24pLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKG5vdGF0aW9uU2Vjb25kcyAtIHRpbWUpIDwgTWF0aC5hYnMoY2xvc2VzdFNlY29uZHMgLSB0aW1lKSkge1xuICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBub3RhdGlvbjtcbiAgICAgICAgICAgICAgICBjbG9zZXN0U2Vjb25kcyA9IG5vdGF0aW9uU2Vjb25kcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjbG9zZXN0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgZW5jb2RlZCBhcyBCYXJzOkJlYXRzOlNpeHRlZW50aHMuXG4gICAgICovXG4gICAgdG9CYXJzQmVhdHNTaXh0ZWVudGhzKCkge1xuICAgICAgICBjb25zdCBxdWFydGVyVGltZSA9IHRoaXMuX2JlYXRzVG9Vbml0cygxKTtcbiAgICAgICAgbGV0IHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcbiAgICAgICAgcXVhcnRlcnMgPSBwYXJzZUZsb2F0KHF1YXJ0ZXJzLnRvRml4ZWQoNCkpO1xuICAgICAgICBjb25zdCBtZWFzdXJlcyA9IE1hdGguZmxvb3IocXVhcnRlcnMgLyB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpO1xuICAgICAgICBsZXQgc2l4dGVlbnRocyA9IChxdWFydGVycyAlIDEpICogNDtcbiAgICAgICAgcXVhcnRlcnMgPSBNYXRoLmZsb29yKHF1YXJ0ZXJzKSAlIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKTtcbiAgICAgICAgY29uc3Qgc2l4dGVlbnRoU3RyaW5nID0gc2l4dGVlbnRocy50b1N0cmluZygpO1xuICAgICAgICBpZiAoc2l4dGVlbnRoU3RyaW5nLmxlbmd0aCA+IDMpIHtcbiAgICAgICAgICAgIC8vIHRoZSBhZGRpdGlvbmFsIHBhcnNlRmxvYXQgcmVtb3ZlcyBpbnNpZ25pZmljYW50IHRyYWlsaW5nIHplcm9lc1xuICAgICAgICAgICAgc2l4dGVlbnRocyA9IHBhcnNlRmxvYXQocGFyc2VGbG9hdChzaXh0ZWVudGhTdHJpbmcpLnRvRml4ZWQoMykpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb2dyZXNzID0gW21lYXN1cmVzLCBxdWFydGVycywgc2l4dGVlbnRoc107XG4gICAgICAgIHJldHVybiBwcm9ncmVzcy5qb2luKFwiOlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHRpY2tzLlxuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJUaW1lID0gdGhpcy5fYmVhdHNUb1VuaXRzKDEpO1xuICAgICAgICBjb25zdCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHF1YXJ0ZXJzICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gc2Vjb25kcy5cbiAgICAgKi9cbiAgICB0b1NlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBhcyBhIG1pZGkgbm90ZS5cbiAgICAgKi9cbiAgICB0b01pZGkoKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHRoaXMudG9GcmVxdWVuY3koKSk7XG4gICAgfVxuICAgIF9ub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQubm93KCk7XG4gICAgfVxufVxuLyoqXG4gKiBDcmVhdGUgYSBUaW1lQ2xhc3MgZnJvbSBhIHRpbWUgc3RyaW5nIG9yIG51bWJlci4gVGhlIHRpbWUgaXMgY29tcHV0ZWQgYWdhaW5zdCB0aGVcbiAqIGdsb2JhbCBUb25lLkNvbnRleHQuIFRvIHVzZSBhIHNwZWNpZmljIGNvbnRleHQsIHVzZSBbW1RpbWVDbGFzc11dXG4gKiBAcGFyYW0gdmFsdWUgQSB2YWx1ZSB3aGljaCByZXByZXNlbnRzIHRpbWVcbiAqIEBwYXJhbSB1bml0cyBUaGUgdmFsdWUncyB1bml0cyBpZiB0aGV5IGNhbid0IGJlIGluZmVycmVkIGJ5IHRoZSB2YWx1ZS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKiBAZXhhbXBsZVxuICogY29uc3QgdGltZSA9IFRvbmUuVGltZShcIjRuXCIpLnRvU2Vjb25kcygpO1xuICogY29uc29sZS5sb2codGltZSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3Qgbm90ZSA9IFRvbmUuVGltZSgxKS50b05vdGF0aW9uKCk7XG4gKiBjb25zb2xlLmxvZyhub3RlKTtcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmcmVxID0gVG9uZS5UaW1lKDAuNSkudG9GcmVxdWVuY3koKTtcbiAqIGNvbnNvbGUubG9nKGZyZXEpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gVGltZSh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8sIG10b2YgfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgZnRvbSwgZ2V0QTQsIHNldEE0IH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuL1RpbWVcIjtcbi8qKlxuICogRnJlcXVlbmN5IGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIEZyZXF1ZW5jeSB2YWx1ZXMuXG4gKiBFdmVudHVhbGx5IGFsbCB0aW1lIHZhbHVlcyBhcmUgZXZhbHVhdGVkIHRvIGhlcnR6IHVzaW5nIHRoZSBgdmFsdWVPZmAgbWV0aG9kLlxuICogQGV4YW1wbGVcbiAqIFRvbmUuRnJlcXVlbmN5KFwiQzNcIik7IC8vIDI2MVxuICogVG9uZS5GcmVxdWVuY3koMzgsIFwibWlkaVwiKTtcbiAqIFRvbmUuRnJlcXVlbmN5KFwiQzNcIikudHJhbnNwb3NlKDQpO1xuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZXF1ZW5jeUNsYXNzIGV4dGVuZHMgVGltZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVxdWVuY3lcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcImh6XCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBbY29uY2VydCB0dW5pbmcgcGl0Y2hdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbmNlcnRfcGl0Y2gpIHdoaWNoIGlzIHVzZWRcbiAgICAgKiB0byBnZW5lcmF0ZSBhbGwgdGhlIG90aGVyIHBpdGNoIHZhbHVlcyBmcm9tIG5vdGVzLiBBNCdzIHZhbHVlcyBpbiBIZXJ0ei5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEE0KCkge1xuICAgICAgICByZXR1cm4gZ2V0QTQoKTtcbiAgICB9XG4gICAgc3RhdGljIHNldCBBNChmcmVxKSB7XG4gICAgICAgIHNldEE0KGZyZXEpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdEFVR01FTlQgQkFTRSBFWFBSRVNTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIF9nZXRFeHByZXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLl9nZXRFeHByZXNzaW9ucygpLCB7XG4gICAgICAgICAgICBtaWRpOiB7XG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/bWlkaSkvLFxuICAgICAgICAgICAgICAgIG1ldGhvZCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0VW5pdHMgPT09IFwibWlkaVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnJlcXVlbmN5Q2xhc3MubXRvZih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5vdGU6IHtcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFthLWddezF9KD86YnwjfHh8YmIpPykoLT9bMC05XSspL2ksXG4gICAgICAgICAgICAgICAgbWV0aG9kKHBpdGNoLCBvY3RhdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBub3RlVG9TY2FsZUluZGV4W3BpdGNoLnRvTG93ZXJDYXNlKCldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBub3RlTnVtYmVyID0gaW5kZXggKyAocGFyc2VJbnQob2N0YXZlLCAxMCkgKyAxKSAqIDEyO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0VW5pdHMgPT09IFwibWlkaVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm90ZU51bWJlcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGcmVxdWVuY3lDbGFzcy5tdG9mKG5vdGVOdW1iZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0cjoge1xuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyk6KFxcZCsoPzpcXC5cXGQrKT8pOj8oXFxkKyg/OlxcLlxcZCspPyk/LyxcbiAgICAgICAgICAgICAgICBtZXRob2QobSwgcSwgcykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG90YWwgPSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAobSAmJiBtICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSAqIHBhcnNlRmxvYXQobSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChxICYmIHEgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCAqPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChxKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgJiYgcyAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICo9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHMpIC8gNCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRFWFBSRVNTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFRyYW5zcG9zZXMgdGhlIGZyZXF1ZW5jeSBieSB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHNlbWl0b25lcy5cbiAgICAgKiBAcmV0dXJuICBBIG5ldyB0cmFuc3Bvc2VkIGZyZXF1ZW5jeVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS50cmFuc3Bvc2UoMyk7IC8vIFwiQzVcIlxuICAgICAqL1xuICAgIHRyYW5zcG9zZShpbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy52YWx1ZU9mKCkgKiBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oaW50ZXJ2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGFrZXMgYW4gYXJyYXkgb2Ygc2VtaXRvbmUgaW50ZXJ2YWxzIGFuZCByZXR1cm5zXG4gICAgICogYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMgdHJhbnNwb3NlZCBieSB0aG9zZSBpbnRlcnZhbHMuXG4gICAgICogQHJldHVybiAgUmV0dXJucyBhbiBhcnJheSBvZiBGcmVxdWVuY2llc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS5oYXJtb25pemUoWzAsIDMsIDddKTsgLy8gW1wiQTRcIiwgXCJDNVwiLCBcIkU1XCJdXG4gICAgICovXG4gICAgaGFybW9uaXplKGludGVydmFscykge1xuICAgICAgICByZXR1cm4gaW50ZXJ2YWxzLm1hcChpbnRlcnZhbCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc3Bvc2UoaW50ZXJ2YWwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRVTklUIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGFzIGEgTUlESSBub3RlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLkZyZXF1ZW5jeShcIkM0XCIpLnRvTWlkaSgpOyAvLyA2MFxuICAgICAqL1xuICAgIHRvTWlkaSgpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20odGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgaW4gU2NpZW50aWZpYyBQaXRjaCBOb3RhdGlvblxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koNjksIFwibWlkaVwiKS50b05vdGUoKTsgLy8gXCJBNFwiXG4gICAgICovXG4gICAgdG9Ob3RlKCkge1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeSgpO1xuICAgICAgICBjb25zdCBsb2cgPSBNYXRoLmxvZzIoZnJlcSAvIEZyZXF1ZW5jeUNsYXNzLkE0KTtcbiAgICAgICAgbGV0IG5vdGVOdW1iZXIgPSBNYXRoLnJvdW5kKDEyICogbG9nKSArIDU3O1xuICAgICAgICBjb25zdCBvY3RhdmUgPSBNYXRoLmZsb29yKG5vdGVOdW1iZXIgLyAxMik7XG4gICAgICAgIGlmIChvY3RhdmUgPCAwKSB7XG4gICAgICAgICAgICBub3RlTnVtYmVyICs9IC0xMiAqIG9jdGF2ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBub3RlTmFtZSA9IHNjYWxlSW5kZXhUb05vdGVbbm90ZU51bWJlciAlIDEyXTtcbiAgICAgICAgcmV0dXJuIG5vdGVOYW1lICsgb2N0YXZlLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZHVyYXRpb24gb2Ygb25lIGN5Y2xlIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgdG9TZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gMSAvIHN1cGVyLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGR1cmF0aW9uIG9mIG9uZSBjeWNsZSBpbiB0aWNrc1xuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJUaW1lID0gdGhpcy5fYmVhdHNUb1VuaXRzKDEpO1xuICAgICAgICBjb25zdCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKHF1YXJ0ZXJzICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFVOSVQgQ09OVkVSU0lPTlMgSEVMUEVSU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFdpdGggbm8gYXJndW1lbnRzLCByZXR1cm4gMFxuICAgICAqL1xuICAgIF9ub0FyZygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gZnJlcTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiAxIC8gKCh0aWNrcyAqIDYwKSAvICh0aGlzLl9nZXRCcG0oKSAqIHRoaXMuX2dldFBQUSgpKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gMSAvIHN1cGVyLl9iZWF0c1RvVW5pdHMoYmVhdHMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiAxIC8gc2Vjb25kcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIE1JREkgbm90ZSB0byBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICogQHBhcmFtICBtaWRpIFRoZSBtaWRpIG51bWJlciB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm4gVGhlIGNvcnJlc3BvbmRpbmcgZnJlcXVlbmN5IHZhbHVlXG4gICAgICovXG4gICAgc3RhdGljIG10b2YobWlkaSkge1xuICAgICAgICByZXR1cm4gbXRvZihtaWRpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIGZyZXF1ZW5jeSB2YWx1ZSB0byBhIE1JREkgbm90ZS5cbiAgICAgKiBAcGFyYW0gZnJlcXVlbmN5IFRoZSB2YWx1ZSB0byBmcmVxdWVuY3kgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKi9cbiAgICBzdGF0aWMgZnRvbShmcmVxdWVuY3kpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oZnJlcXVlbmN5KTtcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0RlJFUVVFTkNZIENPTlZFUlNJT05TXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogTm90ZSB0byBzY2FsZSBpbmRleC5cbiAqIEBoaWRkZW5cbiAqL1xuY29uc3Qgbm90ZVRvU2NhbGVJbmRleCA9IHtcbiAgICBjYmI6IC0yLCBjYjogLTEsIGM6IDAsIFwiYyNcIjogMSwgY3g6IDIsXG4gICAgZGJiOiAwLCBkYjogMSwgZDogMiwgXCJkI1wiOiAzLCBkeDogNCxcbiAgICBlYmI6IDIsIGViOiAzLCBlOiA0LCBcImUjXCI6IDUsIGV4OiA2LFxuICAgIGZiYjogMywgZmI6IDQsIGY6IDUsIFwiZiNcIjogNiwgZng6IDcsXG4gICAgZ2JiOiA1LCBnYjogNiwgZzogNywgXCJnI1wiOiA4LCBneDogOSxcbiAgICBhYmI6IDcsIGFiOiA4LCBhOiA5LCBcImEjXCI6IDEwLCBheDogMTEsXG4gICAgYmJiOiA5LCBiYjogMTAsIGI6IDExLCBcImIjXCI6IDEyLCBieDogMTMsXG59O1xuLyoqXG4gKiBzY2FsZSBpbmRleCB0byBub3RlIChzaGFycHMpXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHNjYWxlSW5kZXhUb05vdGUgPSBbXCJDXCIsIFwiQyNcIiwgXCJEXCIsIFwiRCNcIiwgXCJFXCIsIFwiRlwiLCBcIkYjXCIsIFwiR1wiLCBcIkcjXCIsIFwiQVwiLCBcIkEjXCIsIFwiQlwiXTtcbi8qKlxuICogQ29udmVydCBhIHZhbHVlIGludG8gYSBGcmVxdWVuY3lDbGFzcyBvYmplY3QuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1pZGkgPSBUb25lLkZyZXF1ZW5jeShcIkMzXCIpLnRvTWlkaSgpO1xuICogY29uc29sZS5sb2cobWlkaSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3QgaGVydHogPSBUb25lLkZyZXF1ZW5jeSgzOCwgXCJtaWRpXCIpLnRvRnJlcXVlbmN5KCk7XG4gKiBjb25zb2xlLmxvZyhoZXJ0eik7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBGcmVxdWVuY3kodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBGcmVxdWVuY3lDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVxdWVuY3kuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuL1RpbWVcIjtcbi8qKlxuICogVHJhbnNwb3J0VGltZSBpcyBhIHRoZSB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQnc1xuICogdGltZWxpbmUuIEl0IGlzIHNpbWlsYXIgdG8gVG9uZS5UaW1lLCBidXQgaW5zdGVhZCBvZiBldmFsdWF0aW5nXG4gKiBhZ2FpbnN0IHRoZSBBdWRpb0NvbnRleHQncyBjbG9jaywgaXQgaXMgZXZhbHVhdGVkIGFnYWluc3RcbiAqIHRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbi4gU2VlIFtUcmFuc3BvcnRUaW1lIHdpa2ldKGh0dHBzOi8vZ2l0aHViLmNvbS9Ub25lanMvVG9uZS5qcy93aWtpL1RyYW5zcG9ydFRpbWUpLlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zcG9ydFRpbWVDbGFzcyBleHRlbmRzIFRpbWVDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJhbnNwb3J0VGltZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBpbiB3aGljaGV2ZXIgY29udGV4dCBpcyByZWxldmFudFxuICAgICAqL1xuICAgIF9ub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHM7XG4gICAgfVxufVxuLyoqXG4gKiBUcmFuc3BvcnRUaW1lIGlzIGEgdGhlIHRpbWUgYWxvbmcgdGhlIFRyYW5zcG9ydCdzXG4gKiB0aW1lbGluZS4gSXQgaXMgc2ltaWxhciB0byBbW1RpbWVdXSwgYnV0IGluc3RlYWQgb2YgZXZhbHVhdGluZ1xuICogYWdhaW5zdCB0aGUgQXVkaW9Db250ZXh0J3MgY2xvY2ssIGl0IGlzIGV2YWx1YXRlZCBhZ2FpbnN0XG4gKiB0aGUgVHJhbnNwb3J0J3MgcG9zaXRpb24uIFNlZSBbVHJhbnNwb3J0VGltZSB3aWtpXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UcmFuc3BvcnRUaW1lKS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUcmFuc3BvcnRUaW1lKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydFRpbWUuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9GcmVxdWVuY3lcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpbWVcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCB7IGdldERlZmF1bHRzRnJvbUluc3RhbmNlLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0Jvb2xlYW4sIGlzRGVmaW5lZCwgaXNOdW1iZXIsIGlzU3RyaW5nLCBpc1VuZGVmIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRoZSBCYXNlIGNsYXNzIGZvciBhbGwgbm9kZXMgdGhhdCBoYXZlIGFuIEF1ZGlvQ29udGV4dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVXaXRoQ29udGV4dCBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY29udGV4dFwiXSk7XG4gICAgICAgIGlmICh0aGlzLmRlZmF1bHRDb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQgPSB0aGlzLmRlZmF1bHRDb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldENvbnRleHQoKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIENvbnRleHQgY2xvY2sgcGx1cyB0aGUgbG9va0FoZWFkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2coVG9uZS5ub3coKSk7XG4gICAgICogfSwgMTAwKTtcbiAgICAgKi9cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgKyB0aGlzLmNvbnRleHQubG9va0FoZWFkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBvZiB0aGUgQ29udGV4dCBjbG9jayB3aXRob3V0IGFueSBsb29rQWhlYWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICogXHRjb25zb2xlLmxvZyhUb25lLmltbWVkaWF0ZSgpKTtcbiAgICAgKiB9LCAxMDApO1xuICAgICAqL1xuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgb2Ygb25lIHNhbXBsZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuVHJhbnNwb3J0LnNhbXBsZVRpbWUpO1xuICAgICAqL1xuICAgIGdldCBzYW1wbGVUaW1lKCkge1xuICAgICAgICByZXR1cm4gMSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNlY29uZHMgb2YgMSBwcm9jZXNzaW5nIGJsb2NrICgxMjggc2FtcGxlcylcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuRGVzdGluYXRpb24uYmxvY2tUaW1lKTtcbiAgICAgKi9cbiAgICBnZXQgYmxvY2tUaW1lKCkge1xuICAgICAgICByZXR1cm4gMTI4IC8gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGluY29taW5nIHRpbWUgdG8gc2Vjb25kcy5cbiAgICAgKiBUaGlzIGlzIGNhbGN1bGF0ZWQgYWdhaW5zdCB0aGUgY3VycmVudCBbW1RvbmUuVHJhbnNwb3J0XV0gYnBtXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKGdhaW4udG9TZWNvbmRzKFwiNG5cIikpLCAxMDApO1xuICAgICAqIC8vIHJhbXAgdGhlIHRlbXBvIHRvIDYwIGJwbSBvdmVyIDMwIHNlY29uZHNcbiAgICAgKiBUb25lLmdldFRyYW5zcG9ydCgpLmJwbS5yYW1wVG8oNjAsIDMwKTtcbiAgICAgKi9cbiAgICB0b1NlY29uZHModGltZSkge1xuICAgICAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbnB1dCB0byBhIGZyZXF1ZW5jeSBudW1iZXJcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2coZ2Fpbi50b0ZyZXF1ZW5jeShcIjRuXCIpKTtcbiAgICAgKi9cbiAgICB0b0ZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHJldHVybiBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBmcmVxKS50b0ZyZXF1ZW5jeSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbnB1dCB0aW1lIGludG8gdGlja3NcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2coZ2Fpbi50b1RpY2tzKFwiNG5cIikpO1xuICAgICAqL1xuICAgIHRvVGlja3ModGltZSkge1xuICAgICAgICByZXR1cm4gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRHRVQvU0VUXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogR2V0IGEgc3Vic2V0IG9mIHRoZSBwcm9wZXJ0aWVzIHdoaWNoIGFyZSBpbiB0aGUgcGFydGlhbCBwcm9wc1xuICAgICAqL1xuICAgIF9nZXRQYXJ0aWFsUHJvcGVydGllcyhwcm9wcykge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5nZXQoKTtcbiAgICAgICAgLy8gcmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgcHJvcCB0aGF0IGFyZSBub3QgaW4gdGhlIHBhcnRpYWxcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChpc1VuZGVmKHByb3BzW25hbWVdKSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zW25hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgb2JqZWN0J3MgYXR0cmlidXRlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvc2MuZ2V0KCkpO1xuICAgICAqL1xuICAgIGdldCgpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSBnZXREZWZhdWx0c0Zyb21JbnN0YW5jZSh0aGlzKTtcbiAgICAgICAgT2JqZWN0LmtleXMoZGVmYXVsdHMpLmZvckVhY2goYXR0cmlidXRlID0+IHtcbiAgICAgICAgICAgIGlmIChSZWZsZWN0Lmhhcyh0aGlzLCBhdHRyaWJ1dGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyID0gdGhpc1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQobWVtYmVyKSAmJiBpc0RlZmluZWQobWVtYmVyLnZhbHVlKSAmJiBpc0RlZmluZWQobWVtYmVyLnNldFZhbHVlQXRUaW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0c1thdHRyaWJ1dGVdID0gbWVtYmVyLnZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChtZW1iZXIgaW5zdGFuY2VvZiBUb25lV2l0aENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlci5fZ2V0UGFydGlhbFByb3BlcnRpZXMoZGVmYXVsdHNbYXR0cmlidXRlXSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBtYWtlIHN1cmUgaXQncyBhIHNlcmlhbGl6YWJsZSB0eXBlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXkobWVtYmVyKSB8fCBpc051bWJlcihtZW1iZXIpIHx8IGlzU3RyaW5nKG1lbWJlcikgfHwgaXNCb29sZWFuKG1lbWJlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBhbGwgdW5kZWZpbmVkIGFuZCB1bnNlcmlhbGl6YWJsZSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBkZWZhdWx0c1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBkZWZhdWx0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IG11bHRpcGxlIHByb3BlcnRpZXMgYXQgb25jZSB3aXRoIGFuIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBzZXQgdmFsdWVzIHVzaW5nIGFuIG9iamVjdFxuICAgICAqIGZpbHRlci5zZXQoe1xuICAgICAqIFx0ZnJlcXVlbmN5OiBcIkM2XCIsXG4gICAgICogXHR0eXBlOiBcImhpZ2hwYXNzXCJcbiAgICAgKiB9KTtcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9BbmFsb2dzeW50aF9vY3RhdmVzX2hpZ2htaWQubXAzXCIpLmNvbm5lY3QoZmlsdGVyKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBzZXQocHJvcHMpIHtcbiAgICAgICAgT2JqZWN0LmtleXMocHJvcHMpLmZvckVhY2goYXR0cmlidXRlID0+IHtcbiAgICAgICAgICAgIGlmIChSZWZsZWN0Lmhhcyh0aGlzLCBhdHRyaWJ1dGUpICYmIGlzRGVmaW5lZCh0aGlzW2F0dHJpYnV0ZV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXNbYXR0cmlidXRlXSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdLnZhbHVlKSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdLnNldFZhbHVlQXRUaW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBzbWFsbCBvcHRpbWl6YXRpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNbYXR0cmlidXRlXS52YWx1ZSAhPT0gcHJvcHNbYXR0cmlidXRlXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyaWJ1dGVdLnZhbHVlID0gcHJvcHNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzW2F0dHJpYnV0ZV0gaW5zdGFuY2VvZiBUb25lV2l0aENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyaWJ1dGVdLnNldChwcm9wc1thdHRyaWJ1dGVdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbYXR0cmlidXRlXSA9IHByb3BzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZVdpdGhDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogQSBUaW1lbGluZSBTdGF0ZS4gUHJvdmlkZXMgdGhlIG1ldGhvZHM6IGBzZXRTdGF0ZUF0VGltZShcInN0YXRlXCIsIHRpbWUpYCBhbmQgYGdldFZhbHVlQXRUaW1lKHRpbWUpYFxuICogQHBhcmFtIGluaXRpYWwgVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIFN0YXRlVGltZWxpbmUuICBEZWZhdWx0cyB0byBgdW5kZWZpbmVkYFxuICovXG5leHBvcnQgY2xhc3MgU3RhdGVUaW1lbGluZSBleHRlbmRzIFRpbWVsaW5lIHtcbiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsID0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGF0ZVRpbWVsaW5lXCI7XG4gICAgICAgIHRoaXMuX2luaXRpYWwgPSBpbml0aWFsO1xuICAgICAgICB0aGlzLnNldFN0YXRlQXRUaW1lKHRoaXMuX2luaXRpYWwsIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgc2NoZWR1bGVkIGJlZm9yZSBvciBhdFxuICAgICAqIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybiAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuICAgICAqL1xuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLmdldCh0aW1lKTtcbiAgICAgICAgaWYgKGV2ZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBzdGF0ZSB0byB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgbmFtZSBvZiB0aGUgc3RhdGUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgQW55IGFkZGl0aW9uYWwgb3B0aW9ucyB0aGF0IGFyZSBuZWVkZWQgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIHNldFN0YXRlQXRUaW1lKHN0YXRlLCB0aW1lLCBvcHRpb25zKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHRpbWUsIDApO1xuICAgICAgICB0aGlzLmFkZChPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCB7XG4gICAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgICAgIHRpbWUsXG4gICAgICAgIH0pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZXZlbnQgYmVmb3JlIHRoZSB0aW1lIHdpdGggdGhlIGdpdmVuIHN0YXRlXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgc3RhdGUgdG8gbG9vayBmb3JcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gY2hlY2sgYmVmb3JlXG4gICAgICogQHJldHVybiAgVGhlIGV2ZW50IHdpdGggdGhlIGdpdmVuIHN0YXRlIGJlZm9yZSB0aGUgdGltZVxuICAgICAqL1xuICAgIGdldExhc3RTdGF0ZShzdGF0ZSwgdGltZSkge1xuICAgICAgICAvLyB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXRlID09PSBzdGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBldmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGV2ZW50IGFmdGVyIHRoZSB0aW1lIHdpdGggdGhlIGdpdmVuIHN0YXRlXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgc3RhdGUgdG8gbG9vayBmb3JcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gY2hlY2sgZnJvbVxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aXRoIHRoZSBnaXZlbiBzdGF0ZSBhZnRlciB0aGUgdGltZVxuICAgICAqL1xuICAgIGdldE5leHRTdGF0ZShzdGF0ZSwgdGltZSkge1xuICAgICAgICAvLyB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPCB0aGlzLl90aW1lbGluZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXRlID09PSBzdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RhdGVUaW1lbGluZS5qcy5tYXAiLCJpbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4vVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBFUSB9IGZyb20gXCIuLi91dGlsL01hdGhcIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBQYXJhbSB3cmFwcyB0aGUgbmF0aXZlIFdlYiBBdWRpbydzIEF1ZGlvUGFyYW0gdG8gcHJvdmlkZVxuICogYWRkaXRpb25hbCB1bml0IGNvbnZlcnNpb24gZnVuY3Rpb25hbGl0eS4gSXQgYWxzb1xuICogc2VydmVzIGFzIGEgYmFzZS1jbGFzcyBmb3IgY2xhc3NlcyB3aGljaCBoYXZlIGEgc2luZ2xlLFxuICogYXV0b21hdGFibGUgcGFyYW1ldGVyLlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFBhcmFtIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYXJhbVwiLCBcInVuaXRzXCIsIFwiY29udmVydFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhcmFtXCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGRlbiA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9taW5PdXRwdXQgPSAxZS03O1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYXJhbVwiLCBcInVuaXRzXCIsIFwiY29udmVydFwiXSk7XG4gICAgICAgIGFzc2VydChpc0RlZmluZWQob3B0aW9ucy5wYXJhbSkgJiZcbiAgICAgICAgICAgIChpc0F1ZGlvUGFyYW0ob3B0aW9ucy5wYXJhbSkgfHwgb3B0aW9ucy5wYXJhbSBpbnN0YW5jZW9mIFBhcmFtKSwgXCJwYXJhbSBtdXN0IGJlIGFuIEF1ZGlvUGFyYW1cIik7XG4gICAgICAgIHdoaWxlICghaXNBdWRpb1BhcmFtKG9wdGlvbnMucGFyYW0pKSB7XG4gICAgICAgICAgICBvcHRpb25zLnBhcmFtID0gb3B0aW9ucy5wYXJhbS5fcGFyYW07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3dhcHBhYmxlID0gaXNEZWZpbmVkKG9wdGlvbnMuc3dhcHBhYmxlKSA/IG9wdGlvbnMuc3dhcHBhYmxlIDogZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9zd2FwcGFibGUpIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZVxuICAgICAgICAgICAgdGhpcy5fcGFyYW0gPSBvcHRpb25zLnBhcmFtO1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3BhcmFtKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtID0gdGhpcy5pbnB1dCA9IG9wdGlvbnMucGFyYW07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFRpbWVsaW5lKDEwMDApO1xuICAgICAgICB0aGlzLl9pbml0aWFsVmFsdWUgPSB0aGlzLl9wYXJhbS5kZWZhdWx0VmFsdWU7XG4gICAgICAgIHRoaXMudW5pdHMgPSBvcHRpb25zLnVuaXRzO1xuICAgICAgICB0aGlzLmNvbnZlcnQgPSBvcHRpb25zLmNvbnZlcnQ7XG4gICAgICAgIHRoaXMuX21pblZhbHVlID0gb3B0aW9ucy5taW5WYWx1ZTtcbiAgICAgICAgdGhpcy5fbWF4VmFsdWUgPSBvcHRpb25zLm1heFZhbHVlO1xuICAgICAgICAvLyBpZiB0aGUgdmFsdWUgaXMgZGVmaW5lZCwgc2V0IGl0IGltbWVkaWF0ZWx5XG4gICAgICAgIGlmIChpc0RlZmluZWQob3B0aW9ucy52YWx1ZSkgJiYgb3B0aW9ucy52YWx1ZSAhPT0gdGhpcy5fdG9UeXBlKHRoaXMuX2luaXRpYWxWYWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZUF0VGltZShub3cpO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGhpcy5ub3coKSk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgIC8vIGlmIGl0J3Mgbm90IHRoZSBkZWZhdWx0IG1pblZhbHVlLCByZXR1cm4gaXRcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLl9taW5WYWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9taW5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcInRpbWVcIiB8fCB0aGlzLnVuaXRzID09PSBcImZyZXF1ZW5jeVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcIm5vcm1hbFJhbmdlXCIgfHwgdGhpcy51bml0cyA9PT0gXCJwb3NpdGl2ZVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcInRyYW5zcG9ydFRpbWVcIiB8fCB0aGlzLnVuaXRzID09PSBcInRpY2tzXCIgfHxcbiAgICAgICAgICAgIHRoaXMudW5pdHMgPT09IFwiYnBtXCIgfHwgdGhpcy51bml0cyA9PT0gXCJoZXJ0elwiIHx8IHRoaXMudW5pdHMgPT09IFwic2FtcGxlc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcImF1ZGlvUmFuZ2VcIikge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFwiZGVjaWJlbHNcIikge1xuICAgICAgICAgICAgcmV0dXJuIC1JbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5taW5WYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fbWF4VmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWF4VmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJub3JtYWxSYW5nZVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcImF1ZGlvUmFuZ2VcIikge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWF4VmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVHlwZSBndWFyZCBiYXNlZCBvbiB0aGUgdW5pdCBuYW1lXG4gICAgICovXG4gICAgX2lzKGFyZywgdHlwZSkge1xuICAgICAgICByZXR1cm4gdGhpcy51bml0cyA9PT0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWFrZSBzdXJlIHRoZSB2YWx1ZSBpcyBhbHdheXMgaW4gdGhlIGRlZmluZWQgcmFuZ2VcbiAgICAgKi9cbiAgICBfYXNzZXJ0UmFuZ2UodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm1heFZhbHVlKSAmJiBpc0RlZmluZWQodGhpcy5taW5WYWx1ZSkpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHZhbHVlLCB0aGlzLl9mcm9tVHlwZSh0aGlzLm1pblZhbHVlKSwgdGhpcy5fZnJvbVR5cGUodGhpcy5tYXhWYWx1ZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgZ2l2ZW4gdmFsdWUgZnJvbSB0aGUgdHlwZSBzcGVjaWZpZWQgYnkgUGFyYW0udW5pdHNcbiAgICAgKiBpbnRvIHRoZSBkZXN0aW5hdGlvbiB2YWx1ZSAoc3VjaCBhcyBHYWluIG9yIEZyZXF1ZW5jeSkuXG4gICAgICovXG4gICAgX2Zyb21UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy5jb252ZXJ0ICYmICF0aGlzLm92ZXJyaWRkZW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pcyh2YWwsIFwidGltZVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcyh2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faXModmFsLCBcImRlY2liZWxzXCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRiVG9HYWluKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9pcyh2YWwsIFwiZnJlcXVlbmN5XCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9GcmVxdWVuY3kodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5vdmVycmlkZGVuKSB7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIG92ZXJyaWRkZW4sIHNob3VsZCBvbmx5IHNjaGVkdWxlIDBzXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgcGFyYW1ldGVycyB2YWx1ZSBpbnRvIHRoZSB1bml0cyBzcGVjaWZpZWQgYnkgUGFyYW0udW5pdHMuXG4gICAgICovXG4gICAgX3RvVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udmVydCAmJiB0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBnYWluVG9EYih2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBQlNUUkFDVCBQQVJBTSBJTlRFUkZBQ0VcbiAgICAvLyBhbGwgZG9jcyBhcmUgZ2VuZXJhdGVkIGZyb20gUGFyYW1JbnRlcmZhY2UudHNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBzZXRWYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KHRpbWUpfWApO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcInNldFZhbHVlQXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IE1hdGgubWF4KHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwKTtcbiAgICAgICAgY29uc3QgYWZ0ZXIgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIC8vIGlmIGl0IHdhcyBzZXQgYnlcbiAgICAgICAgaWYgKGJlZm9yZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIgJiYgKGFmdGVyID09PSBudWxsIHx8IGFmdGVyLnR5cGUgPT09IFwic2V0VmFsdWVBdFRpbWVcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy5fZXZlbnRzLmdldEJlZm9yZShiZWZvcmUudGltZSk7XG4gICAgICAgICAgICBsZXQgcHJldmlvdXNWYWw7XG4gICAgICAgICAgICBpZiAocHJldmlvdXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1ZhbCA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzVmFsID0gcHJldmlvdXMudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2V4cG9uZW50aWFsQXBwcm9hY2goYmVmb3JlLnRpbWUsIHByZXZpb3VzVmFsLCBiZWZvcmUudmFsdWUsIGJlZm9yZS5jb25zdGFudCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhZnRlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiIHx8IGFmdGVyLnR5cGUgPT09IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICBsZXQgYmVmb3JlVmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuX2V2ZW50cy5nZXRCZWZvcmUoYmVmb3JlLnRpbWUpO1xuICAgICAgICAgICAgICAgIGlmIChwcmV2aW91cyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBiZWZvcmVWYWx1ZSA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZVZhbHVlID0gcHJldmlvdXMudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fbGluZWFySW50ZXJwb2xhdGUoYmVmb3JlLnRpbWUsIGJlZm9yZVZhbHVlLCBhZnRlci50aW1lLCBhZnRlci52YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fZXhwb25lbnRpYWxJbnRlcnBvbGF0ZShiZWZvcmUudGltZSwgYmVmb3JlVmFsdWUsIGFmdGVyLnRpbWUsIGFmdGVyLnZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh2YWx1ZSk7XG4gICAgfVxuICAgIHNldFJhbXBQb2ludCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWYWwgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9mcm9tVHlwZShjdXJyZW50VmFsKSA9PT0gMCkge1xuICAgICAgICAgICAgY3VycmVudFZhbCA9IHRoaXMuX3RvVHlwZSh0aGlzLl9taW5PdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUoY3VycmVudFZhbCwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKGVuZFRpbWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KGVuZFRpbWUpfWApO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICAgIGxldCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIHRoZSB2YWx1ZSBjYW4ndCBiZSAwXG4gICAgICAgIG51bWVyaWNWYWx1ZSA9IEVRKG51bWVyaWNWYWx1ZSwgMCkgPyB0aGlzLl9taW5PdXRwdXQgOiBudW1lcmljVmFsdWU7XG4gICAgICAgIHRoaXMuX2Fzc2VydFJhbmdlKG51bWVyaWNWYWx1ZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKGVuZFRpbWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0sICR7SlNPTi5zdHJpbmdpZnkoZW5kVGltZSl9YCk7XG4gICAgICAgIC8vIHN0b3JlIHRoZSBldmVudFxuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSArIHRoaXMudG9TZWNvbmRzKHJhbXBUaW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lICsgdGhpcy50b1NlY29uZHMocmFtcFRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCByYW1wVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUsIHJhbXBUaW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmFtcFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSk7XG4gICAgICAgIGNvbnN0IHRpbWVDb25zdGFudCA9IE1hdGgubG9nKHJhbXBUaW1lICsgMSkgLyBNYXRoLmxvZygyMDApO1xuICAgICAgICB0aGlzLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgdGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgLy8gYXQgOTAlIHN0YXJ0IGEgbGluZWFyIHJhbXAgdG8gdGhlIGZpbmFsIHZhbHVlXG4gICAgICAgIHRoaXMuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lICsgcmFtcFRpbWUgKiAwLjkpO1xuICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lICsgcmFtcFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIFRoZSB2YWx1ZSB3aWxsIG5ldmVyIGJlIGFibGUgdG8gYXBwcm9hY2ggd2l0aG91dCB0aW1lQ29uc3RhbnQgPiAwLlxuICAgICAgICBhc3NlcnQoaXNGaW5pdGUodGltZUNvbnN0YW50KSAmJiB0aW1lQ29uc3RhbnQgPiAwLCBcInRpbWVDb25zdGFudCBtdXN0IGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwXCIpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBzZXRUYXJnZXRBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeShzdGFydFRpbWUpfWApO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIGNvbnN0YW50OiB0aW1lQ29uc3RhbnQsXG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcInNldFRhcmdldEF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwic2V0VGFyZ2V0QXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFRhcmdldEF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nID0gMSkge1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgY29uc3Qgc3RhcnRpbmdWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlc1swXSkgKiBzY2FsaW5nO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShzdGFydGluZ1ZhbHVlKSwgc3RhcnRUaW1lKTtcbiAgICAgICAgY29uc3Qgc2VnVGltZSA9IGR1cmF0aW9uIC8gKHZhbHVlcy5sZW5ndGggLSAxKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlc1tpXSkgKiBzY2FsaW5nO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUobnVtZXJpY1ZhbHVlKSwgc3RhcnRUaW1lICsgaSAqIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50IHRvIGNhbmNlbFNjaGVkdWxlZFZhbHVlczogJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJjYW5jZWxTY2hlZHVsZWRWYWx1ZXNcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgdmFsdWVBdFRpbWUgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkpO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHNjaGVkdWxlIGV2ZW50c1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQgdG8gY2FuY2VsQW5kSG9sZEF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJjYW5jZWxBbmRIb2xkQXRUaW1lXCIsIGNvbXB1dGVkVGltZSwgXCJ2YWx1ZT1cIiArIHZhbHVlQXRUaW1lKTtcbiAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gZXZlbnQgYXQgdGhlIGdpdmVuIGNvbXB1dGVkVGltZVxuICAgICAgICAvLyBhbmQgdGhhdCBldmVuIGlzIG5vdCBhIFwic2V0XCJcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcihjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAoYmVmb3JlICYmIEVRKGJlZm9yZS50aW1lLCBjb21wdXRlZFRpbWUpKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgZXZlcnl0aGluZyBhZnRlclxuICAgICAgICAgICAgaWYgKGFmdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChjb21wdXRlZFRpbWUgKyB0aGlzLnNhbXBsZVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGFmdGVyKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICAvLyBjYW5jZWwgdGhlIG5leHQgZXZlbnQocylcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUodmFsdWVBdFRpbWUpLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHZhbHVlQXRUaW1lKSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlQXRUaW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWVBdFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICByYW1wVG8odmFsdWUsIHJhbXBUaW1lID0gMC4xLCBzdGFydFRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiZnJlcXVlbmN5XCIgfHwgdGhpcy51bml0cyA9PT0gXCJicG1cIiB8fCB0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHRoaXMuZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcHBseSBhbGwgb2YgdGhlIHByZXZpb3VzbHkgc2NoZWR1bGVkIGV2ZW50cyB0byB0aGUgcGFzc2VkIGluIFBhcmFtIG9yIEF1ZGlvUGFyYW0uXG4gICAgICogVGhlIGFwcGxpZWQgdmFsdWVzIHdpbGwgc3RhcnQgYXQgdGhlIGNvbnRleHQncyBjdXJyZW50IHRpbWUgYW5kIHNjaGVkdWxlXG4gICAgICogYWxsIG9mIHRoZSBldmVudHMgd2hpY2ggYXJlIHNjaGVkdWxlZCBvbiB0aGlzIFBhcmFtIG9udG8gdGhlIHBhc3NlZCBpbiBwYXJhbS5cbiAgICAgKi9cbiAgICBhcHBseShwYXJhbSkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIC8vIHNldCB0aGUgcGFyYW0ncyB2YWx1ZSBhdCB0aGUgY3VycmVudCB0aW1lIGFuZCBzY2hlZHVsZSBldmVyeXRoaW5nIGVsc2VcbiAgICAgICAgcGFyYW0uc2V0VmFsdWVBdFRpbWUodGhpcy5nZXRWYWx1ZUF0VGltZShub3cpLCBub3cpO1xuICAgICAgICAvLyBpZiB0aGUgcHJldmlvdXMgZXZlbnQgd2FzIGEgY3VydmUsIHRoZW4gc2V0IHRoZSByZXN0IG9mIGl0XG4gICAgICAgIGNvbnN0IHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KG5vdyk7XG4gICAgICAgIGlmIChwcmV2aW91c0V2ZW50ICYmIHByZXZpb3VzRXZlbnQudHlwZSA9PT0gXCJzZXRUYXJnZXRBdFRpbWVcIikge1xuICAgICAgICAgICAgLy8gYXBwcm94IGl0IHVudGlsIHRoZSBuZXh0IGV2ZW50IHdpdGggbGluZWFyIHJhbXBzXG4gICAgICAgICAgICBjb25zdCBuZXh0RXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIocHJldmlvdXNFdmVudC50aW1lKTtcbiAgICAgICAgICAgIC8vIG9yIGZvciAyIHNlY29uZHMgaWYgdGhlcmUgaXMgbm8gZXZlbnRcbiAgICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBuZXh0RXZlbnQgPyBuZXh0RXZlbnQudGltZSA6IG5vdyArIDI7XG4gICAgICAgICAgICBjb25zdCBzdWJkaXZpc2lvbnMgPSAoZW5kVGltZSAtIG5vdykgLyAxMDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBub3c7IGkgPCBlbmRUaW1lOyBpICs9IHN1YmRpdmlzaW9ucykge1xuICAgICAgICAgICAgICAgIHBhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuZ2V0VmFsdWVBdFRpbWUoaSksIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2V2ZW50cy5mb3JFYWNoQWZ0ZXIodGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJjYW5jZWxTY2hlZHVsZWRWYWx1ZXNcIikge1xuICAgICAgICAgICAgICAgIHBhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhldmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICBwYXJhbS5zZXRUYXJnZXRBdFRpbWUoZXZlbnQudmFsdWUsIGV2ZW50LnRpbWUsIGV2ZW50LmNvbnN0YW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtW2V2ZW50LnR5cGVdKGV2ZW50LnZhbHVlLCBldmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlIHRoZSBQYXJhbSdzIGludGVybmFsIEF1ZGlvUGFyYW0uIFdpbGwgYXBwbHkgc2NoZWR1bGVkIGN1cnZlc1xuICAgICAqIG9udG8gdGhlIHBhcmFtZXRlciBhbmQgcmVwbGFjZSB0aGUgY29ubmVjdGlvbnMuXG4gICAgICovXG4gICAgc2V0UGFyYW0ocGFyYW0pIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N3YXBwYWJsZSwgXCJUaGUgUGFyYW0gbXVzdCBiZSBhc3NpZ25lZCBhcyAnc3dhcHBhYmxlJyBpbiB0aGUgY29uc3RydWN0b3JcIik7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gdGhpcy5pbnB1dDtcbiAgICAgICAgaW5wdXQuZGlzY29ubmVjdCh0aGlzLl9wYXJhbSk7XG4gICAgICAgIHRoaXMuYXBwbHkocGFyYW0pO1xuICAgICAgICB0aGlzLl9wYXJhbSA9IHBhcmFtO1xuICAgICAgICBpbnB1dC5jb25uZWN0KHRoaXMuX3BhcmFtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCBkZWZhdWx0VmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodGhpcy5fcGFyYW0uZGVmYXVsdFZhbHVlKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRBVVRPTUFUSU9OIENVUlZFIENBTENVTEFUSU9OU1xuICAgIC8vIFx0TUlUIExpY2Vuc2UsIGNvcHlyaWdodCAoYykgMjAxNCBKb3JkYW4gU2FudGVsbFxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgc2V0VGFyZ2V0QXRUaW1lXG4gICAgX2V4cG9uZW50aWFsQXBwcm9hY2godDAsIHYwLCB2MSwgdGltZUNvbnN0YW50LCB0KSB7XG4gICAgICAgIHJldHVybiB2MSArICh2MCAtIHYxKSAqIE1hdGguZXhwKC0odCAtIHQwKSAvIHRpbWVDb25zdGFudCk7XG4gICAgfVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcbiAgICBfbGluZWFySW50ZXJwb2xhdGUodDAsIHYwLCB0MSwgdjEsIHQpIHtcbiAgICAgICAgcmV0dXJuIHYwICsgKHYxIC0gdjApICogKCh0IC0gdDApIC8gKHQxIC0gdDApKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlcyB0aGUgdGhlIHZhbHVlIGFsb25nIHRoZSBjdXJ2ZSBwcm9kdWNlZCBieSBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXG4gICAgX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUodDAsIHYwLCB0MSwgdjEsIHQpIHtcbiAgICAgICAgcmV0dXJuIHYwICogTWF0aC5wb3codjEgLyB2MCwgKHQgLSB0MCkgLyAodDEgLSB0MCkpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlLCBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuL1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCwgd2FybiB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFRvbmVBdWRpb05vZGUgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGNsYXNzZXMgd2hpY2ggcHJvY2VzcyBhdWRpby5cbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb05vZGUgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGNsYXNzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb05vZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIExpc3QgYWxsIG9mIHRoZSBub2RlIHRoYXQgbXVzdCBiZSBzZXQgdG8gbWF0Y2ggdGhlIENoYW5uZWxQcm9wZXJ0aWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW5wdXRzIGZlZWRpbmcgaW50byB0aGUgQXVkaW9Ob2RlLlxuICAgICAqIEZvciBzb3VyY2Ugbm9kZXMsIHRoaXMgd2lsbCBiZSAwLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9kZSA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhub2RlLm51bWJlck9mSW5wdXRzKTtcbiAgICAgKi9cbiAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5pbnB1dCkpIHtcbiAgICAgICAgICAgIGlmIChpc0F1ZGlvUGFyYW0odGhpcy5pbnB1dCkgfHwgdGhpcy5pbnB1dCBpbnN0YW5jZW9mIFBhcmFtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbnB1dC5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb3V0cHV0cyBvZiB0aGUgQXVkaW9Ob2RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9kZSA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhub2RlLm51bWJlck9mT3V0cHV0cyk7XG4gICAgICovXG4gICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dC5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBVURJTyBQUk9QRVJUSUVTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVXNlZCB0byBkZWNpZGUgd2hpY2ggbm9kZXMgdG8gZ2V0L3NldCBwcm9wZXJ0aWVzIG9uXG4gICAgICovXG4gICAgX2lzQXVkaW9Ob2RlKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIGlzRGVmaW5lZChub2RlKSAmJiAobm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUgfHwgaXNBdWRpb05vZGUobm9kZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIG9mIHRoZSBhdWRpbyBub2RlcyAoZWl0aGVyIGludGVybmFsIG9yIGlucHV0L291dHB1dCkgd2hpY2ggdG9nZXRoZXJcbiAgICAgKiBtYWtlIHVwIGhvdyB0aGUgY2xhc3Mgbm9kZSByZXNwb25kcyB0byBjaGFubmVsIGlucHV0L291dHB1dFxuICAgICAqL1xuICAgIF9nZXRJbnRlcm5hbE5vZGVzKCkge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IHRoaXMuX2ludGVybmFsQ2hhbm5lbHMuc2xpY2UoMCk7XG4gICAgICAgIGlmICh0aGlzLl9pc0F1ZGlvTm9kZSh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgbm9kZUxpc3QucHVzaCh0aGlzLmlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5faXNBdWRpb05vZGUodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dCAhPT0gdGhpcy5vdXRwdXQpIHtcbiAgICAgICAgICAgICAgICBub2RlTGlzdC5wdXNoKHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9kZUxpc3Q7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXVkaW8gb3B0aW9ucyBmb3IgdGhpcyBub2RlIHN1Y2ggYXMgY2hhbm5lbEludGVycHJldGF0aW9uXG4gICAgICogY2hhbm5lbENvdW50LCBldGMuXG4gICAgICogQHBhcmFtIG9wdGlvbnNcbiAgICAgKi9cbiAgICBfc2V0Q2hhbm5lbFByb3BlcnRpZXMob3B0aW9ucykge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IHRoaXMuX2dldEludGVybmFsTm9kZXMoKTtcbiAgICAgICAgbm9kZUxpc3QuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgIG5vZGUuY2hhbm5lbENvdW50ID0gb3B0aW9ucy5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxDb3VudE1vZGUgPSBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IGF1ZGlvIG9wdGlvbnMgZm9yIHRoaXMgbm9kZSBzdWNoIGFzIGNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAqIGNoYW5uZWxDb3VudCwgZXRjLlxuICAgICAqL1xuICAgIF9nZXRDaGFubmVsUHJvcGVydGllcygpIHtcbiAgICAgICAgY29uc3Qgbm9kZUxpc3QgPSB0aGlzLl9nZXRJbnRlcm5hbE5vZGVzKCk7XG4gICAgICAgIGFzc2VydChub2RlTGlzdC5sZW5ndGggPiAwLCBcIlRvbmVBdWRpb05vZGUgZG9lcyBub3QgaGF2ZSBhbnkgaW50ZXJuYWwgbm9kZXNcIik7XG4gICAgICAgIC8vIHVzZSB0aGUgZmlyc3Qgbm9kZSB0byBnZXQgcHJvcGVydGllc1xuICAgICAgICAvLyB0aGV5IHNob3VsZCBhbGwgYmUgdGhlIHNhbWVcbiAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVMaXN0WzBdO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBub2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNoYW5uZWxDb3VudCBpcyB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIHVzZWQgd2hlbiB1cC1taXhpbmcgYW5kIGRvd24tbWl4aW5nXG4gICAgICogY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgMiBleGNlcHQgZm9yXG4gICAgICogc3BlY2lmaWMgbm9kZXMgd2hlcmUgaXRzIHZhbHVlIGlzIHNwZWNpYWxseSBkZXRlcm1pbmVkLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpLmNoYW5uZWxDb3VudDtcbiAgICB9XG4gICAgc2V0IGNoYW5uZWxDb3VudChjaGFubmVsQ291bnQpIHtcbiAgICAgICAgY29uc3QgcHJvcHMgPSB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpO1xuICAgICAgICAvLyBtZXJnZSBpdCB3aXRoIHRoZSBvdGhlciBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuX3NldENoYW5uZWxQcm9wZXJ0aWVzKE9iamVjdC5hc3NpZ24ocHJvcHMsIHsgY2hhbm5lbENvdW50IH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhbm5lbENvdW50TW9kZSBkZXRlcm1pbmVzIGhvdyBjaGFubmVscyB3aWxsIGJlIGNvdW50ZWQgd2hlbiB1cC1taXhpbmcgYW5kXG4gICAgICogZG93bi1taXhpbmcgY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcIm1heFwiLiBUaGlzIGF0dHJpYnV0ZSBoYXMgbm8gZWZmZWN0IGZvciBub2RlcyB3aXRoIG5vIGlucHV0cy5cbiAgICAgKiAqIFwibWF4XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgdGhlIG1heGltdW0gb2YgdGhlIG51bWJlciBvZiBjaGFubmVscyBvZiBhbGwgY29ubmVjdGlvbnMgdG8gYW4gaW5wdXQuIEluIHRoaXMgbW9kZSBjaGFubmVsQ291bnQgaXMgaWdub3JlZC5cbiAgICAgKiAqIFwiY2xhbXBlZC1tYXhcIiAtIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyBkZXRlcm1pbmVkIGFzIGZvciBcIm1heFwiIGFuZCB0aGVuIGNsYW1wZWQgdG8gYSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBnaXZlbiBjaGFubmVsQ291bnQuXG4gICAgICogKiBcImV4cGxpY2l0XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgdGhlIGV4YWN0IHZhbHVlIGFzIHNwZWNpZmllZCBieSB0aGUgY2hhbm5lbENvdW50LlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKS5jaGFubmVsQ291bnRNb2RlO1xuICAgIH1cbiAgICBzZXQgY2hhbm5lbENvdW50TW9kZShjaGFubmVsQ291bnRNb2RlKSB7XG4gICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKTtcbiAgICAgICAgLy8gbWVyZ2UgaXQgd2l0aCB0aGUgb3RoZXIgcHJvcGVydGllc1xuICAgICAgICB0aGlzLl9zZXRDaGFubmVsUHJvcGVydGllcyhPYmplY3QuYXNzaWduKHByb3BzLCB7IGNoYW5uZWxDb3VudE1vZGUgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFubmVsSW50ZXJwcmV0YXRpb24gZGV0ZXJtaW5lcyBob3cgaW5kaXZpZHVhbCBjaGFubmVscyB3aWxsIGJlIHRyZWF0ZWRcbiAgICAgKiB3aGVuIHVwLW1peGluZyBhbmQgZG93bi1taXhpbmcgY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcInNwZWFrZXJzXCIuXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCkuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgIH1cbiAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKGNoYW5uZWxJbnRlcnByZXRhdGlvbikge1xuICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCk7XG4gICAgICAgIC8vIG1lcmdlIGl0IHdpdGggdGhlIG90aGVyIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5fc2V0Q2hhbm5lbFByb3BlcnRpZXMoT2JqZWN0LmFzc2lnbihwcm9wcywgeyBjaGFubmVsSW50ZXJwcmV0YXRpb24gfSkpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDT05ORUNUSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG91dHB1dCBvZiBhIFRvbmVBdWRpb05vZGUgdG8gYW4gQXVkaW9QYXJhbSwgQXVkaW9Ob2RlLCBvciBUb25lQXVkaW9Ob2RlXG4gICAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFRoZSBvdXRwdXQgdG8gY29ubmVjdCB0b1xuICAgICAqIEBwYXJhbSBvdXRwdXROdW0gVGhlIG91dHB1dCB0byBjb25uZWN0IGZyb21cbiAgICAgKiBAcGFyYW0gaW5wdXROdW0gVGhlIGlucHV0IHRvIGNvbm5lY3QgdG9cbiAgICAgKi9cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgY29ubmVjdCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBvdXRwdXQgdG8gdGhlIGNvbnRleHQncyBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcihcIkMyXCIpLnN0YXJ0KCk7XG4gICAgICogb3NjLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKi9cbiAgICB0b0Rlc3RpbmF0aW9uKCkge1xuICAgICAgICB0aGlzLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIG91dHB1dCB0byB0aGUgY29udGV4dCdzIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICogU2VlIFtbdG9EZXN0aW5hdGlvbl1dXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICB0b01hc3RlcigpIHtcbiAgICAgICAgd2FybihcInRvTWFzdGVyKCkgaGFzIGJlZW4gcmVuYW1lZCB0b0Rlc3RpbmF0aW9uKClcIik7XG4gICAgICAgIHJldHVybiB0aGlzLnRvRGVzdGluYXRpb24oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZGlzY29ubmVjdCB0aGUgb3V0cHV0XG4gICAgICovXG4gICAgZGlzY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGRpc2Nvbm5lY3QodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSB0byB0aGUgcmVzdCBvZiB0aGUgbm9kZXMgaW4gc2VyaWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9oYW5kZHJ1bS1sb29wLm1wM1wiKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKDQpLnN0YXJ0KCk7XG4gICAgICogY29uc3QgZGlzdG9ydGlvbiA9IG5ldyBUb25lLkRpc3RvcnRpb24oMC41KTtcbiAgICAgKiAvLyBjb25uZWN0IHRoZSBwbGF5ZXIgdG8gdGhlIGZpbHRlciwgZGlzdG9ydGlvbiBhbmQgdGhlbiB0byB0aGUgbWFzdGVyIG91dHB1dFxuICAgICAqIHBsYXllci5jaGFpbihmaWx0ZXIsIGRpc3RvcnRpb24sIFRvbmUuRGVzdGluYXRpb24pO1xuICAgICAqL1xuICAgIGNoYWluKC4uLm5vZGVzKSB7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcywgLi4ubm9kZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSB0byB0aGUgcmVzdCBvZiB0aGUgbm9kZXMgaW4gcGFyYWxsZWwuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vZHJ1bS1zYW1wbGVzL2NvbmdhLXJoeXRobS5tcDNcIik7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogY29uc3QgcGl0Y2hTaGlmdCA9IG5ldyBUb25lLlBpdGNoU2hpZnQoNCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcihcIkc1XCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBjb25uZWN0IGEgbm9kZSB0byB0aGUgcGl0Y2ggc2hpZnQgYW5kIGZpbHRlciBpbiBwYXJhbGxlbFxuICAgICAqIHBsYXllci5mYW4ocGl0Y2hTaGlmdCwgZmlsdGVyKTtcbiAgICAgKi9cbiAgICBmYW4oLi4ubm9kZXMpIHtcbiAgICAgICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHRoaXMuY29ubmVjdChub2RlKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEaXNwb3NlIGFuZCBkaXNjb25uZWN0XG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dCBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm91dHB1dCBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0F1ZGlvTm9kZSh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFtdO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIENPTk5FQ1RJT05TXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogY29ubmVjdCB0b2dldGhlciBhbGwgb2YgdGhlIGFyZ3VtZW50cyBpbiBzZXJpZXNcbiAqIEBwYXJhbSBub2Rlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdFNlcmllcyguLi5ub2Rlcykge1xuICAgIGNvbnN0IGZpcnN0ID0gbm9kZXMuc2hpZnQoKTtcbiAgICBub2Rlcy5yZWR1Y2UoKHByZXYsIGN1cnJlbnQpID0+IHtcbiAgICAgICAgaWYgKHByZXYgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICBwcmV2LmNvbm5lY3QoY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNBdWRpb05vZGUocHJldikpIHtcbiAgICAgICAgICAgIGNvbm5lY3QocHJldiwgY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGN1cnJlbnQ7XG4gICAgfSwgZmlyc3QpO1xufVxuLyoqXG4gKiBDb25uZWN0IHR3byBub2RlcyB0b2dldGhlciBzbyB0aGF0IHNpZ25hbCBmbG93cyBmcm9tIHRoZVxuICogZmlyc3Qgbm9kZSB0byB0aGUgc2Vjb25kLiBPcHRpb25hbGx5IHNwZWNpZnkgdGhlIGlucHV0IGFuZCBvdXRwdXQgY2hhbm5lbHMuXG4gKiBAcGFyYW0gc3JjTm9kZSBUaGUgc291cmNlIG5vZGVcbiAqIEBwYXJhbSBkc3ROb2RlIFRoZSBkZXN0aW5hdGlvbiBub2RlXG4gKiBAcGFyYW0gb3V0cHV0TnVtYmVyIFRoZSBvdXRwdXQgY2hhbm5lbCBvZiB0aGUgc3JjTm9kZVxuICogQHBhcmFtIGlucHV0TnVtYmVyIFRoZSBpbnB1dCBjaGFubmVsIG9mIHRoZSBkc3ROb2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0KHNyY05vZGUsIGRzdE5vZGUsIG91dHB1dE51bWJlciA9IDAsIGlucHV0TnVtYmVyID0gMCkge1xuICAgIGFzc2VydChpc0RlZmluZWQoc3JjTm9kZSksIFwiQ2Fubm90IGNvbm5lY3QgZnJvbSB1bmRlZmluZWQgbm9kZVwiKTtcbiAgICBhc3NlcnQoaXNEZWZpbmVkKGRzdE5vZGUpLCBcIkNhbm5vdCBjb25uZWN0IHRvIHVuZGVmaW5lZCBub2RlXCIpO1xuICAgIGlmIChkc3ROb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSB8fCBpc0F1ZGlvTm9kZShkc3ROb2RlKSkge1xuICAgICAgICBhc3NlcnQoZHN0Tm9kZS5udW1iZXJPZklucHV0cyA+IDAsIFwiQ2Fubm90IGNvbm5lY3QgdG8gbm9kZSB3aXRoIG5vIGlucHV0c1wiKTtcbiAgICB9XG4gICAgYXNzZXJ0KHNyY05vZGUubnVtYmVyT2ZPdXRwdXRzID4gMCwgXCJDYW5ub3QgY29ubmVjdCBmcm9tIG5vZGUgd2l0aCBubyBvdXRwdXRzXCIpO1xuICAgIC8vIHJlc29sdmUgdGhlIGlucHV0IG9mIHRoZSBkc3ROb2RlXG4gICAgd2hpbGUgKChkc3ROb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSB8fCBkc3ROb2RlIGluc3RhbmNlb2YgUGFyYW0pKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQoZHN0Tm9kZS5pbnB1dCkpIHtcbiAgICAgICAgICAgIGRzdE5vZGUgPSBkc3ROb2RlLmlucHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHdoaWxlIChzcmNOb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHNyY05vZGUub3V0cHV0KSkge1xuICAgICAgICAgICAgc3JjTm9kZSA9IHNyY05vZGUub3V0cHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIG1ha2UgdGhlIGNvbm5lY3Rpb25cbiAgICBpZiAoaXNBdWRpb1BhcmFtKGRzdE5vZGUpKSB7XG4gICAgICAgIHNyY05vZGUuY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3JjTm9kZS5jb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgIH1cbn1cbi8qKlxuICogRGlzY29ubmVjdCBhIG5vZGUgZnJvbSBhbGwgbm9kZXMgb3Igb3B0aW9uYWxseSBpbmNsdWRlIGEgZGVzdGluYXRpb24gbm9kZSBhbmQgaW5wdXQvb3V0cHV0IGNoYW5uZWxzLlxuICogQHBhcmFtIHNyY05vZGUgVGhlIHNvdXJjZSBub2RlXG4gKiBAcGFyYW0gZHN0Tm9kZSBUaGUgZGVzdGluYXRpb24gbm9kZVxuICogQHBhcmFtIG91dHB1dE51bWJlciBUaGUgb3V0cHV0IGNoYW5uZWwgb2YgdGhlIHNyY05vZGVcbiAqIEBwYXJhbSBpbnB1dE51bWJlciBUaGUgaW5wdXQgY2hhbm5lbCBvZiB0aGUgZHN0Tm9kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzY29ubmVjdChzcmNOb2RlLCBkc3ROb2RlLCBvdXRwdXROdW1iZXIgPSAwLCBpbnB1dE51bWJlciA9IDApIHtcbiAgICAvLyByZXNvbHZlIHRoZSBkZXN0aW5hdGlvbiBub2RlXG4gICAgaWYgKGlzRGVmaW5lZChkc3ROb2RlKSkge1xuICAgICAgICB3aGlsZSAoZHN0Tm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgIGRzdE5vZGUgPSBkc3ROb2RlLmlucHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIHJlc29sdmUgdGhlIHNyYyBub2RlXG4gICAgd2hpbGUgKCEoaXNBdWRpb05vZGUoc3JjTm9kZSkpKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQoc3JjTm9kZS5vdXRwdXQpKSB7XG4gICAgICAgICAgICBzcmNOb2RlID0gc3JjTm9kZS5vdXRwdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQXVkaW9QYXJhbShkc3ROb2RlKSkge1xuICAgICAgICBzcmNOb2RlLmRpc2Nvbm5lY3QoZHN0Tm9kZSwgb3V0cHV0TnVtYmVyKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaXNBdWRpb05vZGUoZHN0Tm9kZSkpIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvTm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogQSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBOYXRpdmUgV2ViIEF1ZGlvIEdhaW5Ob2RlLlxuICogVGhlIEdhaW5Ob2RlIGlzIGEgYmFzaWMgYnVpbGRpbmcgYmxvY2sgb2YgdGhlIFdlYiBBdWRpb1xuICogQVBJIGFuZCBpcyB1c2VmdWwgZm9yIHJvdXRpbmcgYXVkaW8gYW5kIGFkanVzdGluZyBnYWlucy5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGdhaW5Ob2RlID0gbmV3IFRvbmUuR2FpbigwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMzApLmNvbm5lY3QoZ2Fpbk5vZGUpLnN0YXJ0KCk7XG4gKiBcdGdhaW5Ob2RlLmdhaW4ucmFtcFRvKDEsIDAuMSk7XG4gKiBcdGdhaW5Ob2RlLmdhaW4ucmFtcFRvKDAsIDAuNCwgMC4yKTtcbiAqIH0sIDAuNywgMSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBHYWluIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhaW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJnYWluXCIsIFwidW5pdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYWluXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgd3JhcHBlZCBHYWluTm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgLy8gaW5wdXQgPSBvdXRwdXRcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoR2Fpbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImdhaW5cIiwgXCJ1bml0c1wiXSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZ2Fpbk5vZGUuZ2FpbixcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZ2FpbixcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImdhaW5cIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgZ2FpbjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImdhaW5cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HYWluLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUsIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgZmlyZS1hbmQtZm9yZ2V0IG5vZGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBPbmVTaG90U291cmNlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlXG4gICAgICAgICAqIHNvdXJjZSBpcyBkb25lIHBsYXlpbmcuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uZW5kZWQgPSBub09wO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0YXJ0IHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0b3AgdGltZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpZCBvZiB0aGUgdGltZW91dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHB1YmxpYyBvdXRwdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgZ2FpbiBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUgPSB0aGlzLm91dHB1dDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldCB0aGUgcGxheWJhY2sgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0U3RhdGVBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhcnRUaW1lICE9PSAtMSAmJlxuICAgICAgICAgICAgICAgIGNvbXB1dGVkVGltZSA+PSB0aGlzLl9zdGFydFRpbWUgJiZcbiAgICAgICAgICAgICAgICAodGhpcy5fc3RvcFRpbWUgPT09IC0xIHx8IGNvbXB1dGVkVGltZSA8PSB0aGlzLl9zdG9wVGltZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdGFydGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgICAgICB0aGlzLl9jdXJ2ZSA9IG9wdGlvbnMuY3VydmU7XG4gICAgICAgIHRoaXMub25lbmRlZCA9IG9wdGlvbnMub25lbmRlZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGN1cnZlOiBcImxpbmVhclwiLFxuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIG9uZW5kZWQ6IG5vT3AsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIF9zdGFydEdhaW4odGltZSwgZ2FpbiA9IDEpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N0YXJ0VGltZSA9PT0gLTEsIFwiU291cmNlIGNhbm5vdCBiZSBzdGFydGVkIG1vcmUgdGhhbiBvbmNlXCIpO1xuICAgICAgICAvLyBhcHBseSBhIGZhZGUgaW4gZW52ZWxvcGVcbiAgICAgICAgY29uc3QgZmFkZUluVGltZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuX2ZhZGVJbik7XG4gICAgICAgIC8vIHJlY29yZCB0aGUgc3RhcnQgdGltZVxuICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSB0aW1lICsgZmFkZUluVGltZTtcbiAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gTWF0aC5tYXgodGhpcy5fc3RhcnRUaW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgZW52ZWxvcGVcbiAgICAgICAgaWYgKGZhZGVJblRpbWUgPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2N1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShnYWluLCB0aW1lICsgZmFkZUluVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZShnYWluLCB0aW1lLCBmYWRlSW5UaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoZ2FpbiwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBub2RlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdG8gc3RvcCB0aGUgc291cmNlXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCB0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcEdhaW4odGhpcy50b1NlY29uZHModGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgc291cmNlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RvcCB0aGUgc291cmNlXG4gICAgICovXG4gICAgX3N0b3BHYWluKHRpbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N0YXJ0VGltZSAhPT0gLTEsIFwiJ3N0YXJ0JyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgJ3N0b3AnXCIpO1xuICAgICAgICAvLyBjYW5jZWwgdGhlIHByZXZpb3VzIHN0b3BcbiAgICAgICAgdGhpcy5jYW5jZWxTdG9wKCk7XG4gICAgICAgIC8vIHRoZSBmYWRlT3V0IHRpbWVcbiAgICAgICAgY29uc3QgZmFkZU91dFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLl9mYWRlT3V0KTtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIHN0b3AgY2FsbGJhY2tcbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKSArIGZhZGVPdXRUaW1lO1xuICAgICAgICB0aGlzLl9zdG9wVGltZSA9IE1hdGgubWF4KHRoaXMuX3N0b3BUaW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICBpZiAoZmFkZU91dFRpbWUgPiAwKSB7XG4gICAgICAgICAgICAvLyBzdGFydCB0aGUgZmFkZSBvdXQgY3VydmUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4ubGluZWFyUmFtcFRvKDAsIGZhZGVPdXRUaW1lLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4udGFyZ2V0UmFtcFRvKDAsIGZhZGVPdXRUaW1lLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHN0b3AgYW55IG9uZ29pbmcgcmFtcHMsIGFuZCBzZXQgdGhlIHZhbHVlIHRvIDBcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICAgICAgdGhpcy5fdGltZW91dCA9IHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIC8vIGFsbG93IGFkZGl0aW9uYWwgdGltZSBmb3IgdGhlIGV4cG9uZW50aWFsIGN1cnZlIHRvIGZ1bGx5IGRlY2F5XG4gICAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsVGFpbCA9IHRoaXMuX2N1cnZlID09PSBcImV4cG9uZW50aWFsXCIgPyBmYWRlT3V0VGltZSAqIDIgOiAwO1xuICAgICAgICAgICAgdGhpcy5fc3RvcFNvdXJjZSh0aGlzLm5vdygpICsgYWRkaXRpb25hbFRhaWwpO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCgpO1xuICAgICAgICB9LCB0aGlzLl9zdG9wVGltZSAtIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIG9uZW5kZWQgY2FsbGJhY2tcbiAgICAgKi9cbiAgICBfb25lbmRlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMub25lbmRlZCAhPT0gbm9PcCkge1xuICAgICAgICAgICAgdGhpcy5vbmVuZGVkKHRoaXMpO1xuICAgICAgICAgICAgLy8gb3ZlcndyaXRlIG9uZW5kZWQgdG8gbWFrZSBzdXJlIGl0IG9ubHkgaXMgY2FsbGVkIG9uY2VcbiAgICAgICAgICAgIHRoaXMub25lbmRlZCA9IG5vT3A7XG4gICAgICAgICAgICAvLyBkaXNwb3NlIHdoZW4gaXQncyBlbmRlZCB0byBmcmVlIHVwIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24gb25seSBpbiB0aGUgb25saW5lIGNvbnRleHRcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZXh0LmlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3Bvc2VDYWxsYmFjayA9ICgpID0+IHRoaXMuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5yZXF1ZXN0SWRsZUNhbGxiYWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnJlcXVlc3RJZGxlQ2FsbGJhY2soZGlzcG9zZUNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZGlzcG9zZUNhbGxiYWNrLCAxMDAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGEgc2NoZWR1bGVkIHN0b3AgZXZlbnRcbiAgICAgKi9cbiAgICBjYW5jZWxTdG9wKCkge1xuICAgICAgICB0aGlzLmxvZyhcImNhbmNlbFN0b3BcIik7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zdGFydFRpbWUgIT09IC0xLCBcIlNvdXJjZSBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBzdG9wIGVudmVsb3BlXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMuX3N0YXJ0VGltZSArIHRoaXMuc2FtcGxlVGltZSk7XG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gLTE7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T25lU2hvdFNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgT25lU2hvdFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvT25lU2hvdFNvdXJjZVwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIGZpcmUtYW5kLWZvcmdldCBDb25zdGFudFNvdXJjZS5cbiAqIEFkZHMgdGhlIGFiaWxpdHkgdG8gcmVzY2hlZHVsZSB0aGUgc3RvcCBtZXRob2QuXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQ29uc3RhbnRTb3VyY2UgZXh0ZW5kcyBPbmVTaG90U291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUNvbnN0YW50U291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib2Zmc2V0XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUNvbnN0YW50U291cmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2lnbmFsIGdlbmVyYXRvclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQ29uc3RhbnRTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJvZmZzZXRcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NvdXJjZSwgdGhpcy5fZ2Fpbk5vZGUpO1xuICAgICAgICB0aGlzLm9mZnNldCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fc291cmNlLm9mZnNldCxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub2Zmc2V0LFxuICAgICAgICAgICAgbWluVmFsdWU6IG9wdGlvbnMubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogb3B0aW9ucy5tYXhWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT25lU2hvdFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgb2Zmc2V0OiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdGFydCB0aGUgc291cmNlXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydEdhaW4oY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5vZmZzZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQ29uc3RhbnRTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi4vY29yZS91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRvbmVDb25zdGFudFNvdXJjZSB9IGZyb20gXCIuL1RvbmVDb25zdGFudFNvdXJjZVwiO1xuLyoqXG4gKiBBIHNpZ25hbCBpcyBhbiBhdWRpby1yYXRlIHZhbHVlLiBUb25lLlNpZ25hbCBpcyBhIGNvcmUgY29tcG9uZW50IG9mIHRoZSBsaWJyYXJ5LlxuICogVW5saWtlIGEgbnVtYmVyLCBTaWduYWxzIGNhbiBiZSBzY2hlZHVsZWQgd2l0aCBzYW1wbGUtbGV2ZWwgYWNjdXJhY3kuIFRvbmUuU2lnbmFsXG4gKiBoYXMgYWxsIG9mIHRoZSBtZXRob2RzIGF2YWlsYWJsZSB0byBuYXRpdmUgV2ViIEF1ZGlvXG4gKiBbQXVkaW9QYXJhbV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtYXVkaW9wYXJhbS1pbnRlcmZhY2UpXG4gKiBhcyB3ZWxsIGFzIGFkZGl0aW9uYWwgY29udmVuaWVuY2VzLiBSZWFkIG1vcmUgYWJvdXQgd29ya2luZyB3aXRoIHNpZ25hbHNcbiAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9TaWduYWxzKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gYSBzY2hlZHVsZWFibGUgc2lnbmFsIHdoaWNoIGNhbiBiZSBjb25uZWN0ZWQgdG8gY29udHJvbCBhbiBBdWRpb1BhcmFtIG9yIGFub3RoZXIgU2lnbmFsXG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoe1xuICogXHR2YWx1ZTogXCJDNFwiLFxuICogXHR1bml0czogXCJmcmVxdWVuY3lcIlxuICogfSkuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAqIC8vIHRoZSBzY2hlZHVsZWQgcmFtcCBjb250cm9scyB0aGUgY29ubmVjdGVkIHNpZ25hbFxuICogc2lnbmFsLnJhbXBUbyhcIkMyXCIsIDQsIFwiKzAuNVwiKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25hbCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2lnbmFsXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBvdmVycmlkZGVuIG9uIGNvbm5lY3Rpb24uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCIsIFwidW5pdHNcIl0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2NvbnN0YW50U291cmNlID0gbmV3IFRvbmVDb25zdGFudFNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBvZmZzZXQ6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5zdGFydCgwKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3BhcmFtID0gdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgLy8gc3RhcnQgaXQgb25seSB3aGVuIGNvbm5lY3RlZCB0byBzb21ldGhpbmdcbiAgICAgICAgY29ubmVjdFNpZ25hbCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQUJTVFJBQ1QgUEFSQU0gSU5URVJGQUNFXG4gICAgLy8ganVzdCBhIHByb3h5IGZvciB0aGUgQ29uc3RhbnRTb3VyY2VOb2RlJ3Mgb2Zmc2V0IEF1ZGlvUGFyYW1cbiAgICAvLyBhbGwgZG9jcyBhcmUgZ2VuZXJhdGVkIGZyb20gQWJzdHJhY3RQYXJhbS50c1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBzZXRSYW1wUG9pbnQodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRSYW1wUG9pbnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0udGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSwgcmFtcFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lLCByYW1wVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICByYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ucmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0udmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgZ2V0IGNvbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5jb252ZXJ0O1xuICAgIH1cbiAgICBzZXQgY29udmVydChjb252ZXJ0KSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNvbnZlcnQgPSBjb252ZXJ0O1xuICAgIH1cbiAgICBnZXQgdW5pdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS51bml0cztcbiAgICB9XG4gICAgZ2V0IG92ZXJyaWRkZW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5vdmVycmlkZGVuO1xuICAgIH1cbiAgICBzZXQgb3ZlcnJpZGRlbihvdmVycmlkZGVuKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLm92ZXJyaWRkZW4gPSBvdmVycmlkZGVuO1xuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tYXhWYWx1ZTtcbiAgICB9XG4gICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWluVmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlZSBbW1BhcmFtLmFwcGx5XV0uXG4gICAgICovXG4gICAgYXBwbHkocGFyYW0pIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uYXBwbHkocGFyYW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIFdoZW4gY29ubmVjdGluZyBmcm9tIGEgc2lnbmFsLCBpdCdzIG5lY2Vzc2FyeSB0byB6ZXJvIG91dCB0aGUgbm9kZSBkZXN0aW5hdGlvblxuICogbm9kZSBpZiB0aGF0IG5vZGUgaXMgYWxzbyBhIHNpZ25hbC4gSWYgdGhlIGRlc3RpbmF0aW9uIGlzIG5vdCAwLCB0aGVuIHRoZSB2YWx1ZXNcbiAqIHdpbGwgYmUgc3VtbWVkLiBUaGlzIG1ldGhvZCBpbnN1cmVzIHRoYXQgdGhlIG91dHB1dCBvZiB0aGUgZGVzdGluYXRpb24gc2lnbmFsIHdpbGxcbiAqIGJlIHRoZSBzYW1lIGFzIHRoZSBzb3VyY2Ugc2lnbmFsLCBtYWtpbmcgdGhlIGRlc3RpbmF0aW9uIHNpZ25hbCBhIHBhc3MgdGhyb3VnaCBub2RlLlxuICogQHBhcmFtIHNpZ25hbCBUaGUgb3V0cHV0IHNpZ25hbCB0byBjb25uZWN0IGZyb21cbiAqIEBwYXJhbSBkZXN0aW5hdGlvbiB0aGUgZGVzdGluYXRpb24gdG8gY29ubmVjdCB0b1xuICogQHBhcmFtIG91dHB1dE51bSB0aGUgb3B0aW9uYWwgb3V0cHV0IG51bWJlclxuICogQHBhcmFtIGlucHV0TnVtIHRoZSBpbnB1dCBudW1iZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3RTaWduYWwoc2lnbmFsLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSkge1xuICAgIGlmIChkZXN0aW5hdGlvbiBpbnN0YW5jZW9mIFBhcmFtIHx8IGlzQXVkaW9QYXJhbShkZXN0aW5hdGlvbikgfHxcbiAgICAgICAgKGRlc3RpbmF0aW9uIGluc3RhbmNlb2YgU2lnbmFsICYmIGRlc3RpbmF0aW9uLm92ZXJyaWRlKSkge1xuICAgICAgICAvLyBjYW5jZWwgY2hhbmdlc1xuICAgICAgICBkZXN0aW5hdGlvbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoMCk7XG4gICAgICAgIC8vIHJlc2V0IHRoZSB2YWx1ZVxuICAgICAgICBkZXN0aW5hdGlvbi5zZXRWYWx1ZUF0VGltZSgwLCAwKTtcbiAgICAgICAgLy8gbWFyayB0aGUgdmFsdWUgYXMgb3ZlcnJpZGRlblxuICAgICAgICBpZiAoZGVzdGluYXRpb24gaW5zdGFuY2VvZiBTaWduYWwpIHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uLm92ZXJyaWRkZW4gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbm5lY3Qoc2lnbmFsLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaWduYWwuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBBIFBhcmFtIGNsYXNzIGp1c3QgZm9yIGNvbXB1dGluZyB0aWNrcy4gU2ltaWxhciB0byB0aGUgW1tQYXJhbV1dIGNsYXNzLFxuICogYnV0IG9mZmVycyBjb252ZXJzaW9uIHRvIEJQTSB2YWx1ZXMgYXMgd2VsbCBhcyBhYmlsaXR5IHRvIGNvbXB1dGUgdGlja1xuICogZHVyYXRpb24gYW5kIGVsYXBzZWQgdGlja3NcbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tQYXJhbSBleHRlbmRzIFBhcmFtIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1BhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrUGFyYW1cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lbGluZSB3aGljaCB0cmFja3MgYWxsIG9mIHRoZSBhdXRvbWF0aW9ucy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBUaW1lbGluZShJbmZpbml0eSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW50ZXJuYWwgaG9sZGVyIGZvciB0aGUgbXVsdGlwbGllciB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbXVsdGlwbGllciA9IDE7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIC8vIHNldCB0aGUgbXVsdGlwbGllclxuICAgICAgICB0aGlzLl9tdWx0aXBsaWVyID0gb3B0aW9ucy5tdWx0aXBsaWVyO1xuICAgICAgICAvLyBjbGVhciB0aGUgdGlja3MgZnJvbSB0aGUgYmVnaW5uaW5nXG4gICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoMCk7XG4gICAgICAgIC8vIHNldCBhbiBpbml0aWFsIGV2ZW50XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGlja3M6IDAsXG4gICAgICAgICAgICB0aW1lOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuX2Zyb21UeXBlKG9wdGlvbnMudmFsdWUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihQYXJhbS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdWx0aXBsaWVyOiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwiaGVydHpcIixcbiAgICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCB0aW1lLCBjb25zdGFudCkge1xuICAgICAgICAvLyBhcHByb3hpbWF0ZSBpdCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wc1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBzdGFydCBmcm9tIHByZXZpb3VzbHkgc2NoZWR1bGVkIHZhbHVlXG4gICAgICAgIGNvbnN0IHByZXZFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgxIC8gY29uc3RhbnQsIDEpKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gc2VnbWVudHM7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc2VnVGltZSA9IGNvbnN0YW50ICogaSArIHRpbWU7XG4gICAgICAgICAgICBjb25zdCByYW1wVmFsID0gdGhpcy5fZXhwb25lbnRpYWxBcHByb2FjaChwcmV2RXZlbnQudGltZSwgcHJldkV2ZW50LnZhbHVlLCBjb21wdXRlZFZhbHVlLCBjb25zdGFudCwgc2VnVGltZSk7XG4gICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShyYW1wVmFsKSwgc2VnVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBzdXBlci5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICBjb25zdCB0aWNrc1VudGlsVGltZSA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBldmVudC50aWNrcyA9IE1hdGgubWF4KHRpY2tzVW50aWxUaW1lLCAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICBjb25zdCB0aWNrc1VudGlsVGltZSA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBldmVudC50aWNrcyA9IE1hdGgubWF4KHRpY2tzVW50aWxUaW1lLCAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgLy8gYXByb3hpbWF0ZSBpdCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wc1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVmFsID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBzdGFydCBmcm9tIHByZXZpb3VzbHkgc2NoZWR1bGVkIHZhbHVlXG4gICAgICAgIGNvbnN0IHByZXZFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIC8vIGFwcHJveCAxMCBzZWdtZW50cyBwZXIgc2Vjb25kXG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgodGltZSAtIHByZXZFdmVudC50aW1lKSAqIDEwLCAxKSk7XG4gICAgICAgIGNvbnN0IHNlZ21lbnREdXIgPSAoKHRpbWUgLSBwcmV2RXZlbnQudGltZSkgLyBzZWdtZW50cyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlZ1RpbWUgPSBzZWdtZW50RHVyICogaSArIHByZXZFdmVudC50aW1lO1xuICAgICAgICAgICAgY29uc3QgcmFtcFZhbCA9IHRoaXMuX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUocHJldkV2ZW50LnRpbWUsIHByZXZFdmVudC52YWx1ZSwgdGltZSwgY29tcHV0ZWRWYWwsIHNlZ1RpbWUpO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUocmFtcFZhbCksIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aWNrIHZhbHVlIGF0IHRoZSB0aW1lLiBUYWtlcyBpbnRvIGFjY291bnRcbiAgICAgKiBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc2NoZWR1bGVkIG9uIHRoZSBzaWduYWwuXG4gICAgICogQHBhcmFtICBldmVudCBUaGUgdGltZSB0byBnZXQgdGhlIHRpY2sgY291bnQgYXRcbiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGlja3Mgd2hpY2ggaGF2ZSBlbGFwc2VkIGF0IHRoZSB0aW1lIGdpdmVuIGFueSBhdXRvbWF0aW9ucy5cbiAgICAgKi9cbiAgICBfZ2V0VGlja3NVbnRpbEV2ZW50KGV2ZW50LCB0aW1lKSB7XG4gICAgICAgIGlmIChldmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgdGlja3M6IDAsXG4gICAgICAgICAgICAgICAgdGltZTogMCxcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNldFZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzVW5kZWYoZXZlbnQudGlja3MpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgZXZlbnQudGlja3MgPSB0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQocHJldmlvdXNFdmVudCwgZXZlbnQudGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmFsMCA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUoZXZlbnQudGltZSkpO1xuICAgICAgICBsZXQgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSkpO1xuICAgICAgICAvLyBpZiBpdCdzIHJpZ2h0IG9uIHRoZSBsaW5lLCB0YWtlIHRoZSBwcmV2aW91cyB2YWx1ZVxuICAgICAgICBjb25zdCBvblRoZUxpbmVFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIGlmIChvblRoZUxpbmVFdmVudCAmJiBvblRoZUxpbmVFdmVudC50aW1lID09PSB0aW1lICYmIG9uVGhlTGluZUV2ZW50LnR5cGUgPT09IFwic2V0VmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSAtIHRoaXMuc2FtcGxlVGltZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwLjUgKiAodGltZSAtIGV2ZW50LnRpbWUpICogKHZhbDAgKyB2YWwxKSArIGV2ZW50LnRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aWNrIHZhbHVlIGF0IHRoZSB0aW1lLiBUYWtlcyBpbnRvIGFjY291bnRcbiAgICAgKiBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc2NoZWR1bGVkIG9uIHRoZSBzaWduYWwuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGdldCB0aGUgdGljayBjb3VudCBhdFxuICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB0aWNrcyB3aGljaCBoYXZlIGVsYXBzZWQgYXQgdGhlIHRpbWUgZ2l2ZW4gYW55IGF1dG9tYXRpb25zLlxuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgodGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KGV2ZW50LCBjb21wdXRlZFRpbWUpLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHRpbWUgb2YgdGhlIG51bWJlciBvZiB0aWNrcyBmcm9tIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtIHRpY2tzIFRoZSBudW1iZXIgb2YgdGlja3MgdG8gY2FsY3VsYXRlXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGdldCB0aGUgbmV4dCB0aWNrIGZyb21cbiAgICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbiBvZiB0aGUgbnVtYmVyIG9mIHRpY2tzIGZyb20gdGhlIGdpdmVuIHRpbWUgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIGdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY3VycmVudFRpY2sgPSB0aGlzLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUaW1lT2ZUaWNrKGN1cnJlbnRUaWNrICsgdGlja3MpIC0gY29tcHV0ZWRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIHRpY2ssIHJldHVybnMgdGhlIHRpbWUgdGhhdCB0aWNrIG9jY3VycyBhdC5cbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIHRoYXQgdGhlIHRpY2sgb2NjdXJzLlxuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaykge1xuICAgICAgICBjb25zdCBiZWZvcmUgPSB0aGlzLl9ldmVudHMuZ2V0KHRpY2ssIFwidGlja3NcIik7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKHRpY2ssIFwidGlja3NcIik7XG4gICAgICAgIGlmIChiZWZvcmUgJiYgYmVmb3JlLnRpY2tzID09PSB0aWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gYmVmb3JlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlICYmIGFmdGVyICYmXG4gICAgICAgICAgICBhZnRlci50eXBlID09PSBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIgJiZcbiAgICAgICAgICAgIGJlZm9yZS52YWx1ZSAhPT0gYWZ0ZXIudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbDAgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGJlZm9yZS50aW1lKSk7XG4gICAgICAgICAgICBjb25zdCB2YWwxID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShhZnRlci50aW1lKSk7XG4gICAgICAgICAgICBjb25zdCBkZWx0YSA9ICh2YWwxIC0gdmFsMCkgLyAoYWZ0ZXIudGltZSAtIGJlZm9yZS50aW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGsgPSBNYXRoLnNxcnQoTWF0aC5wb3codmFsMCwgMikgLSAyICogZGVsdGEgKiAoYmVmb3JlLnRpY2tzIC0gdGljaykpO1xuICAgICAgICAgICAgY29uc3Qgc29sMSA9ICgtdmFsMCArIGspIC8gZGVsdGE7XG4gICAgICAgICAgICBjb25zdCBzb2wyID0gKC12YWwwIC0gaykgLyBkZWx0YTtcbiAgICAgICAgICAgIHJldHVybiAoc29sMSA+IDAgPyBzb2wxIDogc29sMikgKyBiZWZvcmUudGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiZWZvcmUpIHtcbiAgICAgICAgICAgIGlmIChiZWZvcmUudmFsdWUgPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gSW5maW5pdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmVmb3JlLnRpbWUgKyAodGljayAtIGJlZm9yZS50aWNrcykgLyBiZWZvcmUudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGljayAvIHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHNvbWUgbnVtYmVyIG9mIHRpY2tzIHRoZWlyIHRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIGFjY291bnRpbmdcbiAgICAgKiBmb3IgYW55IGF1dG9tYXRpb24gY3VydmVzIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGlja3MgVGhlIG51bWJlciBvZiB0aWNrcyB0byBjb252ZXJ0IHRvIHNlY29uZHMuXG4gICAgICogQHBhcmFtICB3aGVuICBXaGVuIGFsb25nIHRoZSBhdXRvbWF0aW9uIHRpbWVsaW5lIHRvIGNvbnZlcnQgdGhlIHRpY2tzLlxuICAgICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgb2YgdGhlIHRpY2tzLlxuICAgICAqL1xuICAgIHRpY2tzVG9UaW1lKHRpY2tzLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgd2hlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbnZlcnNlIG9mIFtbdGlja3NUb1RpbWVdXS4gQ29udmVydCBhIGR1cmF0aW9uIGluXG4gICAgICogc2Vjb25kcyB0byB0aGUgY29ycmVzcG9uZGluZyBudW1iZXIgb2YgdGlja3MgYWNjb3VudGluZyBmb3IgYW55XG4gICAgICogYXV0b21hdGlvbiBjdXJ2ZXMgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBUaGUgdGltZSBpbnRlcnZhbCB0byBjb252ZXJ0IHRvIHRpY2tzLlxuICAgICAqIEBwYXJhbSAgd2hlbiBXaGVuIGFsb25nIHRoZSBhdXRvbWF0aW9uIHRpbWVsaW5lIHRvIGNvbnZlcnQgdGhlIHRpY2tzLlxuICAgICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uIGluIHRpY2tzLlxuICAgICAqL1xuICAgIHRpbWVUb1RpY2tzKGR1cmF0aW9uLCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBjb25zdCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICBjb25zdCBzdGFydFRpY2tzID0gdGhpcy5nZXRUaWNrc0F0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBlbmRUaWNrcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXJhdGlvbik7XG4gICAgICAgIHJldHVybiBlbmRUaWNrcyAtIHN0YXJ0VGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgZnJvbSB0aGUgdHlwZSB3aGVuIHRoZSB1bml0IHZhbHVlIGlzIEJQTVxuICAgICAqL1xuICAgIF9mcm9tVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiYnBtXCIgJiYgdGhpcy5tdWx0aXBsaWVyKSB7XG4gICAgICAgICAgICByZXR1cm4gMSAvICg2MCAvIHZhbCAvIHRoaXMubXVsdGlwbGllcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuX2Zyb21UeXBlKHZhbCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3BlY2lhbCBjYXNlIG9mIHR5cGUgY29udmVyc2lvbiB3aGVyZSB0aGUgdW5pdHMgPT09IFwiYnBtXCJcbiAgICAgKi9cbiAgICBfdG9UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy51bml0cyA9PT0gXCJicG1cIiAmJiB0aGlzLm11bHRpcGxpZXIpIHtcbiAgICAgICAgICAgIHJldHVybiAodmFsIC8gdGhpcy5tdWx0aXBsaWVyKSAqIDYwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLl90b1R5cGUodmFsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIG11bHRpcGxpZXIgb24gdGhlIGJwbSB2YWx1ZS4gVXNlZnVsIGZvciBzZXR0aW5nIGEgUFBRIHJlbGF0aXZlIHRvIHRoZSBiYXNlIGZyZXF1ZW5jeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgbXVsdGlwbGllcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX211bHRpcGxpZXI7XG4gICAgfVxuICAgIHNldCBtdWx0aXBsaWVyKG0pIHtcbiAgICAgICAgLy8gZ2V0IGFuZCByZXNldCB0aGUgY3VycmVudCB2YWx1ZSB3aXRoIHRoZSBuZXcgbXVsdGlwbGllclxuICAgICAgICAvLyBtaWdodCBiZSBuZWNlc3NhcnkgdG8gY2xlYXIgYWxsIHRoZSBwcmV2aW91cyB2YWx1ZXNcbiAgICAgICAgY29uc3QgY3VycmVudFZhbCA9IHRoaXMudmFsdWU7XG4gICAgICAgIHRoaXMuX211bHRpcGxpZXIgPSBtO1xuICAgICAgICB0aGlzLmNhbmNlbFNjaGVkdWxlZFZhbHVlcygwKTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShjdXJyZW50VmFsLCAwKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrUGFyYW0uanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpY2tQYXJhbSB9IGZyb20gXCIuL1RpY2tQYXJhbVwiO1xuLyoqXG4gKiBUaWNrU2lnbmFsIGV4dGVuZHMgVG9uZS5TaWduYWwsIGJ1dCBhZGRzIHRoZSBjYXBhYmlsaXR5XG4gKiB0byBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBlbGFwc2VkIHRpY2tzLiBleHBvbmVudGlhbCBhbmQgdGFyZ2V0IGN1cnZlc1xuICogYXJlIGFwcHJveGltYXRlZCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wcy5cbiAqXG4gKiBUaGFuayB5b3UgQnJ1bm8gRGlhcywgSC4gU29maWEgUGludG8sIGFuZCBEYXZpZCBNLiBNYXRvcyxcbiAqIGZvciB5b3VyIFtXQUMgcGFwZXJdKGh0dHBzOi8vc21hcnRlY2guZ2F0ZWNoLmVkdS9iaXRzdHJlYW0vaGFuZGxlLzE4NTMvNTQ1ODgvV0FDMjAxNi00OS5wZGYpXG4gKiBkZXNjcmliaW5nIGludGVncmF0aW5nIHRpbWluZyBmdW5jdGlvbnMgZm9yIHRlbXBvIGNhbGN1bGF0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tTaWduYWwgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrU2lnbmFsXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fcGFyYW0gPSBuZXcgVGlja1BhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IG9wdGlvbnMuY29udmVydCxcbiAgICAgICAgICAgIG11bHRpcGxpZXI6IG9wdGlvbnMubXVsdGlwbGllcixcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXVsdGlwbGllcjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRpY2tzVG9UaW1lKHRpY2tzLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS50aWNrc1RvVGltZSh0aWNrcywgd2hlbik7XG4gICAgfVxuICAgIHRpbWVUb1RpY2tzKGR1cmF0aW9uLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS50aW1lVG9UaWNrcyhkdXJhdGlvbiwgd2hlbik7XG4gICAgfVxuICAgIGdldFRpbWVPZlRpY2sodGljaykge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0VGltZU9mVGljayh0aWNrKTtcbiAgICB9XG4gICAgZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHRpbWUpO1xuICAgIH1cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtdWx0aXBsaWVyIG9uIHRoZSBicG0gdmFsdWUuIFVzZWZ1bCBmb3Igc2V0dGluZyBhIFBQUSByZWxhdGl2ZSB0byB0aGUgYmFzZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IG11bHRpcGxpZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tdWx0aXBsaWVyO1xuICAgIH1cbiAgICBzZXQgbXVsdGlwbGllcihtKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLm11bHRpcGxpZXIgPSBtO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja1NpZ25hbC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUaWNrU2lnbmFsIH0gZnJvbSBcIi4vVGlja1NpZ25hbFwiO1xuaW1wb3J0IHsgRVEgfSBmcm9tIFwiLi4vdXRpbC9NYXRoXCI7XG4vKipcbiAqIFVzZXMgW1RpY2tTaWduYWxdKFRpY2tTaWduYWwpIHRvIHRyYWNrIGVsYXBzZWQgdGlja3Mgd2l0aCBjb21wbGV4IGF1dG9tYXRpb24gY3VydmVzLlxuICovXG5leHBvcnQgY2xhc3MgVGlja1NvdXJjZSBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrU291cmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc3RhdGUgdGltZWxpbmVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvZmZzZXQgdmFsdWVzIG9mIHRoZSB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGlja09mZnNldCA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRpY2tTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHN0YXRlXG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCAwKTtcbiAgICAgICAgLy8gYWRkIHRoZSBmaXJzdCBldmVudFxuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKDAsIDApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgIH0sIFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RhdGVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBjbG9jayBhdCB0aGUgZ2l2ZW4gdGltZS4gT3B0aW9uYWxseSBwYXNzIGluIGFuIG9mZnNldFxuICAgICAqIG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSB0aWNrIGNvdW50ZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgVGhlIHRpbWUgdGhlIGNsb2NrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG51bWJlciBvZiB0aWNrcyB0byBzdGFydCB0aGUgc291cmNlIGF0XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChvZmZzZXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZShvZmZzZXQsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGNsb2NrLiBTdG9wcGluZyB0aGUgY2xvY2sgcmVzZXRzIHRoZSB0aWNrIGNvdW50ZXIgdG8gMC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoZXZlbnQgJiYgZXZlbnQudGltZSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbChldmVudC50aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoZXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKDAsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgY2xvY2suIFBhdXNpbmcgZG9lcyBub3QgcmVzZXQgdGhlIHRpY2sgY291bnRlci5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwicGF1c2VkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBzdGFydC9zdG9wL3BhdXNlIGFuZCBzZXRUaWNrQXRUaW1lIGV2ZW50cyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0byBjbGVhciB0aGUgZXZlbnRzIGFmdGVyXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuY2FuY2VsKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBlbGFwc2VkIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgdGljayB2YWx1ZVxuICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB0aWNrc1xuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldExhc3RTdGF0ZShcInN0b3BwZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgLy8gdGhpcyBldmVudCBhbGxvd3MgZm9yRWFjaEJldHdlZW4gdG8gaXRlcmF0ZSB1bnRpbCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgIGNvbnN0IHRtcEV2ZW50ID0geyBzdGF0ZTogXCJwYXVzZWRcIiwgdGltZTogY29tcHV0ZWRUaW1lIH07XG4gICAgICAgIHRoaXMuX3N0YXRlLmFkZCh0bXBFdmVudCk7XG4gICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgdGhlIHByZXZpb3VzIG9mZnNldCBldmVudFxuICAgICAgICBsZXQgbGFzdFN0YXRlID0gc3RvcEV2ZW50O1xuICAgICAgICBsZXQgZWxhcHNlZFRpY2tzID0gMDtcbiAgICAgICAgLy8gaXRlcmF0ZSB0aHJvdWdoIGFsbCB0aGUgZXZlbnRzIHNpbmNlIHRoZSBsYXN0IHN0b3BcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEJldHdlZW4oc3RvcEV2ZW50LnRpbWUsIGNvbXB1dGVkVGltZSArIHRoaXMuc2FtcGxlVGltZSwgZSA9PiB7XG4gICAgICAgICAgICBsZXQgcGVyaW9kU3RhcnRUaW1lID0gbGFzdFN0YXRlLnRpbWU7XG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBvZmZzZXQgZXZlbnQgaW4gdGhpcyBwZXJpb2QgdXNlIHRoYXRcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEV2ZW50ID0gdGhpcy5fdGlja09mZnNldC5nZXQoZS50aW1lKTtcbiAgICAgICAgICAgIGlmIChvZmZzZXRFdmVudCAmJiBvZmZzZXRFdmVudC50aW1lID49IGxhc3RTdGF0ZS50aW1lKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFRpY2tzID0gb2Zmc2V0RXZlbnQudGlja3M7XG4gICAgICAgICAgICAgICAgcGVyaW9kU3RhcnRUaW1lID0gb2Zmc2V0RXZlbnQudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGUuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIGUuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFRpY2tzICs9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKGUudGltZSkgLSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShwZXJpb2RTdGFydFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlID0gZTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgdGVtcG9yYXJ5IGV2ZW50XG4gICAgICAgIHRoaXMuX3N0YXRlLnJlbW92ZSh0bXBFdmVudCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgdGlja3NcbiAgICAgICAgcmV0dXJuIGVsYXBzZWRUaWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiB0aW1lcyB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuIFN0YXJ0cyBjb3VudGluZyBhdCAwXG4gICAgICogYW5kIGluY3JlbWVudHMgYWZ0ZXIgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBSZXR1cm5zIC0xIHdoZW4gc3RvcHBlZC5cbiAgICAgKi9cbiAgICBnZXQgdGlja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRpY2tzQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgdGlja3ModCkge1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHQsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBzaW5jZSB0aWNrcz0wIHRoYXQgdGhlIFRpY2tTb3VyY2UgaGFzIGJlZW4gcnVubmluZy4gQWNjb3VudHNcbiAgICAgKiBmb3IgdGVtcG8gY3VydmVzXG4gICAgICovXG4gICAgZ2V0IHNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNlY29uZHNBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmZyZXF1ZW5jeS50aW1lVG9UaWNrcyhzLCBub3cpO1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHRpY2tzLCBub3cpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqL1xuICAgIGdldFNlY29uZHNBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldExhc3RTdGF0ZShcInN0b3BwZWRcIiwgdGltZSk7XG4gICAgICAgIC8vIHRoaXMgZXZlbnQgYWxsb3dzIGZvckVhY2hCZXR3ZWVuIHRvIGl0ZXJhdGUgdW50aWwgdGhlIGN1cnJlbnQgdGltZVxuICAgICAgICBjb25zdCB0bXBFdmVudCA9IHsgc3RhdGU6IFwicGF1c2VkXCIsIHRpbWUgfTtcbiAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHRtcEV2ZW50KTtcbiAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGUgcHJldmlvdXMgb2Zmc2V0IGV2ZW50XG4gICAgICAgIGxldCBsYXN0U3RhdGUgPSBzdG9wRXZlbnQ7XG4gICAgICAgIGxldCBlbGFwc2VkU2Vjb25kcyA9IDA7XG4gICAgICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIGV2ZW50cyBzaW5jZSB0aGUgbGFzdCBzdG9wXG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0b3BFdmVudC50aW1lLCB0aW1lICsgdGhpcy5zYW1wbGVUaW1lLCBlID0+IHtcbiAgICAgICAgICAgIGxldCBwZXJpb2RTdGFydFRpbWUgPSBsYXN0U3RhdGUudGltZTtcbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIG9mZnNldCBldmVudCBpbiB0aGlzIHBlcmlvZCB1c2UgdGhhdFxuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0RXZlbnQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChlLnRpbWUpO1xuICAgICAgICAgICAgaWYgKG9mZnNldEV2ZW50ICYmIG9mZnNldEV2ZW50LnRpbWUgPj0gbGFzdFN0YXRlLnRpbWUpIHtcbiAgICAgICAgICAgICAgICBlbGFwc2VkU2Vjb25kcyA9IG9mZnNldEV2ZW50LnNlY29uZHM7XG4gICAgICAgICAgICAgICAgcGVyaW9kU3RhcnRUaW1lID0gb2Zmc2V0RXZlbnQudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGUuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIGUuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFNlY29uZHMgKz0gZS50aW1lIC0gcGVyaW9kU3RhcnRUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlID0gZTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgdGVtcG9yYXJ5IGV2ZW50XG4gICAgICAgIHRoaXMuX3N0YXRlLnJlbW92ZSh0bXBFdmVudCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgdGlja3NcbiAgICAgICAgcmV0dXJuIGVsYXBzZWRTZWNvbmRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aWNrcyBUaGUgdGljayB2YWx1ZSB0byBzZXRcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICovXG4gICAgc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbCh0aW1lKTtcbiAgICAgICAgdGhpcy5fdGlja09mZnNldC5hZGQoe1xuICAgICAgICAgICAgc2Vjb25kczogdGhpcy5mcmVxdWVuY3kuZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKSxcbiAgICAgICAgICAgIHRpY2tzLFxuICAgICAgICAgICAgdGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRTdGF0ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGdpdmVuIHRpY2suIFRoZSBzZWNvbmQgYXJndW1lbnRcbiAgICAgKiBpcyB3aGVuIHRvIHRlc3QgYmVmb3JlLiBTaW5jZSB0aWNrcyBjYW4gYmUgc2V0ICh3aXRoIHNldFRpY2tzQXRUaW1lKVxuICAgICAqIHRoZXJlIG1heSBiZSBtdWx0aXBsZSB0aW1lcyBmb3IgYSBnaXZlbiB0aWNrIHZhbHVlLlxuICAgICAqIEBwYXJhbSAgdGljayBUaGUgdGljayBudW1iZXIuXG4gICAgICogQHBhcmFtICBiZWZvcmUgV2hlbiB0byBtZWFzdXJlIHRoZSB0aWNrIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGUgdGlja1xuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaywgYmVmb3JlID0gdGhpcy5ub3coKSkge1xuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChiZWZvcmUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXRlLmdldChiZWZvcmUpO1xuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBNYXRoLm1heChvZmZzZXQudGltZSwgZXZlbnQudGltZSk7XG4gICAgICAgIGNvbnN0IGFic29sdXRlVGlja3MgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShzdGFydFRpbWUpICsgdGljayAtIG9mZnNldC50aWNrcztcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJlcXVlbmN5LmdldFRpbWVPZlRpY2soYWJzb2x1dGVUaWNrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgY2FsbGJhY2sgZXZlbnQgYXQgYWxsIHNjaGVkdWxlZCB0aWNrcyBiZXR3ZWVuIHRoZVxuICAgICAqIHN0YXJ0IHRpbWUgYW5kIHRoZSBlbmQgdGltZVxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lICBUaGUgYmVnaW5uaW5nIG9mIHRoZSBzZWFyY2ggcmFuZ2VcbiAgICAgKiBAcGFyYW0gIGVuZFRpbWUgICAgVGhlIGVuZCBvZiB0aGUgc2VhcmNoIHJhbmdlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBlYWNoIHRpY2tcbiAgICAgKi9cbiAgICBmb3JFYWNoVGlja0JldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBvbmx5IGl0ZXJhdGUgdGhyb3VnaCB0aGUgc2VjdGlvbnMgd2hlcmUgaXQgaXMgXCJzdGFydGVkXCJcbiAgICAgICAgbGV0IGxhc3RTdGF0ZUV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZUV2ZW50ICYmIGxhc3RTdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBldmVudC5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvckVhY2hUaWNrQmV0d2VlbihNYXRoLm1heChsYXN0U3RhdGVFdmVudC50aW1lLCBzdGFydFRpbWUpLCBldmVudC50aW1lIC0gdGhpcy5zYW1wbGVUaW1lLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0U3RhdGVFdmVudCA9IGV2ZW50O1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGVycm9yID0gbnVsbDtcbiAgICAgICAgaWYgKGxhc3RTdGF0ZUV2ZW50ICYmIGxhc3RTdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgY29uc3QgbWF4U3RhcnRUaW1lID0gTWF0aC5tYXgobGFzdFN0YXRlRXZlbnQudGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgIC8vIGZpZ3VyZSBvdXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZnJlcXVlbmN5IHRpY2tzIGFuZCB0aGVcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGlja3MgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShtYXhTdGFydFRpbWUpO1xuICAgICAgICAgICAgY29uc3QgdGlja3NBdFN0YXJ0ID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUobGFzdFN0YXRlRXZlbnQudGltZSk7XG4gICAgICAgICAgICBjb25zdCBkaWZmID0gc3RhcnRUaWNrcyAtIHRpY2tzQXRTdGFydDtcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSBNYXRoLmNlaWwoZGlmZikgLSBkaWZmO1xuICAgICAgICAgICAgLy8gZ3VhcmQgYWdhaW5zdCBmbG9hdGluZyBwb2ludCBpc3N1ZXNcbiAgICAgICAgICAgIG9mZnNldCA9IEVRKG9mZnNldCwgMSkgPyAwIDogb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IG5leHRUaWNrVGltZSA9IHRoaXMuZnJlcXVlbmN5LmdldFRpbWVPZlRpY2soc3RhcnRUaWNrcyArIG9mZnNldCk7XG4gICAgICAgICAgICB3aGlsZSAobmV4dFRpY2tUaW1lIDwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5leHRUaWNrVGltZSwgTWF0aC5yb3VuZCh0aGlzLmdldFRpY2tzQXRUaW1lKG5leHRUaWNrVGltZSkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmV4dFRpY2tUaW1lICs9IHRoaXMuZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcygxLCBuZXh0VGlja1RpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFN0YXRlVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBUaWNrU291cmNlIH0gZnJvbSBcIi4vVGlja1NvdXJjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0Q29udGV4dFJ1bm5pbmcgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBBIHNhbXBsZSBhY2N1cmF0ZSBjbG9jayB3aGljaCBwcm92aWRlcyBhIGNhbGxiYWNrIGF0IHRoZSBnaXZlbiByYXRlLlxuICogV2hpbGUgdGhlIGNhbGxiYWNrIGlzIG5vdCBzYW1wbGUtYWNjdXJhdGUgKGl0IGlzIHN0aWxsIHN1c2NlcHRpYmxlIHRvXG4gKiBsb29zZSBKUyB0aW1pbmcpLCB0aGUgdGltZSBwYXNzZWQgaW4gYXMgdGhlIGFyZ3VtZW50IHRvIHRoZSBjYWxsYmFja1xuICogaXMgcHJlY2lzZS4gRm9yIG1vc3QgYXBwbGljYXRpb25zLCBpdCBpcyBiZXR0ZXIgdG8gdXNlIFRvbmUuVHJhbnNwb3J0XG4gKiBpbnN0ZWFkIG9mIHRoZSBDbG9jayBieSBpdHNlbGYgc2luY2UgeW91IGNhbiBzeW5jaHJvbml6ZSBtdWx0aXBsZSBjYWxsYmFja3MuXG4gKiBAZXhhbXBsZVxuICogLy8gdGhlIGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZCBhcHByb3hpbWF0ZWx5IG9uY2UgYSBzZWNvbmRcbiAqIC8vIGFuZCB3aWxsIHByaW50IHRoZSB0aW1lIGV4YWN0bHkgb25jZSBhIHNlY29uZCBhcGFydC5cbiAqIGNvbnN0IGNsb2NrID0gbmV3IFRvbmUuQ2xvY2sodGltZSA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKHRpbWUpO1xuICogfSwgMSk7XG4gKiBjbG9jay5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIENsb2NrIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2xvY2suZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNsb2NrXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIGF0IHRoZSBzY2hlZHVsZWQgdGljay5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBub09wO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxhc3QgdGltZSB0aGUgbG9vcCBjYWxsYmFjayB3YXMgaW52b2tlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbGFzdFVwZGF0ZSA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBwbGF5YmFjayBzdGF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZShcInN0b3BwZWRcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb250ZXh0IGJvdW5kIHJlZmVyZW5jZSB0byB0aGUgX2xvb3AgbWV0aG9kXG4gICAgICAgICAqIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIHJlbW92ZSB0aGUgZXZlbnQgaW4gdGhlIGVuZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kTG9vcCA9IHRoaXMuX2xvb3AuYmluZCh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENsb2NrLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZSA9IG5ldyBUaWNrU291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSAwO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX3RpY2tTb3VyY2UuZnJlcXVlbmN5O1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgLy8gYWRkIGFuIGluaXRpYWwgc3RhdGVcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIDApO1xuICAgICAgICAvLyBiaW5kIGEgY2FsbGJhY2sgdG8gdGhlIHdvcmtlciB0aHJlYWRcbiAgICAgICAgdGhpcy5jb250ZXh0Lm9uKFwidGlja1wiLCB0aGlzLl9ib3VuZExvb3ApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiIG9yIFwicGF1c2VkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBjbG9jayBhdCB0aGUgZ2l2ZW4gdGltZS4gT3B0aW9uYWxseSBwYXNzIGluIGFuIG9mZnNldFxuICAgICAqIG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSB0aWNrIGNvdW50ZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgVGhlIHRpbWUgdGhlIGNsb2NrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSBvZmZzZXQgIFdoZXJlIHRoZSB0aWNrIGNvdW50ZXIgc3RhcnRzIGNvdW50aW5nIGZyb20uXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgY29udGV4dCBpcyBydW5uaW5nXG4gICAgICAgIGFzc2VydENvbnRleHRSdW5uaW5nKHRoaXMuY29udGV4dCk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBsb29wXG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChjb21wdXRlZFRpbWUgPCB0aGlzLl9sYXN0VXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lLCBvZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBjbG9jay4gU3RvcHBpbmcgdGhlIGNsb2NrIHJlc2V0cyB0aGUgdGljayBjb3VudGVyIHRvIDAuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjbG9jayA9IG5ldyBUb25lLkNsb2NrKHRpbWUgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2codGltZSk7XG4gICAgICogfSwgMSk7XG4gICAgICogY2xvY2suc3RhcnQoKTtcbiAgICAgKiAvLyBzdG9wIHRoZSBjbG9jayBhZnRlciAxMCBzZWNvbmRzXG4gICAgICogY2xvY2suc3RvcChcIisxMFwiKTtcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgY2xvY2suIFBhdXNpbmcgZG9lcyBub3QgcmVzZXQgdGhlIHRpY2sgY291bnRlci5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwicGF1c2VkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLnBhdXNlKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInBhdXNlXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBTdGFydHMgY291bnRpbmcgYXQgMFxuICAgICAqIGFuZCBpbmNyZW1lbnRzIGFmdGVyIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC5cbiAgICAgKi9cbiAgICBnZXQgdGlja3MoKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy5nZXRUaWNrc0F0VGltZSh0aGlzLm5vdygpKSk7XG4gICAgfVxuICAgIHNldCB0aWNrcyh0KSB7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UudGlja3MgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBzaW5jZSB0aWNrcz0wIHRoYXQgdGhlIENsb2NrIGhhcyBiZWVuIHJ1bm5pbmcuIEFjY291bnRzIGZvciB0ZW1wbyBjdXJ2ZXNcbiAgICAgKi9cbiAgICBnZXQgc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2Uuc2Vjb25kcztcbiAgICB9XG4gICAgc2V0IHNlY29uZHMocykge1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnNlY29uZHMgPSBzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqL1xuICAgIGdldFNlY29uZHNBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRTZWNvbmRzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aWNrcyBUaGUgdGljayB2YWx1ZSB0byBzZXRcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICovXG4gICAgc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zZXRUaWNrc0F0VGltZSh0aWNrcywgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGdpdmVuIHRpY2suIFRoZSBzZWNvbmQgYXJndW1lbnRcbiAgICAgKiBpcyB3aGVuIHRvIHRlc3QgYmVmb3JlLiBTaW5jZSB0aWNrcyBjYW4gYmUgc2V0ICh3aXRoIHNldFRpY2tzQXRUaW1lKVxuICAgICAqIHRoZXJlIG1heSBiZSBtdWx0aXBsZSB0aW1lcyBmb3IgYSBnaXZlbiB0aWNrIHZhbHVlLlxuICAgICAqIEBwYXJhbSAgdGljayBUaGUgdGljayBudW1iZXIuXG4gICAgICogQHBhcmFtICBiZWZvcmUgV2hlbiB0byBtZWFzdXJlIHRoZSB0aWNrIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGUgdGlja1xuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaywgYmVmb3JlID0gdGhpcy5ub3coKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRUaW1lT2ZUaWNrKHRpY2ssIGJlZm9yZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICogQHJldHVybiBUaGUgdGljayB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIG5leHQgdGlja1xuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSB0aWNrIG51bWJlci5cbiAgICAgKi9cbiAgICBuZXh0VGlja1RpbWUob2Zmc2V0LCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBjb25zdCBjdXJyZW50VGljayA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGltZU9mVGljayhjdXJyZW50VGljayArIG9mZnNldCwgY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNjaGVkdWxpbmcgbG9vcC5cbiAgICAgKi9cbiAgICBfbG9vcCgpIHtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gdGhpcy5fbGFzdFVwZGF0ZTtcbiAgICAgICAgY29uc3QgZW5kVGltZSA9IHRoaXMubm93KCk7XG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSBlbmRUaW1lO1xuICAgICAgICB0aGlzLmxvZyhcImxvb3BcIiwgc3RhcnRUaW1lLCBlbmRUaW1lKTtcbiAgICAgICAgaWYgKHN0YXJ0VGltZSAhPT0gZW5kVGltZSkge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXRlIGNoYW5nZSBldmVudHNcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZSA9PiB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlLnN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzdGFydGVkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLl90aWNrU291cmNlLmdldFRpY2tzQXRUaW1lKGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiLCBlLnRpbWUsIG9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0b3BwZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlLnRpbWUgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdG9wXCIsIGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBhdXNlZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwicGF1c2VcIiwgZS50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gdGhlIHRpY2sgY2FsbGJhY2tzXG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLmZvckVhY2hUaWNrQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsICh0aW1lLCB0aWNrcykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdGlja3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybiAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY2xvY2sgPSBuZXcgVG9uZS5DbG9jaygpO1xuICAgICAqIGNsb2NrLnN0YXJ0KFwiKzAuMVwiKTtcbiAgICAgKiBjbG9jay5nZXRTdGF0ZUF0VGltZShcIiswLjFcIik7IC8vIHJldHVybnMgXCJzdGFydGVkXCJcbiAgICAgKi9cbiAgICBnZXRTdGF0ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC5vZmYoXCJ0aWNrXCIsIHRoaXMuX2JvdW5kTG9vcCk7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbkVtaXR0ZXIubWl4aW4oQ2xvY2spO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2xvY2suanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIFdlYiBBdWRpbydzIG5hdGl2ZSBbRGVsYXlOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1kZWxheW5vZGUtaW50ZXJmYWNlKS5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGRlbGF5ID0gbmV3IFRvbmUuRGVsYXkoMC4xKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIGNvbm5lY3QgdGhlIHNpZ25hbCB0byBib3RoIHRoZSBkZWxheSBhbmQgdGhlIGRlc3RpbmF0aW9uXG4gKiBcdGNvbnN0IHB1bHNlID0gbmV3IFRvbmUuUHVsc2VPc2NpbGxhdG9yKCkuY29ubmVjdChkZWxheSkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBzdGFydCBhbmQgc3RvcCB0aGUgcHVsc2VcbiAqIFx0cHVsc2Uuc3RhcnQoMCkuc3RvcCgwLjAxKTtcbiAqIH0sIDAuNSwgMSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBEZWxheSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcIm1heERlbGF5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGVsYXlcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKERlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwibWF4RGVsYXlcIl0pO1xuICAgICAgICBjb25zdCBtYXhEZWxheUluU2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKG9wdGlvbnMubWF4RGVsYXkpO1xuICAgICAgICB0aGlzLl9tYXhEZWxheSA9IE1hdGgubWF4KG1heERlbGF5SW5TZWNvbmRzLCB0aGlzLnRvU2Vjb25kcyhvcHRpb25zLmRlbGF5VGltZSkpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlRGVsYXkobWF4RGVsYXlJblNlY29uZHMpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZGVsYXlOb2RlLmRlbGF5VGltZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIG1pblZhbHVlOiAwLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMCxcbiAgICAgICAgICAgIG1heERlbGF5OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gZGVsYXkgdGltZS4gVGhpcyBjYW5ub3QgYmUgY2hhbmdlZCBhZnRlclxuICAgICAqIHRoZSB2YWx1ZSBpcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IuXG4gICAgICovXG4gICAgZ2V0IG1heERlbGF5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWF4RGVsYXk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGdldENvbnRleHQsIHNldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuL09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9Ub25lQXVkaW9CdWZmZXJcIjtcbi8qKlxuICogR2VuZXJhdGUgYSBidWZmZXIgYnkgcmVuZGVyaW5nIGFsbCBvZiB0aGUgVG9uZS5qcyBjb2RlIHdpdGhpbiB0aGUgY2FsbGJhY2sgdXNpbmcgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gKiBUaGUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpcyBjYXBhYmxlIG9mIHJlbmRlcmluZyBtdWNoIGZhc3RlciB0aGFuIHJlYWwgdGltZSBpbiBtYW55IGNhc2VzLlxuICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGFsc28gcGFzc2VzIGluIGFuIG9mZmxpbmUgaW5zdGFuY2Ugb2YgW1tDb250ZXh0XV0gd2hpY2ggY2FuIGJlIHVzZWRcbiAqIHRvIHNjaGVkdWxlIGV2ZW50cyBhbG9uZyB0aGUgVHJhbnNwb3J0LlxuICogQHBhcmFtICBjYWxsYmFjayAgQWxsIFRvbmUuanMgbm9kZXMgd2hpY2ggYXJlIGNyZWF0ZWQgYW5kIHNjaGVkdWxlZCB3aXRoaW4gdGhpcyBjYWxsYmFjayBhcmUgcmVjb3JkZWQgaW50byB0aGUgb3V0cHV0IEJ1ZmZlci5cbiAqIEBwYXJhbSAgZHVyYXRpb24gICAgIHRoZSBhbW91bnQgb2YgdGltZSB0byByZWNvcmQgZm9yLlxuICogQHJldHVybiAgVGhlIHByb21pc2Ugd2hpY2ggaXMgaW52b2tlZCB3aXRoIHRoZSBUb25lQXVkaW9CdWZmZXIgb2YgdGhlIHJlY29yZGVkIG91dHB1dC5cbiAqIEBleGFtcGxlXG4gKiAvLyByZW5kZXIgMiBzZWNvbmRzIG9mIHRoZSBvc2NpbGxhdG9yXG4gKiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHQvLyBvbmx5IG5vZGVzIGNyZWF0ZWQgaW4gdGhpcyBjYWxsYmFjayB3aWxsIGJlIHJlY29yZGVkXG4gKiBcdGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KDApO1xuICogfSwgMikudGhlbigoYnVmZmVyKSA9PiB7XG4gKiBcdC8vIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBvdXRwdXQgYnVmZmVyXG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlcik7XG4gKiB9KTtcbiAqIEBleGFtcGxlXG4gKiAvLyBjYW4gYWxzbyBzY2hlZHVsZSBldmVudHMgYWxvbmcgdGhlIFRyYW5zcG9ydFxuICogLy8gdXNpbmcgdGhlIHBhc3NlZCBpbiBPZmZsaW5lIFRyYW5zcG9ydFxuICogVG9uZS5PZmZsaW5lKCh7IHRyYW5zcG9ydCB9KSA9PiB7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdHRyYW5zcG9ydC5zY2hlZHVsZSh0aW1lID0+IHtcbiAqIFx0XHRvc2Muc3RhcnQodGltZSkuc3RvcCh0aW1lICsgMC4xKTtcbiAqIFx0fSwgMSk7XG4gKiBcdC8vIG1ha2Ugc3VyZSB0byBzdGFydCB0aGUgdHJhbnNwb3J0XG4gKiBcdHRyYW5zcG9ydC5zdGFydCgwLjIpO1xuICogfSwgNCkudGhlbigoYnVmZmVyKSA9PiB7XG4gKiBcdC8vIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBvdXRwdXQgYnVmZmVyXG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlcik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBPZmZsaW5lKGNhbGxiYWNrLCBkdXJhdGlvbiwgY2hhbm5lbHMgPSAyLCBzYW1wbGVSYXRlID0gZ2V0Q29udGV4dCgpLnNhbXBsZVJhdGUpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAvLyBzZXQgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHQgYmFzZWQgb24gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgICAgICBjb25zdCBvcmlnaW5hbENvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoY2hhbm5lbHMsIGR1cmF0aW9uLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFjay9zY2hlZHVsaW5nXG4gICAgICAgIHlpZWxkIGNhbGxiYWNrKGNvbnRleHQpO1xuICAgICAgICAvLyB0aGVuIHJlbmRlciB0aGUgYXVkaW9cbiAgICAgICAgY29uc3QgYnVmZmVyUHJvbWlzZSA9IGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgb3JpZ2luYWwgQXVkaW9Db250ZXh0XG4gICAgICAgIHNldENvbnRleHQob3JpZ2luYWxDb250ZXh0KTtcbiAgICAgICAgLy8gYXdhaXQgdGhlIHJlbmRlcmluZ1xuICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBidWZmZXJQcm9taXNlO1xuICAgICAgICAvLyByZXR1cm4gdGhlIGF1ZGlvXG4gICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKGJ1ZmZlcik7XG4gICAgfSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PZmZsaW5lLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQSBkYXRhIHN0cnVjdHVyZSBmb3IgaG9sZGluZyBtdWx0aXBsZSBidWZmZXJzIGluIGEgTWFwLWxpa2UgZGF0YXN0cnVjdHVyZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGlhbm9TYW1wbGVzID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVycyh7XG4gKiBcdEExOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9BMS5tcDNcIixcbiAqIFx0QTI6IFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL0EyLm1wM1wiLFxuICogfSwgKCkgPT4ge1xuICogXHRjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIHBsYXkgb25lIG9mIHRoZSBzYW1wbGVzIHdoZW4gdGhleSBhbGwgbG9hZFxuICogXHRwbGF5ZXIuYnVmZmVyID0gcGlhbm9TYW1wbGVzLmdldChcIkEyXCIpO1xuICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAqIH0pO1xuICogQGV4YW1wbGVcbiAqIC8vIFRvIHBhc3MgaW4gYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGluIHRoZSBzZWNvbmQgcGFyYW1ldGVyXG4gKiBjb25zdCBidWZmZXJzID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVycyh7XG4gKiBcdCB1cmxzOiB7XG4gKiBcdFx0IEExOiBcIkExLm1wM1wiLFxuICogXHRcdCBBMjogXCJBMi5tcDNcIixcbiAqIFx0IH0sXG4gKiBcdCBvbmxvYWQ6ICgpID0+IGNvbnNvbGUubG9nKFwibG9hZGVkXCIpLFxuICogXHQgYmFzZVVybDogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vXCJcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb0J1ZmZlcnMgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9CdWZmZXJzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGJ1ZmZlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgbG9hZGVkIGJ1ZmZlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudCA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQXVkaW9CdWZmZXJzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiLCBcImJhc2VVcmxcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgdGhpcy5iYXNlVXJsID0gb3B0aW9ucy5iYXNlVXJsO1xuICAgICAgICAvLyBhZGQgZWFjaCBvbmVcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucy51cmxzKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50Kys7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBvcHRpb25zLnVybHNbbmFtZV07XG4gICAgICAgICAgICB0aGlzLmFkZChuYW1lLCB1cmwsIHRoaXMuX2J1ZmZlckxvYWRlZC5iaW5kKHRoaXMsIG9wdGlvbnMub25sb2FkKSwgb3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRydWUgaWYgdGhlIGJ1ZmZlcnMgb2JqZWN0IGhhcyBhIGJ1ZmZlciBieSB0aGF0IG5hbWUuXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUga2V5IG9yIGluZGV4IG9mIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMuaGFzKG5hbWUudG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIGJ1ZmZlciBieSBuYW1lLiBJZiBhbiBhcnJheSB3YXMgbG9hZGVkLFxuICAgICAqIHRoZW4gdXNlIHRoZSBhcnJheSBpbmRleC5cbiAgICAgKiBAcGFyYW0gIG5hbWUgIFRoZSBrZXkgb3IgaW5kZXggb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBnZXQobmFtZSkge1xuICAgICAgICBhc3NlcnQodGhpcy5oYXMobmFtZSksIGBUb25lQXVkaW9CdWZmZXJzIGhhcyBubyBidWZmZXIgbmFtZWQ6ICR7bmFtZX1gKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMuZ2V0KG5hbWUudG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgYnVmZmVyIHdhcyBsb2FkZWQuIGRlY3JlbWVudCB0aGUgY291bnRlci5cbiAgICAgKi9cbiAgICBfYnVmZmVyTG9hZGVkKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudC0tO1xuICAgICAgICBpZiAodGhpcy5fbG9hZGluZ0NvdW50ID09PSAwICYmIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXJzIGFyZSBsb2FkZWQgb3Igbm90XG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5fYnVmZmVycykuZXZlcnkoKFtfLCBidWZmZXJdKSA9PiBidWZmZXIubG9hZGVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgYnVmZmVyIGJ5IG5hbWUgYW5kIHVybCB0byB0aGUgQnVmZmVyc1xuICAgICAqIEBwYXJhbSAgbmFtZSAgICAgIEEgdW5pcXVlIG5hbWUgdG8gZ2l2ZSB0aGUgYnVmZmVyXG4gICAgICogQHBhcmFtICB1cmwgIEVpdGhlciB0aGUgdXJsIG9mIHRoZSBidWZlciwgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cbiAgICAgKiBAcGFyYW0gIG9uZXJyb3IgIEludm9rZWQgaWYgdGhlIGJ1ZmZlciBjYW4ndCBiZSBsb2FkZWRcbiAgICAgKi9cbiAgICBhZGQobmFtZSwgdXJsLCBjYWxsYmFjayA9IG5vT3AsIG9uZXJyb3IgPSBub09wKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyh1cmwpKSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLnNldChuYW1lLnRvU3RyaW5nKCksIG5ldyBUb25lQXVkaW9CdWZmZXIodGhpcy5iYXNlVXJsICsgdXJsLCBjYWxsYmFjaywgb25lcnJvcikpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5zZXQobmFtZS50b1N0cmluZygpLCBuZXcgVG9uZUF1ZGlvQnVmZmVyKHVybCwgY2FsbGJhY2ssIG9uZXJyb3IpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmZvckVhY2goYnVmZmVyID0+IGJ1ZmZlci5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb0J1ZmZlcnMuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IGZ0b20sIG10b2YgfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi9GcmVxdWVuY3lcIjtcbi8qKlxuICogTWlkaSBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIE1pZGkgY2FuIGJlIGNvbnN0cnVjdGVkIHdpdGggb3Igd2l0aG91dCB0aGUgYG5ld2Aga2V5d29yZC4gTWlkaSBjYW4gYmUgcGFzc2VkXG4gKiBpbnRvIHRoZSBwYXJhbWV0ZXIgb2YgYW55IG1ldGhvZCB3aGljaCB0YWtlcyB0aW1lIGFzIGFuIGFyZ3VtZW50LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZGlDbGFzcyBleHRlbmRzIEZyZXF1ZW5jeUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRpQ2xhc3NcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcIm1pZGlcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBmcmVxdWVuY3kgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfZnJlcXVlbmN5VG9Vbml0cyhmcmVxKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl90aWNrc1RvVW5pdHModGlja3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl9iZWF0c1RvVW5pdHMoYmVhdHMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgYXMgYSBNSURJIG5vdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaSg2MCkudG9NaWRpKCk7IC8vIDYwXG4gICAgICovXG4gICAgdG9NaWRpKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5NaWRpKDYwKS50b0ZyZXF1ZW5jeSgpOyAvLyAyNjEuNjI1NTY1MzAwNTk4NlxuICAgICAqL1xuICAgIHRvRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gbXRvZih0aGlzLnRvTWlkaSgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJhbnNwb3NlcyB0aGUgZnJlcXVlbmN5IGJ5IHRoZSBnaXZlbiBudW1iZXIgb2Ygc2VtaXRvbmVzLlxuICAgICAqIEByZXR1cm4gQSBuZXcgdHJhbnNwb3NlZCBNaWRpQ2xhc3NcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaShcIkE0XCIpLnRyYW5zcG9zZSgzKTsgLy8gXCJDNVwiXG4gICAgICovXG4gICAgdHJhbnNwb3NlKGludGVydmFsKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy50b01pZGkoKSArIGludGVydmFsKTtcbiAgICB9XG59XG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIGEgRnJlcXVlbmN5Q2xhc3Mgb2JqZWN0LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE1pZGkodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBNaWRpQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkaS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4vVHJhbnNwb3J0VGltZVwiO1xuLyoqXG4gKiBUaWNrcyBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIFRpY2tzIGNhbiBiZSBjb25zdHJ1Y3RlZCB3aXRoIG9yIHdpdGhvdXQgdGhlIGBuZXdgIGtleXdvcmQuIFRpY2tzIGNhbiBiZSBwYXNzZWRcbiAqIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdCA9IFRvbmUuVGlja3MoXCI0blwiKTsgLy8gYSBxdWFydGVyIG5vdGUgYXMgdGlja3NcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrc0NsYXNzIGV4dGVuZHMgVHJhbnNwb3J0VGltZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrc1wiO1xuICAgICAgICB0aGlzLmRlZmF1bHRVbml0cyA9IFwiaVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdGltZSBpbiB0aGUgZ2l2ZW4gdW5pdHNcbiAgICAgKi9cbiAgICBfbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRQUFEoKSAqIGJlYXRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKHNlY29uZHMgLyAoNjAgLyB0aGlzLl9nZXRCcG0oKSkgKiB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gdGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiB0aWNrc1xuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNlY29uZHNcbiAgICAgKi9cbiAgICB0b1NlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy52YWx1ZU9mKCkgLyB0aGlzLl9nZXRQUFEoKSkgKiAoNjAgLyB0aGlzLl9nZXRCcG0oKSk7XG4gICAgfVxufVxuLyoqXG4gKiBDb252ZXJ0IGEgdGltZSByZXByZXNlbnRhdGlvbiB0byB0aWNrc1xuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFRpY2tzKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrcy5qcy5tYXAiLCJpbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4uL2NvbnRleHQvQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG4vKipcbiAqIERyYXcgaXMgdXNlZnVsIGZvciBzeW5jaHJvbml6aW5nIHZpc3VhbHMgYW5kIGF1ZGlvIGV2ZW50cy5cbiAqIENhbGxiYWNrcyBmcm9tIFRvbmUuVHJhbnNwb3J0IG9yIGFueSBvZiB0aGUgVG9uZS5FdmVudCBjbGFzc2VzXG4gKiBhbHdheXMgaGFwcGVuIF9iZWZvcmVfIHRoZSBzY2hlZHVsZWQgdGltZSBhbmQgYXJlIG5vdCBzeW5jaHJvbml6ZWRcbiAqIHRvIHRoZSBhbmltYXRpb24gZnJhbWUgc28gdGhleSBhcmUgbm90IGdvb2QgZm9yIHRyaWdnZXJpbmcgdGlnaHRseVxuICogc3luY2hyb25pemVkIHZpc3VhbHMgYW5kIHNvdW5kLiBEcmF3IG1ha2VzIGl0IGVhc3kgdG8gc2NoZWR1bGVcbiAqIGNhbGxiYWNrcyB1c2luZyB0aGUgQXVkaW9Db250ZXh0IHRpbWUgYW5kIHVzZXMgcmVxdWVzdEFuaW1hdGlvbkZyYW1lLlxuICogQGV4YW1wbGVcbiAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKCh0aW1lKSA9PiB7XG4gKiBcdC8vIHVzZSB0aGUgdGltZSBhcmd1bWVudCB0byBzY2hlZHVsZSBhIGNhbGxiYWNrIHdpdGggRHJhd1xuICogXHRUb25lLkRyYXcuc2NoZWR1bGUoKCkgPT4ge1xuICogXHRcdC8vIGRvIGRyYXdpbmcgb3IgRE9NIG1hbmlwdWxhdGlvbiBoZXJlXG4gKiBcdFx0Y29uc29sZS5sb2codGltZSk7XG4gKiBcdH0sIHRpbWUpO1xuICogfSwgXCIrMC41XCIpO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBEcmF3IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEcmF3XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZHVyYXRpb24gYWZ0ZXIgd2hpY2ggZXZlbnRzIGFyZSBub3QgaW52b2tlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZXhwaXJhdGlvbiA9IDAuMjU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgYmVmb3JlIHRoZSBzY2hlZHVsZWQgdGltZVxuICAgICAgICAgKiB0aGF0IHRoZSBjYWxsYmFjayBjYW4gYmUgaW52b2tlZC4gRGVmYXVsdCBpc1xuICAgICAgICAgKiBoYWxmIHRoZSB0aW1lIG9mIGFuIGFuaW1hdGlvbiBmcmFtZSAoMC4wMDggc2Vjb25kcykuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFudGljaXBhdGlvbiA9IDAuMDA4O1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBldmVudHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkcmF3IGxvb3BcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kRHJhd0xvb3AgPSB0aGlzLl9kcmF3TG9vcC5iaW5kKHRoaXMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFuaW1hdGlvbiBmcmFtZSBpZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSAtMTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYSBmdW5jdGlvbiBhdCB0aGUgZ2l2ZW4gdGltZSB0byBiZSBpbnZva2VkXG4gICAgICogb24gdGhlIG5lYXJlc3QgYW5pbWF0aW9uIGZyYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIENhbGxiYWNrIGlzIGludm9rZWQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICAgICAgVGhlIHRpbWUgcmVsYXRpdmUgdG8gdGhlIEF1ZGlvQ29udGV4dCB0aW1lIHRvIGludm9rZSB0aGUgY2FsbGJhY2suXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCh0aW1lID0+IHtcbiAgICAgKiBcdFRvbmUuRHJhdy5zY2hlZHVsZSgoKSA9PiBjb25zb2xlLmxvZyh0aW1lKSwgdGltZSk7XG4gICAgICogfSwgMSk7XG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKi9cbiAgICBzY2hlZHVsZShjYWxsYmFjaywgdGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgdGltZTogdGhpcy50b1NlY29uZHModGltZSksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB0aGUgZHJhdyBsb29wIG9uIHRoZSBmaXJzdCBldmVudFxuICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fYm91bmREcmF3TG9vcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICBhZnRlciAgVGltZSBhZnRlciB3aGljaCBzY2hlZHVsZWQgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBzY2hlZHVsaW5nIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKHRoaXMudG9TZWNvbmRzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHJhdyBsb29wXG4gICAgICovXG4gICAgX2RyYXdMb29wKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIHdoaWxlICh0aGlzLl9ldmVudHMubGVuZ3RoICYmIHRoaXMuX2V2ZW50cy5wZWVrKCkudGltZSAtIHRoaXMuYW50aWNpcGF0aW9uIDw9IG5vdykge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9ldmVudHMuc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChldmVudCAmJiBub3cgLSBldmVudC50aW1lIDw9IHRoaXMuZXhwaXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGV2ZW50LmNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9hbmltYXRpb25GcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLl9ib3VuZERyYXdMb29wKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuX2FuaW1hdGlvbkZyYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOSVRJQUxJWkFUSU9OXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbm9uQ29udGV4dEluaXQoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kcmF3ID0gbmV3IERyYXcoeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRyYXcuZGlzcG9zZSgpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EcmF3LmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi9EZWJ1Z1wiO1xuLyoqXG4gKiBTaW1pbGFyIHRvIFRvbmUuVGltZWxpbmUsIGJ1dCBhbGwgZXZlbnRzIHJlcHJlc2VudFxuICogaW50ZXJ2YWxzIHdpdGggYm90aCBcInRpbWVcIiBhbmQgXCJkdXJhdGlvblwiIHRpbWVzLiBUaGVcbiAqIGV2ZW50cyBhcmUgcGxhY2VkIGluIGEgdHJlZSBzdHJ1Y3R1cmUgb3B0aW1pemVkXG4gKiBmb3IgcXVlcnlpbmcgYW4gaW50ZXJzZWN0aW9uIHBvaW50IHdpdGggdGhlIHRpbWVsaW5lXG4gKiBldmVudHMuIEludGVybmFsbHkgdXNlcyBhbiBbSW50ZXJ2YWwgVHJlZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW50ZXJ2YWxfdHJlZSlcbiAqIHRvIHJlcHJlc2VudCB0aGUgZGF0YS5cbiAqL1xuZXhwb3J0IGNsYXNzIEludGVydmFsVGltZWxpbmUgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJJbnRlcnZhbFRpbWVsaW5lXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcm9vdCBub2RlIG9mIHRoZSBpbnRldmFsIHRyZWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgbGVuZ3RoIG9mIHRoZSB0aW1lbGluZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xlbmd0aCA9IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCB0byBhZGQgdG8gdGhlIHRpbWVsaW5lLiBBbGwgZXZlbnRzIG11c3RcbiAgICAgKiBoYXZlIGEgdGltZSBhbmQgZHVyYXRpb24gdmFsdWVcbiAgICAgKiBAcGFyYW0gIGV2ZW50ICBUaGUgZXZlbnQgdG8gYWRkIHRvIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIGFkZChldmVudCkge1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKGV2ZW50LnRpbWUpLCBcIkV2ZW50cyBtdXN0IGhhdmUgYSB0aW1lIHByb3BlcnR5XCIpO1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKGV2ZW50LmR1cmF0aW9uKSwgXCJFdmVudHMgbXVzdCBoYXZlIGEgZHVyYXRpb24gcGFyYW1ldGVyXCIpO1xuICAgICAgICBldmVudC50aW1lID0gZXZlbnQudGltZS52YWx1ZU9mKCk7XG4gICAgICAgIGxldCBub2RlID0gbmV3IEludGVydmFsTm9kZShldmVudC50aW1lLCBldmVudC50aW1lICsgZXZlbnQuZHVyYXRpb24sIGV2ZW50KTtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5pbnNlcnQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbGVuZ3RoKys7XG4gICAgICAgIC8vIFJlc3RydWN0dXJlIHRyZWUgdG8gYmUgYmFsYW5jZWRcbiAgICAgICAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUudXBkYXRlSGVpZ2h0KCk7XG4gICAgICAgICAgICBub2RlLnVwZGF0ZU1heCgpO1xuICAgICAgICAgICAgdGhpcy5fcmViYWxhbmNlKG5vZGUpO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYW4gZXZlbnQgZnJvbSB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIHJlbW92ZSBmcm9tIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIHJlbW92ZShldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2goZXZlbnQudGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgcmVzdWx0cykge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50ID09PSBldmVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVOb2RlKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sZW5ndGgtLTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGl0ZW1zIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcmVhZE9ubHlcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgZXZlbnRzIHdob3NlIHRpbWUgdGltZSBpcyBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgYWZ0ZXIgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLmZvckVhY2hGcm9tKGFmdGVyLCBldmVudCA9PiB0aGlzLnJlbW92ZShldmVudCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSByb290IG5vZGUgYXMgdGhlIGdpdmVuIG5vZGVcbiAgICAgKi9cbiAgICBfc2V0Um9vdChub2RlKSB7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBub2RlO1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5wYXJlbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2UgdGhlIHJlZmVyZW5jZXMgdG8gdGhlIG5vZGUgaW4gdGhlIG5vZGUncyBwYXJlbnRcbiAgICAgKiB3aXRoIHRoZSByZXBsYWNlbWVudCBub2RlLlxuICAgICAqL1xuICAgIF9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIHJlcGxhY2VtZW50KSB7XG4gICAgICAgIGlmIChub2RlLnBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWZ0Q2hpbGQoKSkge1xuICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LnJpZ2h0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2Uobm9kZS5wYXJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChyZXBsYWNlbWVudCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoZSBub2RlIGZyb20gdGhlIHRyZWUgYW5kIHJlcGxhY2UgaXQgd2l0aFxuICAgICAqIGEgc3VjY2Vzc29yIHdoaWNoIGZvbGxvd3MgdGhlIHNjaGVtYS5cbiAgICAgKi9cbiAgICBfcmVtb3ZlTm9kZShub2RlKSB7XG4gICAgICAgIGlmIChub2RlLmxlZnQgPT09IG51bGwgJiYgbm9kZS5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChub2RlLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG5vZGUubGVmdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobm9kZS5sZWZ0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG5vZGUucmlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYmFsYW5jZSA9IG5vZGUuZ2V0QmFsYW5jZSgpO1xuICAgICAgICAgICAgbGV0IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgbGV0IHRlbXAgPSBudWxsO1xuICAgICAgICAgICAgaWYgKGJhbGFuY2UgPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUubGVmdC5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUubGVmdC5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlcGxhY2VtZW50LnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXBsYWNlbWVudC5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50LmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQucGFyZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQubGVmdCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnJpZ2h0ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUucmlnaHQubGVmdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5yaWdodC5sZWZ0O1xuICAgICAgICAgICAgICAgIHdoaWxlIChyZXBsYWNlbWVudC5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQubGVmdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlcGxhY2VtZW50LnBhcmVudCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5wYXJlbnQubGVmdCA9IHJlcGxhY2VtZW50LnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQucGFyZW50O1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5yaWdodCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vZGUucGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWZ0Q2hpbGQoKSkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5sZWZ0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocmVwbGFjZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRlbXApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2UodGVtcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5kaXNwb3NlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGUgdHJlZSB0byB0aGUgbGVmdFxuICAgICAqL1xuICAgIF9yb3RhdGVMZWZ0KG5vZGUpIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG4gICAgICAgIGNvbnN0IGlzTGVmdENoaWxkID0gbm9kZS5pc0xlZnRDaGlsZCgpO1xuICAgICAgICAvLyBNYWtlIG5vZGUucmlnaHQgdGhlIG5ldyByb290IG9mIHRoaXMgc3ViIHRyZWUgKGluc3RlYWQgb2Ygbm9kZSlcbiAgICAgICAgY29uc3QgcGl2b3ROb2RlID0gbm9kZS5yaWdodDtcbiAgICAgICAgaWYgKHBpdm90Tm9kZSkge1xuICAgICAgICAgICAgbm9kZS5yaWdodCA9IHBpdm90Tm9kZS5sZWZ0O1xuICAgICAgICAgICAgcGl2b3ROb2RlLmxlZnQgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChpc0xlZnRDaGlsZCkge1xuICAgICAgICAgICAgICAgIHBhcmVudC5sZWZ0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyZW50LnJpZ2h0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChwaXZvdE5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGUgdHJlZSB0byB0aGUgcmlnaHRcbiAgICAgKi9cbiAgICBfcm90YXRlUmlnaHQobm9kZSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudDtcbiAgICAgICAgY29uc3QgaXNMZWZ0Q2hpbGQgPSBub2RlLmlzTGVmdENoaWxkKCk7XG4gICAgICAgIC8vIE1ha2Ugbm9kZS5sZWZ0IHRoZSBuZXcgcm9vdCBvZiB0aGlzIHN1YiB0cmVlIChpbnN0ZWFkIG9mIG5vZGUpXG4gICAgICAgIGNvbnN0IHBpdm90Tm9kZSA9IG5vZGUubGVmdDtcbiAgICAgICAgaWYgKHBpdm90Tm9kZSkge1xuICAgICAgICAgICAgbm9kZS5sZWZ0ID0gcGl2b3ROb2RlLnJpZ2h0O1xuICAgICAgICAgICAgcGl2b3ROb2RlLnJpZ2h0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNMZWZ0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmVudC5yaWdodCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocGl2b3ROb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBCYWxhbmNlIHRoZSBCU1RcbiAgICAgKi9cbiAgICBfcmViYWxhbmNlKG5vZGUpIHtcbiAgICAgICAgY29uc3QgYmFsYW5jZSA9IG5vZGUuZ2V0QmFsYW5jZSgpO1xuICAgICAgICBpZiAoYmFsYW5jZSA+IDEgJiYgbm9kZS5sZWZ0KSB7XG4gICAgICAgICAgICBpZiAobm9kZS5sZWZ0LmdldEJhbGFuY2UoKSA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVMZWZ0KG5vZGUubGVmdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVSaWdodChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiYWxhbmNlIDwgLTEgJiYgbm9kZS5yaWdodCkge1xuICAgICAgICAgICAgaWYgKG5vZGUucmlnaHQuZ2V0QmFsYW5jZSgpID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZVJpZ2h0KG5vZGUucmlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlTGVmdChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYW4gZXZlbnQgd2hvc2UgdGltZSBhbmQgZHVyYXRpb24gc3BhbiB0aGUgZ2l2ZSB0aW1lLiBXaWxsXG4gICAgICogcmV0dXJuIHRoZSBtYXRjaCB3aG9zZSBcInRpbWVcIiB2YWx1ZSBpcyBjbG9zZXN0IHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aGljaCBzcGFucyB0aGUgZGVzaXJlZCB0aW1lXG4gICAgICovXG4gICAgZ2V0KHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoKHRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGxldCBtYXggPSByZXN1bHRzWzBdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0c1tpXS5sb3cgPiBtYXgubG93KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXggPSByZXN1bHRzW2ldO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtYXguZXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgYWxsTm9kZXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QudHJhdmVyc2Uobm9kZSA9PiBhbGxOb2Rlcy5wdXNoKG5vZGUpKTtcbiAgICAgICAgICAgIGFsbE5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBpbiB3aGljaCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIG92ZXJsYXBzIHdpdGggdGhlIHRpbWUgYW5kIGR1cmF0aW9uIHRpbWUgb2YgdGhlIGV2ZW50LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgb3ZlcmxhcHBpbmdcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEF0VGltZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2godGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICByZXN1bHRzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBpbiB3aGljaCB0aGUgdGltZSBpcyBncmVhdGVyXG4gICAgICogdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoRnJvbSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2hBZnRlcih0aW1lLCByZXN1bHRzKTtcbiAgICAgICAgICAgIHJlc3VsdHMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhub2RlLmV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yb290LnRyYXZlcnNlKG5vZGUgPT4gbm9kZS5kaXNwb3NlKCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5URVJWQUwgTk9ERSBIRUxQRVJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBSZXByZXNlbnRzIGEgbm9kZSBpbiB0aGUgYmluYXJ5IHNlYXJjaCB0cmVlLCB3aXRoIHRoZSBhZGRpdGlvblxuICogb2YgYSBcImhpZ2hcIiB2YWx1ZSB3aGljaCBrZWVwcyB0cmFjayBvZiB0aGUgaGlnaGVzdCB2YWx1ZSBvZlxuICogaXRzIGNoaWxkcmVuLlxuICogUmVmZXJlbmNlczpcbiAqIGh0dHBzOi8vYnJvb2tub3Zhay53b3JkcHJlc3MuY29tLzIwMTMvMTIvMDcvYXVnbWVudGVkLWludGVydmFsLXRyZWUtaW4tYy9cbiAqIGh0dHA6Ly93d3cubWlmLnZ1Lmx0L352YWxkYXMvQUxHT1JJVE1BSS9MSVRFUkFUVVJBL0Nvcm1lbi9Db3JtZW4ucGRmXG4gKiBAcGFyYW0gbG93XG4gKiBAcGFyYW0gaGlnaFxuICovXG5jbGFzcyBJbnRlcnZhbE5vZGUge1xuICAgIGNvbnN0cnVjdG9yKGxvdywgaGlnaCwgZXZlbnQpIHtcbiAgICAgICAgLy8gdGhlIG5vZGVzIHRvIHRoZSBsZWZ0XG4gICAgICAgIHRoaXMuX2xlZnQgPSBudWxsO1xuICAgICAgICAvLyB0aGUgbm9kZXMgdG8gdGhlIHJpZ2h0XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIHBhcmVudCBub2RlXG4gICAgICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIG51bWJlciBvZiBjaGlsZCBub2Rlc1xuICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG4gICAgICAgIHRoaXMuZXZlbnQgPSBldmVudDtcbiAgICAgICAgLy8gdGhlIGxvdyB2YWx1ZVxuICAgICAgICB0aGlzLmxvdyA9IGxvdztcbiAgICAgICAgLy8gdGhlIGhpZ2ggdmFsdWVcbiAgICAgICAgdGhpcy5oaWdoID0gaGlnaDtcbiAgICAgICAgLy8gdGhlIGhpZ2ggdmFsdWUgZm9yIHRoaXMgYW5kIGFsbCBjaGlsZCBub2Rlc1xuICAgICAgICB0aGlzLm1heCA9IHRoaXMuaGlnaDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zZXJ0IGEgbm9kZSBpbnRvIHRoZSBjb3JyZWN0IHNwb3QgaW4gdGhlIHRyZWVcbiAgICAgKi9cbiAgICBpbnNlcnQobm9kZSkge1xuICAgICAgICBpZiAobm9kZS5sb3cgPD0gdGhpcy5sb3cpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlZnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnQgPSBub2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0Lmluc2VydChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHQuaW5zZXJ0KG5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlYXJjaCB0aGUgdHJlZSBmb3Igbm9kZXMgd2hpY2ggb3ZlcmxhcFxuICAgICAqIHdpdGggdGhlIGdpdmVuIHBvaW50XG4gICAgICogQHBhcmFtICBwb2ludCAgVGhlIHBvaW50IHRvIHF1ZXJ5XG4gICAgICogQHBhcmFtICByZXN1bHRzICBUaGUgYXJyYXkgdG8gcHV0IHRoZSByZXN1bHRzXG4gICAgICovXG4gICAgc2VhcmNoKHBvaW50LCByZXN1bHRzKSB7XG4gICAgICAgIC8vIElmIHAgaXMgdG8gdGhlIHJpZ2h0IG9mIHRoZSByaWdodG1vc3QgcG9pbnQgb2YgYW55IGludGVydmFsXG4gICAgICAgIC8vIGluIHRoaXMgbm9kZSBhbmQgYWxsIGNoaWxkcmVuLCB0aGVyZSB3b24ndCBiZSBhbnkgbWF0Y2hlcy5cbiAgICAgICAgaWYgKHBvaW50ID4gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBTZWFyY2ggbGVmdCBjaGlsZHJlblxuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmxlZnQuc2VhcmNoKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDaGVjayB0aGlzIG5vZGVcbiAgICAgICAgaWYgKHRoaXMubG93IDw9IHBvaW50ICYmIHRoaXMuaGlnaCA+IHBvaW50KSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgcCBpcyB0byB0aGUgbGVmdCBvZiB0aGUgdGltZSBvZiB0aGlzIGludGVydmFsLFxuICAgICAgICAvLyB0aGVuIGl0IGNhbid0IGJlIGluIGFueSBjaGlsZCB0byB0aGUgcmlnaHQuXG4gICAgICAgIGlmICh0aGlzLmxvdyA+IHBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VhcmNoIHJpZ2h0IGNoaWxkcmVuXG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaChwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VhcmNoIHRoZSB0cmVlIGZvciBub2RlcyB3aGljaCBhcmUgbGVzc1xuICAgICAqIHRoYW4gdGhlIGdpdmVuIHBvaW50XG4gICAgICogQHBhcmFtICBwb2ludCAgVGhlIHBvaW50IHRvIHF1ZXJ5XG4gICAgICogQHBhcmFtICByZXN1bHRzICBUaGUgYXJyYXkgdG8gcHV0IHRoZSByZXN1bHRzXG4gICAgICovXG4gICAgc2VhcmNoQWZ0ZXIocG9pbnQsIHJlc3VsdHMpIHtcbiAgICAgICAgLy8gQ2hlY2sgdGhpcyBub2RlXG4gICAgICAgIGlmICh0aGlzLmxvdyA+PSBwb2ludCkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVmdC5zZWFyY2hBZnRlcihwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2VhcmNoIHRoZSByaWdodCBzaWRlXG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGNhbGxiYWNrIG9uIHRoaXMgZWxlbWVudCBhbmQgYm90aCBpdCdzIGJyYW5jaGVzXG4gICAgICogQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFja1xuICAgICAqL1xuICAgIHRyYXZlcnNlKGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmxlZnQudHJhdmVyc2UoY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGhlaWdodCBvZiB0aGUgbm9kZVxuICAgICAqL1xuICAgIHVwZGF0ZUhlaWdodCgpIHtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IE1hdGgubWF4KHRoaXMubGVmdC5oZWlnaHQsIHRoaXMucmlnaHQuaGVpZ2h0KSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLnJpZ2h0LmhlaWdodCArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMubGVmdC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgaGVpZ2h0IG9mIHRoZSBub2RlXG4gICAgICovXG4gICAgdXBkYXRlTWF4KCkge1xuICAgICAgICB0aGlzLm1heCA9IHRoaXMuaGlnaDtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5tYXggPSBNYXRoLm1heCh0aGlzLm1heCwgdGhpcy5sZWZ0Lm1heCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubWF4ID0gTWF0aC5tYXgodGhpcy5tYXgsIHRoaXMucmlnaHQubWF4KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFsYW5jZSBpcyBob3cgdGhlIGxlYWZzIGFyZSBkaXN0cmlidXRlZCBvbiB0aGUgbm9kZVxuICAgICAqIEByZXR1cm4gIE5lZ2F0aXZlIG51bWJlcnMgYXJlIGJhbGFuY2VkIHRvIHRoZSByaWdodFxuICAgICAqL1xuICAgIGdldEJhbGFuY2UoKSB7XG4gICAgICAgIGxldCBiYWxhbmNlID0gMDtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBiYWxhbmNlID0gdGhpcy5sZWZ0LmhlaWdodCAtIHRoaXMucmlnaHQuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgYmFsYW5jZSA9IHRoaXMubGVmdC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGJhbGFuY2UgPSAtKHRoaXMucmlnaHQuaGVpZ2h0ICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhbGFuY2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHRydWUgaWYgdGhpcyBub2RlIGlzIHRoZSBsZWZ0IGNoaWxkIG9mIGl0cyBwYXJlbnRcbiAgICAgKi9cbiAgICBpc0xlZnRDaGlsZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50ICE9PSBudWxsICYmIHRoaXMucGFyZW50LmxlZnQgPT09IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGdldC9zZXQgdGhlIGxlZnQgbm9kZVxuICAgICAqL1xuICAgIGdldCBsZWZ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGVmdDtcbiAgICB9XG4gICAgc2V0IGxlZnQobm9kZSkge1xuICAgICAgICB0aGlzLl9sZWZ0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUucGFyZW50ID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZU1heCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQvc2V0IHRoZSByaWdodCBub2RlXG4gICAgICovXG4gICAgZ2V0IHJpZ2h0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmlnaHQ7XG4gICAgfVxuICAgIHNldCByaWdodChub2RlKSB7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUucGFyZW50ID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZU1heCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBudWxsIG91dCByZWZlcmVuY2VzLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fbGVmdCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5ldmVudCA9IG51bGw7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW50ZXJ2YWxUaW1lbGluZS5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9jbG9jay9DbG9ja1wiO1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vY2xvY2svVHJhbnNwb3J0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0NvbnRleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvQmFzZUNvbnRleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvRGVsYXlcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvRGVzdGluYXRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvR2FpblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9PZmZsaW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1BhcmFtXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvRnJlcXVlbmN5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL01pZGlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvVGltZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9UaWNrc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgXCIuL3V0aWwvRHJhd1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9FbWl0dGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL0ludGVydmFsVGltZWxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9UaW1lbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmV4cG9ydCB7IGRiVG9HYWluLCBnYWluVG9EYiwgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvLCBmdG9tLCBtdG9mIH0gZnJvbSBcIi4vdHlwZS9Db252ZXJzaW9uc1wiO1xuZXhwb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMsIGRlZmF1bHRBcmcgfSBmcm9tIFwiLi91dGlsL0RlZmF1bHRzXCI7XG4vLyBnZXQgdGhlIHVuaXRzIGFuZCBleHBvcnQgdGhlbSB1bmRlciB0aGUgXCJVbml0XCIgbmFtZXNwYWNlXG5pbXBvcnQgKiBhcyBVbml0IGZyb20gXCIuL3R5cGUvVW5pdHNcIjtcbmV4cG9ydCB7IFVuaXQgfTtcbi8vIGV4cG9ydCB0aGUgZGVidWcgc3R1ZmYgYXMgRGVidWdcbmltcG9ydCAqIGFzIGRlYnVnIGZyb20gXCIuL3V0aWwvRGVidWdcIjtcbmV4cG9ydCB7IGRlYnVnIH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogVm9sdW1lIGlzIGEgc2ltcGxlIHZvbHVtZSBub2RlLCB1c2VmdWwgZm9yIGNyZWF0aW5nIGEgdm9sdW1lIGZhZGVyLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCB2b2wgPSBuZXcgVG9uZS5Wb2x1bWUoLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdCh2b2wpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBWb2x1bWUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVm9sdW1lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVm9sdW1lXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhWb2x1bWUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMub3V0cHV0LmdhaW47XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLl91bm11dGVkVm9sdW1lID0gb3B0aW9ucy52b2x1bWU7XG4gICAgICAgIC8vIHNldCB0aGUgbXV0ZSBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCB2b2wgPSBuZXcgVG9uZS5Wb2x1bWUoLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3Qodm9sKS5zdGFydCgpO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIHZvbC5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9sdW1lLnZhbHVlID09PSAtSW5maW5pdHk7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLm11dGUgJiYgbXV0ZSkge1xuICAgICAgICAgICAgdGhpcy5fdW5tdXRlZFZvbHVtZSA9IHRoaXMudm9sdW1lLnZhbHVlO1xuICAgICAgICAgICAgLy8gbWF5YmUgaXQgc2hvdWxkIHJhbXAgaGVyZT9cbiAgICAgICAgICAgIHRoaXMudm9sdW1lLnZhbHVlID0gLUluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubXV0ZSAmJiAhbXV0ZSkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWUudmFsdWUgPSB0aGlzLl91bm11dGVkVm9sdW1lO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Wb2x1bWUuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgb25Db250ZXh0Q2xvc2UsIG9uQ29udGV4dEluaXQgfSBmcm9tIFwiLi9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4vVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBBIHNpbmdsZSBtYXN0ZXIgb3V0cHV0IHdoaWNoIGlzIGNvbm5lY3RlZCB0byB0aGVcbiAqIEF1ZGlvRGVzdGluYXRpb25Ob2RlIChha2EgeW91ciBzcGVha2VycykuXG4gKiBJdCBwcm92aWRlcyB1c2VmdWwgY29udmVuaWVuY2VzIHN1Y2ggYXMgdGhlIGFiaWxpdHlcbiAqIHRvIHNldCB0aGUgdm9sdW1lIGFuZCBtdXRlIHRoZSBlbnRpcmUgYXBwbGljYXRpb24uXG4gKiBJdCBhbHNvIGdpdmVzIHlvdSB0aGUgYWJpbGl0eSB0byBhcHBseSBtYXN0ZXIgZWZmZWN0cyB0byB5b3VyIGFwcGxpY2F0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnN0YXJ0KCk7XG4gKiAvLyB0aGUgYXVkaW8gd2lsbCBnbyBmcm9tIHRoZSBvc2NpbGxhdG9yIHRvIHRoZSBzcGVha2Vyc1xuICogb3NjaWxsYXRvci5jb25uZWN0KFRvbmUuZ2V0RGVzdGluYXRpb24oKSk7XG4gKiAvLyBhIGNvbnZlbmllbmNlIGZvciBjb25uZWN0aW5nIHRvIHRoZSBtYXN0ZXIgb3V0cHV0IGlzIGFsc28gcHJvdmlkZWQ6XG4gKiBvc2NpbGxhdG9yLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXN0aW5hdGlvbiBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEZXN0aW5hdGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEZXN0aW5hdGlvblwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IFZvbHVtZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2b2x1bWUgb2YgdGhlIG1hc3RlciBvdXRwdXQgaW4gZGVjaWJlbHMuIC1JbmZpbml0eSBpcyBzaWxlbnQsIGFuZCAwIGlzIG5vIGNoYW5nZS5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgICogb3NjLnN0YXJ0KCk7XG4gICAgICAgICAqIC8vIHJhbXAgdGhlIHZvbHVtZSBkb3duIHRvIHNpbGVudCBvdmVyIDEwIHNlY29uZHNcbiAgICAgICAgICogVG9uZS5nZXREZXN0aW5hdGlvbigpLnZvbHVtZS5yYW1wVG8oLUluZmluaXR5LCAxMCk7XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuaW5wdXQudm9sdW1lO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVzdGluYXRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCB0aGlzLm91dHB1dCwgdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5pbnB1dCwgdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24sIHRoaXMub3V0cHV0XTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgKiBcdC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIFx0VG9uZS5EZXN0aW5hdGlvbi5tdXRlID0gdHJ1ZTtcbiAgICAgKiB9LCAxMDAwKTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLmlucHV0Lm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBtYXN0ZXIgZWZmZWN0cyBjaGFpbi4gTk9URTogdGhpcyB3aWxsIGRpc2Nvbm5lY3QgYW55IG5vZGVzIHdoaWNoIHdlcmUgcHJldmlvdXNseVxuICAgICAqIGNoYWluZWQgaW4gdGhlIG1hc3RlciBlZmZlY3RzIGNoYWluLlxuICAgICAqIEBwYXJhbSBhcmdzIEFsbCBhcmd1bWVudHMgd2lsbCBiZSBjb25uZWN0ZWQgaW4gYSByb3cgYW5kIHRoZSBNYXN0ZXIgd2lsbCBiZSByb3V0ZWQgdGhyb3VnaCBpdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHJvdXRlIGFsbCBhdWRpbyB0aHJvdWdoIGEgZmlsdGVyIGFuZCBjb21wcmVzc29yXG4gICAgICogY29uc3QgbG93cGFzcyA9IG5ldyBUb25lLkZpbHRlcig4MDAsIFwibG93cGFzc1wiKTtcbiAgICAgKiBjb25zdCBjb21wcmVzc29yID0gbmV3IFRvbmUuQ29tcHJlc3NvcigtMTgpO1xuICAgICAqIFRvbmUuRGVzdGluYXRpb24uY2hhaW4obG93cGFzcywgY29tcHJlc3Nvcik7XG4gICAgICovXG4gICAgY2hhaW4oLi4uYXJncykge1xuICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgYXJncy51bnNoaWZ0KHRoaXMuaW5wdXQpO1xuICAgICAgICBhcmdzLnB1c2godGhpcy5vdXRwdXQpO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLmFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYW5uZWxzIHRoZSBzeXN0ZW0gY2FuIG91dHB1dFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc29sZS5sb2coVG9uZS5EZXN0aW5hdGlvbi5tYXhDaGFubmVsQ291bnQpO1xuICAgICAqL1xuICAgIGdldCBtYXhDaGFubmVsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5kZXN0aW5hdGlvbi5tYXhDaGFubmVsQ291bnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQuZGVzdGluYXRpb24gPSBuZXcgRGVzdGluYXRpb24oeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRlc3RpbmF0aW9uLmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVzdGluYXRpb24uanMubWFwIiwiaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi9UaW1lbGluZVwiO1xuaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG4vKipcbiAqIFJlcHJlc2VudHMgYSBzaW5nbGUgdmFsdWUgd2hpY2ggaXMgZ2V0dGFibGUgYW5kIHNldHRhYmxlIGluIGEgdGltZWQgd2F5XG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lbGluZVZhbHVlIGV4dGVuZHMgVG9uZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGluaXRpYWxWYWx1ZSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIHRoZXJlIGlzIG5vIHNjaGVkdWxlZCB2YWx1ZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsVmFsdWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaW1lbGluZVZhbHVlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZWxpbmUgd2hpY2ggc3RvcmVzIHRoZSB2YWx1ZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gbmV3IFRpbWVsaW5lKHsgbWVtb3J5OiAxMCB9KTtcbiAgICAgICAgdGhpcy5faW5pdGlhbFZhbHVlID0gaW5pdGlhbFZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICovXG4gICAgc2V0KHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmFkZCh7XG4gICAgICAgICAgICB2YWx1ZSwgdGltZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKi9cbiAgICBnZXQodGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lLmdldCh0aW1lKTtcbiAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZWxpbmVWYWx1ZS5qcy5tYXAiLCJpbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFRyYW5zcG9ydEV2ZW50IGlzIGFuIGludGVybmFsIGNsYXNzIHVzZWQgYnkgW1tUcmFuc3BvcnRdXVxuICogdG8gc2NoZWR1bGUgZXZlbnRzLiBEbyBubyBpbnZva2UgdGhpcyBjbGFzcyBkaXJlY3RseSwgaXQgaXNcbiAqIGhhbmRsZWQgZnJvbSB3aXRoaW4gVG9uZS5UcmFuc3BvcnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRFdmVudCB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHRyYW5zcG9ydCBUaGUgdHJhbnNwb3J0IG9iamVjdCB3aGljaCB0aGUgZXZlbnQgYmVsb25ncyB0b1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRyYW5zcG9ydCwgb3B0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHVuaXF1ZSBpZCBvZiB0aGUgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaWQgPSBUcmFuc3BvcnRFdmVudC5fZXZlbnRJZCsrO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gT2JqZWN0LmFzc2lnbihUcmFuc3BvcnRFdmVudC5nZXREZWZhdWx0cygpLCBvcHRzKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLl9vbmNlID0gb3B0aW9ucy5vbmNlO1xuICAgICAgICB0aGlzLnRpbWUgPSBvcHRpb25zLnRpbWU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgb25jZTogZmFsc2UsXG4gICAgICAgICAgICB0aW1lOiAwLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGV2ZW50IGNhbGxiYWNrLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIEF1ZGlvQ29udGV4dCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgaW52b2tlKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb25jZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0LmNsZWFyKHRoaXMuaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBDdXJyZW50IElEIGNvdW50ZXJcbiAqL1xuVHJhbnNwb3J0RXZlbnQuX2V2ZW50SWQgPSAwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0RXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydEV2ZW50XCI7XG4vKipcbiAqIFRyYW5zcG9ydFJlcGVhdEV2ZW50IGlzIGFuIGludGVybmFsIGNsYXNzIHVzZWQgYnkgVG9uZS5UcmFuc3BvcnRcbiAqIHRvIHNjaGVkdWxlIHJlcGVhdCBldmVudHMuIFRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRSZXBlYXRFdmVudCBleHRlbmRzIFRyYW5zcG9ydEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gdHJhbnNwb3J0IFRoZSB0cmFuc3BvcnQgb2JqZWN0IHdoaWNoIHRoZSBldmVudCBiZWxvbmdzIHRvXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodHJhbnNwb3J0LCBvcHRzKSB7XG4gICAgICAgIHN1cGVyKHRyYW5zcG9ydCwgb3B0cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSUQgb2YgdGhlIGN1cnJlbnQgdGltZWxpbmUgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIElEIG9mIHRoZSBuZXh0IHRpbWVsaW5lIGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9uZXh0SWQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lIG9mIHRoZSBuZXh0IGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBib3VuZCBzdGFydCBtZXRob2RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kUmVzdGFydCA9IHRoaXMuX3Jlc3RhcnQuYmluZCh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oVHJhbnNwb3J0UmVwZWF0RXZlbnQuZ2V0RGVmYXVsdHMoKSwgb3B0cyk7XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSBuZXcgVGlja3NDbGFzcyh0cmFuc3BvcnQuY29udGV4dCwgb3B0aW9ucy5kdXJhdGlvbikudmFsdWVPZigpO1xuICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IG5ldyBUaWNrc0NsYXNzKHRyYW5zcG9ydC5jb250ZXh0LCBvcHRpb25zLmludGVydmFsKS52YWx1ZU9mKCk7XG4gICAgICAgIHRoaXMuX25leHRUaWNrID0gb3B0aW9ucy50aW1lO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vbihcInN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9uKFwibG9vcFN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IHRoaXMudHJhbnNwb3J0LmNvbnRleHQ7XG4gICAgICAgIHRoaXMuX3Jlc3RhcnQoKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgVHJhbnNwb3J0RXZlbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZHVyYXRpb246IEluZmluaXR5LFxuICAgICAgICAgICAgaW50ZXJ2YWw6IDEsXG4gICAgICAgICAgICBvbmNlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgY2FsbGJhY2suIFJldHVybnMgdGhlIHRpY2sgdGltZSB3aGljaFxuICAgICAqIHRoZSBuZXh0IGV2ZW50IHNob3VsZCBiZSBzY2hlZHVsZWQgYXQuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgQXVkaW9Db250ZXh0IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBpbnZva2UodGltZSkge1xuICAgICAgICAvLyBjcmVhdGUgbW9yZSBldmVudHMgaWYgbmVjZXNzYXJ5XG4gICAgICAgIHRoaXMuX2NyZWF0ZUV2ZW50cyh0aW1lKTtcbiAgICAgICAgLy8gY2FsbCB0aGUgc3VwZXIgY2xhc3NcbiAgICAgICAgc3VwZXIuaW52b2tlKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdXNoIG1vcmUgZXZlbnRzIG9udG8gdGhlIHRpbWVsaW5lIHRvIGtlZXAgdXAgd2l0aCB0aGUgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgX2NyZWF0ZUV2ZW50cyh0aW1lKSB7XG4gICAgICAgIC8vIHNjaGVkdWxlIHRoZSBuZXh0IGV2ZW50XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50cmFuc3BvcnQuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aWNrcyA+PSB0aGlzLnRpbWUgJiYgdGlja3MgPj0gdGhpcy5fbmV4dFRpY2sgJiYgdGhpcy5fbmV4dFRpY2sgKyB0aGlzLl9pbnRlcnZhbCA8IHRoaXMudGltZSArIHRoaXMuZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX25leHRUaWNrICs9IHRoaXMuX2ludGVydmFsO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudElkID0gdGhpcy5fbmV4dElkO1xuICAgICAgICAgICAgdGhpcy5fbmV4dElkID0gdGhpcy50cmFuc3BvcnQuc2NoZWR1bGVPbmNlKHRoaXMuaW52b2tlLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbmV4dFRpY2spLnRvU2Vjb25kcygpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdXNoIG1vcmUgZXZlbnRzIG9udG8gdGhlIHRpbWVsaW5lIHRvIGtlZXAgdXAgd2l0aCB0aGUgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9jdXJyZW50SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9uZXh0SWQpO1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKHRpY2tzID4gdGhpcy50aW1lKSB7XG4gICAgICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZSArIE1hdGguY2VpbCgodGlja3MgLSB0aGlzLnRpbWUpIC8gdGhpcy5faW50ZXJ2YWwpICogdGhpcy5faW50ZXJ2YWw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY3VycmVudElkID0gdGhpcy50cmFuc3BvcnQuc2NoZWR1bGVPbmNlKHRoaXMuaW52b2tlLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbmV4dFRpY2spLnRvU2Vjb25kcygpKTtcbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgKz0gdGhpcy5faW50ZXJ2YWw7XG4gICAgICAgIHRoaXMuX25leHRJZCA9IHRoaXMudHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX25leHRUaWNrKS50b1NlY29uZHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9jdXJyZW50SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9uZXh0SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vZmYoXCJzdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vZmYoXCJsb29wU3RhcnRcIiwgdGhpcy5fYm91bmRSZXN0YXJ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0UmVwZWF0RXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVGltZUNsYXNzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9UaW1lXCI7XG5pbXBvcnQgeyBUaW1lbGluZVZhbHVlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UaW1lbGluZVZhbHVlXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuLi9jb250ZXh0L0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBJbnRlcnZhbFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJ2YWxUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBDbG9jayB9IGZyb20gXCIuL0Nsb2NrXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydEV2ZW50XCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRSZXBlYXRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydFJlcGVhdEV2ZW50XCI7XG4vKipcbiAqIFRyYW5zcG9ydCBmb3IgdGltaW5nIG11c2ljYWwgZXZlbnRzLlxuICogU3VwcG9ydHMgdGVtcG8gY3VydmVzIGFuZCB0aW1lIGNoYW5nZXMuIFVubGlrZSBicm93c2VyLWJhc2VkIHRpbWluZyAoc2V0SW50ZXJ2YWwsIHJlcXVlc3RBbmltYXRpb25GcmFtZSlcbiAqIFRyYW5zcG9ydCB0aW1pbmcgZXZlbnRzIHBhc3MgaW4gdGhlIGV4YWN0IHRpbWUgb2YgdGhlIHNjaGVkdWxlZCBldmVudFxuICogaW4gdGhlIGFyZ3VtZW50IG9mIHRoZSBjYWxsYmFjayBmdW5jdGlvbi4gUGFzcyB0aGF0IHRpbWUgdmFsdWUgdG8gdGhlIG9iamVjdFxuICogeW91J3JlIHNjaGVkdWxpbmcuIDxicj48YnI+XG4gKiBBIHNpbmdsZSB0cmFuc3BvcnQgaXMgY3JlYXRlZCBmb3IgeW91IHdoZW4gdGhlIGxpYnJhcnkgaXMgaW5pdGlhbGl6ZWQuXG4gKiA8YnI+PGJyPlxuICogVGhlIHRyYW5zcG9ydCBlbWl0cyB0aGUgZXZlbnRzOiBcInN0YXJ0XCIsIFwic3RvcFwiLCBcInBhdXNlXCIsIGFuZCBcImxvb3BcIiB3aGljaCBhcmVcbiAqIGNhbGxlZCB3aXRoIHRoZSB0aW1lIG9mIHRoYXQgZXZlbnQgYXMgdGhlIGFyZ3VtZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcmVwZWF0ZWQgZXZlbnQgZXZlcnkgOHRoIG5vdGVcbiAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KCh0aW1lKSA9PiB7XG4gKiBcdC8vIHVzZSB0aGUgY2FsbGJhY2sgdGltZSB0byBzY2hlZHVsZSBldmVudHNcbiAqIFx0b3NjLnN0YXJ0KHRpbWUpLnN0b3AodGltZSArIDAuMSk7XG4gKiB9LCBcIjhuXCIpO1xuICogLy8gdHJhbnNwb3J0IG11c3QgYmUgc3RhcnRlZCBiZWZvcmUgaXQgc3RhcnRzIGludm9raW5nIGV2ZW50c1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnQgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUcmFuc3BvcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJhbnNwb3J0XCI7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdExPT1BJTkdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgdHJhbnNwb3J0IGxvb3BzIG9yIG5vdC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3AgPSBuZXcgVGltZWxpbmVWYWx1ZShmYWxzZSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbG9vcCBzdGFydCBwb3NpdGlvbiBpbiB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb29wIGVuZCBwb3NpdGlvbiBpbiB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IDA7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdFRJTUVMSU5FIEVWRU5UU1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCB0aGUgZXZlbnRzIGluIGFuIG9iamVjdCB0byBrZWVwIHRyYWNrIGJ5IElEXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSB7fTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzY2hlZHVsZWQgZXZlbnRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlcGVhdGVkIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMgPSBuZXcgSW50ZXJ2YWxUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBzeW5jZWQgU2lnbmFsc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN3aW5nIGFtb3VudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3dpbmdBbW91bnQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJhbnNwb3J0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIC8vIENMT0NLL1RFTVBPXG4gICAgICAgIHRoaXMuX3BwcSA9IG9wdGlvbnMucHBxO1xuICAgICAgICB0aGlzLl9jbG9jayA9IG5ldyBDbG9jayh7XG4gICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fcHJvY2Vzc1RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHVuaXRzOiBcImJwbVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmluZENsb2NrRXZlbnRzKCk7XG4gICAgICAgIHRoaXMuYnBtID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kubXVsdGlwbGllciA9IG9wdGlvbnMucHBxO1xuICAgICAgICB0aGlzLmJwbS5zZXRWYWx1ZUF0VGltZShvcHRpb25zLmJwbSwgMCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiYnBtXCIpO1xuICAgICAgICB0aGlzLl90aW1lU2lnbmF0dXJlID0gb3B0aW9ucy50aW1lU2lnbmF0dXJlO1xuICAgICAgICAvLyBTV0lOR1xuICAgICAgICB0aGlzLl9zd2luZ1RpY2tzID0gb3B0aW9ucy5wcHEgLyAyOyAvLyA4blxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBicG06IDEyMCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IFwiNG1cIixcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBwcTogMTkyLFxuICAgICAgICAgICAgc3dpbmc6IDAsXG4gICAgICAgICAgICBzd2luZ1N1YmRpdmlzaW9uOiBcIjhuXCIsXG4gICAgICAgICAgICB0aW1lU2lnbmF0dXJlOiA0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRUSUNLU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIGNhbGxlZCBvbiBldmVyeSB0aWNrXG4gICAgICogQHBhcmFtICB0aWNrVGltZSBjbG9jayByZWxhdGl2ZSB0aWNrIHRpbWVcbiAgICAgKi9cbiAgICBfcHJvY2Vzc1RpY2sodGlja1RpbWUsIHRpY2tzKSB7XG4gICAgICAgIC8vIGRvIHRoZSBsb29wIHRlc3RcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AuZ2V0KHRpY2tUaW1lKSkge1xuICAgICAgICAgICAgaWYgKHRpY2tzID49IHRoaXMuX2xvb3BFbmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wRW5kXCIsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0aGlzLl9sb29wU3RhcnQsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgICAgICB0aWNrcyA9IHRoaXMuX2xvb3BTdGFydDtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wU3RhcnRcIiwgdGlja1RpbWUsIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGlja1RpbWUpKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wXCIsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBoYW5kbGUgc3dpbmdcbiAgICAgICAgaWYgKHRoaXMuX3N3aW5nQW1vdW50ID4gMCAmJlxuICAgICAgICAgICAgdGlja3MgJSB0aGlzLl9wcHEgIT09IDAgJiYgLy8gbm90IG9uIGEgZG93bmJlYXRcbiAgICAgICAgICAgIHRpY2tzICUgKHRoaXMuX3N3aW5nVGlja3MgKiAyKSAhPT0gMCkge1xuICAgICAgICAgICAgLy8gYWRkIHNvbWUgc3dpbmdcbiAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gKHRpY2tzICUgKHRoaXMuX3N3aW5nVGlja3MgKiAyKSkgLyAodGhpcy5fc3dpbmdUaWNrcyAqIDIpO1xuICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gTWF0aC5zaW4oKHByb2dyZXNzKSAqIE1hdGguUEkpICogdGhpcy5fc3dpbmdBbW91bnQ7XG4gICAgICAgICAgICB0aWNrVGltZSArPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N3aW5nVGlja3MgKiAyIC8gMykudG9TZWNvbmRzKCkgKiBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW52b2tlIHRoZSB0aW1lbGluZSBldmVudHMgc2NoZWR1bGVkIG9uIHRoaXMgdGlja1xuICAgICAgICB0aGlzLl90aW1lbGluZS5mb3JFYWNoQXRUaW1lKHRpY2tzLCBldmVudCA9PiBldmVudC5pbnZva2UodGlja1RpbWUpKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRTQ0hFRFVMQUJMRSBFVkVOVFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhbiBldmVudCBhbG9uZyB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBiZSBpbnZva2VkIGF0IHRoZSB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHRvIGludm9rZSB0aGUgY2FsbGJhY2sgYXQuXG4gICAgICogQHJldHVybiBUaGUgaWQgb2YgdGhlIGV2ZW50IHdoaWNoIGNhbiBiZSB1c2VkIGZvciBjYW5jZWxpbmcgdGhlIGV2ZW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc2NoZWR1bGUgYW4gZXZlbnQgb24gdGhlIDE2dGggbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKCh0aW1lKSA9PiB7XG4gICAgICogXHQvLyBpbnZva2VkIG9uIG1lYXN1cmUgMTZcbiAgICAgKiBcdGNvbnNvbGUubG9nKFwibWVhc3VyZSAxNiFcIik7XG4gICAgICogfSwgXCIxNjowOjBcIik7XG4gICAgICovXG4gICAgc2NoZWR1bGUoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgVHJhbnNwb3J0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl90aW1lbGluZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIGEgcmVwZWF0ZWQgZXZlbnQgYWxvbmcgdGhlIHRpbWVsaW5lLiBUaGUgZXZlbnQgd2lsbCBmaXJlXG4gICAgICogYXQgdGhlIGBpbnRlcnZhbGAgc3RhcnRpbmcgYXQgdGhlIGBzdGFydFRpbWVgIGFuZCBmb3IgdGhlIHNwZWNpZmllZFxuICAgICAqIGBkdXJhdGlvbmAuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgIFRoZSBjYWxsYmFjayB0byBpbnZva2UuXG4gICAgICogQHBhcmFtICBpbnRlcnZhbCAgIFRoZSBkdXJhdGlvbiBiZXR3ZWVuIHN1Y2Nlc3NpdmUgY2FsbGJhY2tzLiBNdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyLlxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lICBXaGVuIGFsb25nIHRoZSB0aW1lbGluZSB0aGUgZXZlbnRzIHNob3VsZCBzdGFydCBiZWluZyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIGV2ZW50IHNob3VsZCByZXBlYXQuXG4gICAgICogQHJldHVybiAgVGhlIElEIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnQuIFVzZSB0aGlzIHRvIGNhbmNlbCB0aGUgZXZlbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogLy8gYSBjYWxsYmFjayBpbnZva2VkIGV2ZXJ5IGVpZ2h0aCBub3RlIGFmdGVyIHRoZSBmaXJzdCBtZWFzdXJlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQoKHRpbWUpID0+IHtcbiAgICAgKiBcdG9zYy5zdGFydCh0aW1lKS5zdG9wKHRpbWUgKyAwLjEpO1xuICAgICAqIH0sIFwiOG5cIiwgXCIxbVwiKTtcbiAgICAgKi9cbiAgICBzY2hlZHVsZVJlcGVhdChjYWxsYmFjaywgaW50ZXJ2YWwsIHN0YXJ0VGltZSwgZHVyYXRpb24gPSBJbmZpbml0eSkge1xuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBUcmFuc3BvcnRSZXBlYXRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIGR1cmF0aW9uOiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgZHVyYXRpb24pLnRvVGlja3MoKSxcbiAgICAgICAgICAgIGludGVydmFsOiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgaW50ZXJ2YWwpLnRvVGlja3MoKSxcbiAgICAgICAgICAgIHRpbWU6IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvVGlja3MoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGtpY2sgaXQgb2ZmIGlmIHRoZSBUcmFuc3BvcnQgaXMgc3RhcnRlZFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRFdmVudChldmVudCwgdGhpcy5fcmVwZWF0ZWRFdmVudHMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhbiBldmVudCB0aGF0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBpdCBpcyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIG9uY2UuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdGhlIGNhbGxiYWNrIHNob3VsZCBiZSBpbnZva2VkLlxuICAgICAqIEByZXR1cm5zIFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50LlxuICAgICAqL1xuICAgIHNjaGVkdWxlT25jZShjYWxsYmFjaywgdGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBUcmFuc3BvcnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIG9uY2U6IHRydWUsXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl90aW1lbGluZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFyIHRoZSBwYXNzZWQgaW4gZXZlbnQgaWQgZnJvbSB0aGUgdGltZWxpbmVcbiAgICAgKiBAcGFyYW0gZXZlbnRJZCBUaGUgaWQgb2YgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIGNsZWFyKGV2ZW50SWQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NjaGVkdWxlZEV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudElkKSkge1xuICAgICAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMuX3NjaGVkdWxlZEV2ZW50c1tldmVudElkLnRvU3RyaW5nKCldO1xuICAgICAgICAgICAgaXRlbS50aW1lbGluZS5yZW1vdmUoaXRlbS5ldmVudCk7XG4gICAgICAgICAgICBpdGVtLmV2ZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnRJZC50b1N0cmluZygpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGV2ZW50IHRvIHRoZSBjb3JyZWN0IHRpbWVsaW5lLiBLZWVwIHRyYWNrIG9mIHRoZVxuICAgICAqIHRpbWVsaW5lIGl0IHdhcyBhZGRlZCB0by5cbiAgICAgKiBAcmV0dXJucyB0aGUgZXZlbnQgaWQgd2hpY2ggd2FzIGp1c3QgYWRkZWRcbiAgICAgKi9cbiAgICBfYWRkRXZlbnQoZXZlbnQsIHRpbWVsaW5lKSB7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50c1tldmVudC5pZC50b1N0cmluZygpXSA9IHtcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGltZWxpbmUsXG4gICAgICAgIH07XG4gICAgICAgIHRpbWVsaW5lLmFkZChldmVudCk7XG4gICAgICAgIHJldHVybiBldmVudC5pZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHNjaGVkdWxlZCBldmVudHMgZnJvbSB0aGUgdGltZWxpbmUgYWZ0ZXJcbiAgICAgKiB0aGUgZ2l2ZW4gdGltZS4gUmVwZWF0ZWQgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGlmIHRoZWlyIHN0YXJ0VGltZSBpcyBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSBhZnRlciBDbGVhciBhbGwgZXZlbnRzIGFmdGVyIHRoaXMgdGltZS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIgPSAwKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkQWZ0ZXIgPSB0aGlzLnRvVGlja3MoYWZ0ZXIpO1xuICAgICAgICB0aGlzLl90aW1lbGluZS5mb3JFYWNoRnJvbShjb21wdXRlZEFmdGVyLCBldmVudCA9PiB0aGlzLmNsZWFyKGV2ZW50LmlkKSk7XG4gICAgICAgIHRoaXMuX3JlcGVhdGVkRXZlbnRzLmZvckVhY2hGcm9tKGNvbXB1dGVkQWZ0ZXIsIGV2ZW50ID0+IHRoaXMuY2xlYXIoZXZlbnQuaWQpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U1RBUlQvU1RPUC9QQVVTRVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIEJpbmQgc3RhcnQvc3RvcC9wYXVzZSBldmVudHMgZnJvbSB0aGUgY2xvY2sgYW5kIGVtaXQgdGhlbS5cbiAgICAgKi9cbiAgICBfYmluZENsb2NrRXZlbnRzKCkge1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInN0YXJ0XCIsICh0aW1lLCBvZmZzZXQpID0+IHtcbiAgICAgICAgICAgIG9mZnNldCA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgb2Zmc2V0KS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIHRpbWUsIG9mZnNldCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInN0b3BcIiwgKHRpbWUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgdGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInBhdXNlXCIsICh0aW1lKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJwYXVzZVwiLCB0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIsIG9yIFwicGF1c2VkXCJcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHRyYW5zcG9ydCBhbmQgYWxsIHNvdXJjZXMgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIHRyYW5zcG9ydCBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIHRpbWVsaW5lIG9mZnNldCB0byBzdGFydCB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc3RhcnQgdGhlIHRyYW5zcG9ydCBpbiBvbmUgc2Vjb25kIHN0YXJ0aW5nIGF0IGJlZ2lubmluZyBvZiB0aGUgNXRoIG1lYXN1cmUuXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoXCIrMVwiLCBcIjQ6MDowXCIpO1xuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICBsZXQgb2Zmc2V0VGlja3M7XG4gICAgICAgIGlmIChpc0RlZmluZWQob2Zmc2V0KSkge1xuICAgICAgICAgICAgb2Zmc2V0VGlja3MgPSB0aGlzLnRvVGlja3Mob2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzdGFydCB0aGUgY2xvY2tcbiAgICAgICAgdGhpcy5fY2xvY2suc3RhcnQodGltZSwgb2Zmc2V0VGlja3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgdHJhbnNwb3J0IGFuZCBhbGwgc291cmNlcyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSB0cmFuc3BvcnQgc2hvdWxkIHN0b3AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdG9wKCk7XG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgdHJhbnNwb3J0IGFuZCBhbGwgc291cmNlcyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnBhdXNlKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVG9nZ2xlIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB0cmFuc3BvcnQuIElmIGl0IGlzXG4gICAgICogc3RhcnRlZCwgaXQgd2lsbCBzdG9wIGl0LCBvdGhlcndpc2UgaXQgd2lsbCBzdGFydCB0aGUgVHJhbnNwb3J0LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0b2dnbGUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9jbG9jay5nZXRTdGF0ZUF0VGltZSh0aW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnQodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U0VUVEVSUy9HRVRURVJTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgc2lnbmF0dXJlIGFzIGp1c3QgdGhlIG51bWVyYXRvciBvdmVyIDQuXG4gICAgICogRm9yIGV4YW1wbGUgNC80IHdvdWxkIGJlIGp1c3QgNCBhbmQgNi84IHdvdWxkIGJlIDMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBjb21tb24gdGltZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmUgPSA0O1xuICAgICAqIC8vIDcvOFxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmUgPSBbNywgOF07XG4gICAgICogLy8gdGhpcyB3aWxsIGJlIHJlZHVjZWQgdG8gYSBzaW5nbGUgbnVtYmVyXG4gICAgICogVG9uZS5UcmFuc3BvcnQudGltZVNpZ25hdHVyZTsgLy8gcmV0dXJucyAzLjVcbiAgICAgKi9cbiAgICBnZXQgdGltZVNpZ25hdHVyZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVTaWduYXR1cmU7XG4gICAgfVxuICAgIHNldCB0aW1lU2lnbmF0dXJlKHRpbWVTaWcpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkodGltZVNpZykpIHtcbiAgICAgICAgICAgIHRpbWVTaWcgPSAodGltZVNpZ1swXSAvIHRpbWVTaWdbMV0pICogNDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl90aW1lU2lnbmF0dXJlID0gdGltZVNpZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgVHJhbnNwb3J0Lmxvb3AgPSB0cnVlLCB0aGlzIGlzIHRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KHN0YXJ0UG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKHN0YXJ0UG9zaXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBUcmFuc3BvcnQubG9vcCA9IHRydWUsIHRoaXMgaXMgdGhlIGVuZGluZyBwb3NpdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wRW5kLCBcImlcIikudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MoZW5kUG9zaXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgdHJhbnNwb3J0IGxvb3BzIG9yIG5vdC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3AuZ2V0KHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX2xvb3Auc2V0KGxvb3AsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIHN0b3AgYXQgdGhlIHNhbWUgdGltZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGxvb3Agb3ZlciB0aGUgZmlyc3QgbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNldExvb3BQb2ludHMoMCwgXCIxbVwiKTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5sb29wID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBzZXRMb29wUG9pbnRzKHN0YXJ0UG9zaXRpb24sIGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gc3RhcnRQb3NpdGlvbjtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gZW5kUG9zaXRpb247XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3dpbmcgdmFsdWUuIEJldHdlZW4gMC0xIHdoZXJlIDEgZXF1YWwgdG8gdGhlIG5vdGUgKyBoYWxmIHRoZSBzdWJkaXZpc2lvbi5cbiAgICAgKi9cbiAgICBnZXQgc3dpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zd2luZ0Ftb3VudDtcbiAgICB9XG4gICAgc2V0IHN3aW5nKGFtb3VudCkge1xuICAgICAgICAvLyBzY2FsZSB0aGUgdmFsdWVzIHRvIGEgbm9ybWFsIHJhbmdlXG4gICAgICAgIHRoaXMuX3N3aW5nQW1vdW50ID0gYW1vdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHN1YmRpdmlzaW9uIHdoaWNoIHRoZSBzd2luZyB3aWxsIGJlIGFwcGxpZWQgdG8uXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgYW4gOHRoIG5vdGUuIFZhbHVlIG11c3QgYmUgbGVzc1xuICAgICAqIHRoYW4gYSBxdWFydGVyIG5vdGUuXG4gICAgICovXG4gICAgZ2V0IHN3aW5nU3ViZGl2aXNpb24oKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N3aW5nVGlja3MpLnRvTm90YXRpb24oKTtcbiAgICB9XG4gICAgc2V0IHN3aW5nU3ViZGl2aXNpb24oc3ViZGl2aXNpb24pIHtcbiAgICAgICAgdGhpcy5fc3dpbmdUaWNrcyA9IHRoaXMudG9UaWNrcyhzdWJkaXZpc2lvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbiBpbiBCYXJzOkJlYXRzOlNpeHRlZW50aHMuXG4gICAgICogU2V0dGluZyB0aGUgdmFsdWUgd2lsbCBqdW1wIHRvIHRoYXQgcG9zaXRpb24gcmlnaHQgYXdheS5cbiAgICAgKi9cbiAgICBnZXQgcG9zaXRpb24oKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpLnRvQmFyc0JlYXRzU2l4dGVlbnRocygpO1xuICAgIH1cbiAgICBzZXQgcG9zaXRpb24ocHJvZ3Jlc3MpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3MocHJvZ3Jlc3MpO1xuICAgICAgICB0aGlzLnRpY2tzID0gdGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbiBpbiBzZWNvbmRzXG4gICAgICogU2V0dGluZyB0aGUgdmFsdWUgd2lsbCBqdW1wIHRvIHRoYXQgcG9zaXRpb24gcmlnaHQgYXdheS5cbiAgICAgKi9cbiAgICBnZXQgc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLnNlY29uZHM7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5mcmVxdWVuY3kudGltZVRvVGlja3Mocywgbm93KTtcbiAgICAgICAgdGhpcy50aWNrcyA9IHRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgVHJhbnNwb3J0J3MgbG9vcCBwb3NpdGlvbiBhcyBhIG5vcm1hbGl6ZWQgdmFsdWUuIEFsd2F5c1xuICAgICAqIHJldHVybnMgMCBpZiB0aGUgdHJhbnNwb3J0IGlmIGxvb3AgaXMgbm90IHRydWUuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgcmV0dXJuICh0aWNrcyAtIHRoaXMuX2xvb3BTdGFydCkgLyAodGhpcy5fbG9vcEVuZCAtIHRoaXMuX2xvb3BTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHJhbnNwb3J0cyBjdXJyZW50IHRpY2sgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IHRpY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2sudGlja3M7XG4gICAgfVxuICAgIHNldCB0aWNrcyh0KSB7XG4gICAgICAgIGlmICh0aGlzLl9jbG9jay50aWNrcyAhPT0gdCkge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIC8vIHN0b3AgZXZlcnl0aGluZyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgICAgIC8vIHNjaGVkdWxlIHRvIHN0YXJ0IG9uIHRoZSBuZXh0IHRpY2ssICM1NzNcbiAgICAgICAgICAgICAgICBjb25zdCByZW1haW5pbmdUaWNrID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcyhNYXRoLmNlaWwodGlja3MpIC0gdGlja3MsIG5vdyk7XG4gICAgICAgICAgICAgICAgY29uc3QgdGltZSA9IG5vdyArIHJlbWFpbmluZ1RpY2s7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCB0aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0LCB0aW1lKTtcbiAgICAgICAgICAgICAgICAvLyByZXN0YXJ0IGl0IHdpdGggdGhlIG5ldyB0aW1lXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgdGltZSwgdGhpcy5fY2xvY2suZ2V0U2Vjb25kc0F0VGltZSh0aW1lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0LCBub3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICogQHJldHVybiBUaGUgdGljayB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKHRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHNlY29uZHMgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgZWxhcHNlZCBzZWNvbmRzXG4gICAgICogQHJldHVybiAgVGhlIG51bWJlciBvZiBlbGFwc2VkIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXRTZWNvbmRzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1bHNlcyBQZXIgUXVhcnRlciBub3RlLiBUaGlzIGlzIHRoZSBzbWFsbGVzdCByZXNvbHV0aW9uXG4gICAgICogdGhlIFRyYW5zcG9ydCB0aW1pbmcgc3VwcG9ydHMuIFRoaXMgc2hvdWxkIGJlIHNldCBvbmNlXG4gICAgICogb24gaW5pdGlhbGl6YXRpb24gYW5kIG5vdCBzZXQgYWdhaW4uIENoYW5naW5nIHRoaXMgdmFsdWVcbiAgICAgKiBhZnRlciBvdGhlciBvYmplY3RzIGhhdmUgYmVlbiBjcmVhdGVkIGNhbiBjYXVzZSBwcm9ibGVtcy5cbiAgICAgKi9cbiAgICBnZXQgUFBRKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suZnJlcXVlbmN5Lm11bHRpcGxpZXI7XG4gICAgfVxuICAgIHNldCBQUFEocHBxKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5tdWx0aXBsaWVyID0gcHBxO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNZTkNJTkdcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aW1lIGFsaWduZWQgdG8gdGhlIG5leHQgc3ViZGl2aXNpb25cbiAgICAgKiBvZiB0aGUgVHJhbnNwb3J0LiBJZiB0aGUgVHJhbnNwb3J0IGlzIG5vdCBzdGFydGVkLFxuICAgICAqIGl0IHdpbGwgcmV0dXJuIDAuXG4gICAgICogTm90ZTogdGhpcyB3aWxsIG5vdCB3b3JrIHByZWNpc2VseSBkdXJpbmcgdGVtcG8gcmFtcHMuXG4gICAgICogQHBhcmFtICBzdWJkaXZpc2lvbiAgVGhlIHN1YmRpdmlzaW9uIHRvIHF1YW50aXplIHRvXG4gICAgICogQHJldHVybiAgVGhlIGNvbnRleHQgdGltZSBvZiB0aGUgbmV4dCBzdWJkaXZpc2lvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHRoZSB0cmFuc3BvcnQgbXVzdCBiZSBzdGFydGVkLCBvdGhlcndpc2UgcmV0dXJucyAwXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5uZXh0U3ViZGl2aXNpb24oXCI0blwiKTtcbiAgICAgKi9cbiAgICBuZXh0U3ViZGl2aXNpb24oc3ViZGl2aXNpb24pIHtcbiAgICAgICAgc3ViZGl2aXNpb24gPSB0aGlzLnRvVGlja3Moc3ViZGl2aXNpb24pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIC8vIGlmIHRoZSB0cmFuc3BvcnQncyBub3Qgc3RhcnRlZCwgcmV0dXJuIDBcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIC8vIHRoZSByZW1haW5kZXIgb2YgdGhlIGN1cnJlbnQgdGlja3MgYW5kIHRoZSBzdWJkaXZpc2lvblxuICAgICAgICAgICAgY29uc3QgdHJhbnNwb3J0UG9zID0gdGhpcy5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nVGlja3MgPSBzdWJkaXZpc2lvbiAtIHRyYW5zcG9ydFBvcyAlIHN1YmRpdmlzaW9uO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLm5leHRUaWNrVGltZShyZW1haW5pbmdUaWNrcywgbm93KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBdHRhY2hlcyB0aGUgc2lnbmFsIHRvIHRoZSB0ZW1wbyBjb250cm9sIHNpZ25hbCBzbyB0aGF0XG4gICAgICogYW55IGNoYW5nZXMgaW4gdGhlIHRlbXBvIHdpbGwgY2hhbmdlIHRoZSBzaWduYWwgaW4gdGhlIHNhbWVcbiAgICAgKiByYXRpby5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzaWduYWxcbiAgICAgKiBAcGFyYW0gcmF0aW8gT3B0aW9uYWxseSBwYXNzIGluIHRoZSByYXRpbyBiZXR3ZWVuIHRoZSB0d28gc2lnbmFscy5cbiAgICAgKiBcdFx0XHRPdGhlcndpc2UgaXQgd2lsbCBiZSBjb21wdXRlZCBiYXNlZCBvbiB0aGVpciBjdXJyZW50IHZhbHVlcy5cbiAgICAgKi9cbiAgICBzeW5jU2lnbmFsKHNpZ25hbCwgcmF0aW8pIHtcbiAgICAgICAgaWYgKCFyYXRpbykge1xuICAgICAgICAgICAgLy8gZ2V0IHRoZSBzeW5jIHJhdGlvXG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgaWYgKHNpZ25hbC5nZXRWYWx1ZUF0VGltZShub3cpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnBtID0gdGhpcy5icG0uZ2V0VmFsdWVBdFRpbWUobm93KTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21wdXRlZEZyZXEgPSAxIC8gKDYwIC8gYnBtIC8gdGhpcy5QUFEpO1xuICAgICAgICAgICAgICAgIHJhdGlvID0gc2lnbmFsLmdldFZhbHVlQXRUaW1lKG5vdykgLyBjb21wdXRlZEZyZXE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByYXRpbyA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmF0aW9TaWduYWwgPSBuZXcgR2FpbihyYXRpbyk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5icG0uY29ubmVjdChyYXRpb1NpZ25hbCk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmF0aW9TaWduYWwuY29ubmVjdChzaWduYWwuX3BhcmFtKTtcbiAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscy5wdXNoKHtcbiAgICAgICAgICAgIGluaXRpYWw6IHNpZ25hbC52YWx1ZSxcbiAgICAgICAgICAgIHJhdGlvOiByYXRpb1NpZ25hbCxcbiAgICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpZ25hbC52YWx1ZSA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmNzIGEgcHJldmlvdXNseSBzeW5jZWQgc2lnbmFsIGZyb20gdGhlIHRyYW5zcG9ydCdzIGNvbnRyb2wuXG4gICAgICogU2VlIFRyYW5zcG9ydC5zeW5jU2lnbmFsLlxuICAgICAqL1xuICAgIHVuc3luY1NpZ25hbChzaWduYWwpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuX3N5bmNlZFNpZ25hbHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHN5bmNlZFNpZ25hbCA9IHRoaXMuX3N5bmNlZFNpZ25hbHNbaV07XG4gICAgICAgICAgICBpZiAoc3luY2VkU2lnbmFsLnNpZ25hbCA9PT0gc2lnbmFsKSB7XG4gICAgICAgICAgICAgICAgc3luY2VkU2lnbmFsLnJhdGlvLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICBzeW5jZWRTaWduYWwuc2lnbmFsLnZhbHVlID0gc3luY2VkU2lnbmFsLmluaXRpYWw7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZGlzcG9zZSgpO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBcImJwbVwiKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yZXBlYXRlZEV2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbkVtaXR0ZXIubWl4aW4oVHJhbnNwb3J0KTtcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQudHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydCh7IGNvbnRleHQgfSk7XG59KTtcbm9uQ29udGV4dENsb3NlKGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQudHJhbnNwb3J0LmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0LmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCBcIi4uL2NvcmUvY29udGV4dC9EZXN0aW5hdGlvblwiO1xuaW1wb3J0IFwiLi4vY29yZS9jbG9jay9UcmFuc3BvcnRcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzVW5kZWYgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0LCBhc3NlcnRDb250ZXh0UnVubmluZyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IEdUIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHNvdXJjZXMuXG4gKiBzdGFydC9zdG9wIG9mIHRoaXMuY29udGV4dC50cmFuc3BvcnQuXG4gKlxuICogYGBgXG4gKiAvLyBNdWx0aXBsZSBzdGF0ZSBjaGFuZ2UgZXZlbnRzIGNhbiBiZSBjaGFpbmVkIHRvZ2V0aGVyLFxuICogLy8gYnV0IG11c3QgYmUgc2V0IGluIHRoZSBjb3JyZWN0IG9yZGVyIGFuZCB3aXRoIGFzY2VuZGluZyB0aW1lc1xuICogLy8gT0tcbiAqIHN0YXRlLnN0YXJ0KCkuc3RvcChcIiswLjJcIik7XG4gKiAvLyBPS1xuICogc3RhdGUuc3RhcnQoKS5zdG9wKFwiKzAuMlwiKS5zdGFydChcIiswLjRcIikuc3RvcChcIiswLjdcIilcbiAqIC8vIEJBRFxuICogc3RhdGUuc3RvcChcIiswLjJcIikuc3RhcnQoKTtcbiAqIC8vIEJBRFxuICogc3RhdGUuc3RhcnQoXCIrMC4zXCIpLnN0b3AoXCIrMC4yXCIpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTb3VyY2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogU291cmNlcyBoYXZlIG5vIGlucHV0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgdGhlIHNjaGVkdWxlZCBzdGF0ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN5bmNlZCBgc3RhcnRgIGNhbGxiYWNrIGZ1bmN0aW9uIGZyb20gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIGFsbCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50IGlkc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQbGFjZWhvbGRlciBmdW5jdGlvbnMgZm9yIHN5bmNpbmcvdW5zeW5jaW5nIHRvIHRyYW5zcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQgPSBub09wO1xuICAgICAgICB0aGlzLl9zeW5jZWRTdG9wID0gbm9PcDtcbiAgICAgICAgdGhpcy5fc3RhdGUubWVtb3J5ID0gMTAwO1xuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG11dGU6IG9wdGlvbnMubXV0ZSxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLm9uc3RvcCA9IG9wdGlvbnMub25zdG9wO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBvbnN0b3A6IG5vT3AsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9haG50b25lX2MzLm1wM1wiLCAoKSA9PiB7XG4gICAgICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAgICAgKiBcdGNvbnNvbGUubG9nKHBsYXllci5zdGF0ZSk7XG4gICAgICogfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIG9zYy5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5zdXJlIHRoYXQgdGhlIHNjaGVkdWxlZCB0aW1lIGlzIG5vdCBiZWZvcmUgdGhlIGN1cnJlbnQgdGltZS5cbiAgICAgKiBTaG91bGQgb25seSBiZSB1c2VkIHdoZW4gc2NoZWR1bGVkIHVuc3luY2VkLlxuICAgICAqL1xuICAgIF9jbGFtcFRvQ3VycmVudFRpbWUodGltZSkge1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLm1heCh0aW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBzb3VyY2UgYXQgdGhlIHNwZWNpZmllZCB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLFxuICAgICAqIHN0YXJ0IHRoZSBzb3VyY2Ugbm93LlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBzb3VyY2Ugc2hvdWxkIGJlIHN0YXJ0ZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHNvdXJjZS5zdGFydChcIiswLjVcIik7IC8vIHN0YXJ0cyB0aGUgc291cmNlIDAuNSBzZWNvbmRzIGZyb20gbm93XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBsZXQgY29tcHV0ZWRUaW1lID0gaXNVbmRlZih0aW1lKSAmJiB0aGlzLl9zeW5jZWQgPyB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMgOiB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29tcHV0ZWRUaW1lID0gdGhpcy5fY2xhbXBUb0N1cnJlbnRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIC8vIGlmIGl0J3Mgc3RhcnRlZCwgc3RvcCBpdCBhbmQgcmVzdGFydCBpdFxuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCAmJiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgLy8gdGltZSBzaG91bGQgYmUgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHRoZSBwcmV2aW91cyBzdGFydCB0aW1lXG4gICAgICAgICAgICBhc3NlcnQoR1QoY29tcHV0ZWRUaW1lLCB0aGlzLl9zdGF0ZS5nZXQoY29tcHV0ZWRUaW1lKS50aW1lKSwgXCJTdGFydCB0aW1lIG11c3QgYmUgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHByZXZpb3VzIHN0YXJ0IHRpbWVcIik7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5sb2coXCJyZXN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLnJlc3RhcnQoY29tcHV0ZWRUaW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgICAgIC8vIGFkZCB0aGUgb2Zmc2V0IHRpbWUgdG8gdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQub2Zmc2V0ID0gdGhpcy50b1NlY29uZHMoZGVmYXVsdEFyZyhvZmZzZXQsIDApKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuZHVyYXRpb24gPSBkdXJhdGlvbiA/IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0LCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZC5wdXNoKHNjaGVkKTtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgdHJhbnNwb3J0IGlzIGFscmVhZHkgc3RhcnRlZFxuICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgdGltZSBpcyBncmVhdGVyIHRoYW4gd2hlcmUgdGhlIHRyYW5zcG9ydCBpc1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmdldFNlY29uZHNBdFRpbWUodGhpcy5pbW1lZGlhdGUoKSkgPiBjb21wdXRlZFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQodGhpcy5ub3coKSwgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NlcnRDb250ZXh0UnVubmluZyh0aGlzLmNvbnRleHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBhdCB0aGUgc3BlY2lmaWVkIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sXG4gICAgICogc3RvcCB0aGUgc291cmNlIG5vdy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgc291cmNlIHNob3VsZCBiZSBzdG9wcGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc291cmNlID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzb3VyY2Uuc3RhcnQoKTtcbiAgICAgKiBzb3VyY2Uuc3RvcChcIiswLjVcIik7IC8vIHN0b3BzIHRoZSBzb3VyY2UgMC41IHNlY29uZHMgZnJvbSBub3dcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgbGV0IGNvbXB1dGVkVGltZSA9IGlzVW5kZWYodGltZSkgJiYgdGhpcy5fc3luY2VkID8gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzIDogdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbXB1dGVkVGltZSA9IHRoaXMuX2NsYW1wVG9DdXJyZW50VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIgfHwgaXNEZWZpbmVkKHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKSkpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUodGhpcy5fc3RvcC5iaW5kKHRoaXMpLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZC5wdXNoKHNjaGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc3RhcnQgdGhlIHNvdXJjZS5cbiAgICAgKi9cbiAgICByZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG4gICAgICAgICAgICB0aGlzLl9yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBzb3VyY2UgdG8gdGhlIFRyYW5zcG9ydCBzbyB0aGF0IGFsbCBzdWJzZXF1ZW50XG4gICAgICogY2FsbHMgdG8gYHN0YXJ0YCBhbmQgYHN0b3BgIGFyZSBzeW5jZWQgdG8gdGhlIFRyYW5zcG9ydFRpbWVcbiAgICAgKiBpbnN0ZWFkIG9mIHRoZSBBdWRpb0NvbnRleHQgdGltZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBzeW5jIHRoZSBzb3VyY2Ugc28gdGhhdCBpdCBwbGF5cyBiZXR3ZWVuIDAgYW5kIDAuMyBvbiB0aGUgVHJhbnNwb3J0J3MgdGltZWxpbmVcbiAgICAgKiBvc2Muc3luYygpLnN0YXJ0KDApLnN0b3AoMC4zKTtcbiAgICAgKiAvLyBzdGFydCB0aGUgdHJhbnNwb3J0LlxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICogLy8gc2V0IGl0IHRvIGxvb3Agb25jZSBhIHNlY29uZFxuICAgICAqIFRvbmUuVHJhbnNwb3J0Lmxvb3AgPSB0cnVlO1xuICAgICAqIFRvbmUuVHJhbnNwb3J0Lmxvb3BFbmQgPSAxO1xuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICghdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQgPSAodGltZSwgb2Zmc2V0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdGVFdmVudCA9IHRoaXMuX3N0YXRlLmdldChvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAvLyBsaXN0ZW4gZm9yIHN0YXJ0IGV2ZW50cyB3aGljaCBtYXkgb2NjdXIgaW4gdGhlIG1pZGRsZSBvZiB0aGUgc3luYydlZCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50ICYmIHN0YXRlRXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIHN0YXRlRXZlbnQudGltZSAhPT0gb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIG9mZnNldFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRPZmZzZXQgPSBvZmZzZXQgLSB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGR1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlRXZlbnQuZHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKHN0YXRlRXZlbnQuZHVyYXRpb24pIC0gc3RhcnRPZmZzZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0aW1lLCB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50Lm9mZnNldCkgKyBzdGFydE9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZFN0b3AgPSB0aW1lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWNvbmRzID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5nZXRTZWNvbmRzQXRUaW1lKE1hdGgubWF4KHRpbWUgLSB0aGlzLnNhbXBsZVRpbWUsIDApKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoc2Vjb25kcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRTdGFydCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwibG9vcFN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdG9wXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcImxvb3BFbmRcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgc291cmNlIHRvIHRoZSBUcmFuc3BvcnQuIFNlZSBTb3VyY2Uuc3luY1xuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdG9wXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwibG9vcEVuZFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJsb29wU3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICAvLyBjbGVhciBhbGwgb2YgdGhlIHNjaGVkdWxlZCBpZHNcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkLmZvckVhY2goaWQgPT4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihpZCkpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWQgPSBbXTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKDApO1xuICAgICAgICAvLyBzdG9wIGl0IGFsc29cbiAgICAgICAgdGhpcy5fc3RvcCgwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vbnN0b3AgPSBub09wO1xuICAgICAgICB0aGlzLnVuc3luYygpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IE9uZVNob3RTb3VyY2UgfSBmcm9tIFwiLi4vT25lU2hvdFNvdXJjZVwiO1xuaW1wb3J0IHsgRVEsIEdURSwgTFQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL01hdGhcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBCdWZmZXJTb3VyY2VOb2RlLlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZUJ1ZmZlclNvdXJjZSBleHRlbmRzIE9uZVNob3RTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQnVmZmVyU291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUJ1ZmZlclNvdXJjZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9zY2lsbGF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHRoaXMuY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9zb3VyY2VdO1xuICAgICAgICAvKipcbiAgICAgICAgICogaW5kaWNhdG9ycyBpZiB0aGUgc291cmNlIGhhcyBzdGFydGVkL3N0b3BwZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZVN0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc291cmNlU3RvcHBlZCA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUJ1ZmZlclNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc291cmNlLCB0aGlzLl9nYWluTm9kZSk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5vbmVuZGVkID0gKCkgPT4gdGhpcy5fc3RvcFNvdXJjZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBsYXliYWNrUmF0ZSBvZiB0aGUgYnVmZmVyXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fc291cmNlLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wbGF5YmFja1JhdGUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzZXQgc29tZSB2YWx1ZXMgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gb3B0aW9ucy5sb29wRW5kO1xuICAgICAgICB0aGlzLl9idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKG9wdGlvbnMudXJsLCBvcHRpb25zLm9ubG9hZCwgb3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscy5wdXNoKHRoaXMuX3NvdXJjZSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT25lU2hvdFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB1cmw6IG5ldyBUb25lQXVkaW9CdWZmZXIoKSxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKHQpIHtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCBmYWRlT3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZU91dDtcbiAgICB9XG4gICAgc2V0IGZhZGVPdXQodCkge1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnZlIGFwcGxpZWQgdG8gdGhlIGZhZGVzLCBlaXRoZXIgXCJsaW5lYXJcIiBvciBcImV4cG9uZW50aWFsXCJcbiAgICAgKi9cbiAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGN1cnZlKHQpIHtcbiAgICAgICAgdGhpcy5fY3VydmUgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgYnVmZmVyXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLCBpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICogQHBhcmFtICBnYWluICBUaGUgZ2FpbiB0byBwbGF5IHRoZSBidWZmZXIgYmFjayBhdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uLCBnYWluID0gMSkge1xuICAgICAgICBhc3NlcnQodGhpcy5idWZmZXIubG9hZGVkLCBcImJ1ZmZlciBpcyBlaXRoZXIgbm90IHNldCBvciBub3QgbG9hZGVkXCIpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gYXBwbHkgdGhlIGdhaW4gZW52ZWxvcGVcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSwgZ2Fpbik7XG4gICAgICAgIC8vIGlmIGl0J3MgYSBsb29wIHRoZSBkZWZhdWx0IG9mZnNldCBpcyB0aGUgbG9vcHN0YXJ0IHBvaW50XG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLmxvb3BTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIDBcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIG9mZnNldCBpcyBub3QgbGVzcyB0aGFuIDBcbiAgICAgICAgbGV0IGNvbXB1dGVkT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy50b1NlY29uZHMob2Zmc2V0KSwgMCk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBidWZmZXIgc291cmNlXG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIC8vIG1vZGlmeSB0aGUgb2Zmc2V0IGlmIGl0J3MgZ3JlYXRlciB0aGFuIHRoZSBsb29wIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGxvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmxvb3BFbmQpIHx8IHRoaXMuYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICAgICAgY29uc3QgbG9vcFN0YXJ0ID0gdGhpcy50b1NlY29uZHModGhpcy5sb29wU3RhcnQpO1xuICAgICAgICAgICAgY29uc3QgbG9vcER1cmF0aW9uID0gbG9vcEVuZCAtIGxvb3BTdGFydDtcbiAgICAgICAgICAgIC8vIG1vdmUgdGhlIG9mZnNldCBiYWNrXG4gICAgICAgICAgICBpZiAoR1RFKGNvbXB1dGVkT2Zmc2V0LCBsb29wRW5kKSkge1xuICAgICAgICAgICAgICAgIGNvbXB1dGVkT2Zmc2V0ID0gKChjb21wdXRlZE9mZnNldCAtIGxvb3BTdGFydCkgJSBsb29wRHVyYXRpb24pICsgbG9vcFN0YXJ0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gd2hlbiB0aGUgb2Zmc2V0IGlzIHZlcnkgY2xvc2UgdG8gdGhlIGR1cmF0aW9uLCBzZXQgaXQgdG8gMFxuICAgICAgICAgICAgaWYgKEVRKGNvbXB1dGVkT2Zmc2V0LCB0aGlzLmJ1ZmZlci5kdXJhdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlZE9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhpcy5idWZmZXIubG9hZGVkIHdvdWxkIGhhdmUgcmV0dXJuIGZhbHNlIGlmIHRoZSBBdWRpb0J1ZmZlciB3YXMgdW5kZWZpbmVkXG4gICAgICAgIHRoaXMuX3NvdXJjZS5idWZmZXIgPSB0aGlzLmJ1ZmZlci5nZXQoKTtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmxvb3BFbmQpIHx8IHRoaXMuYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICBpZiAoTFQoY29tcHV0ZWRPZmZzZXQsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlU3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQoY29tcHV0ZWRUaW1lLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgYSBkdXJhdGlvbiBpcyBnaXZlbiwgc2NoZWR1bGUgYSBzdG9wXG4gICAgICAgIGlmIChpc0RlZmluZWQoZHVyYXRpb24pKSB7XG4gICAgICAgICAgICBsZXQgY29tcHV0ZWREdXIgPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgICAgICAvLyBtYWtlIHN1cmUgaXQncyBuZXZlciBuZWdhdGl2ZVxuICAgICAgICAgICAgY29tcHV0ZWREdXIgPSBNYXRoLm1heChjb21wdXRlZER1ciwgMCk7XG4gICAgICAgICAgICB0aGlzLnN0b3AoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIGlmICghdGhpcy5fc291cmNlU3RvcHBlZCAmJiB0aGlzLl9zb3VyY2VTdGFydGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgc3RhcnQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3BTdGFydCA9IHRoaXMudG9TZWNvbmRzKGxvb3BTdGFydCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBlbmQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wRW5kID0gdGhpcy50b1NlY29uZHMobG9vcEVuZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgYmVsb25naW5nIHRvIHRoZSBwbGF5ZXIuXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgc2V0IGJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnNldChidWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3AgPSBsb29wO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlU3RhcnRlZCkge1xuICAgICAgICAgICAgdGhpcy5jYW5jZWxTdG9wKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uub25lbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUJ1ZmZlclNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG4vKipcbiAqIE5vaXNlIGlzIGEgbm9pc2UgZ2VuZXJhdG9yLiBJdCB1c2VzIGxvb3BlZCBub2lzZSBidWZmZXJzIHRvIHNhdmUgb24gcGVyZm9ybWFuY2UuXG4gKiBOb2lzZSBzdXBwb3J0cyB0aGUgbm9pc2UgdHlwZXM6IFwicGlua1wiLCBcIndoaXRlXCIsIGFuZCBcImJyb3duXCIuIFJlYWQgbW9yZSBhYm91dFxuICogY29sb3JzIG9mIG5vaXNlIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbG9yc19vZl9ub2lzZSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGluaXRpYWxpemUgdGhlIG5vaXNlIGFuZCBzdGFydFxuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZShcInBpbmtcIikuc3RhcnQoKTtcbiAqIC8vIG1ha2UgYW4gYXV0b2ZpbHRlciB0byBzaGFwZSB0aGUgbm9pc2VcbiAqIGNvbnN0IGF1dG9GaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKHtcbiAqIFx0ZnJlcXVlbmN5OiBcIjhuXCIsXG4gKiBcdGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAqIFx0b2N0YXZlczogOFxuICogfSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyBjb25uZWN0IHRoZSBub2lzZVxuICogbm9pc2UuY29ubmVjdChhdXRvRmlsdGVyKTtcbiAqIC8vIHN0YXJ0IHRoZSBhdXRvZmlsdGVyIExGT1xuICogYXV0b0ZpbHRlci5zdGFydCgpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgTm9pc2UgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOb2lzZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogUHJpdmF0ZSByZWZlcmVuY2UgdG8gdGhlIHNvdXJjZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgdHlwZTogXCJ3aGl0ZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG5vaXNlLiBDYW4gYmUgXCJ3aGl0ZVwiLCBcImJyb3duXCIsIG9yIFwicGlua1wiLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG5vaXNlLnR5cGUgPSBcImJyb3duXCI7XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGFzc2VydCh0eXBlIGluIF9ub2lzZUJ1ZmZlcnMsIFwiTm9pc2U6IGludmFsaWQgdHlwZTogXCIgKyB0eXBlKTtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgIT09IHR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICAgICAgLy8gaWYgaXQncyBwbGF5aW5nLCBzdG9wIGFuZCByZXN0YXJ0IGl0XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0b3Aobm93KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydChub3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub2lzZS4gQWZmZWN0c1xuICAgICAqIHRoZSBcImZyZXF1ZW5jeVwiIG9mIHRoZSBub2lzZS5cbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnBsYXliYWNrUmF0ZS52YWx1ZSA9IHJhdGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogaW50ZXJuYWwgc3RhcnQgbWV0aG9kXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gX25vaXNlQnVmZmVyc1t0aGlzLl90eXBlXTtcbiAgICAgICAgdGhpcy5fc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgdXJsOiBidWZmZXIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmYWRlSW46IHRoaXMuX2ZhZGVJbixcbiAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuX2ZhZGVPdXQsXG4gICAgICAgICAgICBsb29wOiB0cnVlLFxuICAgICAgICAgICAgb25lbmRlZDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IHRoaXMuX3BsYXliYWNrUmF0ZSxcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdGFydCh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgTWF0aC5yYW5kb20oKSAqIChidWZmZXIuZHVyYXRpb24gLSAwLjAwMSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBpbnRlcm5hbCBzdG9wIG1ldGhvZFxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnN0b3AodGhpcy50b1NlY29uZHModGltZSkpO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gdGltZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmZhZGVJbiA9IHRoaXMuX2ZhZGVJbjtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZU91dCB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVPdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlT3V0O1xuICAgIH1cbiAgICBzZXQgZmFkZU91dCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSB0aW1lO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuZmFkZU91dCA9IHRoaXMuX2ZhZGVPdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICAvLyBUT0RPIGNvdWxkIGJlIG9wdGltaXplZCBieSBjYW5jZWxsaW5nIHRoZSBidWZmZXIgc291cmNlICdzdG9wJ1xuICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRIRSBOT0lTRSBCVUZGRVJTXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBOb2lzZSBidWZmZXIgc3RhdHNcbmNvbnN0IEJVRkZFUl9MRU5HVEggPSA0NDEwMCAqIDU7XG5jb25zdCBOVU1fQ0hBTk5FTFMgPSAyO1xuLyoqXG4gKiBDYWNoZSB0aGUgbm9pc2UgYnVmZmVyc1xuICovXG5jb25zdCBfbm9pc2VDYWNoZSA9IHtcbiAgICBicm93bjogbnVsbCxcbiAgICBwaW5rOiBudWxsLFxuICAgIHdoaXRlOiBudWxsLFxufTtcbi8qKlxuICogVGhlIG5vaXNlIGFycmF5cy4gR2VuZXJhdGVkIG9uIGluaXRpYWxpemF0aW9uLlxuICogYm9ycm93ZWQgaGVhdmlseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS96YWNoYXJ5ZGVudG9uL25vaXNlLmpzXG4gKiAoYykgMjAxMyBaYWNoIERlbnRvbiAoTUlUKVxuICovXG5jb25zdCBfbm9pc2VCdWZmZXJzID0ge1xuICAgIGdldCBicm93bigpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS5icm93bikge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IE5VTV9DSEFOTkVMUzsgY2hhbm5lbE51bSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IG5ldyBGbG9hdDMyQXJyYXkoQlVGRkVSX0xFTkdUSCk7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcbiAgICAgICAgICAgICAgICBsZXQgbGFzdE91dCA9IDAuMDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGl0ZSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IChsYXN0T3V0ICsgKDAuMDIgKiB3aGl0ZSkpIC8gMS4wMjtcbiAgICAgICAgICAgICAgICAgICAgbGFzdE91dCA9IGNoYW5uZWxbaV07XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gKj0gMy41OyAvLyAocm91Z2hseSkgY29tcGVuc2F0ZSBmb3IgZ2FpblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLmJyb3duID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpLmZyb21BcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfbm9pc2VDYWNoZS5icm93bjtcbiAgICB9LFxuICAgIGdldCBwaW5rKCkge1xuICAgICAgICBpZiAoIV9ub2lzZUNhY2hlLnBpbmspIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbE51bSA9IDA7IGNoYW5uZWxOdW0gPCBOVU1fQ0hBTk5FTFM7IGNoYW5uZWxOdW0rKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KEJVRkZFUl9MRU5HVEgpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlcltjaGFubmVsTnVtXSA9IGNoYW5uZWw7XG4gICAgICAgICAgICAgICAgbGV0IGIwLCBiMSwgYjIsIGIzLCBiNCwgYjUsIGI2O1xuICAgICAgICAgICAgICAgIGIwID0gYjEgPSBiMiA9IGIzID0gYjQgPSBiNSA9IGI2ID0gMC4wO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQlVGRkVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoaXRlID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgICAgICAgICAgICBiMCA9IDAuOTk4ODYgKiBiMCArIHdoaXRlICogMC4wNTU1MTc5O1xuICAgICAgICAgICAgICAgICAgICBiMSA9IDAuOTkzMzIgKiBiMSArIHdoaXRlICogMC4wNzUwNzU5O1xuICAgICAgICAgICAgICAgICAgICBiMiA9IDAuOTY5MDAgKiBiMiArIHdoaXRlICogMC4xNTM4NTIwO1xuICAgICAgICAgICAgICAgICAgICBiMyA9IDAuODY2NTAgKiBiMyArIHdoaXRlICogMC4zMTA0ODU2O1xuICAgICAgICAgICAgICAgICAgICBiNCA9IDAuNTUwMDAgKiBiNCArIHdoaXRlICogMC41MzI5NTIyO1xuICAgICAgICAgICAgICAgICAgICBiNSA9IC0wLjc2MTYgKiBiNSAtIHdoaXRlICogMC4wMTY4OTgwO1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldID0gYjAgKyBiMSArIGIyICsgYjMgKyBiNCArIGI1ICsgYjYgKyB3aGl0ZSAqIDAuNTM2MjtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSAqPSAwLjExOyAvLyAocm91Z2hseSkgY29tcGVuc2F0ZSBmb3IgZ2FpblxuICAgICAgICAgICAgICAgICAgICBiNiA9IHdoaXRlICogMC4xMTU5MjY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX25vaXNlQ2FjaGUucGluayA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKS5mcm9tQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX25vaXNlQ2FjaGUucGluaztcbiAgICB9LFxuICAgIGdldCB3aGl0ZSgpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS53aGl0ZSkge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IE5VTV9DSEFOTkVMUzsgY2hhbm5lbE51bSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IG5ldyBGbG9hdDMyQXJyYXkoQlVGRkVSX0xFTkdUSCk7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLndoaXRlID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpLmZyb21BcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfbm9pc2VDYWNoZS53aGl0ZTtcbiAgICB9LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5vaXNlLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgY29ubmVjdCwgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVXNlck1lZGlhIHVzZXMgTWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSB0byBvcGVuIHVwIGFuZCBleHRlcm5hbCBtaWNyb3Bob25lIG9yIGF1ZGlvIGlucHV0LlxuICogQ2hlY2sgW01lZGlhRGV2aWNlcyBBUEkgU3VwcG9ydF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL01lZGlhRGV2aWNlcy9nZXRVc2VyTWVkaWEpXG4gKiB0byBzZWUgd2hpY2ggYnJvd3NlcnMgYXJlIHN1cHBvcnRlZC4gQWNjZXNzIHRvIGFuIGV4dGVybmFsIGlucHV0XG4gKiBpcyBsaW1pdGVkIHRvIHNlY3VyZSAoSFRUUFMpIGNvbm5lY3Rpb25zLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuTWV0ZXIoKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpLmNvbm5lY3QobWV0ZXIpO1xuICogbWljLm9wZW4oKS50aGVuKCgpID0+IHtcbiAqIFx0Ly8gcHJvbWlzZSByZXNvbHZlcyB3aGVuIGlucHV0IGlzIGF2YWlsYWJsZVxuICogXHRjb25zb2xlLmxvZyhcIm1pYyBvcGVuXCIpO1xuICogXHQvLyBwcmludCB0aGUgaW5jb21pbmcgbWljIGxldmVscyBpbiBkZWNpYmVsc1xuICogXHRzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhtZXRlci5nZXRWYWx1ZSgpKSwgMTAwKTtcbiAqIH0pLmNhdGNoKGUgPT4ge1xuICogXHQvLyBwcm9taXNlIGlzIHJlamVjdGVkIHdoZW4gdGhlIHVzZXIgZG9lc24ndCBoYXZlIG9yIGFsbG93IG1pYyBhY2Nlc3NcbiAqIFx0Y29uc29sZS5sb2coXCJtaWMgbm90IG9wZW5cIik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFVzZXJNZWRpYSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhVc2VyTWVkaWEuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJVc2VyTWVkaWFcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFVzZXJNZWRpYS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiXSk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2b2x1bWU6IDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE9wZW4gdGhlIG1lZGlhIHN0cmVhbS4gSWYgYSBzdHJpbmcgaXMgcGFzc2VkIGluLCBpdCBpcyBhc3N1bWVkXG4gICAgICogdG8gYmUgdGhlIGxhYmVsIG9yIGlkIG9mIHRoZSBzdHJlYW0sIGlmIGEgbnVtYmVyIGlzIHBhc3NlZCBpbixcbiAgICAgKiBpdCBpcyB0aGUgaW5wdXQgbnVtYmVyIG9mIHRoZSBzdHJlYW0uXG4gICAgICogQHBhcmFtICBsYWJlbE9ySWQgVGhlIGxhYmVsIG9yIGlkIG9mIHRoZSBhdWRpbyBpbnB1dCBtZWRpYSBkZXZpY2UuXG4gICAgICogICAgICAgICAgICAgICAgICAgV2l0aCBubyBhcmd1bWVudCwgdGhlIGRlZmF1bHQgc3RyZWFtIGlzIG9wZW5lZC5cbiAgICAgKiBAcmV0dXJuIFRoZSBwcm9taXNlIGlzIHJlc29sdmVkIHdoZW4gdGhlIHN0cmVhbSBpcyBvcGVuLlxuICAgICAqL1xuICAgIG9wZW4obGFiZWxPcklkKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQoVXNlck1lZGlhLnN1cHBvcnRlZCwgXCJVc2VyTWVkaWEgaXMgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgICAgIC8vIGNsb3NlIHRoZSBwcmV2aW91cyBzdHJlYW1cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRldmljZXMgPSB5aWVsZCBVc2VyTWVkaWEuZW51bWVyYXRlRGV2aWNlcygpO1xuICAgICAgICAgICAgaWYgKGlzTnVtYmVyKGxhYmVsT3JJZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXZpY2UgPSBkZXZpY2VzW2xhYmVsT3JJZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXZpY2UgPSBkZXZpY2VzLmZpbmQoKGRldmljZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlLmxhYmVsID09PSBsYWJlbE9ySWQgfHwgZGV2aWNlLmRldmljZUlkID09PSBsYWJlbE9ySWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gZGlkbid0IGZpbmQgYSBtYXRjaGluZyBkZXZpY2VcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2RldmljZSAmJiBkZXZpY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlc1swXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZCh0aGlzLl9kZXZpY2UpLCBgTm8gbWF0Y2hpbmcgZGV2aWNlICR7bGFiZWxPcklkfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG8gZ2V0VXNlck1lZGlhXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgICAgICBlY2hvQ2FuY2VsbGF0aW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUsXG4gICAgICAgICAgICAgICAgICAgIG5vaXNlU3VwcHJlc3Npb246IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtb3pOb2lzZVN1cHByZXNzaW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBjb25zdHJhaW50cy5hdWRpby5kZXZpY2VJZCA9IHRoaXMuX2RldmljZS5kZXZpY2VJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IHlpZWxkIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIC8vIHN0YXJ0IGEgbmV3IHNvdXJjZSBvbmx5IGlmIHRoZSBwcmV2aW91cyBvbmUgaXMgY2xvc2VkXG4gICAgICAgICAgICBpZiAoIXRoaXMuX3N0cmVhbSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgICAgICAgICAvLyBXcmFwIGEgTWVkaWFTdHJlYW1Tb3VyY2VOb2RlIGFyb3VuZCB0aGUgbGl2ZSBpbnB1dCBzdHJlYW0uXG4gICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW1Ob2RlID0gdGhpcy5jb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgICAgICAgICAgICAgLy8gQ29ubmVjdCB0aGUgTWVkaWFTdHJlYW1Tb3VyY2VOb2RlIHRvIGEgZ2F0ZSBnYWluIG5vZGVcbiAgICAgICAgICAgICAgICBjb25uZWN0KG1lZGlhU3RyZWFtTm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtID0gbWVkaWFTdHJlYW1Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgbWVkaWEgc3RyZWFtXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zdHJlYW0gJiYgdGhpcy5fbWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMuX3N0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9zdHJlYW0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIG9sZCBtZWRpYSBzdHJlYW1cbiAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RldmljZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdGhlIGxpc3Qgb2YgYXVkaW8gaW5wdXQgZGV2aWNlcyBhdmFpbGFibGUuXG4gICAgICogQHJldHVybiBUaGUgcHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGRldmljZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVXNlck1lZGlhLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VzKSA9PiB7XG4gICAgICogXHQvLyBwcmludCB0aGUgZGV2aWNlIGxhYmVsc1xuICAgICAqIFx0Y29uc29sZS5sb2coZGV2aWNlcy5tYXAoZGV2aWNlID0+IGRldmljZS5sYWJlbCkpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHN0YXRpYyBlbnVtZXJhdGVEZXZpY2VzKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgYWxsRGV2aWNlcyA9IHlpZWxkIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpO1xuICAgICAgICAgICAgcmV0dXJuIGFsbERldmljZXMuZmlsdGVyKGRldmljZSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRldmljZS5raW5kID09PSBcImF1ZGlvaW5wdXRcIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgXCJzdGFydGVkXCIgd2hlbiB0aGUgbWljcm9waG9uZSBpcyBvcGVuXG4gICAgICogYW5kIFwic3RvcHBlZFwiIHdoZW4gdGhlIG1pYyBpcyBjbG9zZWQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RyZWFtICYmIHRoaXMuX3N0cmVhbS5hY3RpdmUgPyBcInN0YXJ0ZWRcIiA6IFwic3RvcHBlZFwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGlkZW50aWZpZXIgZm9yIHRoZSByZXByZXNlbnRlZCBkZXZpY2UgdGhhdCBpc1xuICAgICAqIHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMuIEl0IGlzIHVuLWd1ZXNzYWJsZSBieSBvdGhlciBhcHBsaWNhdGlvbnMgYW5kXG4gICAgICogdW5pcXVlIHRvIHRoZSBvcmlnaW4gb2YgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24uIEl0IGlzIHJlc2V0IHdoZW4gdGhlXG4gICAgICogdXNlciBjbGVhcnMgY29va2llcyAoZm9yIFByaXZhdGUgQnJvd3NpbmcsIGEgZGlmZmVyZW50IGlkZW50aWZpZXIgaXNcbiAgICAgKiB1c2VkIHRoYXQgaXMgbm90IHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMpLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZVxuICAgICAqIGRldmljZSBpcyBub3Qgb3Blbi5cbiAgICAgKi9cbiAgICBnZXQgZGV2aWNlSWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UuZGV2aWNlSWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBncm91cCBpZGVudGlmaWVyLiBUd28gZGV2aWNlcyBoYXZlIHRoZVxuICAgICAqIHNhbWUgZ3JvdXAgaWRlbnRpZmllciBpZiB0aGV5IGJlbG9uZyB0byB0aGUgc2FtZSBwaHlzaWNhbCBkZXZpY2UuXG4gICAgICogUmV0dXJucyBudWxsICB3aGVuIHRoZSBkZXZpY2UgaXMgbm90IG9wZW4uXG4gICAgICovXG4gICAgZ2V0IGdyb3VwSWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UuZ3JvdXBJZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGxhYmVsIGRlc2NyaWJpbmcgdGhpcyBkZXZpY2UgKGZvciBleGFtcGxlIFwiQnVpbHQtaW4gTWljcm9waG9uZVwiKS5cbiAgICAgKiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZSBkZXZpY2UgaXMgbm90IG9wZW4gb3IgbGFiZWwgaXMgbm90IGF2YWlsYWJsZVxuICAgICAqIGJlY2F1c2Ugb2YgcGVybWlzc2lvbnMuXG4gICAgICovXG4gICAgZ2V0IGxhYmVsKCkge1xuICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmxhYmVsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAgICAgKiBtaWMub3BlbigpLnRoZW4oKCkgPT4ge1xuICAgICAqIFx0Ly8gcHJvbWlzZSByZXNvbHZlcyB3aGVuIGlucHV0IGlzIGF2YWlsYWJsZVxuICAgICAqIH0pO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIG1pYy5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGdldFVzZXJNZWRpYSBpcyBzdXBwb3J0ZWQgYnkgdGhlIGJyb3dzZXIuXG4gICAgICovXG4gICAgc3RhdGljIGdldCBzdXBwb3J0ZWQoKSB7XG4gICAgICAgIHJldHVybiBpc0RlZmluZWQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcykgJiZcbiAgICAgICAgICAgIGlzRGVmaW5lZChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VXNlck1lZGlhLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG4vKipcbiAqIFJlbmRlciBhIHNlZ21lbnQgb2YgdGhlIG9zY2lsbGF0b3IgdG8gYW4gb2ZmbGluZSBjb250ZXh0IGFuZCByZXR1cm4gdGhlIHJlc3VsdHMgYXMgYW4gYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlV2F2ZWZvcm0oaW5zdGFuY2UsIGxlbmd0aCkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uID0gbGVuZ3RoIC8gaW5zdGFuY2UuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KDEsIGR1cmF0aW9uLCBpbnN0YW5jZS5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBjbG9uZSA9IG5ldyBpbnN0YW5jZS5jb25zdHJ1Y3RvcihPYmplY3QuYXNzaWduKGluc3RhbmNlLmdldCgpLCB7XG4gICAgICAgICAgICAvLyBzaG91bGQgZG8gMiBpdGVyYXRpb25zXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDIgLyBkdXJhdGlvbixcbiAgICAgICAgICAgIC8vIHplcm8gb3V0IHRoZSBkZXR1bmVcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgfSkpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgY2xvbmUuc3RhcnQoMCk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IHlpZWxkIGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgIHJldHVybiBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgfSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Pc2NpbGxhdG9ySW50ZXJmYWNlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBPbmVTaG90U291cmNlIH0gZnJvbSBcIi4uL09uZVNob3RTb3VyY2VcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBmaXJlLWFuZC1mb3JnZXQgT3NjaWxsYXRvck5vZGUuXG4gKiBBZGRzIHRoZSBhYmlsaXR5IHRvIHJlc2NoZWR1bGUgdGhlIHN0b3AgbWV0aG9kLlxuICogKioqW1tPc2NpbGxhdG9yXV0gaXMgYmV0dGVyIGZvciBtb3N0IHVzZS1jYXNlcyoqKlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZU9zY2lsbGF0b3JOb2RlIGV4dGVuZHMgT25lU2hvdFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVPc2NpbGxhdG9yTm9kZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lT3NjaWxsYXRvck5vZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvc2NpbGxhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5jb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9vc2NpbGxhdG9yXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVPc2NpbGxhdG9yTm9kZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX29zY2lsbGF0b3IsIHRoaXMuX2dhaW5Ob2RlKTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9uZVNob3RTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBvc2NpbGxhdG9yIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9zdG9wU291cmNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIGFuIGFyYml0cmFyeSBjdXN0b20gcGVyaW9kaWMgd2F2ZWZvcm0gZ2l2ZW4gYSBQZXJpb2RpY1dhdmUuXG4gICAgICogQHBhcmFtICBwZXJpb2RpY1dhdmUgUGVyaW9kaWNXYXZlIHNob3VsZCBiZSBjcmVhdGVkIHdpdGggY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmVcbiAgICAgKi9cbiAgICBzZXRQZXJpb2RpY1dhdmUocGVyaW9kaWNXYXZlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvciB0eXBlLiBFaXRoZXIgJ3NpbmUnLCAnc2F3dG9vdGgnLCAnc3F1YXJlJywgb3IgJ3RyaWFuZ2xlJ1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVPc2NpbGxhdG9yTm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGRlZXBFcXVhbHMsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZU9zY2lsbGF0b3JOb2RlIH0gZnJvbSBcIi4vVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIE9zY2lsbGF0b3Igc3VwcG9ydHMgYSBudW1iZXIgb2YgZmVhdHVyZXMgaW5jbHVkaW5nXG4gKiBwaGFzZSByb3RhdGlvbiwgbXVsdGlwbGUgb3NjaWxsYXRvciB0eXBlcyAoc2VlIE9zY2lsbGF0b3IudHlwZSksXG4gKiBhbmQgVHJhbnNwb3J0IHN5bmNpbmcgKHNlZSBPc2NpbGxhdG9yLnN5bmNGcmVxdWVuY3kpLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBtYWtlIGFuZCBzdGFydCBhIDQ0MGh6IHNpbmUgdG9uZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic2luZVwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBtYWluIG9zY2lsbGF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBudWxsO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRldHVuZVwiKTtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBvcHRpb25zLnBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBvcHRpb25zLnBhcnRpYWxDb3VudDtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgaWYgKG9wdGlvbnMucGFydGlhbENvdW50ICYmIG9wdGlvbnMudHlwZSAhPT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuYmFzZVR5cGUgKyBvcHRpb25zLnBhcnRpYWxDb3VudC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIHBhcnRpYWxDb3VudDogMCxcbiAgICAgICAgICAgIHBhcnRpYWxzOiBbXSxcbiAgICAgICAgICAgIHBoYXNlOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyBuZXcgb3NjaWxsYXRvciB3aXRoIHByZXZpb3VzIHZhbHVlc1xuICAgICAgICBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmVPc2NpbGxhdG9yTm9kZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvbmVuZGVkOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBvc2NpbGxhdG9yO1xuICAgICAgICBpZiAodGhpcy5fd2F2ZSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUodGhpcy5fd2F2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGNvbnRyb2wgc2lnbmFsIHRvIHRoZSBvc2NpbGxhdG9yIGZyZXF1ZW5jeSAmIGRldHVuZVxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXN0YXJ0IHRoZSBvc2NpbGxhdG9yLiBEb2VzIG5vdCBzdG9wIHRoZSBvc2NpbGxhdG9yLCBidXQgaW5zdGVhZFxuICAgICAqIGp1c3QgY2FuY2VscyBhbnkgc2NoZWR1bGVkICdzdG9wJyBmcm9tIGJlaW5nIGludm9rZWQuXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJyZXN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNhbmNlbFN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIHNpZ25hbCB0byB0aGUgVHJhbnNwb3J0J3MgYnBtLiBBbnkgY2hhbmdlcyB0byB0aGUgdHJhbnNwb3J0cyBicG0sXG4gICAgICogd2lsbCBhbHNvIGFmZmVjdCB0aGUgb3NjaWxsYXRvcnMgZnJlcXVlbmN5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG9zYy5mcmVxdWVuY3kudmFsdWUgPSA0NDA7XG4gICAgICogLy8gdGhlIHJhdGlvIGJldHdlZW4gdGhlIGJwbSBhbmQgdGhlIGZyZXF1ZW5jeSB3aWxsIGJlIG1haW50YWluZWRcbiAgICAgKiBvc2Muc3luY0ZyZXF1ZW5jeSgpO1xuICAgICAqIC8vIGRvdWJsZSB0aGUgdGVtcG9cbiAgICAgKiBUb25lLlRyYW5zcG9ydC5icG0udmFsdWUgKj0gMjtcbiAgICAgKiAvLyB0aGUgZnJlcXVlbmN5IG9mIHRoZSBvc2NpbGxhdG9yIGlzIGRvdWJsZWQgdG8gODgwXG4gICAgICovXG4gICAgc3luY0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgb3NjaWxsYXRvcidzIGZyZXF1ZW5jeSBmcm9tIHRoZSBUcmFuc3BvcnQuXG4gICAgICogU2VlIE9zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeVxuICAgICAqL1xuICAgIHVuc3luY0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC51bnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgY2FjaGVkIHBlcmlvZGljIHdhdmUuIEF2b2lkcyBoYXZpbmcgdG8gcmVjb21wdXRlXG4gICAgICogdGhlIG9zY2lsbGF0b3IgdmFsdWVzIHdoZW4gdGhleSBoYXZlIGFscmVhZHkgYmVlbiBjb21wdXRlZFxuICAgICAqIHdpdGggdGhlIHNhbWUgdmFsdWVzLlxuICAgICAqL1xuICAgIF9nZXRDYWNoZWRQZXJpb2RpY1dhdmUoKSB7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBjb25zdCBvc2NQcm9wcyA9IE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmZpbmQoZGVzY3JpcHRpb24gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbi5waGFzZSA9PT0gdGhpcy5fcGhhc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgZGVlcEVxdWFscyhkZXNjcmlwdGlvbi5wYXJ0aWFscywgdGhpcy5fcGFydGlhbHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gb3NjUHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBvc2NQcm9wcyA9IE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmZpbmQoZGVzY3JpcHRpb24gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbi50eXBlID09PSB0aGlzLl90eXBlICYmXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnBoYXNlID09PSB0aGlzLl9waGFzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gb3NjUHJvcHMgPyBvc2NQcm9wcy5wYXJ0aWFsQ291bnQgOiB0aGlzLl9wYXJ0aWFsQ291bnQ7XG4gICAgICAgICAgICByZXR1cm4gb3NjUHJvcHM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICBjb25zdCBpc0Jhc2ljVHlwZSA9IFtcInNpbmVcIiwgXCJzcXVhcmVcIiwgXCJzYXd0b290aFwiLCBcInRyaWFuZ2xlXCJdLmluZGV4T2YodHlwZSkgIT09IC0xO1xuICAgICAgICBpZiAodGhpcy5fcGhhc2UgPT09IDAgJiYgaXNCYXNpY1R5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3dhdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSAwO1xuICAgICAgICAgICAgLy8ganVzdCBnbyB3aXRoIHRoZSBiYXNpYyBhcHByb2FjaFxuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHRlc3RlZCB0aGF0IGl0J3MgYSBiYXNpYyB0eXBlXG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGZpcnN0IGNoZWNrIGlmIHRoZSB2YWx1ZSBpcyBjYWNoZWRcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fZ2V0Q2FjaGVkUGVyaW9kaWNXYXZlKCk7XG4gICAgICAgICAgICBpZiAoaXNEZWZpbmVkKGNhY2hlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgcGFydGlhbHMsIHdhdmUgfSA9IGNhY2hlO1xuICAgICAgICAgICAgICAgIHRoaXMuX3dhdmUgPSB3YXZlO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUodGhpcy5fd2F2ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgW3JlYWwsIGltYWddID0gdGhpcy5fZ2V0UmVhbEltYWdpbmFyeSh0eXBlLCB0aGlzLl9waGFzZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGVyaW9kaWNXYXZlID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl93YXZlID0gcGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHRoaXMuX3dhdmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBzZXQgdGhlIGNhY2hlXG4gICAgICAgICAgICAgICAgT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGltYWcsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudDogdGhpcy5fcGFydGlhbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsczogdGhpcy5fcGFydGlhbHMsXG4gICAgICAgICAgICAgICAgICAgIHBoYXNlOiB0aGlzLl9waGFzZSxcbiAgICAgICAgICAgICAgICAgICAgcmVhbCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgd2F2ZTogdGhpcy5fd2F2ZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUubGVuZ3RoID4gMTAwKSB7XG4gICAgICAgICAgICAgICAgICAgIE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGUucmVwbGFjZSh0aGlzLnBhcnRpYWxDb3VudC50b1N0cmluZygpLCBcIlwiKTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIGlmICh0aGlzLnBhcnRpYWxDb3VudCAmJiB0aGlzLl90eXBlICE9PSBcImN1c3RvbVwiICYmIGJhc2VUeXBlICE9PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBiYXNlVHlwZSArIHRoaXMucGFydGlhbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHAsIDApO1xuICAgICAgICBsZXQgdHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICAgIGNvbnN0IHBhcnRpYWwgPSAvXihzaW5lfHRyaWFuZ2xlfHNxdWFyZXxzYXd0b290aCkoXFxkKykkLy5leGVjKHRoaXMuX3R5cGUpO1xuICAgICAgICBpZiAocGFydGlhbCkge1xuICAgICAgICAgICAgdHlwZSA9IHBhcnRpYWxbMV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgIT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIGlmIChwID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGUgKyBwLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBleHRlbmQgb3Igc2hvcnRlbiB0aGUgcGFydGlhbHMgYXJyYXlcbiAgICAgICAgICAgIGNvbnN0IGZ1bGxQYXJ0aWFscyA9IG5ldyBGbG9hdDMyQXJyYXkocCk7XG4gICAgICAgICAgICAvLyBjb3B5IG92ZXIgdGhlIHBhcnRpYWxzIGFycmF5XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscy5mb3JFYWNoKCh2LCBpKSA9PiBmdWxsUGFydGlhbHNbaV0gPSB2KTtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzID0gQXJyYXkuZnJvbShmdWxsUGFydGlhbHMpO1xuICAgICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSByZWFsIGFuZCBpbWFnaW5hcnkgY29tcG9uZW50cyBiYXNlZFxuICAgICAqIG9uIHRoZSBvc2NpbGxhdG9yIHR5cGUuXG4gICAgICogQHJldHVybnMgW3JlYWw6IEZsb2F0MzJBcnJheSwgaW1hZ2luYXJ5OiBGbG9hdDMyQXJyYXldXG4gICAgICovXG4gICAgX2dldFJlYWxJbWFnaW5hcnkodHlwZSwgcGhhc2UpIHtcbiAgICAgICAgY29uc3QgZmZ0U2l6ZSA9IDQwOTY7XG4gICAgICAgIGxldCBwZXJpb2RpY1dhdmVTaXplID0gZmZ0U2l6ZSAvIDI7XG4gICAgICAgIGNvbnN0IHJlYWwgPSBuZXcgRmxvYXQzMkFycmF5KHBlcmlvZGljV2F2ZVNpemUpO1xuICAgICAgICBjb25zdCBpbWFnID0gbmV3IEZsb2F0MzJBcnJheShwZXJpb2RpY1dhdmVTaXplKTtcbiAgICAgICAgbGV0IHBhcnRpYWxDb3VudCA9IDE7XG4gICAgICAgIGlmICh0eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGggKyAxO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICAgICAgcGVyaW9kaWNXYXZlU2l6ZSA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgICAgIC8vIGlmIHRoZSBwYXJ0aWFsIGNvdW50IGlzIDAsIGRvbid0IGJvdGhlciBkb2luZyBhbnkgY29tcHV0YXRpb25cbiAgICAgICAgICAgIGlmICh0aGlzLl9wYXJ0aWFscy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW3JlYWwsIGltYWddO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFydGlhbCA9IC9eKHNpbmV8dHJpYW5nbGV8c3F1YXJlfHNhd3Rvb3RoKShcXGQrKSQvLmV4ZWModHlwZSk7XG4gICAgICAgICAgICBpZiAocGFydGlhbCkge1xuICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IHBhcnNlSW50KHBhcnRpYWxbMl0sIDEwKSArIDE7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gcGFyc2VJbnQocGFydGlhbFsyXSwgMTApO1xuICAgICAgICAgICAgICAgIHR5cGUgPSBwYXJ0aWFsWzFdO1xuICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IE1hdGgubWF4KHBhcnRpYWxDb3VudCwgMik7XG4gICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlU2l6ZSA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG4gPSAxOyBuIDwgcGVyaW9kaWNXYXZlU2l6ZTsgKytuKSB7XG4gICAgICAgICAgICBjb25zdCBwaUZhY3RvciA9IDIgLyAobiAqIE1hdGguUEkpO1xuICAgICAgICAgICAgbGV0IGI7XG4gICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwic2luZVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gKG4gPD0gcGFydGlhbENvdW50KSA/IDEgOiAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsc1tuIC0gMV0gPSBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwic3F1YXJlXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSAobiAmIDEpID8gMiAqIHBpRmFjdG9yIDogMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNhd3Rvb3RoXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSBwaUZhY3RvciAqICgobiAmIDEpID8gMSA6IC0xKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInRyaWFuZ2xlXCI6XG4gICAgICAgICAgICAgICAgICAgIGlmIChuICYgMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYiA9IDIgKiAocGlGYWN0b3IgKiBwaUZhY3RvcikgKiAoKCgobiAtIDEpID4+IDEpICYgMSkgPyAtMSA6IDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYiA9IDA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImN1c3RvbVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gdGhpcy5fcGFydGlhbHNbbiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT3NjaWxsYXRvcjogaW52YWxpZCB0eXBlOiBcIiArIHR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGIgIT09IDApIHtcbiAgICAgICAgICAgICAgICByZWFsW25dID0gLWIgKiBNYXRoLnNpbihwaGFzZSAqIG4pO1xuICAgICAgICAgICAgICAgIGltYWdbbl0gPSBiICogTWF0aC5jb3MocGhhc2UgKiBuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlYWxbbl0gPSAwO1xuICAgICAgICAgICAgICAgIGltYWdbbl0gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbcmVhbCwgaW1hZ107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbXB1dGUgdGhlIGludmVyc2UgRkZUIGZvciBhIGdpdmVuIHBoYXNlLlxuICAgICAqL1xuICAgIF9pbnZlcnNlRkZUKHJlYWwsIGltYWcsIHBoYXNlKSB7XG4gICAgICAgIGxldCBzdW0gPSAwO1xuICAgICAgICBjb25zdCBsZW4gPSByZWFsLmxlbmd0aDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgc3VtICs9IHJlYWxbaV0gKiBNYXRoLmNvcyhpICogcGhhc2UpICsgaW1hZ1tpXSAqIE1hdGguc2luKGkgKiBwaGFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1bTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgb3NjaWxsYXRvciB3aGVuIHN0b3BwZWQuXG4gICAgICogRS5nLiBhIFwic2luZVwiIG9zY2lsbGF0b3Igd2l0aCBwaGFzZSA9IDkwIHdvdWxkIHJldHVybiBhbiBpbml0aWFsIHZhbHVlIG9mIC0xLlxuICAgICAqL1xuICAgIGdldEluaXRpYWxWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgW3JlYWwsIGltYWddID0gdGhpcy5fZ2V0UmVhbEltYWdpbmFyeSh0aGlzLl90eXBlLCAwKTtcbiAgICAgICAgbGV0IG1heFZhbHVlID0gMDtcbiAgICAgICAgY29uc3QgdHdvUGkgPSBNYXRoLlBJICogMjtcbiAgICAgICAgY29uc3QgdGVzdFBvc2l0aW9ucyA9IDMyO1xuICAgICAgICAvLyBjaGVjayBmb3IgcGVha3MgaW4gMTYgcGxhY2VzXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVzdFBvc2l0aW9uczsgaSsrKSB7XG4gICAgICAgICAgICBtYXhWYWx1ZSA9IE1hdGgubWF4KHRoaXMuX2ludmVyc2VGRlQocmVhbCwgaW1hZywgKGkgLyB0ZXN0UG9zaXRpb25zKSAqIHR3b1BpKSwgbWF4VmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbGFtcCgtdGhpcy5faW52ZXJzZUZGVChyZWFsLCBpbWFnLCB0aGlzLl9waGFzZSkgLyBtYXhWYWx1ZSwgLTEsIDEpO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0aWFscy5zbGljZSgwLCB0aGlzLnBhcnRpYWxDb3VudCk7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGg7XG4gICAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiY3VzdG9tXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGhhc2UgKiAoMTgwIC8gTWF0aC5QSSk7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9waGFzZSA9IHBoYXNlICogTWF0aC5QSSAvIDE4MDtcbiAgICAgICAgLy8gcmVzZXQgdGhlIHR5cGVcbiAgICAgICAgdGhpcy50eXBlID0gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fd2F2ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogQ2FjaGUgdGhlIHBlcmlvZGljIHdhdmVzIHRvIGF2b2lkIGhhdmluZyB0byByZWRvIGNvbXB1dGF0aW9uc1xuICovXG5Pc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZSA9IFtdO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbi8qKlxuICogQSBzaWduYWwgb3BlcmF0b3IgaGFzIGFuIGlucHV0IGFuZCBvdXRwdXQgYW5kIG1vZGlmaWVzIHRoZSBzaWduYWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxPcGVyYXRvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbE9wZXJhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY29udGV4dFwiXSkpKTtcbiAgICB9XG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaWduYWxPcGVyYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzRnVuY3Rpb24gfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFdyYXBzIHRoZSBuYXRpdmUgV2ViIEF1ZGlvIEFQSVxuICogW1dhdmVTaGFwZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS13YXZlc2hhcGVybm9kZS1pbnRlcmZhY2UpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyBtdWx0aXBseSB0aGUgb3V0cHV0IG9mIHRoZSBzaWduYWwgYnkgMiB1c2luZyB0aGUgd2F2ZXNoYXBlcidzIGZ1bmN0aW9uXG4gKiBjb25zdCB0aW1lc1R3byA9IG5ldyBUb25lLldhdmVTaGFwZXIoKHZhbCkgPT4gdmFsICogMiwgMjA0OCkuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAqIGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCg0NDApLmNvbm5lY3QodGltZXNUd28pO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgV2F2ZVNoYXBlciBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlU2hhcGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWFwcGluZ1wiLCBcImxlbmd0aFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJXYXZlU2hhcGVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgd2F2ZXNoYXBlciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zaGFwZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IHRvIHRoZSB3YXZlc2hhcGVyIG5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc2hhcGVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBmcm9tIHRoZSB3YXZlc2hhcGVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc2hhcGVyO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZVNoYXBlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1hcHBpbmdcIiwgXCJsZW5ndGhcIl0pO1xuICAgICAgICBpZiAoaXNBcnJheShvcHRpb25zLm1hcHBpbmcpIHx8IG9wdGlvbnMubWFwcGluZyBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSkge1xuICAgICAgICAgICAgdGhpcy5jdXJ2ZSA9IEZsb2F0MzJBcnJheS5mcm9tKG9wdGlvbnMubWFwcGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNGdW5jdGlvbihvcHRpb25zLm1hcHBpbmcpKSB7XG4gICAgICAgICAgICB0aGlzLnNldE1hcChvcHRpb25zLm1hcHBpbmcsIG9wdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBsZW5ndGg6IDEwMjQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVc2VzIGEgbWFwcGluZyBmdW5jdGlvbiB0byBzZXQgdGhlIHZhbHVlIG9mIHRoZSBjdXJ2ZS5cbiAgICAgKiBAcGFyYW0gbWFwcGluZyBUaGUgZnVuY3Rpb24gdXNlZCB0byBkZWZpbmUgdGhlIHZhbHVlcy5cbiAgICAgKiAgICAgICAgICAgICAgICBUaGUgbWFwcGluZyBmdW5jdGlvbiB0YWtlIHR3byBhcmd1bWVudHM6XG4gICAgICogICAgICAgICAgICAgICAgdGhlIGZpcnN0IGlzIHRoZSB2YWx1ZSBhdCB0aGUgY3VycmVudCBwb3NpdGlvblxuICAgICAqICAgICAgICAgICAgICAgIHdoaWNoIGdvZXMgZnJvbSAtMSB0byAxIG92ZXIgdGhlIG51bWJlciBvZiBlbGVtZW50c1xuICAgICAqICAgICAgICAgICAgICAgIGluIHRoZSBjdXJ2ZSBhcnJheS4gVGhlIHNlY29uZCBhcmd1bWVudCBpcyB0aGUgYXJyYXkgcG9zaXRpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzaGFwZXIgPSBuZXcgVG9uZS5XYXZlU2hhcGVyKCk7XG4gICAgICogLy8gbWFwIHRoZSBpbnB1dCBzaWduYWwgZnJvbSBbLTEsIDFdIHRvIFswLCAxMF1cbiAgICAgKiBzaGFwZXIuc2V0TWFwKCh2YWwsIGluZGV4KSA9PiAodmFsICsgMSkgKiA1KTtcbiAgICAgKi9cbiAgICBzZXRNYXAobWFwcGluZywgbGVuZ3RoID0gMTAyNCkge1xuICAgICAgICBjb25zdCBhcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVkID0gKGkgLyAobGVuIC0gMSkpICogMiAtIDE7XG4gICAgICAgICAgICBhcnJheVtpXSA9IG1hcHBpbmcobm9ybWFsaXplZCwgaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdXJ2ZSA9IGFycmF5O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFycmF5IHRvIHNldCBhcyB0aGUgd2F2ZXNoYXBlciBjdXJ2ZS4gRm9yIGxpbmVhciBjdXJ2ZXNcbiAgICAgKiBhcnJheSBsZW5ndGggZG9lcyBub3QgbWFrZSBtdWNoIGRpZmZlcmVuY2UsIGJ1dCBmb3IgY29tcGxleCBjdXJ2ZXNcbiAgICAgKiBsb25nZXIgYXJyYXlzIHdpbGwgcHJvdmlkZSBzbW9vdGhlciBpbnRlcnBvbGF0aW9uLlxuICAgICAqL1xuICAgIGdldCBjdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5jdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGN1cnZlKG1hcHBpbmcpIHtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmN1cnZlID0gbWFwcGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHdoYXQgdHlwZSBvZiBvdmVyc2FtcGxpbmcgKGlmIGFueSkgc2hvdWxkIGJlIHVzZWQgd2hlblxuICAgICAqIGFwcGx5aW5nIHRoZSBzaGFwaW5nIGN1cnZlLiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICBjb25zdCBpc092ZXJTYW1wbGVUeXBlID0gW1wibm9uZVwiLCBcIjJ4XCIsIFwiNHhcIl0uc29tZShzdHIgPT4gc3RyLmluY2x1ZGVzKG92ZXJzYW1wbGluZykpO1xuICAgICAgICBhc3NlcnQoaXNPdmVyU2FtcGxlVHlwZSwgXCJvdmVyc2FtcGxpbmcgbXVzdCBiZSBlaXRoZXIgJ25vbmUnLCAnMngnLCBvciAnNHgnXCIpO1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1XYXZlU2hhcGVyLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIEF1ZGlvVG9HYWluIGNvbnZlcnRzIGFuIGlucHV0IGluIEF1ZGlvUmFuZ2UgWy0xLDFdIHRvIE5vcm1hbFJhbmdlIFswLDFdLlxuICogU2VlIFtbR2FpblRvQXVkaW9dXS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEF1ZGlvVG9HYWluIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1ZGlvVG9HYWluXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbm9kZSB3aGljaCBjb252ZXJ0cyB0aGUgYXVkaW8gcmFuZ2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ub3JtID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogeCA9PiAoeCArIDEpIC8gMixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQXVkaW9SYW5nZSBpbnB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbm9ybTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBHYWluUmFuZ2Ugb3V0cHV0IFswLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9ub3JtO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbm9ybS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1ZGlvVG9HYWluLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG4vKipcbiAqIE11bHRpcGx5IHR3byBpbmNvbWluZyBzaWduYWxzLiBPciwgaWYgYSBudW1iZXIgaXMgZ2l2ZW4gaW4gdGhlIGNvbnN0cnVjdG9yLFxuICogbXVsdGlwbGllcyB0aGUgaW5jb21pbmcgc2lnbmFsIGJ5IHRoYXQgdmFsdWUuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIG11bHRpcGx5IHR3byBzaWduYWxzXG4gKiBjb25zdCBtdWx0ID0gbmV3IFRvbmUuTXVsdGlwbHkoKTtcbiAqIGNvbnN0IHNpZ0EgPSBuZXcgVG9uZS5TaWduYWwoMyk7XG4gKiBjb25zdCBzaWdCID0gbmV3IFRvbmUuU2lnbmFsKDQpO1xuICogc2lnQS5jb25uZWN0KG11bHQpO1xuICogc2lnQi5jb25uZWN0KG11bHQuZmFjdG9yKTtcbiAqIC8vIG91dHB1dCBvZiBtdWx0IGlzIDEyLlxuICogQGV4YW1wbGVcbiAqIC8vIG11bHRpcGx5IGEgc2lnbmFsIGFuZCBhIG51bWJlclxuICogY29uc3QgbXVsdCA9IG5ldyBUb25lLk11bHRpcGx5KDEwKTtcbiAqIGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgyKS5jb25uZWN0KG11bHQpO1xuICogLy8gdGhlIG91dHB1dCBvZiBtdWx0IGlzIDIwLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgTXVsdGlwbHkgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpcGx5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTXVsdGlwbHlcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIG92ZXJyaWRkZW4gb24gY29ubmVjdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGlwbHkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX211bHQgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mYWN0b3IgPSB0aGlzLl9wYXJhbSA9IHRoaXMuX211bHQuZ2FpbjtcbiAgICAgICAgdGhpcy5mYWN0b3Iuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGlwbHkuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEF1ZGlvVG9HYWluIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BdWRpb1RvR2FpblwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbi8qKlxuICogQW4gYW1wbGl0dWRlIG1vZHVsYXRlZCBvc2NpbGxhdG9yIG5vZGUuIEl0IGlzIGltcGxlbWVudGVkIHdpdGhcbiAqIHR3byBvc2NpbGxhdG9ycywgb25lIHdoaWNoIG1vZHVsYXRvcnMgdGhlIG90aGVyJ3MgYW1wbGl0dWRlXG4gKiB0aHJvdWdoIGEgZ2FpbiBub2RlLlxuICogYGBgXG4gKiAgICArLS0tLS0tLS0tLS0tLSsgICAgICAgKy0tLS0tLS0tLS0rXG4gKiAgICB8IENhcnJpZXIgT3NjICs+LS0tLS0tPiBHYWluTm9kZSB8XG4gKiAgICArLS0tLS0tLS0tLS0tLSsgICAgICAgfCAgICAgICAgICArLS0tPk91dHB1dFxuICogICAgICAgICAgICAgICAgICAgICAgKy0tLT4gZ2FpbiAgICAgfFxuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgfCAgICstLS0tLS0tLS0tK1xuICogfCBNb2R1bGF0b3IgT3NjICs+LS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBhbU9zYyA9IG5ldyBUb25lLkFNT3NjaWxsYXRvcigzMCwgXCJzaW5lXCIsIFwic3F1YXJlXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4yLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEFNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFNT3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogY29udmVydCB0aGUgLTEsMSBvdXRwdXQgdG8gMCwxXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUgPSBuZXcgQXVkaW9Ub0dhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwibW9kdWxhdGlvblR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9jYXJyaWVyLmRldHVuZTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLm1vZHVsYXRpb25UeXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNoYWluKHRoaXMuX21vZHVsYXRpb25TY2FsZSwgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY2hhaW4odGhpcy5fbW9kdWxhdGlvbk5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiaGFybW9uaWNpdHlcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDEsXG4gICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBjYXJyaWVyIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2R1bGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFNT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG4vKipcbiAqIEZNT3NjaWxsYXRvciBpbXBsZW1lbnRzIGEgZnJlcXVlbmN5IG1vZHVsYXRpb24gc3ludGhlc2lzXG4gKiBgYGBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0tLS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgICAgICstLS0tLS0tLS0tLS0tKyAgICAgfCBDYXJyaWVyIE9zYyB8XG4gKiB8IE1vZHVsYXRvciBPc2MgKz4tLS0tLS0tPiBHYWluTm9kZSAgICB8ICAgICB8ICAgICAgICAgICAgICstLS0+T3V0cHV0XG4gKiArLS0tLS0tLS0tLS0tLS0tKyAgICAgICAgfCAgICAgICAgICAgICArPi0tLS0+IGZyZXF1ZW5jeSAgIHxcbiAqICAgICAgICAgICAgICAgICAgICAgICArLS0+IGdhaW4gICAgICAgIHwgICAgICstLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgICAgICAgICAgICAgIHwgICstLS0tLS0tLS0tLS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLS0tKyAgIHxcbiAqIHwgbW9kdWxhdGlvbkluZGV4ICs+LS0rXG4gKiArLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGZtT3NjID0gbmV3IFRvbmUuRk1Pc2NpbGxhdG9yKHtcbiAqIFx0XHRmcmVxdWVuY3k6IDIwMCxcbiAqIFx0XHR0eXBlOiBcInNxdWFyZVwiLFxuICogXHRcdG1vZHVsYXRpb25UeXBlOiBcInRyaWFuZ2xlXCIsXG4gKiBcdFx0aGFybW9uaWNpdHk6IDAuMixcbiAqIFx0XHRtb2R1bGF0aW9uSW5kZXg6IDNcbiAqIFx0fSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgRk1Pc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRk1Pc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKTtcbiAgICAgICAgdGhpcy5fY2FycmllciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX2NhcnJpZXIuZGV0dW5lO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMubW9kdWxhdGlvblR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMubW9kdWxhdGlvbkluZGV4LCB0aGlzLl9tb2R1bGF0aW9uTm9kZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jb25uZWN0KHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibW9kdWxhdGlvbkluZGV4XCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiaGFybW9uaWNpdHlcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDEsXG4gICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IDIsXG4gICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2R1bGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZNT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuLyoqXG4gKiBQdWxzZU9zY2lsbGF0b3IgaXMgYW4gb3NjaWxsYXRvciB3aXRoIGNvbnRyb2wgb3ZlciBwdWxzZSB3aWR0aCxcbiAqIGFsc28ga25vd24gYXMgdGhlIGR1dHkgY3ljbGUuIEF0IDUwJSBkdXR5IGN5Y2xlICh3aWR0aCA9IDApIHRoZSB3YXZlIGlzXG4gKiBhIHNxdWFyZSB3YXZlLlxuICogW1JlYWQgbW9yZV0oaHR0cHM6Ly93aWdnbGV3YXZlLndvcmRwcmVzcy5jb20vMjAxNC8wOC8xNi9wdWxzZS13YXZlZm9ybXMtYW5kLWhhcm1vbmljcy8pLlxuICogYGBgXG4gKiAgICB3aWR0aCA9IC0wLjI1ICAgICAgICB3aWR0aCA9IDAuMCAgICAgICAgICB3aWR0aCA9IDAuMjVcbiAqXG4gKiAgICstLS0tLSsgICAgICAgICAgICArLS0tLS0tLSsgICAgICAgKyAgICArLS0tLS0tLSsgICAgICstK1xuICogICB8ICAgICB8ICAgICAgICAgICAgfCAgICAgICB8ICAgICAgIHwgICAgICAgICAgICB8ICAgICB8XG4gKiAgIHwgICAgIHwgICAgICAgICAgICB8ICAgICAgIHwgICAgICAgfCAgICAgICAgICAgIHwgICAgIHxcbiAqICstKyAgICAgKy0tLS0tLS0rICAgICsgICAgICAgKy0tLS0tLS0rICAgICAgICAgICAgKy0tLS0tK1xuICpcbiAqXG4gKiAgICB3aWR0aCA9IC0wLjUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNVxuICpcbiAqICAgICArLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKyAgICstLS0rXG4gKiAgICAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8XG4gKiAgICAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8XG4gKiArLS0tKyAgICstLS0tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0rXG4gKlxuICpcbiAqICAgIHdpZHRoID0gLTAuNzUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC43NVxuICpcbiAqICAgICAgICstKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKyArLS0tLS0rXG4gKiAgICAgICB8IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgfFxuICogICAgICAgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHxcbiAqICstLS0tLSsgKy0tLS0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgcHVsc2UgPSBuZXcgVG9uZS5QdWxzZU9zY2lsbGF0b3IoNTAsIDAuNCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUHVsc2VPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwid2lkdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQdWxzZU9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGdhdGUgdGhlIHdpZHRoIGFtb3VudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaHJlc2hvbGQgdGhlIHNpZ25hbCB0byB0dXJuIGl0IGludG8gYSBzcXVhcmVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RocmVzaCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHZhbCA9PiB2YWwgPD0gMCA/IC0xIDogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQdWxzZU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImF1ZGlvUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLndpZHRoLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fdHJpYW5nbGUuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX3RyaWFuZ2xlLmRldHVuZTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUuY2hhaW4odGhpcy5fdGhyZXNoLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMud2lkdGguY2hhaW4odGhpcy5fd2lkdGhHYXRlLCB0aGlzLl90aHJlc2gpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3aWR0aFwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgcGhhc2U6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInB1bHNlXCIsXG4gICAgICAgICAgICB3aWR0aDogMC4yLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5zdG9wKHRpbWUpO1xuICAgICAgICAvLyB0aGUgd2lkdGggaXMgc3RpbGwgY29ubmVjdGVkIHRvIHRoZSBvdXRwdXQuXG4gICAgICAgIC8vIHRoYXQgbmVlZHMgdG8gYmUgc3RvcHBlZCBhbHNvXG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJpYW5nbGUucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwdWxzZVwiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwdWxzZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZVR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHVsc2VcIi5cbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB1bHNlXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwYXJ0aWFscyBvZiB0aGUgd2F2ZWZvcm0uIENhbm5vdCBzZXQgcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBObyBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlLlxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqSW50ZXJuYWwgdXNlKiBUaGUgY2FycmllciBvc2NpbGxhdG9yIHR5cGUgaXMgZmVkIHRocm91Z2ggdGhlXG4gICAgICogd2F2ZXNoYXBlciBub2RlIHRvIGNyZWF0ZSB0aGUgcHVsc2UuIFVzaW5nIGRpZmZlcmVudCBjYXJyaWVyIG9zY2lsbGF0b3JzXG4gICAgICogY2hhbmdlcyBvc2NpbGxhdG9yJ3MgYmVoYXZpb3IuXG4gICAgICovXG4gICAgc2V0IGNhcnJpZXJUeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwIG1ldGhvZC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53aWR0aC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RocmVzaC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVB1bHNlT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEZhdE9zY2lsbGF0b3IgaXMgYW4gYXJyYXkgb2Ygb3NjaWxsYXRvcnMgd2l0aCBkZXR1bmUgc3ByZWFkIGJldHdlZW4gdGhlIG9zY2lsbGF0b3JzXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZmF0T3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcihcIkFiM1wiLCBcInNhd3Rvb3RoXCIsIDQwKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEZhdE9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGYXRPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInNwcmVhZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZhdE9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhcnJheSBvZiBvc2NpbGxhdG9yc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZhdE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwic3ByZWFkXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IG9wdGlvbnMucGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IG9wdGlvbnMucGFydGlhbENvdW50O1xuICAgICAgICAvLyBzZXQgdGhlIGNvdW50IGluaXRpYWxseVxuICAgICAgICB0aGlzLmNvdW50ID0gb3B0aW9ucy5jb3VudDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvdW50OiAzLFxuICAgICAgICAgICAgc3ByZWFkOiAyMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2Muc3RhcnQodGltZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5zdG9wKHRpbWUpKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MucmVzdGFydCh0aW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIG9zY2lsbGF0b3JzXG4gICAgICovXG4gICAgX2ZvckVhY2goaXRlcmF0b3IpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaXRlcmF0b3IodGhpcy5fb3NjaWxsYXRvcnNbaV0sIGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MudHlwZSA9IHR5cGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9ycy4gSWYgXCJjb3VudFwiIGlzXG4gICAgICogc2V0IHRvIDMgb3NjaWxsYXRvcnMgYW5kIHRoZSBcInNwcmVhZFwiIGlzIHNldCB0byA0MCxcbiAgICAgKiB0aGUgdGhyZWUgb3NjaWxsYXRvcnMgd291bGQgYmUgZGV0dW5lZCBsaWtlIHRoaXM6IFstMjAsIDAsIDIwXVxuICAgICAqIGZvciBhIHRvdGFsIGRldHVuZSBzcHJlYWQgb2YgNDAgY2VudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmYXRPc2MgPSBuZXcgVG9uZS5GYXRPc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogZmF0T3NjLnNwcmVhZCA9IDcwO1xuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zcHJlYWQ7XG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX3NwcmVhZCA9IHNwcmVhZDtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gLXNwcmVhZCAvIDI7XG4gICAgICAgICAgICBjb25zdCBzdGVwID0gc3ByZWFkIC8gKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaCgob3NjLCBpKSA9PiBvc2MuZGV0dW5lLnZhbHVlID0gc3RhcnQgKyBzdGVwICogaSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBkZXR1bmVkIG9zY2lsbGF0b3JzLiBNdXN0IGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDEuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmYXRPc2MgPSBuZXcgVG9uZS5GYXRPc2NpbGxhdG9yKFwiQyMzXCIsIFwic2F3dG9vdGhcIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogLy8gdXNlIDQgc2F3dG9vdGggb3NjaWxsYXRvcnNcbiAgICAgKiBmYXRPc2MuY291bnQgPSA0O1xuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aDtcbiAgICB9XG4gICAgc2V0IGNvdW50KGNvdW50KSB7XG4gICAgICAgIGFzc2VydFJhbmdlKGNvdW50LCAxKTtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCAhPT0gY291bnQpIHtcbiAgICAgICAgICAgIC8vIGRpc3Bvc2UgdGhlIHByZXZpb3VzIG9zY2lsbGF0b3JzXG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MuZGlzcG9zZSgpKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvc2MgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgdm9sdW1lOiAtNiAtIGNvdW50ICogMS4xLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLl90eXBlLFxuICAgICAgICAgICAgICAgICAgICBwaGFzZTogdGhpcy5fcGhhc2UgKyAoaSAvIGNvdW50KSAqIDM2MCxcbiAgICAgICAgICAgICAgICAgICAgcGFydGlhbENvdW50OiB0aGlzLl9wYXJ0aWFsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIG9uc3RvcDogaSA9PT0gMCA/ICgpID0+IHRoaXMub25zdG9wKHRoaXMpIDogbm9PcCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIG9zYy5wYXJ0aWFscyA9IHRoaXMuX3BhcnRpYWxzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KG9zYy5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3Qob3NjLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgb3NjLmRldHVuZS5vdmVycmlkZGVuID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgb3NjLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzW2ldID0gb3NjO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gc2V0IHRoZSBzcHJlYWRcbiAgICAgICAgICAgIHRoaXMuc3ByZWFkID0gdGhpcy5fc3ByZWFkO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaCgob3NjLCBpKSA9PiBvc2MucGhhc2UgPSB0aGlzLl9waGFzZSArIChpIC8gdGhpcy5jb3VudCkgKiAzNjApO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5iYXNlVHlwZSA9IGJhc2VUeXBlKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuX29zY2lsbGF0b3JzWzBdLnR5cGU7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLl90eXBlID0gXCJjdXN0b21cIjtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5wYXJ0aWFscyA9IHBhcnRpYWxzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0ucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQpO1xuICAgICAgICB0aGlzLl90eXBlID0gdGhpcy5fb3NjaWxsYXRvcnNbMF0udHlwZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZhdE9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBQdWxzZU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9QdWxzZU9zY2lsbGF0b3JcIjtcbi8qKlxuICogUFdNT3NjaWxsYXRvciBtb2R1bGF0ZXMgdGhlIHdpZHRoIG9mIGEgVG9uZS5QdWxzZU9zY2lsbGF0b3JcbiAqIGF0IHRoZSBtb2R1bGF0aW9uRnJlcXVlbmN5LiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNvbnRpbnVvdXNseVxuICogY2hhbmdpbmcgdGhlIHRpbWJyZSBvZiB0aGUgb3NjaWxsYXRvciBieSBhbHRlcmluZyB0aGUgaGFybW9uaWNzXG4gKiBnZW5lcmF0ZWQuXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IHB3bSA9IG5ldyBUb25lLlBXTU9zY2lsbGF0b3IoNjAsIDAuMykudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUFdNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtb2R1bGF0aW9uRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUFdNT3NjaWxsYXRvclwiO1xuICAgICAgICB0aGlzLnNvdXJjZVR5cGUgPSBcInB3bVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2NhbGUgdGhlIG9zY2lsbGF0b3Igc28gaXQgZG9lc24ndCBnbyBzaWxlbnRcbiAgICAgICAgICogYXQgdGhlIGV4dHJlbWUgdmFsdWVzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NhbGUgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUFdNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm1vZHVsYXRpb25GcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9wdWxzZSA9IG5ldyBQdWxzZU9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLm1vZHVsYXRpb25GcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjaGFuZ2UgdGhlIHB1bHNlIG9zY2lsbGF0b3IgdHlwZVxuICAgICAgICB0aGlzLl9wdWxzZS5jYXJyaWVyVHlwZSA9IFwic2luZVwiO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25GcmVxdWVuY3kgPSB0aGlzLl9wdWxzZS5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX21vZHVsYXRvci5kZXR1bmU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9zY2FsZSwgdGhpcy5fcHVsc2Uud2lkdGgpO1xuICAgICAgICB0aGlzLl9wdWxzZS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibW9kdWxhdGlvbkZyZXF1ZW5jeVwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkZyZXF1ZW5jeTogMC40LFxuICAgICAgICAgICAgcGhhc2U6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInB3bVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fcHVsc2Uuc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3B1bHNlLnN0b3AodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJlc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9wdWxzZS5yZXN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwd21cIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIFwicHdtXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlVHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwd21cIi5cbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB3bVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGFydGlhbHMgb2YgdGhlIHdhdmVmb3JtLiBDYW5ub3Qgc2V0IHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGVcbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTm8gcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZS5cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcHVsc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBXTU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzTnVtYmVyLCBpc1N0cmluZyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgQU1Pc2NpbGxhdG9yIH0gZnJvbSBcIi4vQU1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBGYXRPc2NpbGxhdG9yIH0gZnJvbSBcIi4vRmF0T3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgRk1Pc2NpbGxhdG9yIH0gZnJvbSBcIi4vRk1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IFB1bHNlT3NjaWxsYXRvciB9IGZyb20gXCIuL1B1bHNlT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgUFdNT3NjaWxsYXRvciB9IGZyb20gXCIuL1BXTU9zY2lsbGF0b3JcIjtcbmNvbnN0IE9tbmlPc2NpbGxhdG9yU291cmNlTWFwID0ge1xuICAgIGFtOiBBTU9zY2lsbGF0b3IsXG4gICAgZmF0OiBGYXRPc2NpbGxhdG9yLFxuICAgIGZtOiBGTU9zY2lsbGF0b3IsXG4gICAgb3NjaWxsYXRvcjogT3NjaWxsYXRvcixcbiAgICBwdWxzZTogUHVsc2VPc2NpbGxhdG9yLFxuICAgIHB3bTogUFdNT3NjaWxsYXRvcixcbn07XG4vKipcbiAqIE9tbmlPc2NpbGxhdG9yIGFnZ3JlZ2F0ZXMgYWxsIG9mIHRoZSBvc2NpbGxhdG9yIHR5cGVzIGludG8gb25lLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoXCJDIzRcIiwgXCJwd21cIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgT21uaU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPbW5pT3NjaWxsYXRvclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgICAgICAvLyBzZXQgdGhlIG9wdGlvbnNcbiAgICAgICAgdGhpcy5zZXQob3B0aW9ucyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBGTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgQU1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIEZhdE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQ2FuIGJlIGFueSBvZiB0aGUgYmFzaWMgdHlwZXM6IHNpbmUsIHNxdWFyZSwgdHJpYW5nbGUsIHNhd3Rvb3RoLiBPclxuICAgICAqIHByZWZpeCB0aGUgYmFzaWMgdHlwZXMgd2l0aCBcImZtXCIsIFwiYW1cIiwgb3IgXCJmYXRcIiB0byB1c2UgdGhlIEZNT3NjaWxsYXRvciwgQU1Pc2NpbGxhdG9yIG9yIEZhdE9zY2lsbGF0b3JcbiAgICAgKiB0eXBlcy4gVGhlIG9zY2lsbGF0b3IgY291bGQgYWxzbyBiZSBzZXQgdG8gXCJwd21cIiBvciBcInB1bHNlXCIuIEFsbCBvZiB0aGUgcGFyYW1ldGVycyBvZiB0aGVcbiAgICAgKiBvc2NpbGxhdG9yJ3MgY2xhc3MgYXJlIGFjY2Vzc2libGUgd2hlbiB0aGUgb3NjaWxsYXRvciBpcyBzZXQgdG8gdGhhdCB0eXBlLCBidXQgdGhyb3dzIGFuIGVycm9yXG4gICAgICogd2hlbiBpdCdzIG5vdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9tbmlPc2MgPSBuZXcgVG9uZS5PbW5pT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG9tbmlPc2MudHlwZSA9IFwicHdtXCI7XG4gICAgICogLy8gbW9kdWxhdGlvbkZyZXF1ZW5jeSBpcyBwYXJhbWV0ZXIgd2hpY2ggaXMgYXZhaWxhYmxlXG4gICAgICogLy8gb25seSB3aGVuIHRoZSB0eXBlIGlzIFwicHdtXCIuXG4gICAgICogb21uaU9zYy5tb2R1bGF0aW9uRnJlcXVlbmN5LnZhbHVlID0gMC41O1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICBsZXQgcHJlZml4ID0gXCJcIjtcbiAgICAgICAgaWYgKFtcImFtXCIsIFwiZm1cIiwgXCJmYXRcIl0uc29tZShwID0+IHRoaXMuX3NvdXJjZVR5cGUgPT09IHApKSB7XG4gICAgICAgICAgICBwcmVmaXggPSB0aGlzLl9zb3VyY2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcmVmaXggKyB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgaWYgKHR5cGUuc3Vic3RyKDAsIDIpID09PSBcImZtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJmbVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZS5zdWJzdHIoMCwgMikgPT09IFwiYW1cIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcImFtXCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlLnN1YnN0cigyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlLnN1YnN0cigwLCAzKSA9PT0gXCJmYXRcIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcImZhdFwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gXCJwd21cIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcInB3bVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09IFwicHVsc2VcIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcInB1bHNlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcIm9zY2lsbGF0b3JcIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHZhbHVlIGlzIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIHR5cGUgaXMgbm90IFwiY3VzdG9tXCIuXG4gICAgICogVGhpcyBpcyBub3QgYXZhaWxhYmxlIG9uIFwicHdtXCIgYW5kIFwicHVsc2VcIiBvc2NpbGxhdG9yIHR5cGVzLlxuICAgICAqIFNlZSBbW09zY2lsbGF0b3IucGFydGlhbHNdXVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICBpZiAoIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSAmJiAhdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB3bVwiKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwYXJ0aWFsQ291bnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiYgIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldChwcm9wcykge1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHR5cGUgaXMgc2V0IGZpcnN0XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhcyhwcm9wcywgXCJ0eXBlXCIpICYmIHByb3BzLnR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IHByb3BzLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlbiBzZXQgdGhlIHJlc3RcbiAgICAgICAgc3VwZXIuc2V0KHByb3BzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG9zY2lsbGF0b3IgdG8gdGhlIGZyZXF1ZW5jeSBhbmQgZGV0dW5lIHNpZ25hbHNcbiAgICAgKi9cbiAgICBfY3JlYXRlTmV3T3NjaWxsYXRvcihvc2NUeXBlKSB7XG4gICAgICAgIGlmIChvc2NUeXBlICE9PSB0aGlzLl9zb3VyY2VUeXBlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VUeXBlID0gb3NjVHlwZTtcbiAgICAgICAgICAgIGNvbnN0IE9zY0NvbnN0cnVjdG9yID0gT21uaU9zY2lsbGF0b3JTb3VyY2VNYXBbb3NjVHlwZV07XG4gICAgICAgICAgICAvLyBzaG9ydCBkZWxheSB0byBhdm9pZCBjbGlja3Mgb24gdGhlIGNoYW5nZVxuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkT3NjID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgICAgICBvbGRPc2Muc3RvcChub3cpO1xuICAgICAgICAgICAgICAgIC8vIGRpc3Bvc2UgdGhlIG9sZCBvbmVcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiBvbGRPc2MuZGlzcG9zZSgpLCB0aGlzLmJsb2NrVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IE9zY0NvbnN0cnVjdG9yKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5vbnN0b3AgPSAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQobm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc291cmNlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoNDQwLCBcImZtc3F1YXJlXCIpO1xuICAgICAqIGNvbnNvbGUubG9nKG9tbmlPc2Muc291cmNlVHlwZSk7IC8vICdmbSdcbiAgICAgKi9cbiAgICBnZXQgc291cmNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZVR5cGU7XG4gICAgfVxuICAgIHNldCBzb3VyY2VUeXBlKHNUeXBlKSB7XG4gICAgICAgIC8vIHRoZSBiYXNldHlwZSBkZWZhdWx0cyB0byBzaW5lXG4gICAgICAgIGxldCBiYXNlVHlwZSA9IFwic2luZVwiO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvci50eXBlICE9PSBcInB3bVwiICYmIHRoaXMuX29zY2lsbGF0b3IudHlwZSAhPT0gXCJwdWxzZVwiKSB7XG4gICAgICAgICAgICBiYXNlVHlwZSA9IHRoaXMuX29zY2lsbGF0b3IudHlwZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHR5cGVcbiAgICAgICAgaWYgKHNUeXBlID09PSBcImZtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiZm1cIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcImFtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiYW1cIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcImZhdFwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImZhdFwiICsgYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwib3NjaWxsYXRvclwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJwdWxzZVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcInB1bHNlXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwicHdtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwicHdtXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2dldE9zY1R5cGUob3NjLCBzb3VyY2VUeXBlKSB7XG4gICAgICAgIHJldHVybiBvc2MgaW5zdGFuY2VvZiBPbW5pT3NjaWxsYXRvclNvdXJjZU1hcFtzb3VyY2VUeXBlXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gU2VlIFtbT3NjaWxsYXRvci5iYXNlVHlwZV1dXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoNDQwLCBcImZtc3F1YXJlNFwiKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvbW5pT3NjLnNvdXJjZVR5cGUsIG9tbmlPc2MuYmFzZVR5cGUsIG9tbmlPc2MucGFydGlhbENvdW50KTtcbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiZcbiAgICAgICAgICAgICF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpICYmXG4gICAgICAgICAgICBiYXNlVHlwZSAhPT0gXCJwdWxzZVwiICYmIGJhc2VUeXBlICE9PSBcInB3bVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmJhc2VUeXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHdpZHRoIG9mIHRoZSBvc2NpbGxhdG9yIHdoZW4gc291cmNlVHlwZSA9PT0gXCJwdWxzZVwiLlxuICAgICAqIFNlZSBbW1BXTU9zY2lsbGF0b3Iud2lkdGhdXVxuICAgICAqL1xuICAgIGdldCB3aWR0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGV0dW5lZCBvc2NpbGxhdG9ycyB3aGVuIHNvdXJjZVR5cGUgPT09IFwiZmF0XCIuXG4gICAgICogU2VlIFtbRmF0T3NjaWxsYXRvci5jb3VudF1dXG4gICAgICovXG4gICAgZ2V0IGNvdW50KCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IuY291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBjb3VudChjb3VudCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSAmJiBpc051bWJlcihjb3VudCkpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY291bnQgPSBjb3VudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9ycyB3aGVuIHNvdXJjZVR5cGUgPT09IFwiZmF0XCIuXG4gICAgICogU2VlIFtbRmF0T3NjaWxsYXRvci5jb3VudF1dXG4gICAgICovXG4gICAgZ2V0IHNwcmVhZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnNwcmVhZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikgJiYgaXNOdW1iZXIoc3ByZWFkKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zcHJlYWQgPSBzcHJlYWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yLiBPbmx5IGlmIHRoZSBvc2NpbGxhdG9yIGlzIHNldCB0byBcImFtXCIgb3IgXCJmbVwiIHR5cGVzLlxuICAgICAqIFNlZSBbW0FNT3NjaWxsYXRvcl1dIG9yIFtbRk1Pc2NpbGxhdG9yXV1cbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikgfHwgdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImFtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKG1UeXBlKSB7XG4gICAgICAgIGlmICgodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZtXCIpIHx8IHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJhbVwiKSkgJiYgaXNTdHJpbmcobVR5cGUpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25UeXBlID0gbVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb24gaW5kZXggd2hlbiB0aGUgc291cmNlVHlwZSA9PT0gXCJmbVwiXG4gICAgICogU2VlIFtbRk1Pc2NpbGxhdG9yXV0uXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25JbmRleCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IubW9kdWxhdGlvbkluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYXJtb25pY2l0eSBpcyB0aGUgZnJlcXVlbmN5IHJhdGlvIGJldHdlZW4gdGhlIGNhcnJpZXIgYW5kIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvcnMuXG4gICAgICogU2VlIFtbQU1Pc2NpbGxhdG9yXV0gb3IgW1tGTU9zY2lsbGF0b3JdXVxuICAgICAqL1xuICAgIGdldCBoYXJtb25pY2l0eSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSB8fCB0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiYW1cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmhhcm1vbmljaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbW9kdWxhdGlvbkZyZXF1ZW5jeSBTaWduYWwgb2YgdGhlIG9zY2lsbGF0b3Igd2hlbiBzb3VyY2VUeXBlID09PSBcInB3bVwiXG4gICAgICogc2VlIFtbUFdNT3NjaWxsYXRvcl1dXG4gICAgICogQG1pbiAwLjFcbiAgICAgKiBAbWF4IDVcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvbkZyZXF1ZW5jeSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25GcmVxdWVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PbW5pT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0U2VyaWVzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuLyoqXG4gKiBBZGQgYSBzaWduYWwgYW5kIGEgbnVtYmVyIG9yIHR3byBzaWduYWxzLiBXaGVuIG5vIHZhbHVlIGlzXG4gKiBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIFRvbmUuQWRkIHdpbGwgc3VtIGlucHV0IGFuZCBgYWRkZW5kYFxuICogSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIHRoZSBpdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSBpbnB1dC5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFkZCA9IG5ldyBUb25lLkFkZCgyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGFkZC5hZGRlbmQuc2V0VmFsdWVBdFRpbWUoMSwgMC4yKTtcbiAqIFx0Y29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDIpO1xuICogXHQvLyBhZGQgYSBzaWduYWwgYW5kIGEgc2NhbGFyXG4gKiBcdHNpZ25hbC5jb25uZWN0KGFkZCk7XG4gKiBcdHNpZ25hbC5zZXRWYWx1ZUF0VGltZSgxLCAwLjEpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEFkZCBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoQWRkLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBZGRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzdW1taW5nIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N1bSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB3aGljaCBpcyBhZGRlZCB0byB0aGUgaW5wdXQgc2lnbmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFkZGVuZCA9IHRoaXMuX3BhcmFtO1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuX2NvbnN0YW50U291cmNlLCB0aGlzLl9zdW0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWRkLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4vQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIHNjYWxpbmcgb24gYW4gaW5wdXQgc2lnbmFsLlxuICogU2NhbGVzIGEgTm9ybWFsUmFuZ2UgaW5wdXQgdG8gYmV0d2VlblxuICogb3V0cHV0TWluIGFuZCBvdXRwdXRNYXguXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNjYWxlID0gbmV3IFRvbmUuU2NhbGUoNTAsIDEwMCk7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHNjYWxlKTtcbiAqIC8vIHRoZSBvdXRwdXQgb2Ygc2NhbGUgZXF1YWxzIDc1XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2FsZSBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTY2FsZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2NhbGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtaW5cIiwgXCJtYXhcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0ID0gdGhpcy5pbnB1dCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tYXggLSBvcHRpb25zLm1pbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FkZCA9IHRoaXMub3V0cHV0ID0gbmV3IEFkZCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5taW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taW4gPSBvcHRpb25zLm1pbjtcbiAgICAgICAgdGhpcy5fbWF4ID0gb3B0aW9ucy5tYXg7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsT3BlcmF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIG51bWJlciBpcyBvdXRwdXQgd2hlbiB0aGUgdmFsdWUgaW5wdXQgdmFsdWUgaXMgMC5cbiAgICAgKi9cbiAgICBnZXQgbWluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWluO1xuICAgIH1cbiAgICBzZXQgbWluKG1pbikge1xuICAgICAgICB0aGlzLl9taW4gPSBtaW47XG4gICAgICAgIHRoaXMuX3NldFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG91dHB1dCB2YWx1ZS4gVGhpcyBudW1iZXIgaXMgb3V0cHV0IHdoZW4gdGhlIHZhbHVlIGlucHV0IHZhbHVlIGlzIDEuXG4gICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heDtcbiAgICB9XG4gICAgc2V0IG1heChtYXgpIHtcbiAgICAgICAgdGhpcy5fbWF4ID0gbWF4O1xuICAgICAgICB0aGlzLl9zZXRSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXQgdGhlIHZhbHVlc1xuICAgICAqL1xuICAgIF9zZXRSYW5nZSgpIHtcbiAgICAgICAgdGhpcy5fYWRkLnZhbHVlID0gdGhpcy5fbWluO1xuICAgICAgICB0aGlzLl9tdWx0LnZhbHVlID0gdGhpcy5fbWF4IC0gdGhpcy5fbWluO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX211bHQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TY2FsZS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0LCBkaXNjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbi8qKlxuICogVG9uZS5aZXJvIG91dHB1dHMgMCdzIGF0IGF1ZGlvLXJhdGUuIFRoZSByZWFzb24gdGhpcyBoYXMgdG8gYmVcbiAqIGl0J3Mgb3duIGNsYXNzIGlzIHRoYXQgbWFueSBicm93c2VycyBvcHRpbWl6ZSBvdXQgVG9uZS5TaWduYWxcbiAqIHdpdGggYSB2YWx1ZSBvZiAwIGFuZCB3aWxsIG5vdCBwcm9jZXNzIG5vZGVzIGZ1cnRoZXIgZG93biB0aGUgZ3JhcGguXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBaZXJvIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFplcm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlplcm9cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBnYWluIG5vZGUgd2hpY2ggY29ubmVjdHMgdGhlIGNvbnN0YW50IHNvdXJjZSB0byB0aGUgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nYWluID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPbmx5IG91dHB1dHMgMFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluO1xuICAgICAgICAvKipcbiAgICAgICAgICogbm8gaW5wdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29ubmVjdCh0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMCksIHRoaXMuX2dhaW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgZGlzY29ubmVjdCh0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMCksIHRoaXMuX2dhaW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1aZXJvLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi8uLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgY29ubmVjdFNpZ25hbCwgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFplcm8gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1plcm9cIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG4vKipcbiAqIExGTyBzdGFuZHMgZm9yIGxvdyBmcmVxdWVuY3kgb3NjaWxsYXRvci4gTEZPIHByb2R1Y2VzIGFuIG91dHB1dCBzaWduYWxcbiAqIHdoaWNoIGNhbiBiZSBhdHRhY2hlZCB0byBhbiBBdWRpb1BhcmFtIG9yIFRvbmUuU2lnbmFsXG4gKiBpbiBvcmRlciB0byBtb2R1bGF0ZSB0aGF0IHBhcmFtZXRlciB3aXRoIGFuIG9zY2lsbGF0b3IuIFRoZSBMRk8gY2FuXG4gKiBhbHNvIGJlIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0IHRvIHN0YXJ0L3N0b3AgYW5kIGNoYW5nZSB3aGVuIHRoZSB0ZW1wbyBjaGFuZ2VzLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBsZm8gPSBuZXcgVG9uZS5MRk8oXCI0blwiLCA0MDAsIDQwMDApLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIExGTyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhMRk8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtaW5cIiwgXCJtYXhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMRk9cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB0aGF0IHRoZSBMRk8gb3V0cHV0cyB3aGVuIGl0J3Mgc3RvcHBlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RvcHBlZFZhbHVlID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgcHJpdmF0ZSBwbGFjZWhvbGRlciBmb3IgdGhlIHVuaXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl91bml0cyA9IFwibnVtYmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgaW5wdXQgdmFsdWUgaXMgY29udmVydGVkIHVzaW5nIHRoZSBbW3VuaXRzXV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY29udmVydCA9IHRydWU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcml2YXRlIG1ldGhvZHMgYm9ycm93ZWQgZnJvbSBQYXJhbVxuICAgICAgICAgKi9cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9mcm9tVHlwZSA9IFBhcmFtLnByb3RvdHlwZS5fZnJvbVR5cGU7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fdG9UeXBlID0gUGFyYW0ucHJvdG90eXBlLl90b1R5cGU7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5faXMgPSBQYXJhbS5wcm90b3R5cGUuX2lzO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2NsYW1wVmFsdWUgPSBQYXJhbS5wcm90b3R5cGUuX2NsYW1wVmFsdWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMRk8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtaW5cIiwgXCJtYXhcIl0pO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IE9zY2lsbGF0b3Iob3B0aW9ucyk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUdhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmFtcGxpdHVkZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFtcGxpdHVkZSA9IHRoaXMuX2FtcGxpdHVkZUdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbCA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiYXVkaW9SYW5nZVwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl96ZXJvcyA9IG5ldyBaZXJvKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hMmcgPSBuZXcgQXVkaW9Ub0dhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3NjYWxlciA9IHRoaXMub3V0cHV0ID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heDogb3B0aW9ucy5tYXgsXG4gICAgICAgICAgICBtaW46IG9wdGlvbnMubWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51bml0cyA9IG9wdGlvbnMudW5pdHM7XG4gICAgICAgIHRoaXMubWluID0gb3B0aW9ucy5taW47XG4gICAgICAgIHRoaXMubWF4ID0gb3B0aW9ucy5tYXg7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jaGFpbih0aGlzLl9hbXBsaXR1ZGVHYWluLCB0aGlzLl9hMmcsIHRoaXMuX3NjYWxlcik7XG4gICAgICAgIHRoaXMuX3plcm9zLmNvbm5lY3QodGhpcy5fYTJnKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5jb25uZWN0KHRoaXMuX2EyZyk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImFtcGxpdHVkZVwiLCBcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMucGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYW1wbGl0dWRlOiAxLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBcIjRuXCIsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIExGTy5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0aGUgTEZPIHdpbGwgc3RhcnRcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIExGTy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdGhlIExGTyB3aWxsIHN0b3BcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnNldFZhbHVlQXRUaW1lKHRoaXMuX3N0b3BwZWRWYWx1ZSwgdGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIHN0YXJ0L3N0b3AvcGF1c2UgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAqIGFuZCB0aGUgZnJlcXVlbmN5IHRvIHRoZSBicG0gb2YgdGhlIHRyYW5zcG9ydFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbGZvID0gbmV3IFRvbmUuTEZPKFwiOG5cIik7XG4gICAgICogbGZvLnN5bmMoKS5zdGFydCgwKTtcbiAgICAgKiAvLyB0aGUgcmF0ZSBvZiB0aGUgTEZPIHdpbGwgYWx3YXlzIGJlIGFuIGVpZ2h0aCBub3RlLCBldmVuIGFzIHRoZSB0ZW1wbyBjaGFuZ2VzXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zeW5jKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogdW5zeW5jIHRoZSBMRk8gZnJvbSB0cmFuc3BvcnQgY29udHJvbFxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci51bnN5bmNGcmVxdWVuY3koKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFmdGVyIHRoZSBvc2NpbGxhdG9yIHdhdmVmb3JtIGlzIHVwZGF0ZWQsIHJlc2V0IHRoZSBgX3N0b3BwZWRTaWduYWxgIHZhbHVlIHRvIG1hdGNoIHRoZSB1cGRhdGVkIHdhdmVmb3JtXG4gICAgICovXG4gICAgX3NldFN0b3BwZWRWYWx1ZSgpIHtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFZhbHVlID0gdGhpcy5fb3NjaWxsYXRvci5nZXRJbml0aWFsVmFsdWUoKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC52YWx1ZSA9IHRoaXMuX3N0b3BwZWRWYWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gb3V0cHV0IG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh0aGlzLl9zY2FsZXIubWluKTtcbiAgICB9XG4gICAgc2V0IG1pbihtaW4pIHtcbiAgICAgICAgbWluID0gdGhpcy5fZnJvbVR5cGUobWluKTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLm1pbiA9IG1pbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gb3V0cHV0IG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh0aGlzLl9zY2FsZXIubWF4KTtcbiAgICB9XG4gICAgc2V0IG1heChtYXgpIHtcbiAgICAgICAgbWF4ID0gdGhpcy5fZnJvbVR5cGUobWF4KTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLm1heCA9IG1heDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3I6IFNlZSBbW09zY2lsbGF0b3IudHlwZV1dXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fc2V0U3RvcHBlZFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvc2NpbGxhdG9yJ3MgcGFydGlhbHMgYXJyYXk6IFNlZSBbW09zY2lsbGF0b3IucGFydGlhbHNdXVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3NldFN0b3BwZWRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGhhc2Ugb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9zZXRTdG9wcGVkVmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG91dHB1dCB1bml0cyBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCB1bml0cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VuaXRzO1xuICAgIH1cbiAgICBzZXQgdW5pdHModmFsKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNaW4gPSB0aGlzLm1pbjtcbiAgICAgICAgY29uc3QgY3VycmVudE1heCA9IHRoaXMubWF4O1xuICAgICAgICAvLyBjb252ZXJ0IHRoZSBtaW4gYW5kIHRoZSBtYXhcbiAgICAgICAgdGhpcy5fdW5pdHMgPSB2YWw7XG4gICAgICAgIHRoaXMubWluID0gY3VycmVudE1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBjdXJyZW50TWF4O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG5vZGUgdGhlIGRlc3RpbmF0aW9uIHRvIGNvbm5lY3QgdG9cbiAgICAgKiBAcGFyYW0gb3V0cHV0TnVtIHRoZSBvcHRpb25hbCBvdXRwdXQgbnVtYmVyXG4gICAgICogQHBhcmFtIGlucHV0TnVtIHRoZSBpbnB1dCBudW1iZXJcbiAgICAgKi9cbiAgICBjb25uZWN0KG5vZGUsIG91dHB1dE51bSwgaW5wdXROdW0pIHtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBQYXJhbSB8fCBub2RlIGluc3RhbmNlb2YgU2lnbmFsKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnZlcnQgPSBub2RlLmNvbnZlcnQ7XG4gICAgICAgICAgICB0aGlzLnVuaXRzID0gbm9kZS51bml0cztcbiAgICAgICAgfVxuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIG5vZGUsIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3plcm9zLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYTJnLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYW1wbGl0dWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TEZPLmpzLm1hcCIsImltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIG51bWJlciBpcyBpbiB0aGUgZ2l2ZW4gcmFuZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5nZShtaW4sIG1heCA9IEluZmluaXR5KSB7XG4gICAgY29uc3QgdmFsdWVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2UobmV3VmFsdWUsIG1pbiwgbWF4KTtcbiAgICAgICAgICAgICAgICB2YWx1ZU1hcC5zZXQodGhpcywgbmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuLyoqXG4gKiBDb252ZXJ0IHRoZSB0aW1lIHRvIHNlY29uZHMgYW5kIGFzc2VydCB0aGF0IHRoZSB0aW1lIGlzIGluIGJldHdlZW4gdGhlIHR3b1xuICogdmFsdWVzIHdoZW4gYmVpbmcgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGltZVJhbmdlKG1pbiwgbWF4ID0gSW5maW5pdHkpIHtcbiAgICBjb25zdCB2YWx1ZU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZU1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyhuZXdWYWx1ZSksIG1pbiwgbWF4KTtcbiAgICAgICAgICAgICAgICB2YWx1ZU1hcC5zZXQodGhpcywgbmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVjb3JhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciwgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc1VuZGVmIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQnVmZmVyU291cmNlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIFBsYXllciBpcyBhbiBhdWRpbyBmaWxlIHBsYXllciB3aXRoIHN0YXJ0LCBsb29wLCBhbmQgc3RvcCBmdW5jdGlvbnMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvZ29uZ18xLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBwbGF5IGFzIHNvb24gYXMgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUGxheWVyIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGxheWVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGFjdGl2ZSBidWZmZXIgc291cmNlIG5vZGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0gbmV3IFNldCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcih7XG4gICAgICAgICAgICBvbmxvYWQ6IHRoaXMuX29ubG9hZC5iaW5kKHRoaXMsIG9wdGlvbnMub25sb2FkKSxcbiAgICAgICAgICAgIG9uZXJyb3I6IG9wdGlvbnMub25lcnJvcixcbiAgICAgICAgICAgIHJldmVyc2U6IG9wdGlvbnMucmV2ZXJzZSxcbiAgICAgICAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF1dG9zdGFydCA9IG9wdGlvbnMuYXV0b3N0YXJ0O1xuICAgICAgICB0aGlzLl9sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXV0b3N0YXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIGZhZGVJbjogMCxcbiAgICAgICAgICAgIGZhZGVPdXQ6IDAsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb2FkIHRoZSBhdWRpbyBmaWxlIGFzIGFuIGF1ZGlvIGJ1ZmZlci5cbiAgICAgKiBEZWNvZGVzIHRoZSBhdWRpbyBhc3luY2hyb25vdXNseSBhbmQgaW52b2tlc1xuICAgICAqIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG4gICAgICogTm90ZTogdGhpcyBkb2VzIG5vdCBuZWVkIHRvIGJlIGNhbGxlZCBpZiBhIHVybFxuICAgICAqIHdhcyBwYXNzZWQgaW4gdG8gdGhlIGNvbnN0cnVjdG9yLiBPbmx5IHVzZSB0aGlzXG4gICAgICogaWYgeW91IHdhbnQgdG8gbWFudWFsbHkgbG9hZCBhIG5ldyB1cmwuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBidWZmZXIgdG8gbG9hZC4gRmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZSBicm93c2VyLlxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICB5aWVsZCB0aGlzLl9idWZmZXIubG9hZCh1cmwpO1xuICAgICAgICAgICAgdGhpcy5fb25sb2FkKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGNhbGxiYWNrIHdoZW4gdGhlIGJ1ZmZlciBpcyBsb2FkZWQuXG4gICAgICovXG4gICAgX29ubG9hZChjYWxsYmFjayA9IG5vT3ApIHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgaWYgKHRoaXMuYXV0b3N0YXJ0KSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgY2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGRvbmUgcGxheWluZy5cbiAgICAgKi9cbiAgICBfb25Tb3VyY2VFbmQoc291cmNlKSB7XG4gICAgICAgIC8vIGludm9rZSB0aGUgb25zdG9wIGZ1bmN0aW9uXG4gICAgICAgIHRoaXMub25zdG9wKHRoaXMpO1xuICAgICAgICAvLyBkZWxldGUgdGhlIHNvdXJjZSBmcm9tIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmRlbGV0ZShzb3VyY2UpO1xuICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcy5zaXplID09PSAwICYmICF0aGlzLl9zeW5jZWQgJiZcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSAnaW1wbGljaXRFbmQnIGV2ZW50IGFuZCByZXBsYWNlIHdpdGggYW4gZXhwbGljaXQgZW5kXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGhpcy5ub3coKSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgdGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUGxheSB0aGUgYnVmZmVyIGF0IHRoZSBnaXZlbiBzdGFydFRpbWUuIE9wdGlvbmFsbHkgYWRkIGFuIG9mZnNldFxuICAgICAqIGFuZC9vciBkdXJhdGlvbiB3aGljaCB3aWxsIHBsYXkgdGhlIGJ1ZmZlciBmcm9tIGEgcG9zaXRpb25cbiAgICAgKiB3aXRoaW4gdGhlIGJ1ZmZlciBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLCBpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBzdXBlci5zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydChzdGFydFRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgLy8gaWYgaXQncyBhIGxvb3AgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIHRoZSBsb29wU3RhcnQgcG9pbnRcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IG9mZnNldCBpcyAwXG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29tcHV0ZSB0aGUgdmFsdWVzIGluIHNlY29uZHNcbiAgICAgICAgY29uc3QgY29tcHV0ZWRPZmZzZXQgPSB0aGlzLnRvU2Vjb25kcyhvZmZzZXQpO1xuICAgICAgICAvLyBjb21wdXRlIHRoZSBkdXJhdGlvbiB3aGljaCBpcyBlaXRoZXIgdGhlIHBhc3NlZCBpbiBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLmR1cmF0aW9uIC0gb2Zmc2V0XG4gICAgICAgIGNvbnN0IG9yaWdEdXJhdGlvbiA9IGR1cmF0aW9uO1xuICAgICAgICBkdXJhdGlvbiA9IGRlZmF1bHRBcmcoZHVyYXRpb24sIE1hdGgubWF4KHRoaXMuX2J1ZmZlci5kdXJhdGlvbiAtIGNvbXB1dGVkT2Zmc2V0LCAwKSk7XG4gICAgICAgIGxldCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAvLyBzY2FsZSBpdCBieSB0aGUgcGxheWJhY2sgcmF0ZVxuICAgICAgICBjb21wdXRlZER1cmF0aW9uID0gY29tcHV0ZWREdXJhdGlvbiAvIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICAgICAgLy8gZ2V0IHRoZSBzdGFydCB0aW1lXG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIHNvdXJjZVxuICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICB1cmw6IHRoaXMuX2J1ZmZlcixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZhZGVJbjogdGhpcy5mYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLmZhZGVPdXQsXG4gICAgICAgICAgICBsb29wOiB0aGlzLl9sb29wLFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5fbG9vcEVuZCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogdGhpcy5fbG9vcFN0YXJ0LFxuICAgICAgICAgICAgb25lbmRlZDogdGhpcy5fb25Tb3VyY2VFbmQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogdGhpcy5fcGxheWJhY2tSYXRlLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgLy8gc2V0IHRoZSBsb29waW5nIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKCF0aGlzLl9sb29wICYmICF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIC8vIGNhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0YXJ0VGltZSArIGNvbXB1dGVkRHVyYXRpb24pO1xuICAgICAgICAgICAgLy8gaWYgaXQncyBub3QgbG9vcGluZywgc2V0IHRoZSBzdGF0ZSBjaGFuZ2UgYXQgdGhlIGVuZCBvZiB0aGUgc2FtcGxlXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgc3RhcnRUaW1lICsgY29tcHV0ZWREdXJhdGlvbiwge1xuICAgICAgICAgICAgICAgIGltcGxpY2l0RW5kOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhcnJheSBvZiBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmFkZChzb3VyY2UpO1xuICAgICAgICAvLyBzdGFydCBpdFxuICAgICAgICBpZiAodGhpcy5fbG9vcCAmJiBpc1VuZGVmKG9yaWdEdXJhdGlvbikpIHtcbiAgICAgICAgICAgIHNvdXJjZS5zdGFydChzdGFydFRpbWUsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHN1YnRyYWN0IHRoZSBmYWRlIG91dCB0aW1lXG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQoc3RhcnRUaW1lLCBjb21wdXRlZE9mZnNldCwgY29tcHV0ZWREdXJhdGlvbiAtIHRoaXMudG9TZWNvbmRzKHRoaXMuZmFkZU91dCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgcGxheWJhY2suXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2Uuc3RvcChjb21wdXRlZFRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbmQgdGhlbiByZXN0YXJ0IHRoZSBwbGF5ZXIgZnJvbSB0aGUgYmVnaW5uaW5nIChvciBvZmZzZXQpXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLFxuICAgICAqIFx0XHRcdFx0XHRpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHN1cGVyLnJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWVrIHRvIGEgc3BlY2lmaWMgdGltZSBpbiB0aGUgcGxheWVyJ3MgYnVmZmVyLiBJZiB0aGVcbiAgICAgKiBzb3VyY2UgaXMgbm8gbG9uZ2VyIHBsYXlpbmcgYXQgdGhhdCB0aW1lLCBpdCB3aWxsIHN0b3AuXG4gICAgICogQHBhcmFtIG9mZnNldCBUaGUgdGltZSB0byBzZWVrIHRvLlxuICAgICAqIEBwYXJhbSB3aGVuIFRoZSB0aW1lIGZvciB0aGUgc2VlayBldmVudCB0byBvY2N1ci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2d1cmdsaW5nX3RoZXJlbWluXzEubXAzXCIsICgpID0+IHtcbiAgICAgKiBcdHBsYXllci5zdGFydCgpO1xuICAgICAqIFx0Ly8gc2VlayB0byB0aGUgb2Zmc2V0IGluIDEgc2Vjb25kIGZyb20gbm93XG4gICAgICogXHRwbGF5ZXIuc2VlaygwLjQsIFwiKzFcIik7XG4gICAgICogfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqL1xuICAgIHNlZWsob2Zmc2V0LCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkT2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgICAgIC8vIGlmIGl0J3MgY3VycmVudGx5IHBsYXlpbmcsIHN0b3AgaXRcbiAgICAgICAgICAgIHRoaXMuX3N0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIC8vIHJlc3RhcnQgaXQgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0KGNvbXB1dGVkVGltZSwgY29tcHV0ZWRPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIGVuZC4gV2lsbCBvbmx5IGxvb3AgaWYgbG9vcCBpcyBzZXQgdG8gdHJ1ZS5cbiAgICAgKiBAcGFyYW0gbG9vcFN0YXJ0IFRoZSBsb29wIHN0YXJ0IHRpbWVcbiAgICAgKiBAcGFyYW0gbG9vcEVuZCBUaGUgbG9vcCBlbmQgdGltZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvbWFsZXZvaWNlc19hYTJfRjMubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBsb29wIGJldHdlZW4gdGhlIGdpdmVuIHBvaW50c1xuICAgICAqIHBsYXllci5zZXRMb29wUG9pbnRzKDAuMiwgMC4zKTtcbiAgICAgKiBwbGF5ZXIubG9vcCA9IHRydWU7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgc2V0TG9vcFBvaW50cyhsb29wU3RhcnQsIGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgc3RhcnQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGxvb3BTdGFydCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKGxvb3BTdGFydCksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBnZXQgdGhlIGN1cnJlbnQgc291cmNlXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLmxvb3BTdGFydCA9IGxvb3BTdGFydDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBlbmQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKGxvb3BFbmQpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2V0IHRoZSBjdXJyZW50IHNvdXJjZVxuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5sb29wRW5kID0gbG9vcEVuZDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgYmVsb25naW5nIHRvIHRoZSBwbGF5ZXIuXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgc2V0IGJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnNldChidWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9icmVha2JlYXQubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBwbGF5ZXIubG9vcCA9IHRydWU7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIC8vIGlmIG5vIGNoYW5nZSwgZG8gbm90aGluZ1xuICAgICAgICBpZiAodGhpcy5fbG9vcCA9PT0gbG9vcCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuICAgICAgICAvLyBzZXQgdGhlIGxvb3Agb2YgYWxsIG9mIHRoZSBzb3VyY2VzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLmxvb3AgPSBsb29wO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGxvb3ApIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbmV4dCBzdG9wRXZlbnRcbiAgICAgICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0b3BwZWRcIiwgdGhpcy5ub3coKSk7XG4gICAgICAgICAgICBpZiAoc3RvcEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0b3BFdmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBOb3JtYWwgc3BlZWQgaXMgMS4gVGhlIHBpdGNoIHdpbGwgY2hhbmdlIHdpdGggdGhlIHBsYXliYWNrIHJhdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9mZW1hbGV2b2ljZXNfYWEyX0E1Lm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gcGxheSBhdCAxLzQgc3BlZWRcbiAgICAgKiBwbGF5ZXIucGxheWJhY2tSYXRlID0gMC4yNTtcbiAgICAgKiAvLyBwbGF5IGFzIHNvb24gYXMgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBzdG9wIGV2ZW50IHNpbmNlIGl0J3MgYXQgYSBkaWZmZXJlbnQgdGltZSBub3dcbiAgICAgICAgY29uc3Qgc3RvcEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0TmV4dFN0YXRlKFwic3RvcHBlZFwiLCBub3cpO1xuICAgICAgICBpZiAoc3RvcEV2ZW50ICYmIHN0b3BFdmVudC5pbXBsaWNpdEVuZCkge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0b3BFdmVudC50aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLmNhbmNlbFN0b3AoKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IGFsbCB0aGUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5wbGF5YmFja1JhdGUuc2V0VmFsdWVBdFRpbWUocmF0ZSwgbm93KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgc2hvdWxkIGJlIHJldmVyc2VkXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9jaGltZV8xLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogcGxheWVyLnJldmVyc2UgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCByZXZlcnNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLnJldmVyc2U7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICB0aGlzLl9idWZmZXIucmV2ZXJzZSA9IHJldjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmxvYWRlZDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICAvLyBkaXNjb25uZWN0IGFsbCBvZiB0aGUgcGxheWVyc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgUGxheWVyLnByb3RvdHlwZSwgXCJmYWRlSW5cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgUGxheWVyLnByb3RvdHlwZSwgXCJmYWRlT3V0XCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QbGF5ZXIuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVycyB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBQbGF5ZXIgfSBmcm9tIFwiLi9QbGF5ZXJcIjtcbi8qKlxuICogUGxheWVycyBjb21iaW5lcyBtdWx0aXBsZSBbW1BsYXllcl1dIG9iamVjdHMuXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBQbGF5ZXJzIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllcnMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCJdLCBcInVybHNcIikpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsYXllcnNcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBsYXllcnMgaGFzIG5vIGlucHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjb250YWluZXIgb2YgYWxsIG9mIHRoZSBwbGF5ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wbGF5ZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVycy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgdm9sdW1lIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IG5ldyBUb25lQXVkaW9CdWZmZXJzKHtcbiAgICAgICAgICAgIHVybHM6IG9wdGlvbnMudXJscyxcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmJhc2VVcmwsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3JcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG11dGUgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlSW4gdGltZSBvZiB0aGUgZW52ZWxvcGUgYXBwbGllZCB0byB0aGUgc291cmNlLlxuICAgICAqL1xuICAgIGdldCBmYWRlSW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlSW47XG4gICAgfVxuICAgIHNldCBmYWRlSW4oZmFkZUluKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IGZhZGVJbjtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiB7XG4gICAgICAgICAgICBwbGF5ZXIuZmFkZUluID0gZmFkZUluO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgZWFjaCBvZiB0aGUgc291cmNlcy5cbiAgICAgKi9cbiAgICBnZXQgZmFkZU91dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVPdXQ7XG4gICAgfVxuICAgIHNldCBmYWRlT3V0KGZhZGVPdXQpIHtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IGZhZGVPdXQ7XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4ge1xuICAgICAgICAgICAgcGxheWVyLmZhZGVPdXQgPSBmYWRlT3V0O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXRlIG9mIHRoZSBwbGF5ZXJzIG9iamVjdC4gUmV0dXJucyBcInN0YXJ0ZWRcIiBpZiBhbnkgb2YgdGhlIHBsYXllcnMgYXJlIHBsYXlpbmcuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICBjb25zdCBwbGF5aW5nID0gQXJyYXkuZnJvbSh0aGlzLl9wbGF5ZXJzKS5zb21lKChbXywgcGxheWVyXSkgPT4gcGxheWVyLnN0YXRlID09PSBcInN0YXJ0ZWRcIik7XG4gICAgICAgIHJldHVybiBwbGF5aW5nID8gXCJzdGFydGVkXCIgOiBcInN0b3BwZWRcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJ1ZSBpZiB0aGUgYnVmZmVycyBvYmplY3QgaGFzIGEgYnVmZmVyIGJ5IHRoYXQgbmFtZS5cbiAgICAgKiBAcGFyYW0gbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmhhcyhuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgcGxheWVyIGJ5IG5hbWUuXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUgcGxheWVycyBuYW1lIGFzIGRlZmluZWQgaW4gdGhlIGNvbnN0cnVjdG9yIG9iamVjdCBvciBgYWRkYCBtZXRob2QuXG4gICAgICovXG4gICAgcGxheWVyKG5hbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuaGFzKG5hbWUpLCBgTm8gUGxheWVyIHdpdGggdGhlIG5hbWUgJHtuYW1lfSBleGlzdHMgb24gdGhpcyBvYmplY3RgKTtcbiAgICAgICAgaWYgKCF0aGlzLl9wbGF5ZXJzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgY29uc3QgcGxheWVyID0gbmV3IFBsYXllcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGZhZGVJbjogdGhpcy5fZmFkZUluLFxuICAgICAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuX2ZhZGVPdXQsXG4gICAgICAgICAgICAgICAgdXJsOiB0aGlzLl9idWZmZXJzLmdldChuYW1lKSxcbiAgICAgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fcGxheWVycy5zZXQobmFtZSwgcGxheWVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWVycy5nZXQobmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGFsbCB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmxvYWRlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgcGxheWVyIGJ5IG5hbWUgYW5kIHVybCB0byB0aGUgUGxheWVyc1xuICAgICAqIEBwYXJhbSAgbmFtZSBBIHVuaXF1ZSBuYW1lIHRvIGdpdmUgdGhlIHBsYXllclxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZXIgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGFkZChuYW1lLCB1cmwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5fYnVmZmVycy5oYXMobmFtZSksIFwiQSBidWZmZXIgd2l0aCB0aGF0IG5hbWUgYWxyZWFkeSBleGlzdHMgb24gdGhpcyBvYmplY3RcIik7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG5hbWUsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbGwgb2YgdGhlIHBsYXllcnMgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0byBzdG9wIGFsbCBvZiB0aGUgcGxheWVycy5cbiAgICAgKi9cbiAgICBzdG9wQWxsKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiBwbGF5ZXIuc3RvcCh0aW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiBwbGF5ZXIuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBsYXllcnMuanMubWFwIiwiaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBDbG9jayB9IGZyb20gXCIuLi8uLi9jb3JlL2Nsb2NrL0Nsb2NrXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vVG9uZUJ1ZmZlclNvdXJjZVwiO1xuaW1wb3J0IHsgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEdyYWluUGxheWVyIGltcGxlbWVudHMgW2dyYW51bGFyIHN5bnRoZXNpc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvR3JhbnVsYXJfc3ludGhlc2lzKS5cbiAqIEdyYW51bGFyIFN5bnRoZXNpcyBlbmFibGVzIHlvdSB0byBhZGp1c3QgcGl0Y2ggYW5kIHBsYXliYWNrIHJhdGUgaW5kZXBlbmRlbnRseS4gVGhlIGdyYWluU2l6ZSBpcyB0aGVcbiAqIGFtb3VudCBvZiB0aW1lIGVhY2ggc21hbGwgY2h1bmsgb2YgYXVkaW8gaXMgcGxheWVkIGZvciBhbmQgdGhlIG92ZXJsYXAgaXMgdGhlXG4gKiBhbW91bnQgb2YgY3Jvc3NmYWRpbmcgdHJhbnNpdGlvbiB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBncmFpbnMuXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBHcmFpblBsYXllciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyYWluUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR3JhaW5QbGF5ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEludGVybmFsIGxvb3BTdGFydCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEludGVybmFsIGxvb3BTdGFydCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGN1cnJlbnRseSBwbGF5aW5nIEJ1ZmZlclNvdXJjZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyYWluUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKHtcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgICAgICByZXZlcnNlOiBvcHRpb25zLnJldmVyc2UsXG4gICAgICAgICAgICB1cmw6IG9wdGlvbnMudXJsLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xvY2sgPSBuZXcgQ2xvY2soe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSAvIG9wdGlvbnMuZ3JhaW5TaXplXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5fZ3JhaW5TaXplID0gb3B0aW9ucy5ncmFpblNpemU7XG4gICAgICAgIHRoaXMuX292ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gb3B0aW9ucy5kZXR1bmU7XG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIHRoaXMub3ZlcmxhcCA9IG9wdGlvbnMub3ZlcmxhcDtcbiAgICAgICAgdGhpcy5sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLmdyYWluU2l6ZSA9IG9wdGlvbnMuZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9IG9wdGlvbnMucmV2ZXJzZTtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJzdG9wXCIsIHRoaXMuX29uc3RvcC5iaW5kKHRoaXMpKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIG92ZXJsYXA6IDAuMSxcbiAgICAgICAgICAgIGdyYWluU2l6ZTogMC4yLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgb2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBncmFpblNpemUgPSAxIC8gdGhpcy5fY2xvY2suZnJlcXVlbmN5LmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLl9jbG9jay5zdGFydCh0aW1lLCBvZmZzZXQgLyBncmFpblNpemUpO1xuICAgICAgICBpZiAoZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHMoZHVyYXRpb24pKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIGFuZCB0aGVuIHJlc3RhcnQgdGhlIHBsYXllciBmcm9tIHRoZSBiZWdpbm5pbmcgKG9yIG9mZnNldClcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcGxheWVyIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc2FtcGxlIHRvIHN0YXJ0IGF0LlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb24gaXMgZ2l2ZW4sXG4gICAgICogXHRcdFx0XHRcdGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcbiAgICAgKi9cbiAgICByZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgc3VwZXIucmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0b3AgbWV0aG9kXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9jbG9jay5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIHdoZW4gdGhlIGNsb2NrIGlzIHN0b3BwZWRcbiAgICAgKi9cbiAgICBfb25zdG9wKHRpbWUpIHtcbiAgICAgICAgLy8gc3RvcCB0aGUgcGxheWVyc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4ge1xuICAgICAgICAgICAgc291cmNlLmZhZGVPdXQgPSAwO1xuICAgICAgICAgICAgc291cmNlLnN0b3AodGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlZCBvbiBlYWNoIGNsb2NrIHRpY2suIHNjaGVkdWxlZCBhIG5ldyBncmFpbiBhdCB0aGlzIHRpbWUuXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICAvLyBjaGVjayBpZiBpdCBzaG91bGQgc3RvcCBsb29waW5nXG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRpY2tzICogdGhpcy5fZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLmxvZyhcIm9mZnNldFwiLCBvZmZzZXQpO1xuICAgICAgICBpZiAoIXRoaXMubG9vcCAmJiBvZmZzZXQgPiB0aGlzLmJ1ZmZlci5kdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUsIHRoZSBmYWRlIGluIHNob3VsZCBiZSAwXG4gICAgICAgIGNvbnN0IGZhZGVJbiA9IG9mZnNldCA8IHRoaXMuX292ZXJsYXAgPyAwIDogdGhpcy5fb3ZlcmxhcDtcbiAgICAgICAgLy8gY3JlYXRlIGEgYnVmZmVyIHNvdXJjZVxuICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1cmw6IHRoaXMuYnVmZmVyLFxuICAgICAgICAgICAgZmFkZUluOiBmYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLl9vdmVybGFwLFxuICAgICAgICAgICAgbG9vcDogdGhpcy5sb29wLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiB0aGlzLl9sb29wU3RhcnQsXG4gICAgICAgICAgICBsb29wRW5kOiB0aGlzLl9sb29wRW5kLFxuICAgICAgICAgICAgLy8gY29tcHV0ZSB0aGUgcGxheWJhY2tSYXRlIGJhc2VkIG9uIHRoZSBkZXR1bmVcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKHRoaXMuZGV0dW5lIC8gMTAwKVxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgc291cmNlLnN0YXJ0KHRpbWUsIHRoaXMuX2dyYWluU2l6ZSAqIHRpY2tzKTtcbiAgICAgICAgc291cmNlLnN0b3AodGltZSArIHRoaXMuX2dyYWluU2l6ZSAvIHRoaXMucGxheWJhY2tSYXRlKTtcbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnB1c2goc291cmNlKTtcbiAgICAgICAgLy8gcmVtb3ZlIGl0IHdoZW4gaXQncyBkb25lXG4gICAgICAgIHNvdXJjZS5vbmVuZGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9hY3RpdmVTb3VyY2VzLmluZGV4T2Yoc291cmNlKTtcbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBzYW1wbGVcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgYXNzZXJ0UmFuZ2UocmF0ZSwgMC4wMDEpO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICB0aGlzLmdyYWluU2l6ZSA9IHRoaXMuX2dyYWluU2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3Agc3RhcnQgdGltZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHModGltZSksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3AgZW5kIHRpbWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGlyZWN0aW9uIHRoZSBidWZmZXIgc2hvdWxkIHBsYXkgaW5cbiAgICAgKi9cbiAgICBnZXQgcmV2ZXJzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLnJldmVyc2U7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICB0aGlzLmJ1ZmZlci5yZXZlcnNlID0gcmV2O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2l6ZSBvZiBlYWNoIGNodW5rIG9mIGF1ZGlvIHRoYXQgdGhlXG4gICAgICogYnVmZmVyIGlzIGNob3BwZWQgaW50byBhbmQgcGxheWVkIGJhY2sgYXQuXG4gICAgICovXG4gICAgZ2V0IGdyYWluU2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dyYWluU2l6ZTtcbiAgICB9XG4gICAgc2V0IGdyYWluU2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2dyYWluU2l6ZSA9IHRoaXMudG9TZWNvbmRzKHNpemUpO1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kuc2V0VmFsdWVBdFRpbWUodGhpcy5fcGxheWJhY2tSYXRlIC8gdGhpcy5fZ3JhaW5TaXplLCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIG9mIHRoZSBjcm9zcy1mYWRlIGJldHdlZW4gc3VjY2Vzc2l2ZSBncmFpbnMuXG4gICAgICovXG4gICAgZ2V0IG92ZXJsYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vdmVybGFwO1xuICAgIH1cbiAgICBzZXQgb3ZlcmxhcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZShjb21wdXRlZFRpbWUsIDApO1xuICAgICAgICB0aGlzLl9vdmVybGFwID0gY29tcHV0ZWRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBhbGwgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5idWZmZXIubG9hZGVkO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4gc291cmNlLmRpc3Bvc2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdyYWluUGxheWVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL05vaXNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Vc2VyTWVkaWFcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9BTU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvRk1Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1B1bHNlT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9GYXRPc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1BXTU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL0xGT1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9QbGF5ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9QbGF5ZXJzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvR3JhaW5QbGF5ZXJcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIFJldHVybiB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgYW4gaW5jb21pbmcgc2lnbmFsLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYWJzID0gbmV3IFRvbmUuQWJzKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHRjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMSk7XG4gKiBcdHNpZ25hbC5yYW1wVG8oLTEsIDAuNSk7XG4gKiBcdHNpZ25hbC5jb25uZWN0KGFicyk7XG4gKiB9LCAwLjUsIDEpO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgQWJzIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFic1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5vZGUgd2hpY2ggY29udmVydHMgdGhlIGF1ZGlvIHJhbmdlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWJzID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogdmFsID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoTWF0aC5hYnModmFsKSA8IDAuMDAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQXVkaW9SYW5nZSBpbnB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fYWJzO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCByYW5nZSBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fYWJzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWJzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWJzLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIEdhaW5Ub0F1ZGlvIGNvbnZlcnRzIGFuIGlucHV0IGluIE5vcm1hbFJhbmdlIFswLDFdIHRvIEF1ZGlvUmFuZ2UgWy0xLDFdLlxuICogU2VlIFtbQXVkaW9Ub0dhaW5dXS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdhaW5Ub0F1ZGlvIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdhaW5Ub0F1ZGlvXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbm9kZSB3aGljaCBjb252ZXJ0cyB0aGUgYXVkaW8gcmFuZ2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ub3JtID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogeCA9PiBNYXRoLmFicyh4KSAqIDIgLSAxLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBOb3JtYWxSYW5nZSBpbnB1dCBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9ub3JtO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEF1ZGlvUmFuZ2Ugb3V0cHV0IFstMSwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fbm9ybTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vcm0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HYWluVG9BdWRpby5qcy5tYXAiLCJpbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIE5lZ2F0ZSB0aGUgaW5jb21pbmcgc2lnbmFsLiBpLmUuIGFuIGlucHV0IHNpZ25hbCBvZiAxMCB3aWxsIG91dHB1dCAtMTBcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbmVnID0gbmV3IFRvbmUuTmVnYXRlKCk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoLTIpLmNvbm5lY3QobmVnKTtcbiAqIC8vIG91dHB1dCBvZiBuZWcgaXMgcG9zaXRpdmUgMi5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIE5lZ2F0ZSBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOZWdhdGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG5lZ2F0aW9uIGlzIGRvbmUgYnkgbXVsdGlwbHlpbmcgYnkgLTFcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX211bHRpcGx5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAtMSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgYW5kIG91dHB1dCBhcmUgZXF1YWwgdG8gdGhlIG11bHRpcGx5IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9tdWx0aXBseTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9tdWx0aXBseTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKiBAcmV0dXJucyB7TmVnYXRlfSB0aGlzXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5lZ2F0ZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0U2VyaWVzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE5lZ2F0ZSB9IGZyb20gXCIuLi9zaWduYWwvTmVnYXRlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuLyoqXG4gKiBTdWJ0cmFjdCB0aGUgc2lnbmFsIGNvbm5lY3RlZCB0byB0aGUgaW5wdXQgaXMgc3VidHJhY3RlZCBmcm9tIHRoZSBzaWduYWwgY29ubmVjdGVkXG4gKiBUaGUgc3VidHJhaGVuZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gc3VidHJhY3QgYSBzY2FsYXIgZnJvbSBhIHNpZ25hbFxuICogY29uc3Qgc3ViID0gbmV3IFRvbmUuU3VidHJhY3QoMSk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoNCkuY29ubmVjdChzdWIpO1xuICogLy8gdGhlIG91dHB1dCBvZiBzdWIgaXMgMy5cbiAqIEBleGFtcGxlXG4gKiAvLyBzdWJ0cmFjdCB0d28gc2lnbmFsc1xuICogY29uc3Qgc3ViID0gbmV3IFRvbmUuU3VidHJhY3QoKTtcbiAqIGNvbnN0IHNpZ0EgPSBuZXcgVG9uZS5TaWduYWwoMTApO1xuICogY29uc3Qgc2lnQiA9IG5ldyBUb25lLlNpZ25hbCgyLjUpO1xuICogc2lnQS5jb25uZWN0KHN1Yik7XG4gKiBzaWdCLmNvbm5lY3Qoc3ViLnN1YnRyYWhlbmQpO1xuICogLy8gb3V0cHV0IG9mIHN1YiBpcyA3LjVcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnRyYWN0IGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTdWJ0cmFjdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3VidHJhY3RcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzdW1taW5nIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N1bSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5lZ2F0ZSB0aGUgaW5wdXQgb2YgdGhlIHNlY29uZCBpbnB1dCBiZWZvcmUgY29ubmVjdGluZyBpdCB0byB0aGUgc3VtbWluZyBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbmVnID0gbmV3IE5lZ2F0ZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB3aGljaCBpcyBzdWJ0cmFjdGVkIGZyb20gdGhlIG1haW4gc2lnbmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnN1YnRyYWhlbmQgPSB0aGlzLl9wYXJhbTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLl9jb25zdGFudFNvdXJjZSwgdGhpcy5fbmVnLCB0aGlzLl9zdW0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbmVnLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3VidHJhY3QuanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi9NdWx0aXBseVwiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBHcmVhdGVyVGhhblplcm8gb3V0cHV0cyAxIHdoZW4gdGhlIGlucHV0IGlzIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiB6ZXJvXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGd0MCA9IG5ldyBUb25lLkdyZWF0ZXJUaGFuWmVybygpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChndDApO1xuICogXHRzaWcuc2V0VmFsdWVBdFRpbWUoLTEsIDAuMDUpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuWmVybyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhblplcm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyZWF0ZXJUaGFuWmVyb1wiO1xuICAgICAgICB0aGlzLl90aHJlc2ggPSB0aGlzLm91dHB1dCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGxlbmd0aDogMTI3LFxuICAgICAgICAgICAgbWFwcGluZzogKHZhbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwgPD0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IHRoaXMuaW5wdXQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDEwMDAwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9zY2FsZS5jb25uZWN0KHRoaXMuX3RocmVzaCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aHJlc2guZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmVhdGVyVGhhblplcm8uanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTdWJ0cmFjdCB9IGZyb20gXCIuL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbmltcG9ydCB7IEdyZWF0ZXJUaGFuWmVybyB9IGZyb20gXCIuL0dyZWF0ZXJUaGFuWmVyb1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBPdXRwdXQgMSBpZiB0aGUgc2lnbmFsIGlzIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUsIG90aGVyd2lzZSBvdXRwdXRzIDAuXG4gKiBjYW4gY29tcGFyZSB0d28gc2lnbmFscyBvciBhIHNpZ25hbCBhbmQgYSBudW1iZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBndCA9IG5ldyBUb25lLkdyZWF0ZXJUaGFuKDIpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDQpLmNvbm5lY3QoZ3QpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyZWF0ZXJUaGFuXCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyZWF0ZXJUaGFuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9zdWJ0cmFjdCA9IHRoaXMuaW5wdXQgPSBuZXcgU3VidHJhY3Qoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2d0eiA9IHRoaXMub3V0cHV0ID0gbmV3IEdyZWF0ZXJUaGFuWmVybyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5jb21wYXJhdG9yID0gdGhpcy5fcGFyYW0gPSB0aGlzLl9zdWJ0cmFjdC5zdWJ0cmFoZW5kO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImNvbXBhcmF0b3JcIik7XG4gICAgICAgIC8vIGNvbm5lY3RcbiAgICAgICAgdGhpcy5fc3VidHJhY3QuY29ubmVjdCh0aGlzLl9ndHopO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ3R6LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VidHJhY3QuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNvbXBhcmF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmVhdGVyVGhhbi5qcy5tYXAiLCJpbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFBvdyBhcHBsaWVzIGFuIGV4cG9uZW50IHRvIHRoZSBpbmNvbWluZyBzaWduYWwuIFRoZSBpbmNvbWluZyBzaWduYWwgbXVzdCBiZSBBdWRpb1JhbmdlIFstMSwgMV1cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcG93ID0gbmV3IFRvbmUuUG93KDIpO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChwb3cpO1xuICogLy8gb3V0cHV0IG9mIHBvdyBpcyAwLjI1LlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgUG93IGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvdy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBvd1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUG93LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9leHBvbmVudFNjYWxlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHRoaXMuX2V4cEZ1bmMob3B0aW9ucy52YWx1ZSksXG4gICAgICAgICAgICBsZW5ndGg6IDgxOTIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9leHBvbmVudCA9IG9wdGlvbnMudmFsdWU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsT3BlcmF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiB0aGUgZnVuY3Rpb24gd2hpY2ggbWFwcyB0aGUgd2F2ZXNoYXBlclxuICAgICAqIEBwYXJhbSBleHBvbmVudCBleHBvbmVudCB2YWx1ZVxuICAgICAqL1xuICAgIF9leHBGdW5jKGV4cG9uZW50KSB7XG4gICAgICAgIHJldHVybiAodmFsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5wb3coTWF0aC5hYnModmFsKSwgZXhwb25lbnQpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgb2YgdGhlIGV4cG9uZW50LlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4cG9uZW50O1xuICAgIH1cbiAgICBzZXQgdmFsdWUoZXhwb25lbnQpIHtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQgPSBleHBvbmVudDtcbiAgICAgICAgdGhpcy5fZXhwb25lbnRTY2FsZXIuc2V0TWFwKHRoaXMuX2V4cEZ1bmModGhpcy5fZXhwb25lbnQpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9leHBvbmVudFNjYWxlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBvdy5qcy5tYXAiLCJpbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuL1NjYWxlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFBvdyB9IGZyb20gXCIuL1Bvd1wiO1xuLyoqXG4gKiBQZXJmb3JtcyBhbiBleHBvbmVudGlhbCBzY2FsaW5nIG9uIGFuIGlucHV0IHNpZ25hbC5cbiAqIFNjYWxlcyBhIE5vcm1hbFJhbmdlIHZhbHVlIFswLDFdIGV4cG9uZW50aWFsbHlcbiAqIHRvIHRoZSBvdXRwdXQgcmFuZ2Ugb2Ygb3V0cHV0TWluIHRvIG91dHB1dE1heC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzY2FsZUV4cCA9IG5ldyBUb25lLlNjYWxlRXhwKDAsIDEwMCwgMik7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHNjYWxlRXhwKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFNjYWxlRXhwIGV4dGVuZHMgU2NhbGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlRXhwLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCIsIFwiZXhwb25lbnRcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2NhbGVFeHBcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlRXhwLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCIsIFwiZXhwb25lbnRcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZXhwID0gbmV3IFBvdyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5leHBvbmVudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2V4cC5jb25uZWN0KHRoaXMuX211bHQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNjYWxlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGV4cG9uZW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zdGVhZCBvZiBpbnRlcnBvbGF0aW5nIGxpbmVhcmx5IGJldHdlZW4gdGhlIFtbbWluXV0gYW5kXG4gICAgICogW1ttYXhdXSB2YWx1ZXMsIHNldHRpbmcgdGhlIGV4cG9uZW50IHdpbGwgaW50ZXJwb2xhdGUgYmV0d2VlblxuICAgICAqIHRoZSB0d28gdmFsdWVzIHdpdGggYW4gZXhwb25lbnRpYWwgY3VydmUuXG4gICAgICovXG4gICAgZ2V0IGV4cG9uZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgZXhwb25lbnQoZXhwKSB7XG4gICAgICAgIHRoaXMuX2V4cC52YWx1ZSA9IGV4cDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9leHAuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TY2FsZUV4cC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBUb25lQ29uc3RhbnRTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQ29uc3RhbnRTb3VyY2VcIjtcbi8qKlxuICogQWRkcyB0aGUgYWJpbGl0eSB0byBzeW5jaHJvbml6ZSB0aGUgc2lnbmFsIHRvIHRoZSBbW1RyYW5zcG9ydF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTeW5jZWRTaWduYWwgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3luY2VkU2lnbmFsXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEb24ndCBvdmVycmlkZSB3aGVuIHNvbWV0aGluZyBpcyBjb25uZWN0ZWQgdG8gdGhlIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKTtcbiAgICAgICAgdGhpcy5fbGFzdFZhbCA9IG9wdGlvbnMudmFsdWU7XG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGhpcy5fb25UaWNrLmJpbmQodGhpcyksIFwiMWlcIik7XG4gICAgICAgIHRoaXMuX3N5bmNlZENhbGxiYWNrID0gdGhpcy5fYW5jaG9yVmFsdWUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0YXJ0XCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0b3BcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICAvLyBkaXNjb25uZWN0IHRoZSBjb25zdGFudCBzb3VyY2UgZnJvbSB0aGUgb3V0cHV0IGFuZCByZXBsYWNlIGl0IHdpdGggYW5vdGhlciBvbmVcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5zdG9wKDApO1xuICAgICAgICAvLyBjcmVhdGUgYSBuZXcgb25lXG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZUNvbnN0YW50U291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICB9KS5zdGFydCgwKTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCBldmVyeSB0aWNrLlxuICAgICAqL1xuICAgIF9vblRpY2sodGltZSkge1xuICAgICAgICBjb25zdCB2YWwgPSBzdXBlci5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICAvLyBhcHByb3hpbWF0ZSByYW1wIGN1cnZlcyB3aXRoIGxpbmVhciByYW1wc1xuICAgICAgICBpZiAodGhpcy5fbGFzdFZhbCAhPT0gdmFsKSB7XG4gICAgICAgICAgICB0aGlzLl9sYXN0VmFsID0gdmFsO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LnNldFZhbHVlQXRUaW1lKHZhbCwgdGltZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQW5jaG9yIHRoZSB2YWx1ZSBhdCB0aGUgc3RhcnQgYW5kIHN0b3Agb2YgdGhlIFRyYW5zcG9ydFxuICAgICAqL1xuICAgIF9hbmNob3JWYWx1ZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHN1cGVyLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgIHRoaXMuX2xhc3RWYWwgPSB2YWw7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldC5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQuc2V0VmFsdWVBdFRpbWUodmFsLCB0aW1lKTtcbiAgICB9XG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHJldHVybiBzdXBlci5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgIH1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMoc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgc3VwZXIuc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIGNvbXB1dGVkVGltZSwgZHVyYXRpb24sIHNjYWxpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuY2FuY2VsQW5kSG9sZEF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0UmFtcFBvaW50KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5zZXRSYW1wUG9pbnQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5leHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIodGhpcy5fc3luY2VkKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwicGF1c2VcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInN0b3BcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN5bmNlZFNpZ25hbC5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9BZGRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0Fic1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vQXVkaW9Ub0dhaW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL0dhaW5Ub0F1ZGlvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9HcmVhdGVyVGhhblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vR3JlYXRlclRoYW5aZXJvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NdWx0aXBseVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTmVnYXRlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Qb3dcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NpZ25hbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2NhbGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NjYWxlRXhwXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TdWJ0cmFjdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3luY2VkU2lnbmFsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9aZXJvXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIsIF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwsIFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHJhbmdlLCB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBFbnZlbG9wZSBpcyBhbiBbQURTUl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ludGhlc2l6ZXIjQURTUl9lbnZlbG9wZSlcbiAqIGVudmVsb3BlIGdlbmVyYXRvci4gRW52ZWxvcGUgb3V0cHV0cyBhIHNpZ25hbCB3aGljaFxuICogY2FuIGJlIGNvbm5lY3RlZCB0byBhbiBBdWRpb1BhcmFtIG9yIFRvbmUuU2lnbmFsLlxuICogYGBgXG4gKiAgICAgICAgICAgL1xcXG4gKiAgICAgICAgICAvICBcXFxuICogICAgICAgICAvICAgIFxcXG4gKiAgICAgICAgLyAgICAgIFxcXG4gKiAgICAgICAvICAgICAgICBcXF9fX19fX19fX19fXG4gKiAgICAgIC8gICAgICAgICAgICAgICAgICAgICBcXFxuICogICAgIC8gICAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiAgICAvICAgICAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiAgIC8gICAgICAgICAgICAgICAgICAgICAgICAgICBcXFxuICogYGBgXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAqIFx0XHRhdHRhY2s6IDAuMSxcbiAqIFx0XHRkZWNheTogMC4yLFxuICogXHRcdHN1c3RhaW46IDAuNSxcbiAqIFx0XHRyZWxlYXNlOiAwLjgsXG4gKiBcdH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0ZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuNSk7XG4gKiB9LCAxLjUsIDEpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRW52ZWxvcGUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRW52ZWxvcGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzaWduYWwgd2hpY2ggaXMgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2lnID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IHNpZ25hbCBvZiB0aGUgZW52ZWxvcGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc2lnO1xuICAgICAgICAvKipcbiAgICAgICAgICogRW52ZWxvcGUgaGFzIG5vIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKTtcbiAgICAgICAgdGhpcy5hdHRhY2sgPSBvcHRpb25zLmF0dGFjaztcbiAgICAgICAgdGhpcy5kZWNheSA9IG9wdGlvbnMuZGVjYXk7XG4gICAgICAgIHRoaXMuc3VzdGFpbiA9IG9wdGlvbnMuc3VzdGFpbjtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLmF0dGFja0N1cnZlID0gb3B0aW9ucy5hdHRhY2tDdXJ2ZTtcbiAgICAgICAgdGhpcy5yZWxlYXNlQ3VydmUgPSBvcHRpb25zLnJlbGVhc2VDdXJ2ZTtcbiAgICAgICAgdGhpcy5kZWNheUN1cnZlID0gb3B0aW9ucy5kZWNheUN1cnZlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwibGluZWFyXCIsXG4gICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgZGVjYXlDdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgICAgIHJlbGVhc2VDdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgc3VzdGFpbjogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZW52ZWxvcGUuIFVzZWZ1bCBmb3JcbiAgICAgKiBzeW5jaHJvbml6aW5nIHZpc3VhbCBvdXRwdXQgdG8gdGhlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VydmVcbiAgICAgKiBAcGFyYW0gIGN1cnZlXG4gICAgICogQHBhcmFtICBkaXJlY3Rpb24gIEluL091dFxuICAgICAqIEByZXR1cm4gVGhlIGN1cnZlIG5hbWVcbiAgICAgKi9cbiAgICBfZ2V0Q3VydmUoY3VydmUsIGRpcmVjdGlvbikge1xuICAgICAgICBpZiAoaXNTdHJpbmcoY3VydmUpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3VydmU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBjdXJ2ZXMgYXJyYXlcbiAgICAgICAgICAgIGxldCBjdXJ2ZU5hbWU7XG4gICAgICAgICAgICBmb3IgKGN1cnZlTmFtZSBpbiBFbnZlbG9wZUN1cnZlcykge1xuICAgICAgICAgICAgICAgIGlmIChFbnZlbG9wZUN1cnZlc1tjdXJ2ZU5hbWVdW2RpcmVjdGlvbl0gPT09IGN1cnZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJ2ZU5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gcmV0dXJuIHRoZSBjdXN0b20gY3VydmVcbiAgICAgICAgICAgIHJldHVybiBjdXJ2ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3NpZ24gYSB0aGUgY3VydmUgdG8gdGhlIGdpdmVuIG5hbWUgdXNpbmcgdGhlIGRpcmVjdGlvblxuICAgICAqIEBwYXJhbSAgbmFtZVxuICAgICAqIEBwYXJhbSAgZGlyZWN0aW9uIEluL091dFxuICAgICAqIEBwYXJhbSAgY3VydmVcbiAgICAgKi9cbiAgICBfc2V0Q3VydmUobmFtZSwgZGlyZWN0aW9uLCBjdXJ2ZSkge1xuICAgICAgICAvLyBjaGVjayBpZiBpdCdzIGEgdmFsaWQgdHlwZVxuICAgICAgICBpZiAoaXNTdHJpbmcoY3VydmUpICYmIFJlZmxlY3QuaGFzKEVudmVsb3BlQ3VydmVzLCBjdXJ2ZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnZlRGVmID0gRW52ZWxvcGVDdXJ2ZXNbY3VydmVdO1xuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGN1cnZlRGVmKSkge1xuICAgICAgICAgICAgICAgIGlmIChuYW1lICE9PSBcIl9kZWNheUN1cnZlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlRGVmW2RpcmVjdGlvbl07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlRGVmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQXJyYXkoY3VydmUpICYmIG5hbWUgIT09IFwiX2RlY2F5Q3VydmVcIikge1xuICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRW52ZWxvcGU6IGludmFsaWQgY3VydmU6IFwiICsgY3VydmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgYXR0YWNrLlxuICAgICAqIENhbiBiZSBhbnkgb2YgdGhlc2Ugc3RyaW5nczpcbiAgICAgKiAqIFwibGluZWFyXCJcbiAgICAgKiAqIFwiZXhwb25lbnRpYWxcIlxuICAgICAqICogXCJzaW5lXCJcbiAgICAgKiAqIFwiY29zaW5lXCJcbiAgICAgKiAqIFwiYm91bmNlXCJcbiAgICAgKiAqIFwicmlwcGxlXCJcbiAgICAgKiAqIFwic3RlcFwiXG4gICAgICpcbiAgICAgKiBDYW4gYWxzbyBiZSBhbiBhcnJheSB3aGljaCBkZXNjcmliZXMgdGhlIGN1cnZlLiBWYWx1ZXNcbiAgICAgKiBpbiB0aGUgYXJyYXkgYXJlIGV2ZW5seSBzdWJkaXZpZGVkIGFuZCBsaW5lYXJseVxuICAgICAqIGludGVycG9sYXRlZCBvdmVyIHRoZSBkdXJhdGlvbiBvZiB0aGUgYXR0YWNrLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gICAgICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSgwLjQpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBcdGVudi5hdHRhY2tDdXJ2ZSA9IFwibGluZWFyXCI7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCBhdHRhY2tDdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEN1cnZlKHRoaXMuX2F0dGFja0N1cnZlLCBcIkluXCIpO1xuICAgIH1cbiAgICBzZXQgYXR0YWNrQ3VydmUoY3VydmUpIHtcbiAgICAgICAgdGhpcy5fc2V0Q3VydmUoXCJfYXR0YWNrQ3VydmVcIiwgXCJJblwiLCBjdXJ2ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgcmVsZWFzZS4gU2VlIHRoZSBhdHRhY2sgY3VydmUgdHlwZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAgICAgKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAgICAgKiBcdFx0cmVsZWFzZTogMC44XG4gICAgICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIFx0Ly8gcmVsZWFzZSBjdXJ2ZSBjb3VsZCBhbHNvIGJlIGRlZmluZWQgYnkgYW4gYXJyYXlcbiAgICAgKiBcdGVudi5yZWxlYXNlQ3VydmUgPSBbMSwgMC4zLCAwLjQsIDAuMiwgMC43LCAwXTtcbiAgICAgKiBcdGVudi50cmlnZ2VyUmVsZWFzZSgwLjIpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCByZWxlYXNlQ3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDdXJ2ZSh0aGlzLl9yZWxlYXNlQ3VydmUsIFwiT3V0XCIpO1xuICAgIH1cbiAgICBzZXQgcmVsZWFzZUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIHRoaXMuX3NldEN1cnZlKFwiX3JlbGVhc2VDdXJ2ZVwiLCBcIk91dFwiLCBjdXJ2ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgZGVjYXkgZWl0aGVyIFwibGluZWFyXCIgb3IgXCJleHBvbmVudGlhbFwiXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAgICAgKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAgICAgKiBcdFx0c3VzdGFpbjogMC4xLFxuICAgICAqIFx0XHRkZWNheTogMC41XG4gICAgICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYuZGVjYXlDdXJ2ZSA9IFwibGluZWFyXCI7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCBkZWNheUN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjYXlDdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGRlY2F5Q3VydmUoY3VydmUpIHtcbiAgICAgICAgYXNzZXJ0KFtcImxpbmVhclwiLCBcImV4cG9uZW50aWFsXCJdLnNvbWUoYyA9PiBjID09PSBjdXJ2ZSksIGBJbnZhbGlkIGVudmVsb3BlIGN1cnZlOiAke2N1cnZlfWApO1xuICAgICAgICB0aGlzLl9kZWNheUN1cnZlID0gY3VydmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjay9kZWNheSBwb3J0aW9uIG9mIHRoZSBBRFNSIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIGVudmVsb3BlIHNjYWxlcyB0aGUgdmFsZXMuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlciBiZXR3ZWVuIDAtMVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoZW52KS5zdGFydCgpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIGF0dGFjayAwLjUgc2Vjb25kcyBmcm9tIG5vdyB3aXRoIGEgdmVsb2NpdHkgb2YgMC4yXG4gICAgICogZW52LnRyaWdnZXJBdHRhY2soXCIrMC41XCIsIDAuMik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyQXR0YWNrXCIsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKTtcbiAgICAgICAgbGV0IGF0dGFjayA9IG9yaWdpbmFsQXR0YWNrO1xuICAgICAgICBjb25zdCBkZWNheSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpO1xuICAgICAgICAvLyBjaGVjayBpZiBpdCdzIG5vdCBhIGNvbXBsZXRlIGF0dGFja1xuICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID4gMCkge1xuICAgICAgICAgICAgLy8gc3VidHJhY3QgdGhlIGN1cnJlbnQgdmFsdWUgZnJvbSB0aGUgYXR0YWNrIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGF0dGFja1JhdGUgPSAxIC8gYXR0YWNrO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nRGlzdGFuY2UgPSAxIC0gY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgLy8gdGhlIGF0dGFjayBpcyBub3cgdGhlIHJlbWFpbmluZyB0aW1lXG4gICAgICAgICAgICBhdHRhY2sgPSByZW1haW5pbmdEaXN0YW5jZSAvIGF0dGFja1JhdGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYXR0YWNrXG4gICAgICAgIGlmIChhdHRhY2sgPCB0aGlzLnNhbXBsZVRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgICAgICAvLyBjYXNlIHdoZXJlIHRoZSBhdHRhY2sgdGltZSBpcyAwIHNob3VsZCBzZXQgaW5zdGFudGx5XG4gICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVBdFRpbWUodmVsb2NpdHksIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2F0dGFja0N1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcubGluZWFyUmFtcFRvKHZlbG9jaXR5LCBhdHRhY2ssIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2F0dGFja0N1cnZlID09PSBcImV4cG9uZW50aWFsXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy50YXJnZXRSYW1wVG8odmVsb2NpdHksIGF0dGFjaywgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgIGxldCBjdXJ2ZSA9IHRoaXMuX2F0dGFja0N1cnZlO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGN1cnZlXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGN1cnZlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhlIHN0YXJ0aW5nIGluZGV4IGlzIGJldHdlZW4gdGhlIHR3byB2YWx1ZXNcbiAgICAgICAgICAgICAgICBpZiAoY3VydmVbaSAtIDFdIDw9IGN1cnJlbnRWYWx1ZSAmJiBjdXJyZW50VmFsdWUgPD0gY3VydmVbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgY3VydmUgPSB0aGlzLl9hdHRhY2tDdXJ2ZS5zbGljZShpKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGluZGV4IGlzIHRoZSBjdXJyZW50IHZhbHVlXG4gICAgICAgICAgICAgICAgICAgIGN1cnZlWzBdID0gY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVDdXJ2ZUF0VGltZShjdXJ2ZSwgdGltZSwgYXR0YWNrLCB2ZWxvY2l0eSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZGVjYXlcbiAgICAgICAgaWYgKGRlY2F5ICYmIHRoaXMuc3VzdGFpbiA8IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlY2F5VmFsdWUgPSB2ZWxvY2l0eSAqIHRoaXMuc3VzdGFpbjtcbiAgICAgICAgICAgIGNvbnN0IGRlY2F5U3RhcnQgPSB0aW1lICsgYXR0YWNrO1xuICAgICAgICAgICAgdGhpcy5sb2coXCJkZWNheVwiLCBkZWNheVN0YXJ0KTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kZWNheUN1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKGRlY2F5VmFsdWUsIGRlY2F5ICsgZGVjYXlTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKGRlY2F5VmFsdWUsIGRlY2F5U3RhcnQsIGRlY2F5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlcnMgdGhlIHJlbGVhc2Ugb2YgdGhlIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlIHNob3VsZCBzdGFydC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3Ioe1xuICAgICAqIFx0dHlwZTogXCJzYXd0b290aFwiXG4gICAgICogfSkuY29ubmVjdChlbnYpLnN0YXJ0KCk7XG4gICAgICogZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIGhhbGYgYSBzZWNvbmQgYWZ0ZXIgdGhlIGF0dGFja1xuICAgICAqIGVudi50cmlnZ2VyUmVsZWFzZShcIiswLjVcIik7XG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIHRpbWUpO1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCByZWxlYXNlID0gdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKTtcbiAgICAgICAgICAgIGlmIChyZWxlYXNlIDwgdGhpcy5zYW1wbGVUaW1lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fcmVsZWFzZUN1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUbygwLCByZWxlYXNlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3JlbGVhc2VDdXJ2ZSA9PT0gXCJleHBvbmVudGlhbFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLnRhcmdldFJhbXBUbygwLCByZWxlYXNlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzc2VydChpc0FycmF5KHRoaXMuX3JlbGVhc2VDdXJ2ZSksIFwicmVsZWFzZUN1cnZlIG11c3QgYmUgZWl0aGVyICdsaW5lYXInLCAnZXhwb25lbnRpYWwnIG9yIGFuIGFycmF5XCIpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUN1cnZlQXRUaW1lKHRoaXMuX3JlbGVhc2VDdXJ2ZSwgdGltZSwgcmVsZWFzZSwgY3VycmVudFZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzY2hlZHVsZWQgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuIFRoaXMgd2lsbFxuICAgICAqIHJldHVybiB0aGUgdW5jb252ZXJ0ZWQgKHJhdykgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSgwLjUsIDEsIDAuNCwgMik7XG4gICAgICogZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDIpO1xuICAgICAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKGVudi5nZXRWYWx1ZUF0VGltZShUb25lLm5vdygpKSksIDEwMCk7XG4gICAgICovXG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2lnLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiB0cmlnZ2VyQXR0YWNrUmVsZWFzZSBpcyBzaG9ydGhhbmQgZm9yIHRyaWdnZXJBdHRhY2ssIHRoZW4gd2FpdGluZ1xuICAgICAqIHNvbWUgZHVyYXRpb24sIHRoZW4gdHJpZ2dlclJlbGVhc2UuXG4gICAgICogQHBhcmFtIGR1cmF0aW9uIFRoZSBkdXJhdGlvbiBvZiB0aGUgc3VzdGFpbi5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBlbnZlbG9wZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGVudikuc3RhcnQoKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIDAuNSBzZWNvbmRzIGFmdGVyIHRoZSBhdHRhY2tcbiAgICAgKiBlbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoMC41KTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSh0aW1lICsgdGhpcy50b1NlY29uZHMoZHVyYXRpb24pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgYWxsIHNjaGVkdWxlZCBlbnZlbG9wZSBjaGFuZ2VzIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9zaWcuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMudG9TZWNvbmRzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBlbnZlbG9wZSB0byBhIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICovXG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtYmVyID0gMCwgaW5wdXROdW1iZXIgPSAwKSB7XG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIHRoZSBlbnZlbG9wZSBjdXJ2ZSB0byBhbiBhcnJheSBvZiB0aGUgZ2l2ZW4gbGVuZ3RoLlxuICAgICAqIEdvb2QgZm9yIHZpc3VhbGl6aW5nIHRoZSBlbnZlbG9wZSBjdXJ2ZS4gUmVzY2FsZXMgdGhlIGR1cmF0aW9uIG9mIHRoZVxuICAgICAqIGVudmVsb3BlIHRvIGZpdCB0aGUgbGVuZ3RoLlxuICAgICAqL1xuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb24gPSBsZW5ndGggLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoMSwgZHVyYXRpb24sIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSB0aGUgQURTUiBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uIHdpdGggMjAlIHN1c3RhaW4gdGltZVxuICAgICAgICAgICAgY29uc3QgYXR0YWNrUG9ydGlvbiA9IHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpO1xuICAgICAgICAgICAgY29uc3QgZW52ZWxvcGVEdXJhdGlvbiA9IGF0dGFja1BvcnRpb24gKyB0aGlzLnRvU2Vjb25kcyh0aGlzLnJlbGVhc2UpO1xuICAgICAgICAgICAgY29uc3Qgc3VzdGFpblRpbWUgPSBlbnZlbG9wZUR1cmF0aW9uICogMC4xO1xuICAgICAgICAgICAgY29uc3QgdG90YWxEdXJhdGlvbiA9IGVudmVsb3BlRHVyYXRpb24gKyBzdXN0YWluVGltZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGNsb25lID0gbmV3IHRoaXMuY29uc3RydWN0b3IoT2JqZWN0LmFzc2lnbih0aGlzLmdldCgpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiBkdXJhdGlvbiAqIHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKSAvIHRvdGFsRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgZGVjYXk6IGR1cmF0aW9uICogdGhpcy50b1NlY29uZHModGhpcy5kZWNheSkgLyB0b3RhbER1cmF0aW9uLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IGR1cmF0aW9uICogdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKSAvIHRvdGFsRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgY29udGV4dFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgY2xvbmUuX3NpZy50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAgICBjbG9uZS50cmlnZ2VyQXR0YWNrUmVsZWFzZShkdXJhdGlvbiAqIChhdHRhY2tQb3J0aW9uICsgc3VzdGFpblRpbWUpIC8gdG90YWxEdXJhdGlvbiwgMCk7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lnLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwiYXR0YWNrXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJkZWNheVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcmFuZ2UoMCwgMSlcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJzdXN0YWluXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJyZWxlYXNlXCIsIHZvaWQgMCk7XG4vKipcbiAqIEdlbmVyYXRlIHNvbWUgY29tcGxleCBlbnZlbG9wZSBjdXJ2ZXMuXG4gKi9cbmNvbnN0IEVudmVsb3BlQ3VydmVzID0gKCgpID0+IHtcbiAgICBjb25zdCBjdXJ2ZUxlbiA9IDEyODtcbiAgICBsZXQgaTtcbiAgICBsZXQgaztcbiAgICAvLyBjb3NpbmUgY3VydmVcbiAgICBjb25zdCBjb3NpbmVDdXJ2ZSA9IFtdO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIGNvc2luZUN1cnZlW2ldID0gTWF0aC5zaW4oKGkgLyAoY3VydmVMZW4gLSAxKSkgKiAoTWF0aC5QSSAvIDIpKTtcbiAgICB9XG4gICAgLy8gcmlwcGxlIGN1cnZlXG4gICAgY29uc3QgcmlwcGxlQ3VydmUgPSBbXTtcbiAgICBjb25zdCByaXBwbGVDdXJ2ZUZyZXEgPSA2LjQ7XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuIC0gMTsgaSsrKSB7XG4gICAgICAgIGsgPSAoaSAvIChjdXJ2ZUxlbiAtIDEpKTtcbiAgICAgICAgY29uc3Qgc2luZVdhdmUgPSBNYXRoLnNpbihrICogKE1hdGguUEkgKiAyKSAqIHJpcHBsZUN1cnZlRnJlcSAtIE1hdGguUEkgLyAyKSArIDE7XG4gICAgICAgIHJpcHBsZUN1cnZlW2ldID0gc2luZVdhdmUgLyAxMCArIGsgKiAwLjgzO1xuICAgIH1cbiAgICByaXBwbGVDdXJ2ZVtjdXJ2ZUxlbiAtIDFdID0gMTtcbiAgICAvLyBzdGFpcnMgY3VydmVcbiAgICBjb25zdCBzdGFpcnNDdXJ2ZSA9IFtdO1xuICAgIGNvbnN0IHN0ZXBzID0gNTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuICAgICAgICBzdGFpcnNDdXJ2ZVtpXSA9IE1hdGguY2VpbCgoaSAvIChjdXJ2ZUxlbiAtIDEpKSAqIHN0ZXBzKSAvIHN0ZXBzO1xuICAgIH1cbiAgICAvLyBpbi1vdXQgZWFzaW5nIGN1cnZlXG4gICAgY29uc3Qgc2luZUN1cnZlID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgayA9IGkgLyAoY3VydmVMZW4gLSAxKTtcbiAgICAgICAgc2luZUN1cnZlW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcyhNYXRoLlBJICogaykpO1xuICAgIH1cbiAgICAvLyBhIGJvdW5jZSBjdXJ2ZVxuICAgIGNvbnN0IGJvdW5jZUN1cnZlID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgayA9IGkgLyAoY3VydmVMZW4gLSAxKTtcbiAgICAgICAgY29uc3QgZnJlcSA9IE1hdGgucG93KGssIDMpICogNCArIDAuMjtcbiAgICAgICAgY29uc3QgdmFsID0gTWF0aC5jb3MoZnJlcSAqIE1hdGguUEkgKiAyICogayk7XG4gICAgICAgIGJvdW5jZUN1cnZlW2ldID0gTWF0aC5hYnModmFsICogKDEgLSBrKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludmVydCBhIHZhbHVlIGN1cnZlIHRvIG1ha2UgaXQgd29yayBmb3IgdGhlIHJlbGVhc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbnZlcnRDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICBjb25zdCBvdXQgPSBuZXcgQXJyYXkoY3VydmUubGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjdXJ2ZS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgb3V0W2pdID0gMSAtIGN1cnZlW2pdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJldmVyc2UgdGhlIGN1cnZlXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmV2ZXJzZUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIHJldHVybiBjdXJ2ZS5zbGljZSgwKS5yZXZlcnNlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGF0dGFjayBhbmQgcmVsZWFzZSBjdXJ2ZSBhcnJheXNcbiAgICAgKi9cbiAgICByZXR1cm4ge1xuICAgICAgICBib3VuY2U6IHtcbiAgICAgICAgICAgIEluOiBpbnZlcnRDdXJ2ZShib3VuY2VDdXJ2ZSksXG4gICAgICAgICAgICBPdXQ6IGJvdW5jZUN1cnZlLFxuICAgICAgICB9LFxuICAgICAgICBjb3NpbmU6IHtcbiAgICAgICAgICAgIEluOiBjb3NpbmVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogcmV2ZXJzZUN1cnZlKGNvc2luZUN1cnZlKSxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwb25lbnRpYWw6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgbGluZWFyOiBcImxpbmVhclwiLFxuICAgICAgICByaXBwbGU6IHtcbiAgICAgICAgICAgIEluOiByaXBwbGVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUocmlwcGxlQ3VydmUpLFxuICAgICAgICB9LFxuICAgICAgICBzaW5lOiB7XG4gICAgICAgICAgICBJbjogc2luZUN1cnZlLFxuICAgICAgICAgICAgT3V0OiBpbnZlcnRDdXJ2ZShzaW5lQ3VydmUpLFxuICAgICAgICB9LFxuICAgICAgICBzdGVwOiB7XG4gICAgICAgICAgICBJbjogc3RhaXJzQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IGludmVydEN1cnZlKHN0YWlyc0N1cnZlKSxcbiAgICAgICAgfSxcbiAgICB9O1xufSkoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBCYXNlLWNsYXNzIGZvciBhbGwgaW5zdHJ1bWVudHNcbiAqL1xuZXhwb3J0IGNsYXNzIEluc3RydW1lbnQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgYWxsIGV2ZW50cyBzY2hlZHVsZWQgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgKiB3aGVuIHRoZSBpbnN0cnVtZW50IGlzICdzeW5jZWQnXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHRoZSBpbnN0cnVtZW50IGlzIGN1cnJlbnRseSBzeW5jZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyQXR0YWNrID0gdGhpcy50cmlnZ2VyQXR0YWNrO1xuICAgICAgICB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyUmVsZWFzZSA9IHRoaXMudHJpZ2dlclJlbGVhc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGluc3RydW1lbnQgdG8gdGhlIFRyYW5zcG9ydC4gQWxsIHN1YnNlcXVlbnQgY2FsbHMgb2ZcbiAgICAgKiBbW3RyaWdnZXJBdHRhY2tdXSBhbmQgW1t0cmlnZ2VyUmVsZWFzZV1dIHdpbGwgYmUgc2NoZWR1bGVkIGFsb25nIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmbVN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBmbVN5bnRoLnZvbHVtZS52YWx1ZSA9IC02O1xuICAgICAqIGZtU3ludGguc3luYygpO1xuICAgICAqIC8vIHNjaGVkdWxlIDMgbm90ZXMgd2hlbiB0aGUgdHJhbnNwb3J0IGZpcnN0IHN0YXJ0c1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIsIDApO1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJFNFwiLCBcIjhuXCIsIFwiOG5cIik7XG4gICAgICogZm1TeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkc0XCIsIFwiOG5cIiwgXCI0blwiKTtcbiAgICAgKiAvLyBzdGFydCB0aGUgdHJhbnNwb3J0IHRvIGhlYXIgdGhlIG5vdGVzXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXQgX3N5bmNcbiAgICAgKi9cbiAgICBfc3luY1N0YXRlKCkge1xuICAgICAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGFuZ2VkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcmFwIHRoZSBnaXZlbiBtZXRob2Qgc28gdGhhdCBpdCBjYW4gYmUgc3luY2hyb25pemVkXG4gICAgICogQHBhcmFtIG1ldGhvZCBXaGljaCBtZXRob2QgdG8gd3JhcCBhbmQgc3luY1xuICAgICAqIEBwYXJhbSAgdGltZVBvc2l0aW9uIFdoYXQgcG9zaXRpb24gdGhlIHRpbWUgYXJndW1lbnQgYXBwZWFycyBpblxuICAgICAqL1xuICAgIF9zeW5jTWV0aG9kKG1ldGhvZCwgdGltZVBvc2l0aW9uKSB7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gdGhpc1tcIl9vcmlnaW5hbF9cIiArIG1ldGhvZF0gPSB0aGlzW21ldGhvZF07XG4gICAgICAgIHRoaXNbbWV0aG9kXSA9ICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0aW1lID0gYXJnc1t0aW1lUG9zaXRpb25dO1xuICAgICAgICAgICAgY29uc3QgaWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgYXJnc1t0aW1lUG9zaXRpb25dID0gdDtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH0sIHRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzLnB1c2goaWQpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGluc3RydW1lbnQgZnJvbSB0aGUgVHJhbnNwb3J0XG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMuZm9yRWFjaChpZCA9PiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGlkKSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IFtdO1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayA9IHRoaXMuX29yaWdpbmFsX3RyaWdnZXJBdHRhY2s7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlID0gdGhpcy5fb3JpZ2luYWxfdHJpZ2dlclJlbGVhc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgdGhlbiB0aGUgcmVsZWFzZSBhZnRlciB0aGUgZHVyYXRpb24uXG4gICAgICogQHBhcmFtICBub3RlICAgICBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIG5vdGUgc2hvdWxkIGJlIGhlbGQgZm9yIGJlZm9yZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJpbmcgdGhlIHJlbGVhc2UuIFRoaXMgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMC5cbiAgICAgKiBAcGFyYW0gdGltZSAgV2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRoZSBub3RlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHRyaWdnZXIgXCJDNFwiIGZvciB0aGUgZHVyYXRpb24gb2YgYW4gOHRoIG5vdGVcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZSwgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqIEByZXR1cm5zIHtJbnN0cnVtZW50fSB0aGlzXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW5zdHJ1bWVudC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuLi9pbnN0cnVtZW50L0luc3RydW1lbnRcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIG90aGVyIG1vbm9waG9uaWMgaW5zdHJ1bWVudHMgdG8gZXh0ZW5kLlxuICovXG5leHBvcnQgY2xhc3MgTW9ub3Bob25pYyBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnBvcnRhbWVudG8gPSBvcHRpb25zLnBvcnRhbWVudG87XG4gICAgICAgIHRoaXMub25zaWxlbmNlID0gb3B0aW9ucy5vbnNpbGVuY2U7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBvbnNpbGVuY2U6IG5vT3AsXG4gICAgICAgICAgICBwb3J0YW1lbnRvOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIG9mIHRoZSBub3RlIG9wdGlvbmFsbHkgd2l0aCBhIGdpdmVuIHZlbG9jaXR5LlxuICAgICAqIEBwYXJhbSAgbm90ZSBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBub3RlIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBzY2FsZXIgZGV0ZXJtaW5lcyBob3cgXCJsb3VkXCIgdGhlIG5vdGUgd2lsbCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIG5vdGUgYSBoYWxmIHNlY29uZCBmcm9tIG5vdyBhdCBoYWxmIHZlbG9jaXR5XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIsIFwiKzAuNVwiLCAwLjUpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sobm90ZSwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCBub3RlLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHNlY29uZHMsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5zZXROb3RlKG5vdGUsIHNlY29uZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSAgdGltZSBJZiBubyB0aW1lIGlzIGdpdmVuLCB0aGUgcmVsZWFzZSBoYXBwZW5zIGltbWVkaWF0bHlcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2UgYSBzZWNvbmQgZnJvbSBub3dcbiAgICAgKiBzeW50aC50cmlnZ2VyUmVsZWFzZShcIisxXCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCB0aW1lKTtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHNlY29uZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBub3RlIGF0IHRoZSBnaXZlbiB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLCB0aGUgbm90ZVxuICAgICAqIHdpbGwgc2V0IGltbWVkaWF0ZWx5LlxuICAgICAqIEBwYXJhbSBub3RlIFRoZSBub3RlIHRvIGNoYW5nZSB0by5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgc2V0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFwiQzRcIik7XG4gICAgICogLy8gY2hhbmdlIHRvIEYjNiBpbiBvbmUgcXVhcnRlciBub3RlIGZyb20gbm93LlxuICAgICAqIHN5bnRoLnNldE5vdGUoXCJGIzZcIiwgXCIrNG5cIik7XG4gICAgICovXG4gICAgc2V0Tm90ZShub3RlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZEZyZXF1ZW5jeSA9IG5vdGUgaW5zdGFuY2VvZiBGcmVxdWVuY3lDbGFzcyA/IG5vdGUudG9GcmVxdWVuY3koKSA6IG5vdGU7XG4gICAgICAgIGlmICh0aGlzLnBvcnRhbWVudG8gPiAwICYmIHRoaXMuZ2V0TGV2ZWxBdFRpbWUoY29tcHV0ZWRUaW1lKSA+IDAuMDUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvcnRUaW1lID0gdGhpcy50b1NlY29uZHModGhpcy5wb3J0YW1lbnRvKTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmV4cG9uZW50aWFsUmFtcFRvKGNvbXB1dGVkRnJlcXVlbmN5LCBwb3J0VGltZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LnNldFZhbHVlQXRUaW1lKGNvbXB1dGVkRnJlcXVlbmN5LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgTW9ub3Bob25pYy5wcm90b3R5cGUsIFwicG9ydGFtZW50b1wiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9ub3Bob25pYy5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4vRW52ZWxvcGVcIjtcbi8qKlxuICogQW1wbGl0dWRlRW52ZWxvcGUgaXMgYSBUb25lLkVudmVsb3BlIGNvbm5lY3RlZCB0byBhIGdhaW4gbm9kZS5cbiAqIFVubGlrZSBUb25lLkVudmVsb3BlLCB3aGljaCBvdXRwdXRzIHRoZSBlbnZlbG9wZSdzIHZhbHVlLCBBbXBsaXR1ZGVFbnZlbG9wZSBhY2NlcHRzXG4gKiBhbiBhdWRpbyBzaWduYWwgYXMgdGhlIGlucHV0IGFuZCB3aWxsIGFwcGx5IHRoZSBlbnZlbG9wZSB0byB0aGUgYW1wbGl0dWRlXG4gKiBvZiB0aGUgc2lnbmFsLlxuICogUmVhZCBtb3JlIGFib3V0IEFEU1IgRW52ZWxvcGVzIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bnRoZXNpemVyI0FEU1JfZW52ZWxvcGUpLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYW1wRW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoe1xuICogXHRcdGF0dGFjazogMC4xLFxuICogXHRcdGRlY2F5OiAwLjIsXG4gKiBcdFx0c3VzdGFpbjogMS4wLFxuICogXHRcdHJlbGVhc2U6IDAuOFxuICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIGNyZWF0ZSBhbiBvc2NpbGxhdG9yIGFuZCBjb25uZWN0IGl0XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGFtcEVudikuc3RhcnQoKTtcbiAqIFx0Ly8gdHJpZ2dlciB0aGUgZW52ZWxvcGVzIGF0dGFjayBhbmQgcmVsZWFzZSBcIjh0XCIgYXBhcnRcbiAqIFx0YW1wRW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiOHRcIik7XG4gKiB9LCAxLjUsIDEpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQW1wbGl0dWRlRW52ZWxvcGUgZXh0ZW5kcyBFbnZlbG9wZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFtcGxpdHVkZUVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFtcGxpdHVkZUVudmVsb3BlXCI7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgdGhpcy5fc2lnLmNvbm5lY3QodGhpcy5fZ2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QW1wbGl0dWRlRW52ZWxvcGUuanMubWFwIiwiaW1wb3J0IHsgQW1wbGl0dWRlRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE9tbmlPc2NpbGxhdG9yIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbi8qKlxuICogU3ludGggaXMgY29tcG9zZWQgc2ltcGx5IG9mIGEgW1tPbW5pT3NjaWxsYXRvcl1dIHJvdXRlZCB0aHJvdWdoIGFuIFtbQW1wbGl0dWRlRW52ZWxvcGVdXS5cbiAqIGBgYFxuICogKy0tLS0tLS0tLS0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiB8IE9tbmlPc2NpbGxhdG9yICs+LS0+IEFtcGxpdHVkZUVudmVsb3BlICs+LS0+IE91dHB1dFxuICogKy0tLS0tLS0tLS0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSBuZXcgT21uaU9zY2lsbGF0b3IoT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSxcbiAgICAgICAgfSwgb3B0aW9ucy5vc2NpbGxhdG9yKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLm9zY2lsbGF0b3IuZGV0dW5lO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9LCBvcHRpb25zLmVudmVsb3BlKSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIG9zY2lsbGF0b3JzIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmNoYWluKHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wib3NjaWxsYXRvclwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4zLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFsuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0XG4gICAgICogQHBhcmFtIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZSAoMC0xKVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgLy8gdGhlIGVudmVsb3Blc1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHJlbGVhc2UgcG9ydGlvbiwgc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkRGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KTtcbiAgICAgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyBjb21wdXRlZEF0dGFjayArIGNvbXB1dGVkRGVjYXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5yZWxlYXNlKSk7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IFN5bnRoIH0gZnJvbSBcIi4vU3ludGhcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgYm90aCBBTSBhbmQgRk0gc3ludGhzXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2R1bGF0aW9uU3ludGggZXh0ZW5kcyBNb25vcGhvbmljIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9kdWxhdGlvblN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1vZHVsYXRpb25TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9kdWxhdGlvblN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIgPSBuZXcgU3ludGgoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogb3B0aW9ucy5vc2NpbGxhdG9yLFxuICAgICAgICAgICAgZW52ZWxvcGU6IG9wdGlvbnMuZW52ZWxvcGUsXG4gICAgICAgICAgICBvbnNpbGVuY2U6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpLFxuICAgICAgICAgICAgdm9sdW1lOiAtMTAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgU3ludGgoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogb3B0aW9ucy5tb2R1bGF0aW9uLFxuICAgICAgICAgICAgZW52ZWxvcGU6IG9wdGlvbnMubW9kdWxhdGlvbkVudmVsb3BlLFxuICAgICAgICAgICAgdm9sdW1lOiAtMTAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSB0aGlzLl9jYXJyaWVyLm9zY2lsbGF0b3I7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUgPSB0aGlzLl9jYXJyaWVyLmVudmVsb3BlO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb24gPSB0aGlzLl9tb2R1bGF0b3Iub3NjaWxsYXRvcjtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uRW52ZWxvcGUgPSB0aGlzLl9tb2R1bGF0b3IuZW52ZWxvcGU7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICAgICAgbWluVmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJoYXJtb25pY2l0eVwiLCBcIm9zY2lsbGF0b3JcIiwgXCJlbnZlbG9wZVwiLCBcIm1vZHVsYXRpb25cIiwgXCJtb2R1bGF0aW9uRW52ZWxvcGVcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDMsXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFtcbiAgICAgICAgICAgICAgICAuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksXG4gICAgICAgICAgICAgICAgXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgICAgICBcImRldHVuZVwiXG4gICAgICAgICAgICBdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2luZVwiXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAxLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG1vZHVsYXRpb246IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgW1xuICAgICAgICAgICAgICAgIC4uLk9iamVjdC5rZXlzKFNvdXJjZS5nZXREZWZhdWx0cygpKSxcbiAgICAgICAgICAgICAgICBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgICAgIFwiZGV0dW5lXCJcbiAgICAgICAgICAgIF0pLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcXVhcmVcIlxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtb2R1bGF0aW9uRW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fY2Fycmllci5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9jYXJyaWVyLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vZHVsYXRpb25TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTW9kdWxhdGlvblN5bnRoIH0gZnJvbSBcIi4vTW9kdWxhdGlvblN5bnRoXCI7XG4vKipcbiAqIEFNU3ludGggdXNlcyB0aGUgb3V0cHV0IG9mIG9uZSBUb25lLlN5bnRoIHRvIG1vZHVsYXRlIHRoZVxuICogYW1wbGl0dWRlIG9mIGFub3RoZXIgVG9uZS5TeW50aC4gVGhlIGhhcm1vbmljaXR5ICh0aGUgcmF0aW8gYmV0d2VlblxuICogdGhlIHR3byBzaWduYWxzKSBhZmZlY3RzIHRoZSB0aW1icmUgb2YgdGhlIG91dHB1dCBzaWduYWwgZ3JlYXRseS5cbiAqIFJlYWQgbW9yZSBhYm91dCBBbXBsaXR1ZGUgTW9kdWxhdGlvbiBTeW50aGVzaXMgb25cbiAqIFtTb3VuZE9uU291bmRdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwNDEwMzY1My9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb206ODAvc29zL21hcjAwL2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLkFNU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiNG5cIik7XG4gKlxuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEFNU3ludGggZXh0ZW5kcyBNb2R1bGF0aW9uU3ludGgge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBTVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFNU3ludGhcIjtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlID0gbmV3IEF1ZGlvVG9HYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMuX2NhcnJpZXIuZGV0dW5lLCB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNoYWluKHRoaXMuX21vZHVsYXRpb25TY2FsZSwgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY2hhaW4odGhpcy5fbW9kdWxhdGlvbk5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BTVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFRoaW4gd3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBXZWIgQXVkaW8gW0JpcXVhZEZpbHRlck5vZGVdKGh0dHBzOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI2JpcXVhZGZpbHRlcm5vZGUpLlxuICogQmlxdWFkRmlsdGVyIGlzIHNpbWlsYXIgdG8gW1tGaWx0ZXJdXSBidXQgZG9lc24ndCBoYXZlIHRoZSBvcHRpb24gdG8gc2V0IHRoZSBcInJvbGxvZmZcIiB2YWx1ZS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEJpcXVhZEZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXF1YWRGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQmlxdWFkRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXF1YWRGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9maWx0ZXI7XG4gICAgICAgIHRoaXMuUSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5nYWluID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmdhaW4sXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLmdhaW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGlzIEJpcXVhZEZpbHRlck5vZGUuIEZvciBhIGNvbXBsZXRlIGxpc3Qgb2YgdHlwZXMgYW5kIHRoZWlyIGF0dHJpYnV0ZXMsIHNlZSB0aGVcbiAgICAgKiBbV2ViIEF1ZGlvIEFQSV0oaHR0cHM6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jZG9tLWJpcXVhZGZpbHRlcnR5cGUtbG93cGFzcylcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbHRlci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gW1wibG93cGFzc1wiLCBcImhpZ2hwYXNzXCIsIFwiYmFuZHBhc3NcIixcbiAgICAgICAgICAgIFwibG93c2hlbGZcIiwgXCJoaWdoc2hlbGZcIiwgXCJub3RjaFwiLCBcImFsbHBhc3NcIiwgXCJwZWFraW5nXCJdO1xuICAgICAgICBhc3NlcnQodHlwZXMuaW5kZXhPZih0eXBlKSAhPT0gLTEsIGBJbnZhbGlkIGZpbHRlciB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUuIFRoaXMgY3VydmUgcmVwcmVzZW50cyBob3cgdGhlIGZpbHRlclxuICAgICAqIHJlc3BvbnNlcyB0byBmcmVxdWVuY2llcyBiZXR3ZWVuIDIwaHotMjBraHouXG4gICAgICogQHBhcmFtICBsZW4gVGhlIG51bWJlciBvZiB2YWx1ZXMgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlIGJldHdlZW4gMjAtMjBrSHpcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShsZW4gPSAxMjgpIHtcbiAgICAgICAgLy8gc3RhcnQgd2l0aCBhbGwgMXNcbiAgICAgICAgY29uc3QgZnJlcVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybSA9IE1hdGgucG93KGkgLyBsZW4sIDIpO1xuICAgICAgICAgICAgY29uc3QgZnJlcSA9IG5vcm0gKiAoMjAwMDAgLSAyMCkgKyAyMDtcbiAgICAgICAgICAgIGZyZXFWYWx1ZXNbaV0gPSBmcmVxO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hZ1ZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgY29uc3QgcGhhc2VWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIC8vIGNsb25lIHRoZSBmaWx0ZXIgdG8gcmVtb3ZlIGFueSBjb25uZWN0aW9ucyB3aGljaCBtYXkgYmUgY2hhbmdpbmcgdGhlIHZhbHVlXG4gICAgICAgIGNvbnN0IGZpbHRlckNsb25lID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICBmaWx0ZXJDbG9uZS50eXBlID0gdGhpcy50eXBlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5RLnZhbHVlID0gdGhpcy5RLnZhbHVlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5mcmVxdWVuY3kudmFsdWUgPSB0aGlzLmZyZXF1ZW5jeS52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZ2Fpbi52YWx1ZSA9IHRoaXMuZ2Fpbi52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcVZhbHVlcywgbWFnVmFsdWVzLCBwaGFzZVZhbHVlcyk7XG4gICAgICAgIHJldHVybiBtYWdWYWx1ZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpcXVhZEZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc051bWJlciB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgQmlxdWFkRmlsdGVyIH0gZnJvbSBcIi4vQmlxdWFkRmlsdGVyXCI7XG4vKipcbiAqIFRvbmUuRmlsdGVyIGlzIGEgZmlsdGVyIHdoaWNoIGFsbG93cyBmb3IgYWxsIG9mIHRoZSBzYW1lIG5hdGl2ZSBtZXRob2RzXG4gKiBhcyB0aGUgW0JpcXVhZEZpbHRlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWJpcXVhZGZpbHRlcm5vZGUtaW50ZXJmYWNlKS5cbiAqIFRvbmUuRmlsdGVyIGhhcyB0aGUgYWRkZWQgYWJpbGl0eSB0byBzZXQgdGhlIGZpbHRlciByb2xsb2ZmIGF0IC0xMlxuICogKGRlZmF1bHQpLCAtMjQgYW5kIC00OC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoMTUwMCwgXCJoaWdocGFzc1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBmaWx0ZXIuZnJlcXVlbmN5LnJhbXBUbygyMDAwMCwgMTApO1xuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLmNvbm5lY3QoZmlsdGVyKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJyb2xsb2ZmXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmlsdGVyXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZmlsdGVycyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInJvbGxvZmZcIl0pO1xuICAgICAgICB0aGlzLl9maWx0ZXJzID0gW107XG4gICAgICAgIHRoaXMuUSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZ2FpbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMucm9sbG9mZiA9IG9wdGlvbnMucm9sbG9mZjtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZGV0dW5lXCIsIFwiZnJlcXVlbmN5XCIsIFwiZ2FpblwiLCBcIlFcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMzUwLFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgICAgIHJvbGxvZmY6IC0xMixcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIGZpbHRlci4gVHlwZXM6IFwibG93cGFzc1wiLCBcImhpZ2hwYXNzXCIsXG4gICAgICogXCJiYW5kcGFzc1wiLCBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIG9yIFwicGVha2luZ1wiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBjb25zdCB0eXBlcyA9IFtcImxvd3Bhc3NcIiwgXCJoaWdocGFzc1wiLCBcImJhbmRwYXNzXCIsXG4gICAgICAgICAgICBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIFwicGVha2luZ1wiXTtcbiAgICAgICAgYXNzZXJ0KHR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xLCBgSW52YWxpZCBmaWx0ZXIgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiBmaWx0ZXIudHlwZSA9IHR5cGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcm9sbG9mZiBvZiB0aGUgZmlsdGVyIHdoaWNoIGlzIHRoZSBkcm9wIGluIGRiXG4gICAgICogcGVyIG9jdGF2ZS4gSW1wbGVtZW50ZWQgaW50ZXJuYWxseSBieSBjYXNjYWRpbmcgZmlsdGVycy5cbiAgICAgKiBPbmx5IGFjY2VwdHMgdGhlIHZhbHVlcyAtMTIsIC0yNCwgLTQ4IGFuZCAtOTYuXG4gICAgICovXG4gICAgZ2V0IHJvbGxvZmYoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yb2xsb2ZmO1xuICAgIH1cbiAgICBzZXQgcm9sbG9mZihyb2xsb2ZmKSB7XG4gICAgICAgIGNvbnN0IHJvbGxvZmZOdW0gPSBpc051bWJlcihyb2xsb2ZmKSA/IHJvbGxvZmYgOiBwYXJzZUludChyb2xsb2ZmLCAxMCk7XG4gICAgICAgIGNvbnN0IHBvc3NpYmlsaXRpZXMgPSBbLTEyLCAtMjQsIC00OCwgLTk2XTtcbiAgICAgICAgbGV0IGNhc2NhZGluZ0NvdW50ID0gcG9zc2liaWxpdGllcy5pbmRleE9mKHJvbGxvZmZOdW0pO1xuICAgICAgICAvLyBjaGVjayB0aGUgcm9sbG9mZiBpcyB2YWxpZFxuICAgICAgICBhc3NlcnQoY2FzY2FkaW5nQ291bnQgIT09IC0xLCBgcm9sbG9mZiBjYW4gb25seSBiZSAke3Bvc3NpYmlsaXRpZXMuam9pbihcIiwgXCIpfWApO1xuICAgICAgICBjYXNjYWRpbmdDb3VudCArPSAxO1xuICAgICAgICB0aGlzLl9yb2xsb2ZmID0gcm9sbG9mZk51bTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaChmaWx0ZXIgPT4gZmlsdGVyLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMgPSBuZXcgQXJyYXkoY2FzY2FkaW5nQ291bnQpO1xuICAgICAgICBmb3IgKGxldCBjb3VudCA9IDA7IGNvdW50IDwgY2FzY2FkaW5nQ291bnQ7IGNvdW50KyspIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IG5ldyBCaXF1YWRGaWx0ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmlsdGVyLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdChmaWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QoZmlsdGVyLmRldHVuZSk7XG4gICAgICAgICAgICB0aGlzLlEuY29ubmVjdChmaWx0ZXIuUSk7XG4gICAgICAgICAgICB0aGlzLmdhaW4uY29ubmVjdChmaWx0ZXIuZ2Fpbik7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXJzW2NvdW50XSA9IGZpbHRlcjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gdGhpcy5fZmlsdGVycztcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9pbnRlcm5hbENoYW5uZWxzLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlLiBUaGlzIGN1cnZlIHJlcHJlc2VudHMgaG93IHRoZSBmaWx0ZXJcbiAgICAgKiByZXNwb25zZXMgdG8gZnJlcXVlbmNpZXMgYmV0d2VlbiAyMGh6LTIwa2h6LlxuICAgICAqIEBwYXJhbSAgbGVuIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZSBiZXR3ZWVuIDIwLTIwa0h6XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuID0gMTI4KSB7XG4gICAgICAgIGNvbnN0IGZpbHRlckNsb25lID0gbmV3IEJpcXVhZEZpbHRlcih7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IHRoaXMuZnJlcXVlbmN5LnZhbHVlLFxuICAgICAgICAgICAgZ2FpbjogdGhpcy5nYWluLnZhbHVlLFxuICAgICAgICAgICAgUTogdGhpcy5RLnZhbHVlLFxuICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgIGRldHVuZTogdGhpcy5kZXR1bmUudmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB3aXRoIGFsbCAxc1xuICAgICAgICBjb25zdCB0b3RhbFJlc3BvbnNlID0gbmV3IEZsb2F0MzJBcnJheShsZW4pLm1hcCgoKSA9PiAxKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZmlsdGVyQ2xvbmUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2goKHZhbCwgaSkgPT4gdG90YWxSZXNwb25zZVtpXSAqPSB2YWwpO1xuICAgICAgICB9KTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdG90YWxSZXNwb25zZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IHtcbiAgICAgICAgICAgIGZpbHRlci5kaXNwb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBbXCJkZXR1bmVcIiwgXCJmcmVxdWVuY3lcIiwgXCJnYWluXCIsIFwiUVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IFBvdyB9IGZyb20gXCIuLi8uLi9zaWduYWwvUG93XCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogRnJlcXVlbmN5RW52ZWxvcGUgaXMgYW4gW1tFbnZlbG9wZV1dIHdoaWNoIHJhbXBzIGJldHdlZW4gW1tiYXNlRnJlcXVlbmN5XV1cbiAqIGFuZCBbW29jdGF2ZXNdXS4gSXQgY2FuIGFsc28gaGF2ZSBhbiBvcHRpb25hbCBbW2V4cG9uZW50XV0gdG8gYWRqdXN0IHRoZSBjdXJ2ZVxuICogd2hpY2ggaXQgcmFtcHMuXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIGNvbnN0IGZyZXFFbnYgPSBuZXcgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZSh7XG4gKiBcdGF0dGFjazogMC4yLFxuICogXHRiYXNlRnJlcXVlbmN5OiBcIkMyXCIsXG4gKiBcdG9jdGF2ZXM6IDRcbiAqIH0pO1xuICogZnJlcUVudi5jb25uZWN0KG9zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAqIGZyZXFFbnYudHJpZ2dlckF0dGFjaygpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRnJlcXVlbmN5RW52ZWxvcGUgZXh0ZW5kcyBFbnZlbG9wZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeUVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZXF1ZW5jeUVudmVsb3BlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pO1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLmJhc2VGcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9leHBvbmVudCA9IHRoaXMuaW5wdXQgPSBuZXcgUG93KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmV4cG9uZW50XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IHRoaXMub3V0cHV0ID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogdGhpcy5fYmFzZUZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1heDogdGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIHRoaXMuX29jdGF2ZXMpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2lnLmNoYWluKHRoaXMuX2V4cG9uZW50LCB0aGlzLl9zY2FsZSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgZXhwb25lbnQ6IDEsXG4gICAgICAgICAgICBvY3RhdmVzOiA0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGVudmVsb3BlJ3MgbWluaW11bSBvdXRwdXQgdmFsdWUuIFRoaXMgaXMgdGhlIHZhbHVlIHdoaWNoIGl0XG4gICAgICogc3RhcnRzIGF0LlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3kobWluKSB7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KG1pbik7XG4gICAgICAgIGFzc2VydFJhbmdlKGZyZXEsIDApO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gZnJlcTtcbiAgICAgICAgdGhpcy5fc2NhbGUubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBtYXggdmFsdWUgd2hlbiB0aGUgbWluIGNoYW5nZXNcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5IHRoYXQgdGhlXG4gICAgICogZW52ZWxvcGUgd2lsbCBzY2FsZSB0by5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdGF2ZXMpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdGF2ZXM7XG4gICAgICAgIHRoaXMuX3NjYWxlLm1heCA9IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3RhdmVzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGVudmVsb3BlJ3MgZXhwb25lbnQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IGV4cG9uZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwb25lbnQudmFsdWU7XG4gICAgfVxuICAgIHNldCBleHBvbmVudChleHBvbmVudCkge1xuICAgICAgICB0aGlzLl9leHBvbmVudC52YWx1ZSA9IGV4cG9uZW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZXF1ZW5jeUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IEFtcGxpdHVkZUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi4vaW5zdHJ1bWVudC9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9GcmVxdWVuY3lFbnZlbG9wZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBNb25vU3ludGggaXMgY29tcG9zZWQgb2Ygb25lIGBvc2NpbGxhdG9yYCwgb25lIGBmaWx0ZXJgLCBhbmQgdHdvIGBlbnZlbG9wZXNgLlxuICogVGhlIGFtcGxpdHVkZSBvZiB0aGUgT3NjaWxsYXRvciBhbmQgdGhlIGN1dG9mZiBmcmVxdWVuY3kgb2YgdGhlXG4gKiBGaWx0ZXIgYXJlIGNvbnRyb2xsZWQgYnkgRW52ZWxvcGVzLlxuICogPGltZyBzcmM9XCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kcmF3aW5ncy9kLzFnYVkxREY5X0h6a29kcWY4SkkxQ2cyVlpmd1NFbHBGUWZJOTRJUXdhZDM4L3B1Yj93PTkyNCZoPTI0MFwiPlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTW9ub1N5bnRoKHtcbiAqIFx0b3NjaWxsYXRvcjoge1xuICogXHRcdHR5cGU6IFwic3F1YXJlXCJcbiAqIFx0fSxcbiAqIFx0ZW52ZWxvcGU6IHtcbiAqIFx0XHRhdHRhY2s6IDAuMVxuICogXHR9XG4gKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTW9ub1N5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb25vU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSBuZXcgT21uaU9zY2lsbGF0b3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLm9zY2lsbGF0b3IsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpLFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLm9zY2lsbGF0b3IuZGV0dW5lO1xuICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBGaWx0ZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zLmZpbHRlciwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlID0gbmV3IEZyZXF1ZW5jeUVudmVsb3BlKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXJFbnZlbG9wZSwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5lbnZlbG9wZSwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBvc2NpbGxhdG9ycyB0byB0aGUgb3V0cHV0XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5jaGFpbih0aGlzLmZpbHRlciwgdGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBmaWx0ZXIgZW52ZWxvcGVcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS5jb25uZWN0KHRoaXMuZmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm9zY2lsbGF0b3JcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIiwgXCJmaWx0ZXJcIiwgXCJmaWx0ZXJFbnZlbG9wZVwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC45LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBmaWx0ZXI6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRmlsdGVyLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgICAgICByb2xsb2ZmOiAtMTIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGZpbHRlckVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEZyZXF1ZW5jeUVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjYsXG4gICAgICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjIsXG4gICAgICAgICAgICAgICAgZXhwb25lbnQ6IDIsXG4gICAgICAgICAgICAgICAgb2N0YXZlczogMyxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAyLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuNSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIGF0dGFjayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgdGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlICgwLTEpXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkQXR0YWNrID0gdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5hdHRhY2spO1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWREZWNheSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpO1xuICAgICAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIGNvbXB1dGVkQXR0YWNrICsgY29tcHV0ZWREZWNheSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gdGltZSB0aGUgdGltZSB0aGUgcmVsZWFzZSBzaG91bGQgc3RhcnRcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKTtcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Nb25vU3ludGguanMubWFwIiwiaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbmltcG9ydCB7IE1vbm9TeW50aCB9IGZyb20gXCIuL01vbm9TeW50aFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IEdhaW4sIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBEdW9TeW50aCBpcyBhIG1vbm9waG9uaWMgc3ludGggY29tcG9zZWQgb2YgdHdvIFtbTW9ub1N5bnRoc11dIHJ1biBpbiBwYXJhbGxlbCB3aXRoIGNvbnRyb2wgb3ZlciB0aGVcbiAqIGZyZXF1ZW5jeSByYXRpbyBiZXR3ZWVuIHRoZSB0d28gdm9pY2VzIGFuZCB2aWJyYXRvIGVmZmVjdC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBkdW9TeW50aCA9IG5ldyBUb25lLkR1b1N5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogZHVvU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjJuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIER1b1N5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKER1b1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkR1b1N5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhEdW9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnZvaWNlMCA9IG5ldyBNb25vU3ludGgoT2JqZWN0LmFzc2lnbihvcHRpb25zLnZvaWNlMCwge1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb25zaWxlbmNlOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKVxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMudm9pY2UxID0gbmV3IE1vbm9TeW50aChPYmplY3QuYXNzaWduKG9wdGlvbnMudm9pY2UxLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl92aWJyYXRvID0gbmV3IExGTyh7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMudmlicmF0b1JhdGUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IC01MCxcbiAgICAgICAgICAgIG1heDogNTBcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSB2aWJyYXRvIGltbWVkaWF0ZWx5XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8uc3RhcnQoKTtcbiAgICAgICAgdGhpcy52aWJyYXRvUmF0ZSA9IHRoaXMuX3ZpYnJhdG8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl92aWJyYXRvR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLnZpYnJhdG9BbW91bnRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlicmF0b0Ftb3VudCA9IHRoaXMuX3ZpYnJhdG9HYWluLmdhaW47XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiA0NDBcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMudm9pY2UwLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMudm9pY2UxLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8uY29ubmVjdCh0aGlzLl92aWJyYXRvR2Fpbik7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluLmZhbih0aGlzLnZvaWNlMC5kZXR1bmUsIHRoaXMudm9pY2UxLmRldHVuZSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmZhbih0aGlzLnZvaWNlMC5kZXR1bmUsIHRoaXMudm9pY2UxLmRldHVuZSk7XG4gICAgICAgIHRoaXMudm9pY2UwLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLnZvaWNlMS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1widm9pY2UwXCIsIFwidm9pY2UxXCIsIFwiZnJlcXVlbmN5XCIsIFwidmlicmF0b0Ftb3VudFwiLCBcInZpYnJhdG9SYXRlXCJdKTtcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnZvaWNlMC5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKSArIHRoaXMudm9pY2UxLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2aWJyYXRvQW1vdW50OiAwLjUsXG4gICAgICAgICAgICB2aWJyYXRvUmF0ZTogNSxcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAxLjUsXG4gICAgICAgICAgICB2b2ljZTA6IGRlZXBNZXJnZShvbWl0RnJvbU9iamVjdChNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJFbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHZvaWNlMTogZGVlcE1lcmdlKG9taXRGcm9tT2JqZWN0KE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGZpbHRlckVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTAuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTEuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMC5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMS5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2ljZTAuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvaWNlMS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92aWJyYXRvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52aWJyYXRvUmF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUR1b1N5bnRoLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBNb2R1bGF0aW9uU3ludGggfSBmcm9tIFwiLi9Nb2R1bGF0aW9uU3ludGhcIjtcbi8qKlxuICogRk1TeW50aCBpcyBjb21wb3NlZCBvZiB0d28gVG9uZS5TeW50aHMgd2hlcmUgb25lIFRvbmUuU3ludGggbW9kdWxhdGVzXG4gKiB0aGUgZnJlcXVlbmN5IG9mIGEgc2Vjb25kIFRvbmUuU3ludGguIEEgbG90IG9mIHNwZWN0cmFsIGNvbnRlbnRcbiAqIGNhbiBiZSBleHBsb3JlZCB1c2luZyB0aGUgbW9kdWxhdGlvbkluZGV4IHBhcmFtZXRlci4gUmVhZCBtb3JlIGFib3V0XG4gKiBmcmVxdWVuY3kgbW9kdWxhdGlvbiBzeW50aGVzaXMgb24gU291bmQgT24gU291bmQ6IFtQYXJ0IDFdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwMzEyMzcwNC9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb20vc29zL2FwcjAwL2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLCBbUGFydCAyXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDMxMTU4MzUvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tL3Nvcy9tYXkwMC9hcnRpY2xlcy9zeW50aC5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmbVN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNVwiLCBcIjRuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGTVN5bnRoIGV4dGVuZHMgTW9kdWxhdGlvblN5bnRoIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGTVN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGTVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm1vZHVsYXRpb25JbmRleCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5tb2R1bGF0aW9uSW5kZXgsIHRoaXMuX21vZHVsYXRpb25Ob2RlKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMuX2NhcnJpZXIuZGV0dW5lLCB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNvbm5lY3QodGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vZHVsYXRpb25TeW50aC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IDEwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZNU3ludGguanMubWFwIiwiaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZNT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9GTU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG4vKipcbiAqIEluaGFybW9uaWMgcmF0aW8gb2YgZnJlcXVlbmNpZXMgYmFzZWQgb24gdGhlIFJvbGFuZCBUUi04MDhcbiAqIFRha2VuIGZyb20gaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvcGFwZXJzL3RyLTgwOC1jeW1iYWwtcGh5c2ljYWxseS1pbmZvcm1lZC1jaXJjdWl0LWJlbmRhYmxlLWRpZ2l0YWwtbW9kZWxcbiAqL1xuY29uc3QgaW5oYXJtUmF0aW9zID0gWzEuMCwgMS40ODMsIDEuOTMyLCAyLjU0NiwgMi42MzAsIDMuODk3XTtcbi8qKlxuICogQSBoaWdobHkgaW5oYXJtb25pYyBhbmQgc3BlY3RyYWxseSBjb21wbGV4IHNvdXJjZSB3aXRoIGEgaGlnaHBhc3MgZmlsdGVyXG4gKiBhbmQgYW1wbGl0dWRlIGVudmVsb3BlIHdoaWNoIGlzIGdvb2QgZm9yIG1ha2luZyBtZXRhbGxvcGhvbmUgc291bmRzLlxuICogQmFzZWQgb24gQ3ltYmFsU3ludGggYnkgW0Bwb2x5cmh5dGhtYXRpY10oaHR0cHM6Ly9naXRodWIuY29tL3BvbHlyaHl0aG1hdGljKS5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1NvdW5kIG9uIFNvdW5kXShodHRwczovL3Nob3J0dXJsLmF0L3JTWjEyKS5cbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRhbFN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGFsU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWV0YWxTeW50aFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFycmF5IG9mIEZNT3NjaWxsYXRvcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZnJlcXVlbmN5IG11bHRpcGxpZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9mcmVxTXVsdGlwbGllcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGFsU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5faGlnaHBhc3MgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIC8vIFE6IC0zLjAxMDI5OTk1NjYzOTgxMjUsXG4gICAgICAgICAgICBROiAwLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJoaWdocGFzc1wiLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5oYXJtUmF0aW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBvc2MgPSBuZXcgRk1Pc2NpbGxhdG9yKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgaGFybW9uaWNpdHk6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiBvcHRpb25zLm1vZHVsYXRpb25JbmRleCxcbiAgICAgICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgICAgICAgICBvbnN0b3A6IGkgPT09IDAgPyAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSA6IG5vT3AsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgb3NjLmNvbm5lY3QodGhpcy5faGlnaHBhc3MpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnNbaV0gPSBvc2M7XG4gICAgICAgICAgICBjb25zdCBtdWx0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGluaGFybVJhdGlvc1tpXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzW2ldID0gbXVsdDtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKG11bHQsIG9zYy5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdChvc2MuZGV0dW5lKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heDogNzAwMCxcbiAgICAgICAgICAgIG1pbjogdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLnJlc29uYW5jZSksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEVudmVsb3BlKHtcbiAgICAgICAgICAgIGF0dGFjazogb3B0aW9ucy5lbnZlbG9wZS5hdHRhY2ssXG4gICAgICAgICAgICBhdHRhY2tDdXJ2ZTogXCJsaW5lYXJcIixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlY2F5OiBvcHRpb25zLmVudmVsb3BlLmRlY2F5LFxuICAgICAgICAgICAgcmVsZWFzZTogb3B0aW9ucy5lbnZlbG9wZS5yZWxlYXNlLFxuICAgICAgICAgICAgc3VzdGFpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuY2hhaW4odGhpcy5fZmlsdGVyRnJlcVNjYWxlciwgdGhpcy5faGlnaHBhc3MuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZS5nYWluKTtcbiAgICAgICAgLy8gc2V0IHRoZSBvY3RhdmVzXG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDAxLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAxLjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4yLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBoYXJtb25pY2l0eTogNS4xLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiAzMixcbiAgICAgICAgICAgIG9jdGF2ZXM6IDEuNSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogNDAwMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjay5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRoYXQgdGhlIGVudmVsb3BlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KHRpbWUpKTtcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4ge1xuICAgICAgICAgICAgICAgIG9zYy5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjaykgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgZW52ZWxvcGUuXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0aGUgcmVsZWFzZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb25JbmRleCBvZiB0aGUgb3NjaWxsYXRvcnMgd2hpY2ggbWFrZSB1cCB0aGUgc291cmNlLlxuICAgICAqIHNlZSBbW0ZNT3NjaWxsYXRvci5tb2R1bGF0aW9uSW5kZXhdXVxuICAgICAqIEBtaW4gMVxuICAgICAqIEBtYXggMTAwXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25JbmRleCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLm1vZHVsYXRpb25JbmRleC52YWx1ZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25JbmRleCh2YWwpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gKG9zYy5tb2R1bGF0aW9uSW5kZXgudmFsdWUgPSB2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGhhcm1vbmljaXR5IG9mIHRoZSBvc2NpbGxhdG9ycyB3aGljaCBtYWtlIHVwIHRoZSBzb3VyY2UuXG4gICAgICogc2VlIFRvbmUuRk1Pc2NpbGxhdG9yLmhhcm1vbmljaXR5XG4gICAgICogQG1pbiAwLjFcbiAgICAgKiBAbWF4IDEwXG4gICAgICovXG4gICAgZ2V0IGhhcm1vbmljaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0uaGFybW9uaWNpdHkudmFsdWU7XG4gICAgfVxuICAgIHNldCBoYXJtb25pY2l0eSh2YWwpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gKG9zYy5oYXJtb25pY2l0eS52YWx1ZSA9IHZhbCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG93ZXIgbGV2ZWwgb2YgdGhlIGhpZ2hwYXNzIGZpbHRlciB3aGljaCBpcyBhdHRhY2hlZCB0byB0aGUgZW52ZWxvcGUuXG4gICAgICogVGhpcyB2YWx1ZSBzaG91bGQgYmUgYmV0d2VlbiBbMCwgNzAwMF1cbiAgICAgKiBAbWluIDBcbiAgICAgKiBAbWF4IDcwMDBcbiAgICAgKi9cbiAgICBnZXQgcmVzb25hbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5taW47XG4gICAgfVxuICAgIHNldCByZXNvbmFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluID0gdGhpcy50b0ZyZXF1ZW5jeSh2YWwpO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgYWJvdmUgdGhlIFwicmVzb25hbmNlXCIgZnJlcXVlbmN5XG4gICAgICogdGhhdCB0aGUgZmlsdGVyIHJhbXBzIGR1cmluZyB0aGUgYXR0YWNrL2RlY2F5IGVudmVsb3BlXG4gICAgICogQG1pbiAwXG4gICAgICogQG1heCA4XG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyh2YWwpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IHZhbDtcbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5tYXggPSB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1pbiAqIE1hdGgucG93KDIsIHZhbCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVycy5mb3JFYWNoKGZyZXFNdWx0ID0+IGZyZXFNdWx0LmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2hpZ2hwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0YWxTeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbmltcG9ydCB7IFN5bnRoIH0gZnJvbSBcIi4vU3ludGhcIjtcbmltcG9ydCB7IHJhbmdlLCB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBNZW1icmFuZVN5bnRoIG1ha2VzIGtpY2sgYW5kIHRvbSBzb3VuZHMgdXNpbmcgYSBzaW5nbGUgb3NjaWxsYXRvclxuICogd2l0aCBhbiBhbXBsaXR1ZGUgZW52ZWxvcGUgYW5kIGZyZXF1ZW5jeSByYW1wLiBBIFRvbmUuT21uaU9zY2lsbGF0b3JcbiAqIGlzIHJvdXRlZCB0aHJvdWdoIGEgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSB0byB0aGUgb3V0cHV0LiBUaGUgZHJ1bVxuICogcXVhbGl0eSBvZiB0aGUgc291bmQgY29tZXMgZnJvbSB0aGUgZnJlcXVlbmN5IGVudmVsb3BlIGFwcGxpZWRcbiAqIGR1cmluZyBNZW1icmFuZVN5bnRoLnRyaWdnZXJBdHRhY2sobm90ZSkuIFRoZSBmcmVxdWVuY3kgZW52ZWxvcGVcbiAqIHN0YXJ0cyBhdCA8Y29kZT5ub3RlICogLm9jdGF2ZXM8L2NvZGU+IGFuZCByYW1wcyB0byA8Y29kZT5ub3RlPC9jb2RlPlxuICogb3ZlciB0aGUgZHVyYXRpb24gb2YgPGNvZGU+LnBpdGNoRGVjYXk8L2NvZGU+LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTWVtYnJhbmVTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzJcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZW1icmFuZVN5bnRoIGV4dGVuZHMgU3ludGgge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZW1icmFuZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1lbWJyYW5lU3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBvcnRhbWVudG8gaXMgaWdub3JlZCBpbiB0aGlzIHN5bnRoLiB1c2UgcGl0Y2ggZGVjYXkgaW5zdGVhZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucG9ydGFtZW50byA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZW1icmFuZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMucGl0Y2hEZWNheSA9IG9wdGlvbnMucGl0Y2hEZWNheTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJvc2NpbGxhdG9yXCIsIFwiZW52ZWxvcGVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBTeW50aC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZToge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDEsXG4gICAgICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgICAgICBkZWNheTogMC40LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEuNCxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDEwLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBpdGNoRGVjYXk6IDAuMDUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzZXROb3RlKG5vdGUsIHRpbWUpIHtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBoZXJ0eiA9IHRoaXMudG9GcmVxdWVuY3kobm90ZSBpbnN0YW5jZW9mIEZyZXF1ZW5jeUNsYXNzID8gbm90ZS50b0ZyZXF1ZW5jeSgpIDogbm90ZSk7XG4gICAgICAgIGNvbnN0IG1heE5vdGUgPSBoZXJ0eiAqIHRoaXMub2N0YXZlcztcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZShtYXhOb3RlLCBzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKGhlcnR6LCBzZWNvbmRzICsgdGhpcy50b1NlY29uZHModGhpcy5waXRjaERlY2F5KSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHJhbmdlKDApXG5dLCBNZW1icmFuZVN5bnRoLnByb3RvdHlwZSwgXCJvY3RhdmVzXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIE1lbWJyYW5lU3ludGgucHJvdG90eXBlLCBcInBpdGNoRGVjYXlcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1lbWJyYW5lU3ludGguanMubWFwIiwiaW1wb3J0IHsgQW1wbGl0dWRlRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOb2lzZSB9IGZyb20gXCIuLi9zb3VyY2UvTm9pc2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG4vKipcbiAqIFRvbmUuTm9pc2VTeW50aCBpcyBjb21wb3NlZCBvZiBbW05vaXNlXV0gdGhyb3VnaCBhbiBbW0FtcGxpdHVkZUVudmVsb3BlXV0uXG4gKiBgYGBcbiAqICstLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogfCBOb2lzZSArPi0tPiBBbXBsaXR1ZGVFbnZlbG9wZSArPi0tPiBPdXRwdXRcbiAqICstLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgbm9pc2VTeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBub2lzZVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiOG5cIiwgMC4wNSk7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTm9pc2VTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk5vaXNlU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5ub2lzZSA9IG5ldyBOb2lzZShPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSwgb3B0aW9ucy5ub2lzZSkpO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9LCBvcHRpb25zLmVudmVsb3BlKSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIG5vaXNlIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgdGhpcy5ub2lzZS5jaGFpbih0aGlzLmVudmVsb3BlLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4wLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBub2lzZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChOb2lzZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ3aGl0ZVwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3Blcy4gVW5saWtlIG90aGVyXG4gICAgICogaW5zdHJ1bWVudHMsIFRvbmUuTm9pc2VTeW50aCBkb2Vzbid0IGhhdmUgYSBub3RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9pc2VTeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogbm9pc2VTeW50aC50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyB0aGUgZW52ZWxvcGVzXG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBub2lzZVxuICAgICAgICB0aGlzLm5vaXNlLnN0YXJ0KHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLm5vaXNlLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVzLlxuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm5vaXNlLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAwKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2UoZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKHRpbWUgKyBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubm9pc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Tm9pc2VTeW50aC5qcy5tYXAiLCIvKipcbiAqIEFsbCBvZiB0aGUgY2xhc3NlcyBvciBmdW5jdGlvbnMgd2hpY2ggYXJlIGxvYWRlZCBpbnRvIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZVxuICovXG5jb25zdCB3b3JrbGV0Q29udGV4dCA9IG5ldyBTZXQoKTtcbi8qKlxuICogQWRkIGEgY2xhc3MgdG8gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRUb1dvcmtsZXQoY2xhc3NPckZ1bmN0aW9uKSB7XG4gICAgd29ya2xldENvbnRleHQuYWRkKGNsYXNzT3JGdW5jdGlvbik7XG59XG4vKipcbiAqIFJlZ2lzdGVyIGEgcHJvY2Vzc29yIGluIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSB3aXRoIHRoZSBnaXZlbiBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclByb2Nlc3NvcihuYW1lLCBjbGFzc0Rlc2MpIHtcbiAgICBjb25zdCBwcm9jZXNzb3IgPSAvKiBqYXZhc2NyaXB0ICovIGByZWdpc3RlclByb2Nlc3NvcihcIiR7bmFtZX1cIiwgJHtjbGFzc0Rlc2N9KWA7XG4gICAgd29ya2xldENvbnRleHQuYWRkKHByb2Nlc3Nvcik7XG59XG4vKipcbiAqIEdldCBhbGwgb2YgdGhlIG1vZHVsZXMgd2hpY2ggaGF2ZSBiZWVuIHJlZ2lzdGVyZWQgdG8gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3JrbGV0R2xvYmFsU2NvcGUoKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20od29ya2xldENvbnRleHQpLmpvaW4oXCJcXG5cIik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Xb3JrbGV0R2xvYmFsU2NvcGUuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGdldFdvcmtsZXRHbG9iYWxTY29wZSB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb1dvcmtsZXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb1dvcmtsZXRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjb25zdHJ1Y3RvciBvcHRpb25zIGZvciB0aGUgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy53b3JrbGV0T3B0aW9ucyA9IHt9O1xuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCB3aGVuIHRoZXJlIGlzIGFuIGVycm9yIGluIHRoZSBwcm9jZXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9ucHJvY2Vzc29yZXJyb3IgPSBub09wO1xuICAgICAgICBjb25zdCBibG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbZ2V0V29ya2xldEdsb2JhbFNjb3BlKCldLCB7IHR5cGU6IFwidGV4dC9qYXZhc2NyaXB0XCIgfSkpO1xuICAgICAgICBjb25zdCBuYW1lID0gdGhpcy5fYXVkaW9Xb3JrbGV0TmFtZSgpO1xuICAgICAgICB0aGlzLl9kdW1teUdhaW4gPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICB0aGlzLl9kdW1teVBhcmFtID0gdGhpcy5fZHVtbXlHYWluLmdhaW47XG4gICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBwcm9jZXNzb3JcbiAgICAgICAgdGhpcy5jb250ZXh0LmFkZEF1ZGlvV29ya2xldE1vZHVsZShibG9iVXJsLCBuYW1lKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgd29ya2xldCB3aGVuIGl0J3MgcmVhZFxuICAgICAgICAgICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd29ya2xldCA9IHRoaXMuY29udGV4dC5jcmVhdGVBdWRpb1dvcmtsZXROb2RlKG5hbWUsIHRoaXMud29ya2xldE9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQub25wcm9jZXNzb3JlcnJvciA9IHRoaXMub25wcm9jZXNzb3JlcnJvci5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgIHRoaXMub25SZWFkeSh0aGlzLl93b3JrbGV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZHVtbXlHYWluLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgaWYgKHRoaXMuX3dvcmtsZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQucG9ydC5wb3N0TWVzc2FnZShcImRpc3Bvc2VcIik7XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9Xb3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IGFkZFRvV29ya2xldCB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuY29uc3QgdG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHQvKipcblx0ICogVGhlIGJhc2UgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGZvciB1c2UgaW4gVG9uZS5qcy4gV29ya3Mgd2l0aCB0aGUgW1tUb25lQXVkaW9Xb3JrbGV0XV0uIFxuXHQgKi9cblx0Y2xhc3MgVG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG5cblx0XHRjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG5cdFx0XHRcblx0XHRcdHN1cGVyKG9wdGlvbnMpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiBJZiB0aGUgcHJvY2Vzc29yIHdhcyBkaXNwb3NlZCBvciBub3QuIEtlZXAgYWxpdmUgdW50aWwgaXQncyBkaXNwb3NlZC5cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5kaXNwb3NlZCA9IGZhbHNlO1xuXHRcdCAgIFx0LyoqIFxuXHRcdFx0ICogVGhlIG51bWJlciBvZiBzYW1wbGVzIGluIHRoZSBwcm9jZXNzaW5nIGJsb2NrXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMuYmxvY2tTaXplID0gMTI4O1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0aGUgc2FtcGxlIHJhdGVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTtcblxuXHRcdFx0dGhpcy5wb3J0Lm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xuXHRcdFx0XHQvLyB3aGVuIGl0IHJlY2VpdmVzIGEgZGlzcG9zZSBcblx0XHRcdFx0aWYgKGV2ZW50LmRhdGEgPT09IFwiZGlzcG9zZVwiKSB7XG5cdFx0XHRcdFx0dGhpcy5kaXNwb3NlZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHR9XG5gO1xuYWRkVG9Xb3JrbGV0KHRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3IpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCBcIi4vVG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvci53b3JrbGV0XCI7XG5pbXBvcnQgeyBhZGRUb1dvcmtsZXQgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCBzaW5nbGVJT1Byb2Nlc3MgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0LyoqXG5cdCAqIEFic3RyYWN0IGNsYXNzIGZvciBhIHNpbmdsZSBpbnB1dC9vdXRwdXQgcHJvY2Vzc29yLiBcblx0ICogaGFzIGEgJ2dlbmVyYXRlJyBmdW5jdGlvbiB3aGljaCBwcm9jZXNzZXMgb25lIHNhbXBsZSBhdCBhIHRpbWVcblx0ICovXG5cdGNsYXNzIFNpbmdsZUlPUHJvY2Vzc29yIGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG5cblx0XHRjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG5cdFx0XHRzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnMsIHtcblx0XHRcdFx0bnVtYmVyT2ZJbnB1dHM6IDEsXG5cdFx0XHRcdG51bWJlck9mT3V0cHV0czogMVxuXHRcdFx0fSkpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiBIb2xkcyB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGFuZCBhIHNpbmdsZSB2YWx1ZSBvZiB0aGF0XG5cdFx0XHQgKiBwYXJhbWV0ZXIgYXQgdGhlIGN1cnJlbnQgc2FtcGxlXG5cdFx0XHQgKiBAdHlwZSB7IFtuYW1lOiBzdHJpbmddOiBudW1iZXIgfVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnBhcmFtcyA9IHt9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogR2VuZXJhdGUgYW4gb3V0cHV0IHNhbXBsZSBmcm9tIHRoZSBpbnB1dCBzYW1wbGUgYW5kIHBhcmFtZXRlcnNcblx0XHQgKiBAYWJzdHJhY3Rcblx0XHQgKiBAcGFyYW0gaW5wdXQgbnVtYmVyXG5cdFx0ICogQHBhcmFtIGNoYW5uZWwgbnVtYmVyXG5cdFx0ICogQHBhcmFtIHBhcmFtZXRlcnMgeyBbbmFtZTogc3RyaW5nXTogbnVtYmVyIH1cblx0XHQgKiBAcmV0dXJucyBudW1iZXJcblx0XHQgKi9cblx0XHRnZW5lcmF0ZSgpe31cblxuXHRcdC8qKlxuXHRcdCAqIFVwZGF0ZSB0aGUgcHJpdmF0ZSBwYXJhbXMgb2JqZWN0IHdpdGggdGhlIFxuXHRcdCAqIHZhbHVlcyBvZiB0aGUgcGFyYW1ldGVycyBhdCB0aGUgZ2l2ZW4gaW5kZXhcblx0XHQgKiBAcGFyYW0gcGFyYW1ldGVycyB7IFtuYW1lOiBzdHJpbmddOiBGbG9hdDMyQXJyYXkgfSxcblx0XHQgKiBAcGFyYW0gaW5kZXggbnVtYmVyXG5cdFx0ICovXG5cdFx0dXBkYXRlUGFyYW1zKHBhcmFtZXRlcnMsIGluZGV4KSB7XG5cdFx0XHRmb3IgKGNvbnN0IHBhcmFtTmFtZSBpbiBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRcdGNvbnN0IHBhcmFtID0gcGFyYW1ldGVyc1twYXJhbU5hbWVdO1xuXHRcdFx0XHRpZiAocGFyYW0ubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRcdHRoaXMucGFyYW1zW3BhcmFtTmFtZV0gPSBwYXJhbWV0ZXJzW3BhcmFtTmFtZV1baW5kZXhdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMucGFyYW1zW3BhcmFtTmFtZV0gPSBwYXJhbWV0ZXJzW3BhcmFtTmFtZV1bMF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBQcm9jZXNzIGEgc2luZ2xlIGZyYW1lIG9mIHRoZSBhdWRpb1xuXHRcdCAqIEBwYXJhbSBpbnB1dHMgRmxvYXQzMkFycmF5W11bXVxuXHRcdCAqIEBwYXJhbSBvdXRwdXRzIEZsb2F0MzJBcnJheVtdW11cblx0XHQgKi9cblx0XHRwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykge1xuXHRcdFx0Y29uc3QgaW5wdXQgPSBpbnB1dHNbMF07XG5cdFx0XHRjb25zdCBvdXRwdXQgPSBvdXRwdXRzWzBdO1xuXHRcdFx0Ly8gZ2V0IHRoZSBwYXJhbWV0ZXIgdmFsdWVzXG5cdFx0XHRjb25zdCBjaGFubmVsQ291bnQgPSBNYXRoLm1heChpbnB1dCAmJiBpbnB1dC5sZW5ndGggfHwgMCwgb3V0cHV0Lmxlbmd0aCk7XG5cdFx0XHRmb3IgKGxldCBzYW1wbGUgPSAwOyBzYW1wbGUgPCB0aGlzLmJsb2NrU2l6ZTsgc2FtcGxlKyspIHtcblx0XHRcdFx0dGhpcy51cGRhdGVQYXJhbXMocGFyYW1ldGVycywgc2FtcGxlKTtcblx0XHRcdFx0Zm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBjaGFubmVsQ291bnQ7IGNoYW5uZWwrKykge1xuXHRcdFx0XHRcdGNvbnN0IGlucHV0U2FtcGxlID0gaW5wdXQgJiYgaW5wdXQubGVuZ3RoID8gaW5wdXRbY2hhbm5lbF1bc2FtcGxlXSA6IDA7XG5cdFx0XHRcdFx0b3V0cHV0W2NoYW5uZWxdW3NhbXBsZV0gPSB0aGlzLmdlbmVyYXRlKGlucHV0U2FtcGxlLCBjaGFubmVsLCB0aGlzLnBhcmFtcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiAhdGhpcy5kaXNwb3NlZDtcblx0XHR9XG5cdH07XG5gO1xuYWRkVG9Xb3JrbGV0KHNpbmdsZUlPUHJvY2Vzcyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IGFkZFRvV29ya2xldCB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuY29uc3QgZGVsYXlMaW5lID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdC8qKlxuXHQgKiBBIG11bHRpY2hhbm5lbCBidWZmZXIgZm9yIHVzZSB3aXRoaW4gYW4gQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGFzIGEgZGVsYXkgbGluZVxuXHQgKi9cblx0Y2xhc3MgRGVsYXlMaW5lIHtcblx0XHRcblx0XHRjb25zdHJ1Y3RvcihzaXplLCBjaGFubmVscykge1xuXHRcdFx0dGhpcy5idWZmZXIgPSBbXTtcblx0XHRcdHRoaXMud3JpdGVIZWFkID0gW11cblx0XHRcdHRoaXMuc2l6ZSA9IHNpemU7XG5cblx0XHRcdC8vIGNyZWF0ZSB0aGUgZW1wdHkgY2hhbm5lbHNcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbm5lbHM7IGkrKykge1xuXHRcdFx0XHR0aGlzLmJ1ZmZlcltpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaXplKTtcblx0XHRcdFx0dGhpcy53cml0ZUhlYWRbaV0gPSAwO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIFB1c2ggYSB2YWx1ZSBvbnRvIHRoZSBlbmRcblx0XHQgKiBAcGFyYW0gY2hhbm5lbCBudW1iZXJcblx0XHQgKiBAcGFyYW0gdmFsdWUgbnVtYmVyXG5cdFx0ICovXG5cdFx0cHVzaChjaGFubmVsLCB2YWx1ZSkge1xuXHRcdFx0dGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gKz0gMTtcblx0XHRcdGlmICh0aGlzLndyaXRlSGVhZFtjaGFubmVsXSA+IHRoaXMuc2l6ZSkge1xuXHRcdFx0XHR0aGlzLndyaXRlSGVhZFtjaGFubmVsXSA9IDA7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmJ1ZmZlcltjaGFubmVsXVt0aGlzLndyaXRlSGVhZFtjaGFubmVsXV0gPSB2YWx1ZTtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBHZXQgdGhlIHJlY29yZGVkIHZhbHVlIG9mIHRoZSBjaGFubmVsIGdpdmVuIHRoZSBkZWxheVxuXHRcdCAqIEBwYXJhbSBjaGFubmVsIG51bWJlclxuXHRcdCAqIEBwYXJhbSBkZWxheSBudW1iZXIgZGVsYXkgc2FtcGxlc1xuXHRcdCAqL1xuXHRcdGdldChjaGFubmVsLCBkZWxheSkge1xuXHRcdFx0bGV0IHJlYWRIZWFkID0gdGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gLSBNYXRoLmZsb29yKGRlbGF5KTtcblx0XHRcdGlmIChyZWFkSGVhZCA8IDApIHtcblx0XHRcdFx0cmVhZEhlYWQgKz0gdGhpcy5zaXplO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXMuYnVmZmVyW2NoYW5uZWxdW3JlYWRIZWFkXTtcblx0XHR9XG5cdH1cbmA7XG5hZGRUb1dvcmtsZXQoZGVsYXlMaW5lKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlbGF5TGluZS53b3JrbGV0LmpzLm1hcCIsImltcG9ydCBcIi4uLy4uL2NvcmUvd29ya2xldC9TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0XCI7XG5pbXBvcnQgXCIuLi8uLi9jb3JlL3dvcmtsZXQvRGVsYXlMaW5lLndvcmtsZXRcIjtcbmltcG9ydCB7IHJlZ2lzdGVyUHJvY2Vzc29yIH0gZnJvbSBcIi4uLy4uL2NvcmUvd29ya2xldC9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCB3b3JrbGV0TmFtZSA9IFwiZmVlZGJhY2stY29tYi1maWx0ZXJcIjtcbmNvbnN0IGZlZWRiYWNrQ29tYkZpbHRlciA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHRjbGFzcyBGZWVkYmFja0NvbWJGaWx0ZXJXb3JrbGV0IGV4dGVuZHMgU2luZ2xlSU9Qcm9jZXNzb3Ige1xuXG5cdFx0Y29uc3RydWN0b3Iob3B0aW9ucykge1xuXHRcdFx0c3VwZXIob3B0aW9ucyk7XG5cdFx0XHR0aGlzLmRlbGF5TGluZSA9IG5ldyBEZWxheUxpbmUodGhpcy5zYW1wbGVSYXRlLCBvcHRpb25zLmNoYW5uZWxDb3VudCB8fCAyKTtcblx0XHR9XG5cblx0XHRzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkge1xuXHRcdFx0cmV0dXJuIFt7XG5cdFx0XHRcdG5hbWU6IFwiZGVsYXlUaW1lXCIsXG5cdFx0XHRcdGRlZmF1bHRWYWx1ZTogMC4xLFxuXHRcdFx0XHRtaW5WYWx1ZTogMCxcblx0XHRcdFx0bWF4VmFsdWU6IDEsXG5cdFx0XHRcdGF1dG9tYXRpb25SYXRlOiBcImstcmF0ZVwiXG5cdFx0XHR9LCB7XG5cdFx0XHRcdG5hbWU6IFwiZmVlZGJhY2tcIixcblx0XHRcdFx0ZGVmYXVsdFZhbHVlOiAwLjUsXG5cdFx0XHRcdG1pblZhbHVlOiAwLFxuXHRcdFx0XHRtYXhWYWx1ZTogMC45OTk5LFxuXHRcdFx0XHRhdXRvbWF0aW9uUmF0ZTogXCJrLXJhdGVcIlxuXHRcdFx0fV07XG5cdFx0fVxuXG5cdFx0Z2VuZXJhdGUoaW5wdXQsIGNoYW5uZWwsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IGRlbGF5ZWRTYW1wbGUgPSB0aGlzLmRlbGF5TGluZS5nZXQoY2hhbm5lbCwgcGFyYW1ldGVycy5kZWxheVRpbWUgKiB0aGlzLnNhbXBsZVJhdGUpO1xuXHRcdFx0dGhpcy5kZWxheUxpbmUucHVzaChjaGFubmVsLCBpbnB1dCArIGRlbGF5ZWRTYW1wbGUgKiBwYXJhbWV0ZXJzLmZlZWRiYWNrKTtcblx0XHRcdHJldHVybiBkZWxheWVkU2FtcGxlO1xuXHRcdH1cblx0fVxuYDtcbnJlZ2lzdGVyUHJvY2Vzc29yKHdvcmtsZXROYW1lLCBmZWVkYmFja0NvbWJGaWx0ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tDb21iRmlsdGVyLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb1dvcmtsZXQgfSBmcm9tIFwiLi4vLi4vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXRcIjtcbmltcG9ydCB7IHdvcmtsZXROYW1lIH0gZnJvbSBcIi4vRmVlZGJhY2tDb21iRmlsdGVyLndvcmtsZXRcIjtcbi8qKlxuICogQ29tYiBmaWx0ZXJzIGFyZSBiYXNpYyBidWlsZGluZyBibG9ja3MgZm9yIHBoeXNpY2FsIG1vZGVsaW5nLiBSZWFkIG1vcmVcbiAqIGFib3V0IGNvbWIgZmlsdGVycyBvbiBbQ0NSTUEncyB3ZWJzaXRlXShodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9+am9zL3Bhc3AvRmVlZGJhY2tfQ29tYl9GaWx0ZXJzLmh0bWwpLlxuICpcbiAqIFRoaXMgY29tYiBmaWx0ZXIgaXMgaW1wbGVtZW50ZWQgd2l0aCB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB3aGljaCBhbGxvd3MgaXQgdG8gaGF2ZSBmZWVkYmFjayBkZWxheXMgbGVzcyB0aGFuIHRoZVxuICogV2ViIEF1ZGlvIHByb2Nlc3NpbmcgYmxvY2sgb2YgMTI4IHNhbXBsZXMuIFRoZXJlIGlzIGEgcG9seWZpbGwgZm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3QgeWV0IHN1cHBvcnQgdGhlXG4gKiBBdWRpb1dvcmtsZXROb2RlLCBidXQgaXQgd2lsbCBhZGQgc29tZSBsYXRlbmN5IGFuZCBoYXZlIHNsb3dlciBwZXJmb3JtYW5jZSB0aGFuIHRoZSBBdWRpb1dvcmtsZXROb2RlLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tDb21iRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZlZWRiYWNrQ29tYkZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcInJlc29uYW5jZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZlZWRiYWNrQ29tYkZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICBtaW5WYWx1ZTogMCxcbiAgICAgICAgICAgIG1heFZhbHVlOiAxLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlc29uYW5jZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yZXNvbmFuY2UsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyZXNvbmFuY2VcIiwgXCJkZWxheVRpbWVcIl0pO1xuICAgIH1cbiAgICBfYXVkaW9Xb3JrbGV0TmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHdvcmtsZXROYW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG4gICAgICovXG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMC4xLFxuICAgICAgICAgICAgcmVzb25hbmNlOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBvblJlYWR5KG5vZGUpIHtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCBub2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbnN0IGRlbGF5VGltZSA9IG5vZGUucGFyYW1ldGVycy5nZXQoXCJkZWxheVRpbWVcIik7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuc2V0UGFyYW0oZGVsYXlUaW1lKTtcbiAgICAgICAgY29uc3QgZmVlZGJhY2sgPSBub2RlLnBhcmFtZXRlcnMuZ2V0KFwiZmVlZGJhY2tcIik7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2Uuc2V0UGFyYW0oZmVlZGJhY2spO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0NvbWJGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG4vKipcbiAqIEEgb25lIHBvbGUgZmlsdGVyIHdpdGggNmRiLXBlci1vY3RhdmUgcm9sbG9mZi4gRWl0aGVyIFwiaGlnaHBhc3NcIiBvciBcImxvd3Bhc3NcIi5cbiAqIE5vdGUgdGhhdCBjaGFuZ2luZyB0aGUgdHlwZSBvciBmcmVxdWVuY3kgbWF5IHJlc3VsdCBpbiBhIGRpc2NvbnRpbnVpdHkgd2hpY2hcbiAqIGNhbiBzb3VuZCBsaWtlIGEgY2xpY2sgb3IgcG9wLlxuICogUmVmZXJlbmNlczpcbiAqICogaHR0cDovL3d3dy5lYXJsZXZlbC5jb20vbWFpbi8yMDEyLzEyLzE1L2Etb25lLXBvbGUtZmlsdGVyL1xuICogKiBodHRwOi8vd3d3LmRzcGd1aWRlLmNvbS9jaDE5LzIuaHRtXG4gKiAqIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRhbGl5LWJvYnJvdi9qcy1yb2Nrcy9ibG9iL21hc3Rlci9zcmMvYXBwL2F1ZGlvL2VmZmVjdHMvb25lLXBvbGUtZmlsdGVycy50c1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgT25lUG9sZUZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPbmVQb2xlRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9uZVBvbGVGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE9uZVBvbGVGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gb3B0aW9ucy5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDg4MCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBmaWx0ZXIgYW5kIGRpc3Bvc2UgdGhlIG9sZCBvbmVcbiAgICAgKi9cbiAgICBfY3JlYXRlRmlsdGVyKCkge1xuICAgICAgICBjb25zdCBvbGRGaWx0ZXIgPSB0aGlzLl9maWx0ZXI7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KHRoaXMuX2ZyZXF1ZW5jeSk7XG4gICAgICAgIGNvbnN0IHQgPSAxIC8gKDIgKiBNYXRoLlBJICogZnJlcSk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcImxvd3Bhc3NcIikge1xuICAgICAgICAgICAgY29uc3QgYTAgPSAxIC8gKHQgKiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICBjb25zdCBiMSA9IGEwIC0gMTtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoW2EwLCAwXSwgWzEsIGIxXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBiMSA9IDEgLyAodCAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKSAtIDE7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKFsxLCAtMV0sIFsxLCBiMV0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fZmlsdGVyLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGlmIChvbGRGaWx0ZXIpIHtcbiAgICAgICAgICAgIC8vIGRpc3Bvc2UgaXQgb24gdGhlIG5leHQgYmxvY2tcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KG9sZEZpbHRlcik7XG4gICAgICAgICAgICAgICAgICAgIG9sZEZpbHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgdGhpcy5ibG9ja1RpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IGZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGZyZXF1ZW5jeShmcSkge1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBmcTtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBPbmVQb2xlIEZpbHRlciB0eXBlLCBlaXRoZXIgXCJoaWdocGFzc1wiIG9yIFwibG93cGFzc1wiXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0KSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0O1xuICAgICAgICB0aGlzLl9jcmVhdGVGaWx0ZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUuIFRoaXMgY3VydmUgcmVwcmVzZW50cyBob3cgdGhlIGZpbHRlclxuICAgICAqIHJlc3BvbnNlcyB0byBmcmVxdWVuY2llcyBiZXR3ZWVuIDIwaHotMjBraHouXG4gICAgICogQHBhcmFtICBsZW4gVGhlIG51bWJlciBvZiB2YWx1ZXMgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlIGJldHdlZW4gMjAtMjBrSHpcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShsZW4gPSAxMjgpIHtcbiAgICAgICAgY29uc3QgZnJlcVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybSA9IE1hdGgucG93KGkgLyBsZW4sIDIpO1xuICAgICAgICAgICAgY29uc3QgZnJlcSA9IG5vcm0gKiAoMjAwMDAgLSAyMCkgKyAyMDtcbiAgICAgICAgICAgIGZyZXFWYWx1ZXNbaV0gPSBmcmVxO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hZ1ZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgY29uc3QgcGhhc2VWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIHRoaXMuX2ZpbHRlci5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxVmFsdWVzLCBtYWdWYWx1ZXMsIHBoYXNlVmFsdWVzKTtcbiAgICAgICAgcmV0dXJuIG1hZ1ZhbHVlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PbmVQb2xlRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRmVlZGJhY2tDb21iRmlsdGVyIH0gZnJvbSBcIi4vRmVlZGJhY2tDb21iRmlsdGVyXCI7XG5pbXBvcnQgeyBPbmVQb2xlRmlsdGVyIH0gZnJvbSBcIi4vT25lUG9sZUZpbHRlclwiO1xuLyoqXG4gKiBBIGxvd3Bhc3MgZmVlZGJhY2sgY29tYiBmaWx0ZXIuIEl0IGlzIHNpbWlsYXIgdG9cbiAqIFtbRmVlZGJhY2tDb21iRmlsdGVyXV0sIGJ1dCBpbmNsdWRlcyBhIGxvd3Bhc3MgZmlsdGVyLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTG93cGFzc0NvbWJGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTG93cGFzc0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIiwgXCJkYW1wZW5pbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMb3dwYXNzQ29tYkZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTG93cGFzc0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIiwgXCJkYW1wZW5pbmdcIl0pO1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVyID0gdGhpcy5vdXRwdXQgPSBuZXcgRmVlZGJhY2tDb21iRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICByZXNvbmFuY2U6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9jb21iRmlsdGVyLmRlbGF5VGltZTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSB0aGlzLl9jb21iRmlsdGVyLnJlc29uYW5jZTtcbiAgICAgICAgdGhpcy5fbG93cGFzcyA9IHRoaXMuaW5wdXQgPSBuZXcgT25lUG9sZUZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZGFtcGVuaW5nLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmNvbm5lY3QodGhpcy5fY29tYkZpbHRlcik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkYW1wZW5pbmc6IDMwMDAsXG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRhbXBlbmluZyBjb250cm9sIG9mIHRoZSBmZWVkYmFja1xuICAgICAqL1xuICAgIGdldCBkYW1wZW5pbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhmcSkge1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeSA9IGZxO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TG93cGFzc0NvbWJGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgTG93cGFzc0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOb2lzZSB9IGZyb20gXCIuLi9zb3VyY2UvTm9pc2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG4vKipcbiAqIEthcnBsdXMtU3RyaW5nIHN0cmluZyBzeW50aGVzaXMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGx1Y2t5ID0gbmV3IFRvbmUuUGx1Y2tTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzRcIiwgXCIrMC41XCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDM1wiLCBcIisxXCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDMlwiLCBcIisxLjVcIik7XG4gKiBwbHVja3kudHJpZ2dlckF0dGFjayhcIkMxXCIsIFwiKzJcIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgUGx1Y2tTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQbHVja1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsdWNrU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsdWNrU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fbm9pc2UgPSBuZXcgTm9pc2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJwaW5rXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXR0YWNrTm9pc2UgPSBvcHRpb25zLmF0dGFja05vaXNlO1xuICAgICAgICB0aGlzLl9sZmNmID0gbmV3IExvd3Bhc3NDb21iRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRhbXBlbmluZzogb3B0aW9ucy5kYW1wZW5pbmcsXG4gICAgICAgICAgICByZXNvbmFuY2U6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSBvcHRpb25zLnJlc29uYW5jZTtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLl9ub2lzZS5jb25uZWN0KHRoaXMuX2xmY2YpO1xuICAgICAgICB0aGlzLl9sZmNmLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2tOb2lzZTogMSxcbiAgICAgICAgICAgIGRhbXBlbmluZzogNDAwMCxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC43LFxuICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkYW1wZW5pbmcgY29udHJvbC4gaS5lLiB0aGUgbG93cGFzcyBmaWx0ZXIgZnJlcXVlbmN5IG9mIHRoZSBjb21iIGZpbHRlclxuICAgICAqIEBtaW4gMFxuICAgICAqIEBtYXggNzAwMFxuICAgICAqL1xuICAgIGdldCBkYW1wZW5pbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZmNmLmRhbXBlbmluZztcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhmcSkge1xuICAgICAgICB0aGlzLl9sZmNmLmRhbXBlbmluZyA9IGZxO1xuICAgIH1cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZnJlcSA9IHRoaXMudG9GcmVxdWVuY3kobm90ZSk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgZGVsYXlBbW91bnQgPSAxIC8gZnJlcTtcbiAgICAgICAgdGhpcy5fbGZjZi5kZWxheVRpbWUuc2V0VmFsdWVBdFRpbWUoZGVsYXlBbW91bnQsIHRpbWUpO1xuICAgICAgICB0aGlzLl9ub2lzZS5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbm9pc2Uuc3RvcCh0aW1lICsgZGVsYXlBbW91bnQgKiB0aGlzLmF0dGFja05vaXNlKTtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2UuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICB0aGlzLl9sZmNmLnJlc29uYW5jZS5zZXRWYWx1ZUF0VGltZSh0aGlzLnJlc29uYW5jZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSYW1wIGRvd24gdGhlIFtbcmVzb25hbmNlXV0gdG8gMCBvdmVyIHRoZSBkdXJhdGlvbiBvZiB0aGUgcmVsZWFzZSB0aW1lLlxuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2UubGluZWFyUmFtcFRvKDAsIHRoaXMucmVsZWFzZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vaXNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZjZi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBsdWNrU3ludGguanMubWFwIiwiaW1wb3J0IHsgTWlkaUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9NaWRpXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyBTeW50aCB9IGZyb20gXCIuL1N5bnRoXCI7XG5pbXBvcnQgeyBhc3NlcnQsIHdhcm4gfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFBvbHlTeW50aCBoYW5kbGVzIHZvaWNlIGNyZWF0aW9uIGFuZCBhbGxvY2F0aW9uIGZvciBhbnlcbiAqIGluc3RydW1lbnRzIHBhc3NlZCBpbiBhcyB0aGUgc2Vjb25kIHBhcmFtdGVyLiBQb2x5U3ludGggaXNcbiAqIG5vdCBhIHN5bnRoZXNpemVyIGJ5IGl0c2VsZiwgaXQgbWVyZWx5IG1hbmFnZXMgdm9pY2VzIG9mXG4gKiBvbmUgb2YgdGhlIG90aGVyIHR5cGVzIG9mIHN5bnRocywgYWxsb3dpbmcgYW55IG9mIHRoZVxuICogbW9ub3Bob25pYyBzeW50aGVzaXplcnMgdG8gYmUgcG9seXBob25pYy5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBzZXQgdGhlIGF0dHJpYnV0ZXMgYWNyb3NzIGFsbCB0aGUgdm9pY2VzIHVzaW5nICdzZXQnXG4gKiBzeW50aC5zZXQoeyBkZXR1bmU6IC0xMjAwIH0pO1xuICogLy8gcGxheSBhIGNob3JkXG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDNFwiLCBcIkU0XCIsIFwiQTRcIl0sIDEpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBvbHlTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQb2x5U3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2ljZVwiLCBcIm9wdGlvbnNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQb2x5U3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2b2ljZXMgd2hpY2ggYXJlIG5vdCBjdXJyZW50bHkgaW4gdXNlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIHZvaWNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGFsbG9jYXRlZCB2b2ljZXMgZm9yIHRoaXMgc3ludGguXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl92b2ljZXMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBHQyB0aW1lb3V0LiBIZWxkIHNvIHRoYXQgaXQgY291bGQgYmUgY2FuY2VsbGVkIHdoZW4gdGhlIG5vZGUgaXMgZGlzcG9zZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nY1RpbWVvdXQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgbW92aW5nIGF2ZXJhZ2Ugb2YgdGhlIG51bWJlciBvZiBhY3RpdmUgdm9pY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvbHlTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvaWNlXCIsIFwib3B0aW9uc1wiXSk7XG4gICAgICAgIC8vIGNoZWNrIGFnYWluc3QgdGhlIG9sZCBBUEkgKHByZSAxNC4zLjApXG4gICAgICAgIGFzc2VydCghaXNOdW1iZXIob3B0aW9ucy52b2ljZSksIFwiREVQUkVDQVRFRDogVGhlIHBvbHlwaG9ueSBjb3VudCBpcyBubyBsb25nZXIgdGhlIGZpcnN0IGFyZ3VtZW50LlwiKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSBvcHRpb25zLnZvaWNlLmdldERlZmF1bHRzKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdHMsIG9wdGlvbnMub3B0aW9ucyk7XG4gICAgICAgIHRoaXMudm9pY2UgPSBvcHRpb25zLnZvaWNlO1xuICAgICAgICB0aGlzLm1heFBvbHlwaG9ueSA9IG9wdGlvbnMubWF4UG9seXBob255O1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGZpcnN0IHZvaWNlXG4gICAgICAgIHRoaXMuX2R1bW15Vm9pY2UgPSB0aGlzLl9nZXROZXh0QXZhaWxhYmxlVm9pY2UoKTtcbiAgICAgICAgLy8gcmVtb3ZlIGl0IGZyb20gdGhlIHZvaWNlcyBsaXN0XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdm9pY2VzLmluZGV4T2YodGhpcy5fZHVtbXlWb2ljZSk7XG4gICAgICAgIHRoaXMuX3ZvaWNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAvLyBraWNrIG9mZiB0aGUgR0MgaW50ZXJ2YWxcbiAgICAgICAgdGhpcy5fZ2NUaW1lb3V0ID0gdGhpcy5jb250ZXh0LnNldEludGVydmFsKHRoaXMuX2NvbGxlY3RHYXJiYWdlLmJpbmQodGhpcyksIDEpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4UG9seXBob255OiAzMixcbiAgICAgICAgICAgIG9wdGlvbnM6IHt9LFxuICAgICAgICAgICAgdm9pY2U6IFN5bnRoLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBhY3RpdmUgdm9pY2VzLlxuICAgICAqL1xuICAgIGdldCBhY3RpdmVWb2ljZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmVWb2ljZXMubGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIHdoZW4gdGhlIHNvdXJjZSBpcyBkb25lIG1ha2luZyBzb3VuZCwgc28gdGhhdCBpdCBjYW4gYmVcbiAgICAgKiByZWFkZGVkIHRvIHRoZSBwb29sIG9mIGF2YWlsYWJsZSB2b2ljZXNcbiAgICAgKi9cbiAgICBfbWFrZVZvaWNlQXZhaWxhYmxlKHZvaWNlKSB7XG4gICAgICAgIHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5wdXNoKHZvaWNlKTtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBtaWRpIG5vdGUgZnJvbSAnYWN0aXZlIHZvaWNlcydcbiAgICAgICAgY29uc3QgYWN0aXZlVm9pY2VJbmRleCA9IHRoaXMuX2FjdGl2ZVZvaWNlcy5maW5kSW5kZXgoKGUpID0+IGUudm9pY2UgPT09IHZvaWNlKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzLnNwbGljZShhY3RpdmVWb2ljZUluZGV4LCAxKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFuIGF2YWlsYWJsZSB2b2ljZSBmcm9tIHRoZSBwb29sIG9mIGF2YWlsYWJsZSB2b2ljZXMuXG4gICAgICogSWYgb25lIGlzIG5vdCBhdmFpbGFibGUgYW5kIHRoZSBtYXhQb2x5cGhvbnkgbGltaXQgaXMgcmVhY2hlZCxcbiAgICAgKiBzdGVhbCBhIHZvaWNlLCBvdGhlcndpc2UgcmV0dXJuIG51bGwuXG4gICAgICovXG4gICAgX2dldE5leHRBdmFpbGFibGVWb2ljZSgpIHtcbiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGF2YWlsYWJsZSB2b2ljZXMsIHJldHVybiB0aGUgZmlyc3Qgb25lXG4gICAgICAgIGlmICh0aGlzLl9hdmFpbGFibGVWb2ljZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXZhaWxhYmxlVm9pY2VzLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdm9pY2VzLmxlbmd0aCA8IHRoaXMubWF4UG9seXBob255KSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgdGhlcmUgaXMgc3RpbGwgbW9yZSBtYXhQb2x5cGhvbnksIG1ha2UgYSBuZXcgdm9pY2VcbiAgICAgICAgICAgIGNvbnN0IHZvaWNlID0gbmV3IHRoaXMudm9pY2UoT2JqZWN0LmFzc2lnbih0aGlzLm9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgb25zaWxlbmNlOiB0aGlzLl9tYWtlVm9pY2VBdmFpbGFibGUuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIHZvaWNlLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fdm9pY2VzLnB1c2godm9pY2UpO1xuICAgICAgICAgICAgcmV0dXJuIHZvaWNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgd2FybihcIk1heCBwb2x5cGhvbnkgZXhjZWVkZWQuIE5vdGUgZHJvcHBlZC5cIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogT2NjYXNpb25hbGx5IGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgYWxsb2NhdGVkIHZvaWNlcyB3aGljaCBjYW4gYmUgY2xlYW5lZCB1cC5cbiAgICAgKi9cbiAgICBfY29sbGVjdEdhcmJhZ2UoKSB7XG4gICAgICAgIHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgPSBNYXRoLm1heCh0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzICogMC45NSwgdGhpcy5hY3RpdmVWb2ljZXMpO1xuICAgICAgICBpZiAodGhpcy5fYXZhaWxhYmxlVm9pY2VzLmxlbmd0aCAmJiB0aGlzLl92b2ljZXMubGVuZ3RoID4gTWF0aC5jZWlsKHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgKyAxKSkge1xuICAgICAgICAgICAgLy8gdGFrZSBvZmYgYW4gYXZhaWxhYmxlIG5vdGVcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0QXZhaWwgPSB0aGlzLl9hdmFpbGFibGVWb2ljZXMuc2hpZnQoKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdm9pY2VzLmluZGV4T2YoZmlyc3RBdmFpbCk7XG4gICAgICAgICAgICB0aGlzLl92b2ljZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZXh0LmlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgIGZpcnN0QXZhaWwuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB3aGljaCB0cmlnZ2VycyB0aGUgYXR0YWNrXG4gICAgICovXG4gICAgX3RyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpTm90ZSA9IG5ldyBNaWRpQ2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIGNvbnN0IHZvaWNlID0gdGhpcy5fZ2V0TmV4dEF2YWlsYWJsZVZvaWNlKCk7XG4gICAgICAgICAgICBpZiAodm9pY2UpIHtcbiAgICAgICAgICAgICAgICB2b2ljZS50cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIG1pZGk6IG1pZGlOb3RlLCB2b2ljZSwgcmVsZWFzZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCBub3RlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB3aGljaCB0cmlnZ2VycyB0aGUgcmVsZWFzZVxuICAgICAqL1xuICAgIF90cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSkge1xuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaU5vdGUgPSBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2FjdGl2ZVZvaWNlcy5maW5kKCh7IG1pZGksIHJlbGVhc2VkIH0pID0+IG1pZGkgPT09IG1pZGlOb3RlICYmICFyZWxlYXNlZCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIHJlbGVhc2Ugb24gdGhhdCBub3RlXG4gICAgICAgICAgICAgICAgZXZlbnQudm9pY2UudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgICAgICAgICAgLy8gbWFyayBpdCBhcyByZWxlYXNlZFxuICAgICAgICAgICAgICAgIGV2ZW50LnJlbGVhc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIG5vdGUsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgdGhlIGF0dGFjay9yZWxlYXNlIGV2ZW50cy4gSWYgdGhlIHRpbWUgaXMgaW4gdGhlIGZ1dHVyZSwgdGhlbiBpdCBzaG91bGQgc2V0IGEgdGltZW91dFxuICAgICAqIHRvIHdhaXQgZm9yIGp1c3QtaW4tdGltZSBzY2hlZHVsaW5nXG4gICAgICovXG4gICAgX3NjaGVkdWxlRXZlbnQodHlwZSwgbm90ZXMsIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5kaXNwb3NlZCwgXCJTeW50aCB3YXMgYWxyZWFkeSBkaXNwb3NlZFwiKTtcbiAgICAgICAgLy8gaWYgdGhlIG5vdGVzIGFyZSBncmVhdGVyIHRoYW4gdGhpcyBhbW91bnQgb2YgdGltZSBpbiB0aGUgZnV0dXJlLCB0aGV5IHNob3VsZCBiZSBzY2hlZHVsZWQgd2l0aCBzZXRUaW1lb3V0XG4gICAgICAgIGlmICh0aW1lIDw9IHRoaXMubm93KCkpIHtcbiAgICAgICAgICAgIC8vIGRvIGl0IGltbWVkaWF0ZWx5XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gXCJhdHRhY2tcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJSZWxlYXNlKG5vdGVzLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNjaGVkdWxlIGl0IHRvIHN0YXJ0IGluIHRoZSBmdXR1cmVcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KHR5cGUsIG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICB9LCB0aW1lIC0gdGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKiBAcGFyYW0gIG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSBzdGFydCB0aW1lIG9mIHRoZSBub3RlLlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIG5vdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aChUb25lLkZNU3ludGgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyB0cmlnZ2VyIGEgY2hvcmQgaW1tZWRpYXRlbHkgd2l0aCBhIHZlbG9jaXR5IG9mIDAuMlxuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soW1wiQWIzXCIsIFwiQzRcIiwgXCJGNVwiXSwgVG9uZS5ub3coKSwgMC4yKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG4gICAgICAgICAgICBub3RlcyA9IFtub3Rlc107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlRXZlbnQoXCJhdHRhY2tcIiwgbm90ZXMsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgbm90ZS4gVW5saWtlIG1vbm9waG9uaWMgaW5zdHJ1bWVudHMsXG4gICAgICogYSBub3RlIChvciBhcnJheSBvZiBub3RlcykgbmVlZHMgdG8gYmUgcGFzc2VkIGluIGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiAgICAgKiBAcGFyYW0gIG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdGhlIHJlbGVhc2Ugd2lsbCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvbHkgPSBuZXcgVG9uZS5Qb2x5U3ludGgoVG9uZS5BTVN5bnRoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcG9seS50cmlnZ2VyQXR0YWNrKFtcIkFiM1wiLCBcIkM0XCIsIFwiRjVcIl0pO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2Ugb2YgdGhlIGdpdmVuIG5vdGVzLlxuICAgICAqIHBvbHkudHJpZ2dlclJlbGVhc2UoW1wiQWIzXCIsIFwiQzRcIl0sIFwiKzFcIik7XG4gICAgICogcG9seS50cmlnZ2VyUmVsZWFzZShcIkY1XCIsIFwiKzNcIik7XG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KFwicmVsZWFzZVwiLCBub3RlcywgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSBhZnRlciB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uXG4gICAgICogQHBhcmFtICBub3RlcyBUaGUgbm90ZXMgdG8gcGxheS4gQWNjZXB0cyBhIHNpbmdsZSAgRnJlcXVlbmN5IG9yIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gdGhlIGR1cmF0aW9uIG9mIHRoZSBub3RlXG4gICAgICogQHBhcmFtICB0aW1lICBpZiBubyB0aW1lIGlzIGdpdmVuLCBkZWZhdWx0cyB0byBub3dcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgYXR0YWNrICgwLTEpXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2x5ID0gbmV3IFRvbmUuUG9seVN5bnRoKFRvbmUuQU1TeW50aCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIGNhbiBwYXNzIGluIGFuIGFycmF5IG9mIGR1cmF0aW9ucyBhcyB3ZWxsXG4gICAgICogcG9seS50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJFYjNcIiwgXCJHNFwiLCBcIkJiNFwiLCBcIkQ1XCJdLCBbNCwgMywgMiwgMV0pO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGVzLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayhub3RlcywgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmIChpc0FycmF5KGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzQXJyYXkobm90ZXMpLCBcIklmIHRoZSBkdXJhdGlvbiBpcyBhbiBhcnJheSwgdGhlIG5vdGVzIG11c3QgYWxzbyBiZSBhbiBhcnJheVwiKTtcbiAgICAgICAgICAgIG5vdGVzID0gbm90ZXM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vdGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IGR1cmF0aW9uW01hdGgubWluKGksIGR1cmF0aW9uLmxlbmd0aCAtIDEpXTtcbiAgICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvblNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyhkKTtcbiAgICAgICAgICAgICAgICBhc3NlcnQoZHVyYXRpb25TZWNvbmRzID4gMCwgXCJUaGUgZHVyYXRpb24gbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzW2ldLCBjb21wdXRlZFRpbWUgKyBkdXJhdGlvblNlY29uZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAgICAgYXNzZXJ0KGR1cmF0aW9uU2Vjb25kcyA+IDAsIFwiVGhlIGR1cmF0aW9uIG11c3QgYmUgZ3JlYXRlciB0aGFuIDBcIik7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzLCBjb21wdXRlZFRpbWUgKyBkdXJhdGlvblNlY29uZHMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgYSBtZW1iZXIvYXR0cmlidXRlIG9mIHRoZSB2b2ljZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvbHkgPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gc2V0IGFsbCBvZiB0aGUgdm9pY2VzIHVzaW5nIGFuIG9wdGlvbnMgb2JqZWN0IGZvciB0aGUgc3ludGggdHlwZVxuICAgICAqIHBvbHkuc2V0KHtcbiAgICAgKiBcdGVudmVsb3BlOiB7XG4gICAgICogXHRcdGF0dGFjazogMC4yNVxuICAgICAqIFx0fVxuICAgICAqIH0pO1xuICAgICAqIHBvbHkudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJCYjNcIiwgMC4yKTtcbiAgICAgKi9cbiAgICBzZXQob3B0aW9ucykge1xuICAgICAgICAvLyByZW1vdmUgb3B0aW9ucyB3aGljaCBhcmUgY29udHJvbGxlZCBieSB0aGUgUG9seVN5bnRoXG4gICAgICAgIGNvbnN0IHNhbml0aXplZE9wdGlvbnMgPSBvbWl0RnJvbU9iamVjdChvcHRpb25zLCBbXCJvbnNpbGVuY2VcIiwgXCJjb250ZXh0XCJdKTtcbiAgICAgICAgLy8gc3RvcmUgYWxsIG9mIHRoZSBvcHRpb25zXG4gICAgICAgIHRoaXMub3B0aW9ucyA9IGRlZXBNZXJnZSh0aGlzLm9wdGlvbnMsIHNhbml0aXplZE9wdGlvbnMpO1xuICAgICAgICB0aGlzLl92b2ljZXMuZm9yRWFjaCh2b2ljZSA9PiB2b2ljZS5zZXQoc2FuaXRpemVkT3B0aW9ucykpO1xuICAgICAgICB0aGlzLl9kdW1teVZvaWNlLnNldChzYW5pdGl6ZWRPcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2R1bW15Vm9pY2UuZ2V0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiBhbGwgdGhlIGN1cnJlbnRseSBhY3RpdmUgdm9pY2VzIGltbWVkaWF0ZWx5LlxuICAgICAqIFVzZWZ1bCBmb3Igc2lsZW5jaW5nIHRoZSBzeW50aC5cbiAgICAgKi9cbiAgICByZWxlYXNlQWxsKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcy5mb3JFYWNoKCh7IHZvaWNlIH0pID0+IHtcbiAgICAgICAgICAgIHZvaWNlLnRyaWdnZXJSZWxlYXNlKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kdW1teVZvaWNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9pY2VzLmZvckVhY2godiA9PiB2LmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcyA9IFtdO1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMgPSBbXTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFySW50ZXJ2YWwodGhpcy5fZ2NUaW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UG9seVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlcnMgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnNcIjtcbmltcG9ydCB7IGZ0b21mLCBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8gfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNOb3RlLCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4uL2luc3RydW1lbnQvSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFBhc3MgaW4gYW4gb2JqZWN0IHdoaWNoIG1hcHMgdGhlIG5vdGUncyBwaXRjaCBvciBtaWRpIHZhbHVlIHRvIHRoZSB1cmwsXG4gKiB0aGVuIHlvdSBjYW4gdHJpZ2dlciB0aGUgYXR0YWNrIGFuZCByZWxlYXNlIG9mIHRoYXQgbm90ZSBsaWtlIG90aGVyIGluc3RydW1lbnRzLlxuICogQnkgYXV0b21hdGljYWxseSByZXBpdGNoaW5nIHRoZSBzYW1wbGVzLCBpdCBpcyBwb3NzaWJsZSB0byBwbGF5IHBpdGNoZXMgd2hpY2hcbiAqIHdlcmUgbm90IGV4cGxpY2l0bHkgaW5jbHVkZWQgd2hpY2ggY2FuIHNhdmUgbG9hZGluZyB0aW1lLlxuICpcbiAqIEZvciBzYW1wbGUgb3IgYnVmZmVyIHBsYXliYWNrIHdoZXJlIHJlcGl0Y2hpbmcgaXMgbm90IG5lY2Vzc2FyeSxcbiAqIHVzZSBbW1BsYXllcl1dLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNhbXBsZXIgPSBuZXcgVG9uZS5TYW1wbGVyKHtcbiAqIFx0dXJsczoge1xuICogXHRcdEExOiBcIkExLm1wM1wiLFxuICogXHRcdEEyOiBcIkEyLm1wM1wiLFxuICogXHR9LFxuICogXHRiYXNlVXJsOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9cIixcbiAqIFx0b25sb2FkOiAoKSA9PiB7XG4gKiBcdFx0c2FtcGxlci50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDMVwiLCBcIkUxXCIsIFwiRzFcIiwgXCJCMVwiXSwgMC41KTtcbiAqIFx0fVxuICogfSkudG9EZXN0aW5hdGlvbigpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNhbXBsZXIgZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2FtcGxlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIiwgXCJiYXNlVXJsXCJdLCBcInVybHNcIikpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNhbXBsZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvYmplY3Qgb2YgYWxsIGN1cnJlbnRseSBwbGF5aW5nIEJ1ZmZlclNvdXJjZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTYW1wbGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiLCBcImJhc2VVcmxcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgY29uc3QgdXJsTWFwID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMudXJscykuZm9yRWFjaCgobm90ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm90ZU51bWJlciA9IHBhcnNlSW50KG5vdGUsIDEwKTtcbiAgICAgICAgICAgIGFzc2VydChpc05vdGUobm90ZSlcbiAgICAgICAgICAgICAgICB8fCAoaXNOdW1iZXIobm90ZU51bWJlcikgJiYgaXNGaW5pdGUobm90ZU51bWJlcikpLCBgdXJsIGtleSBpcyBuZWl0aGVyIGEgbm90ZSBvciBtaWRpIHBpdGNoOiAke25vdGV9YCk7XG4gICAgICAgICAgICBpZiAoaXNOb3RlKG5vdGUpKSB7XG4gICAgICAgICAgICAgICAgLy8gY29udmVydCB0aGUgbm90ZSBuYW1lIHRvIE1JRElcbiAgICAgICAgICAgICAgICBjb25zdCBtaWQgPSBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgICAgICB1cmxNYXBbbWlkXSA9IG9wdGlvbnMudXJsc1tub3RlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzTnVtYmVyKG5vdGVOdW1iZXIpICYmIGlzRmluaXRlKG5vdGVOdW1iZXIpKSB7XG4gICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGlmIGl0J3MgbnVtYmVycyBhc3N1bWUgaXQncyBtaWRpXG4gICAgICAgICAgICAgICAgdXJsTWFwW25vdGVOdW1iZXJdID0gb3B0aW9ucy51cmxzW25vdGVOdW1iZXJdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IG5ldyBUb25lQXVkaW9CdWZmZXJzKHtcbiAgICAgICAgICAgIHVybHM6IHVybE1hcCxcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmJhc2VVcmwsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFjayA9IG9wdGlvbnMuYXR0YWNrO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBvcHRpb25zLnJlbGVhc2U7XG4gICAgICAgIHRoaXMuY3VydmUgPSBvcHRpb25zLmN1cnZlO1xuICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrIGlmIGl0J3MgYWxyZWFkeSBsb2FkZWRcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcnMubG9hZGVkKSB7XG4gICAgICAgICAgICAvLyBpbnZva2Ugb25sb2FkIGRlZmVycmVkXG4gICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKG9wdGlvbnMub25sb2FkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLFxuICAgICAgICAgICAgYmFzZVVybDogXCJcIixcbiAgICAgICAgICAgIGN1cnZlOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcmVsZWFzZTogMC4xLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGluIHN0ZXBzIGJldHdlZW4gdGhlIGdpdmVuIG1pZGkgbm90ZSBhdCB0aGUgY2xvc2V0cyBzYW1wbGUuXG4gICAgICovXG4gICAgX2ZpbmRDbG9zZXN0KG1pZGkpIHtcbiAgICAgICAgLy8gc2VhcmNoZXMgd2l0aGluIDggb2N0YXZlcyBvZiB0aGUgZ2l2ZW4gbWlkaSBub3RlXG4gICAgICAgIGNvbnN0IE1BWF9JTlRFUlZBTCA9IDk2O1xuICAgICAgICBsZXQgaW50ZXJ2YWwgPSAwO1xuICAgICAgICB3aGlsZSAoaW50ZXJ2YWwgPCBNQVhfSU5URVJWQUwpIHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGFib3ZlIGFuZCBiZWxvd1xuICAgICAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcnMuaGFzKG1pZGkgKyBpbnRlcnZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gLWludGVydmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fYnVmZmVycy5oYXMobWlkaSAtIGludGVydmFsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcnZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGludGVydmFsKys7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBhdmFpbGFibGUgYnVmZmVycyBmb3Igbm90ZTogJHttaWRpfWApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gIG5vdGVzXHRUaGUgbm90ZSB0byBwbGF5LCBvciBhbiBhcnJheSBvZiBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgIFdoZW4gdG8gcGxheSB0aGUgbm90ZVxuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRvIHBsYXkgdGhlIHNhbXBsZSBiYWNrLlxuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgbm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpRmxvYXQgPSBmdG9tZihuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b0ZyZXF1ZW5jeSgpKTtcbiAgICAgICAgICAgIGNvbnN0IG1pZGkgPSBNYXRoLnJvdW5kKG1pZGlGbG9hdCk7XG4gICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBtaWRpRmxvYXQgLSBtaWRpO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgY2xvc2VzdCBub3RlIHBpdGNoXG4gICAgICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gdGhpcy5fZmluZENsb3Nlc3QobWlkaSk7XG4gICAgICAgICAgICBjb25zdCBjbG9zZXN0Tm90ZSA9IG1pZGkgLSBkaWZmZXJlbmNlO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fYnVmZmVycy5nZXQoY2xvc2VzdE5vdGUpO1xuICAgICAgICAgICAgY29uc3QgcGxheWJhY2tSYXRlID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGRpZmZlcmVuY2UgKyByZW1haW5kZXIpO1xuICAgICAgICAgICAgLy8gcGxheSB0aGF0IG5vdGVcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lQnVmZmVyU291cmNlKHtcbiAgICAgICAgICAgICAgICB1cmw6IGJ1ZmZlcixcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgY3VydmU6IHRoaXMuY3VydmUsXG4gICAgICAgICAgICAgICAgZmFkZUluOiB0aGlzLmF0dGFjayxcbiAgICAgICAgICAgICAgICBmYWRlT3V0OiB0aGlzLnJlbGVhc2UsXG4gICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlLFxuICAgICAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQodGltZSwgMCwgYnVmZmVyLmR1cmF0aW9uIC8gcGxheWJhY2tSYXRlLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGFjdGl2ZSBzb3VyY2VzXG4gICAgICAgICAgICBpZiAoIWlzQXJyYXkodGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zZXQobWlkaSwgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGl0IHdoZW4gaXQncyBkb25lXG4gICAgICAgICAgICBzb3VyY2Uub25lbmRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcyAmJiB0aGlzLl9hY3RpdmVTb3VyY2VzLmhhcyhtaWRpKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc291cmNlcy5pbmRleE9mKHNvdXJjZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtICBub3Rlc1x0VGhlIG5vdGUgdG8gcmVsZWFzZSwgb3IgYW4gYXJyYXkgb2Ygbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBcdFdoZW4gdG8gcmVsZWFzZSB0aGUgbm90ZS5cbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIG5vdGVzLCB0aW1lKTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpID0gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBub3RlXG4gICAgICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcy5oYXMobWlkaSkgJiYgdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlcyA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpO1xuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlLnN0b3AodGltZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zZXQobWlkaSwgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2UgYWxsIGN1cnJlbnRseSBhY3RpdmUgbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBcdFdoZW4gdG8gcmVsZWFzZSB0aGUgbm90ZXMuXG4gICAgICovXG4gICAgcmVsZWFzZUFsbCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlcyA9PiB7XG4gICAgICAgICAgICB3aGlsZSAoc291cmNlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgc291cmNlLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGF0dGFjayBwaGFzZSwgdGhlbiBhZnRlciB0aGUgZHVyYXRpb24sIGludm9rZSB0aGUgcmVsZWFzZS5cbiAgICAgKiBAcGFyYW0gIG5vdGVzXHRUaGUgbm90ZSB0byBwbGF5IGFuZCByZWxlYXNlLCBvciBhbiBhcnJheSBvZiBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIFRoZSB0aW1lIHRoZSBub3RlIHNob3VsZCBiZSBoZWxkXG4gICAgICogQHBhcmFtICB0aW1lICAgICBXaGVuIHRvIHN0YXJ0IHRoZSBhdHRhY2tcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBvZiB0aGUgYXR0YWNrXG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZXMsIGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayhub3RlcywgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmIChpc0FycmF5KGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzQXJyYXkobm90ZXMpLCBcIm5vdGVzIG11c3QgYmUgYW4gYXJyYXkgd2hlbiBkdXJhdGlvbiBpcyBhcnJheVwiKTtcbiAgICAgICAgICAgIG5vdGVzLmZvckVhY2goKG5vdGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IGR1cmF0aW9uW01hdGgubWluKGluZGV4LCBkdXJhdGlvbi5sZW5ndGggLSAxKV07XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3RlLCBjb21wdXRlZFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZXMsIGNvbXB1dGVkVGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIG5vdGUgdG8gdGhlIHNhbXBsZXIuXG4gICAgICogQHBhcmFtICBub3RlICAgICAgVGhlIGJ1ZmZlcidzIHBpdGNoLlxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZmVyLCBvciBhIGJ1ZmZlciB3aGljaCB3aWxsIGJlIGFkZGVkIHdpdGggdGhlIGdpdmVuIG5hbWUuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGFkZChub3RlLCB1cmwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGFzc2VydChpc05vdGUobm90ZSkgfHwgaXNGaW5pdGUobm90ZSksIGBub3RlIG11c3QgYmUgYSBwaXRjaCBvciBtaWRpOiAke25vdGV9YCk7XG4gICAgICAgIGlmIChpc05vdGUobm90ZSkpIHtcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIG5vdGUgbmFtZSB0byBNSURJXG4gICAgICAgICAgICBjb25zdCBtaWQgPSBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG1pZCwgdXJsLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgaXQncyBudW1iZXJzIGFzc3VtZSBpdCdzIG1pZGlcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG5vdGUsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmxvYWRlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlcyA9PiB7XG4gICAgICAgICAgICBzb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFNhbXBsZXIucHJvdG90eXBlLCBcImF0dGFja1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBTYW1wbGVyLnByb3RvdHlwZSwgXCJyZWxlYXNlXCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TYW1wbGVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0FNU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0R1b1N5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GTVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NZXRhbFN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NZW1icmFuZVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Nb25vU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL05vaXNlU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BsdWNrU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BvbHlTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2FtcGxlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3ludGhcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCBcIi4uL2NvcmUvY2xvY2svVHJhbnNwb3J0XCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0Jvb2xlYW4sIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVG9uZUV2ZW50IGFic3RyYWN0cyBhd2F5IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUgYW5kIHByb3ZpZGVzIGEgc2NoZWR1bGFibGVcbiAqIGNhbGxiYWNrIGZvciBhIHNpbmdsZSBvciByZXBlYXRhYmxlIGV2ZW50cyBhbG9uZyB0aGUgdGltZWxpbmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgY2hvcmRFdmVudCA9IG5ldyBUb25lLlRvbmVFdmVudCgoKHRpbWUsIGNob3JkKSA9PiB7XG4gKiBcdC8vIHRoZSBjaG9yZCBhcyB3ZWxsIGFzIHRoZSBleGFjdCB0aW1lIG9mIHRoZSBldmVudFxuICogXHQvLyBhcmUgcGFzc2VkIGluIGFzIGFyZ3VtZW50cyB0byB0aGUgY2FsbGJhY2sgZnVuY3Rpb25cbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoY2hvcmQsIDAuNSwgdGltZSk7XG4gKiB9KSwgW1wiRDRcIiwgXCJFNFwiLCBcIkY0XCJdKTtcbiAqIC8vIHN0YXJ0IHRoZSBjaG9yZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0cmFuc3BvcnQgdGltZWxpbmVcbiAqIGNob3JkRXZlbnQuc3RhcnQoKTtcbiAqIC8vIGxvb3AgaXQgZXZlcnkgbWVhc3VyZSBmb3IgOCBtZWFzdXJlc1xuICogY2hvcmRFdmVudC5sb29wID0gODtcbiAqIGNob3JkRXZlbnQubG9vcEVuZCA9IFwiMW1cIjtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgVG9uZUV2ZW50IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVFdmVudFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVHJhY2tzIHRoZSBzY2hlZHVsZWQgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgZGVsYXkgdGltZSBmcm9tIHdoZW4gdGhlIGV2ZW50IGlzIHNjaGVkdWxlZCB0byBzdGFydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhcnRPZmZzZXQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLnZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKG9wdGlvbnMubG9vcFN0YXJ0KTtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhvcHRpb25zLmxvb3BFbmQpO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBvcHRpb25zLnByb2JhYmlsaXR5O1xuICAgICAgICB0aGlzLl9odW1hbml6ZSA9IG9wdGlvbnMuaHVtYW5pemU7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuX3N0YXRlLmluY3JlYXNpbmcgPSB0cnVlO1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgZXZlbnRzIGZvciB0aGUgZmlyc3QgdGltZVxuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgaHVtYW5pemU6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiBcIjFtXCIsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiAxLFxuICAgICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNjaGVkdWxlIGFsbCBvZiB0aGUgZXZlbnRzIGFsb25nIHRoZSB0aW1lbGluZVxuICAgICAqIHdpdGggdGhlIHVwZGF0ZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSBhZnRlciBPbmx5IHJlc2NoZWR1bGVzIGV2ZW50cyBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBfcmVzY2hlZHVsZUV2ZW50cyhhZnRlciA9IC0xKSB7XG4gICAgICAgIC8vIGlmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCBzY2hlZHVsZXMgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEZyb20oYWZ0ZXIsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbjtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQuaWQgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIoZXZlbnQuaWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydFRpY2sgPSBldmVudC50aW1lICsgTWF0aC5yb3VuZCh0aGlzLnN0YXJ0T2Zmc2V0IC8gdGhpcy5fcGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbG9vcCA9PT0gdHJ1ZSB8fCBpc051bWJlcih0aGlzLl9sb29wKSAmJiB0aGlzLl9sb29wID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IEluZmluaXR5O1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOdW1iZXIodGhpcy5fbG9vcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gKHRoaXMuX2xvb3ApICogdGhpcy5fZ2V0TG9vcER1cmF0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0QWZ0ZXIoc3RhcnRUaWNrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBNYXRoLm1pbihkdXJhdGlvbiwgbmV4dEV2ZW50LnRpbWUgLSBzdGFydFRpY2spO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbiAhPT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNjaGVkdWxlIGEgc3RvcCBzaW5jZSBpdCdzIGZpbml0ZSBkdXJhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHN0YXJ0VGljayArIGR1cmF0aW9uICsgMSwgeyBpZDogLTEgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9nZXRMb29wRHVyYXRpb24oKSk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCh0aGlzLl90aWNrLmJpbmQodGhpcyksIGludGVydmFsLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGljayksIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSh0aGlzLl90aWNrLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaWNrKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIG5vdGUsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpY2tzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXJ0IGZyb20gdGhlIHNjaGVkdWxlZCBzdGFydCB0aW1lLlxuICAgICAqL1xuICAgIGdldCBzdGFydE9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gb2Zmc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvYmFiaWxpdHkgb2YgdGhlIG5vdGVzIGJlaW5nIHRyaWdnZXJlZC5cbiAgICAgKi9cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBzZXQgdG8gdHJ1ZSwgd2lsbCBhcHBseSBzbWFsbCByYW5kb20gdmFyaWF0aW9uXG4gICAgICogdG8gdGhlIGNhbGxiYWNrIHRpbWUuIElmIHRoZSB2YWx1ZSBpcyBnaXZlbiBhcyBhIHRpbWUsIGl0IHdpbGwgcmFuZG9taXplXG4gICAgICogYnkgdGhhdCBhbW91bnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBldmVudCA9IG5ldyBUb25lLlRvbmVFdmVudCgpO1xuICAgICAqIGV2ZW50Lmh1bWFuaXplID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9odW1hbml6ZSA9IHZhcmlhdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIG5vdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRoZSBldmVudCBzaG91bGQgc3RhcnQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSA9PT0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmFkZCh7XG4gICAgICAgICAgICAgICAgaWQ6IC0xLFxuICAgICAgICAgICAgICAgIHN0YXRlOiBcInN0YXJ0ZWRcIixcbiAgICAgICAgICAgICAgICB0aW1lOiB0aWNrcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cyh0aWNrcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIEV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0aGUgZXZlbnQgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsKHRpbWUpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCB0aWNrcywgeyBpZDogLTEgfSk7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0QmVmb3JlKHRpY2tzKTtcbiAgICAgICAgICAgIGxldCByZXNjaGVkdWxUaW1lID0gdGlja3M7XG4gICAgICAgICAgICBpZiAocHJldmlvdXNFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc2NoZWR1bFRpbWUgPSBwcmV2aW91c0V2ZW50LnRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKHJlc2NoZWR1bFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgYWxsIHNjaGVkdWxlZCBldmVudHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBhZnRlciB3aGljaCBldmVudHMgd2lsbCBiZSBjYW5jZWwuXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IGRlZmF1bHRBcmcodGltZSwgLUluZmluaXR5KTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hGcm9tKHRpY2tzLCBldmVudCA9PiB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGV2ZW50LmlkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aWNrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlci4gQWxzb1xuICAgICAqIGNoZWNrcyBpZiB0aGUgRXZlbnQgaXMgZG9uZSBwbGF5aW5nXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBvZiB0aGUgZXZlbnQgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoIXRoaXMubXV0ZSAmJiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9iYWJpbGl0eSA8IDEgJiYgTWF0aC5yYW5kb20oKSA+IHRoaXMucHJvYmFiaWxpdHkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5odW1hbml6ZSkge1xuICAgICAgICAgICAgICAgIGxldCB2YXJpYXRpb24gPSAwLjAyO1xuICAgICAgICAgICAgICAgIGlmICghaXNCb29sZWFuKHRoaXMuaHVtYW5pemUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhdGlvbiA9IHRoaXMudG9TZWNvbmRzKHRoaXMuaHVtYW5pemUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aW1lICs9IChNYXRoLnJhbmRvbSgpICogMiAtIDEpICogdmFyaWF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB0aGlzLnZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGR1cmF0aW9uIG9mIHRoZSBsb29wLlxuICAgICAqL1xuICAgIF9nZXRMb29wRHVyYXRpb24oKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKCh0aGlzLl9sb29wRW5kIC0gdGhpcy5fbG9vcFN0YXJ0KSAvIHRoaXMuX3BsYXliYWNrUmF0ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBub3RlIHNob3VsZCBsb29wIG9yIG5vdFxuICAgICAqIGJldHdlZW4gVG9uZUV2ZW50Lmxvb3BTdGFydCBhbmRcbiAgICAgKiBUb25lRXZlbnQubG9vcEVuZC4gSWYgc2V0IHRvIHRydWUsXG4gICAgICogdGhlIGV2ZW50IHdpbGwgbG9vcCBpbmRlZmluaXRlbHksXG4gICAgICogaWYgc2V0IHRvIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAxXG4gICAgICogaXQgd2lsbCBwbGF5IGEgc3BlY2lmaWMgbnVtYmVyIG9mXG4gICAgICogdGltZXMsIGlmIHNldCB0byBmYWxzZSwgMCBvciAxLCB0aGVcbiAgICAgKiBwYXJ0IHdpbGwgb25seSBwbGF5IG9uY2UuXG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub3RlLiBEZWZhdWx0cyB0byAxLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm90ZSA9IG5ldyBUb25lLlRvbmVFdmVudCgpO1xuICAgICAqIG5vdGUubG9vcCA9IHRydWU7XG4gICAgICogLy8gcmVwZWF0IHRoZSBub3RlIHR3aWNlIGFzIGZhc3RcbiAgICAgKiBub3RlLnBsYXliYWNrUmF0ZSA9IDI7XG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3BFbmQgcG9pbnQgaXMgdGhlIHRpbWUgdGhlIGV2ZW50IHdpbGwgbG9vcFxuICAgICAqIGlmIFRvbmVFdmVudC5sb29wIGlzIHRydWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BFbmQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MobG9vcEVuZCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgd2hlbiB0aGUgbG9vcCBzaG91bGQgc3RhcnQuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcFN0YXJ0KS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKGxvb3BTdGFydCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2YgdGhlIGxvb3AgaW50ZXJ2YWwuXG4gICAgICogUmV0dXJucyAwIGlmIHRoZSBldmVudCBpcyBub3Qgc3RhcnRlZCB5ZXQgb3JcbiAgICAgKiBpdCBpcyBub3Qgc2V0IHRvIGxvb3AuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpY2tzO1xuICAgICAgICAgICAgY29uc3QgbGFzdEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KHRpY2tzKTtcbiAgICAgICAgICAgIGlmIChsYXN0RXZlbnQgIT09IG51bGwgJiYgbGFzdEV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvb3BEdXJhdGlvbiA9IHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gKHRpY2tzIC0gbGFzdEV2ZW50LnRpbWUpICUgbG9vcER1cmF0aW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9ncmVzcyAvIGxvb3BEdXJhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNhbmNlbCgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVFdmVudC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lRXZlbnQgfSBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBMb29wIGNyZWF0ZXMgYSBsb29wZWQgY2FsbGJhY2sgYXQgdGhlXG4gKiBzcGVjaWZpZWQgaW50ZXJ2YWwuIFRoZSBjYWxsYmFjayBjYW4gYmVcbiAqIHN0YXJ0ZWQsIHN0b3BwZWQgYW5kIHNjaGVkdWxlZCBhbG9uZ1xuICogdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGxvb3AgPSBuZXcgVG9uZS5Mb29wKCh0aW1lKSA9PiB7XG4gKiBcdC8vIHRyaWdnZXJlZCBldmVyeSBlaWdodGggbm90ZS5cbiAqIFx0Y29uc29sZS5sb2codGltZSk7XG4gKiB9LCBcIjhuXCIpLnN0YXJ0KDApO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgTG9vcCBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKExvb3AuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImludGVydmFsXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTG9vcFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTG9vcC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiaW50ZXJ2YWxcIl0pO1xuICAgICAgICB0aGlzLl9ldmVudCA9IG5ldyBUb25lRXZlbnQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICBsb29wRW5kOiBvcHRpb25zLmludGVydmFsLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiBvcHRpb25zLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiBvcHRpb25zLnByb2JhYmlsaXR5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgLy8gc2V0IHRoZSBpdGVyYXRpb25zXG4gICAgICAgIHRoaXMuaXRlcmF0aW9ucyA9IG9wdGlvbnMuaXRlcmF0aW9ucztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaW50ZXJ2YWw6IFwiNG5cIixcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgaXRlcmF0aW9uczogSW5maW5pdHksXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogMSxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgaHVtYW5pemU6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgbG9vcCBhdCB0aGUgc3BlY2lmaWVkIHRpbWUgYWxvbmcgdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdGFydCB0aGUgTG9vcC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgbG9vcCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgTG9vcC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBhbGwgc2NoZWR1bGVkIGV2ZW50cyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIGFmdGVyIHdoaWNoIGV2ZW50cyB3aWxsIGJlIGNhbmNlbC5cbiAgICAgKi9cbiAgICBjYW5jZWwodGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5jYW5jZWwodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgbm90ZXMgc2hvdWxkIGJlIGNhbGxlZFxuICAgICAqIEBwYXJhbSB0aW1lICBUaGUgdGltZSB0aGUgZXZlbnQgb2NjdXJzXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3RhdGUgb2YgdGhlIExvb3AsIGVpdGhlciBzdGFydGVkIG9yIHN0b3BwZWQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9ncmVzcyBvZiB0aGUgbG9vcCBhcyBhIHZhbHVlIGJldHdlZW4gMC0xLiAwLCB3aGVuIHRoZSBsb29wIGlzIHN0b3BwZWQgb3IgZG9uZSBpdGVyYXRpbmcuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucHJvZ3Jlc3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBjYWxsYmFja3MuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsb29wID0gbmV3IFRvbmUuTG9vcCgpO1xuICAgICAqIGxvb3AuaW50ZXJ2YWwgPSBcIjhuXCI7IC8vIGxvb3AgZXZlcnkgOG5cbiAgICAgKi9cbiAgICBnZXQgaW50ZXJ2YWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgaW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQubG9vcEVuZCA9IGludGVydmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbG9vcC4gVGhlIG5vcm1hbCBwbGF5YmFjayByYXRlIGlzIDEgKG5vIGNoYW5nZSkuXG4gICAgICogQSBgcGxheWJhY2tSYXRlYCBvZiAyIHdvdWxkIGJlIHR3aWNlIGFzIGZhc3QuXG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnBsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnBsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJhbmRvbSB2YXJpYXRpb24gKy8tMC4wMXMgdG8gdGhlIHNjaGVkdWxlZCB0aW1lLlxuICAgICAqIE9yIGdpdmUgaXQgYSB0aW1lIHZhbHVlIHdoaWNoIGl0IHdpbGwgcmFuZG9taXplIGJ5LlxuICAgICAqL1xuICAgIGdldCBodW1hbml6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lmh1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50Lmh1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvYmFibHkgb2YgdGhlIGNhbGxiYWNrIGJlaW5nIGludm9rZWQuXG4gICAgICovXG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnByb2JhYmlsaXR5ID0gcHJvYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0aW5nIHRoZSBMb29wIG1lYW5zIHRoYXQgbm8gY2FsbGJhY2tzIGFyZSBpbnZva2VkLlxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpdGVyYXRpb25zIG9mIHRoZSBsb29wLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgSW5maW5pdHlgIChsb29wIGZvcmV2ZXIpLlxuICAgICAqL1xuICAgIGdldCBpdGVyYXRpb25zKCkge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnQubG9vcCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lmxvb3A7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IGl0ZXJhdGlvbnMoaXRlcnMpIHtcbiAgICAgICAgaWYgKGl0ZXJzID09PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnQubG9vcCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudC5sb29wID0gaXRlcnM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxvb3AuanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1VuZGVmIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVFdmVudCB9IGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLyoqXG4gKiBQYXJ0IGlzIGEgY29sbGVjdGlvbiBUb25lRXZlbnRzIHdoaWNoIGNhbiBiZSBzdGFydGVkL3N0b3BwZWQgYW5kIGxvb3BlZCBhcyBhIHNpbmdsZSB1bml0LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKCh0aW1lLCBub3RlKSA9PiB7XG4gKiBcdC8vIHRoZSBub3RlcyBnaXZlbiBhcyB0aGUgc2Vjb25kIGVsZW1lbnQgaW4gdGhlIGFycmF5XG4gKiBcdC8vIHdpbGwgYmUgcGFzc2VkIGluIGFzIHRoZSBzZWNvbmQgYXJndW1lbnRcbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgXCI4blwiLCB0aW1lKTtcbiAqIH0pLCBbWzAsIFwiQzJcIl0sIFtcIjA6MlwiLCBcIkMzXCJdLCBbXCIwOjM6MlwiLCBcIkcyXCJdXSk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyB1c2UgYW4gYXJyYXkgb2Ygb2JqZWN0cyBhcyBsb25nIGFzIHRoZSBvYmplY3QgaGFzIGEgXCJ0aW1lXCIgYXR0cmlidXRlXG4gKiBjb25zdCBwYXJ0ID0gbmV3IFRvbmUuUGFydCgoKHRpbWUsIHZhbHVlKSA9PiB7XG4gKiBcdC8vIHRoZSB2YWx1ZSBpcyBhbiBvYmplY3Qgd2hpY2ggY29udGFpbnMgYm90aCB0aGUgbm90ZSBhbmQgdGhlIHZlbG9jaXR5XG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKHZhbHVlLm5vdGUsIFwiOG5cIiwgdGltZSwgdmFsdWUudmVsb2NpdHkpO1xuICogfSksIFt7IHRpbWU6IDAsIG5vdGU6IFwiQzNcIiwgdmVsb2NpdHk6IDAuOSB9LFxuICogXHR7IHRpbWU6IFwiMDoyXCIsIG5vdGU6IFwiQzRcIiwgdmVsb2NpdHk6IDAuNSB9XG4gKiBdKS5zdGFydCgwKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhcnQgZXh0ZW5kcyBUb25lRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXJ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXJ0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUcmFja3MgdGhlIHNjaGVkdWxlZCBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGV2ZW50cyB0aGF0IGJlbG9uZyB0byB0aGlzIHBhcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiXSk7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGluZ3MgYXJlIGFzc2lnbmVkIGluIHRoZSByaWdodCBvcmRlclxuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gYWRkIHRoZSBldmVudHNcbiAgICAgICAgb3B0aW9ucy5ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBcnJheShldmVudCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZChldmVudFswXSwgZXZlbnRbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lRXZlbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZXZlbnRzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICBXaGVuIHRvIHN0YXJ0IHRoZSBwYXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0ICBUaGUgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBwYXJ0IHRvIGJlZ2luIHBsYXlpbmcgYXQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMuX2xvb3AgPyB0aGlzLl9sb29wU3RhcnQgOiAwKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMuX2xvb3BTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZE9mZnNldCA9IHRoaXMudG9UaWNrcyhvZmZzZXQpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHtcbiAgICAgICAgICAgICAgICBpZDogLTEsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiBjb21wdXRlZE9mZnNldCxcbiAgICAgICAgICAgICAgICBzdGF0ZTogXCJzdGFydGVkXCIsXG4gICAgICAgICAgICAgICAgdGltZTogdGlja3MsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0Tm90ZShldmVudCwgdGlja3MsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgZXZlbnQgaW4gdGhlIGdpdmVuIGV2ZW50IGF0IHRoZSBjb3JyZWN0IHRpbWUgZ2l2ZW5cbiAgICAgKiB0aGUgdGlja3MgYW5kIG9mZnNldCBhbmQgbG9vcGluZy5cbiAgICAgKiBAcGFyYW0gIGV2ZW50XG4gICAgICogQHBhcmFtICB0aWNrc1xuICAgICAqIEBwYXJhbSAgb2Zmc2V0XG4gICAgICovXG4gICAgX3N0YXJ0Tm90ZShldmVudCwgdGlja3MsIG9mZnNldCkge1xuICAgICAgICB0aWNrcyAtPSBvZmZzZXQ7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPj0gdGhpcy5fbG9vcFN0YXJ0ICYmIGV2ZW50LnN0YXJ0T2Zmc2V0IDwgdGhpcy5fbG9vcEVuZCkge1xuICAgICAgICAgICAgICAgIGlmIChldmVudC5zdGFydE9mZnNldCA8IG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBzdGFydCBpdCBvbiB0aGUgbmV4dCBsb29wXG4gICAgICAgICAgICAgICAgICAgIHRpY2tzICs9IHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBldmVudC5zdGFydChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRpY2tzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BTdGFydCAmJiBldmVudC5zdGFydE9mZnNldCA+PSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICBldmVudC5sb29wID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0ID49IG9mZnNldCkge1xuICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBzdGFydE9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50LnN0YXJ0T2Zmc2V0ICs9IHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aWNrcyk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCB0aWNrcyk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQuc3RvcCh0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQvU2V0IGFuIEV2ZW50J3MgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW4gYW5kIG5vIGV2ZW50IGV4aXN0cyBhdFxuICAgICAqIHRoZSBnaXZlbiB0aW1lLCBvbmUgd2lsbCBiZSBjcmVhdGVkIHdpdGggdGhhdCB2YWx1ZS5cbiAgICAgKiBJZiB0d28gZXZlbnRzIGFyZSBhdCB0aGUgc2FtZSB0aW1lLCB0aGUgZmlyc3Qgb25lIHdpbGxcbiAgICAgKiBiZSByZXR1cm5lZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCk7XG4gICAgICogcGFydC5hdChcIjFtXCIpOyAvLyByZXR1cm5zIHRoZSBwYXJ0IGF0IHRoZSBmaXJzdCBtZWFzdXJlXG4gICAgICogcGFydC5hdChcIjJtXCIsIFwiQzJcIik7IC8vIHNldCB0aGUgdmFsdWUgYXQgXCIybVwiIHRvIEMyLlxuICAgICAqIC8vIGlmIGFuIGV2ZW50IGRpZG4ndCBleGlzdCBhdCB0aGF0IHRpbWUsIGl0IHdpbGwgYmUgY3JlYXRlZC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSBvZiB0aGUgZXZlbnQgdG8gZ2V0IG9yIHNldC5cbiAgICAgKiBAcGFyYW0gdmFsdWUgSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW4sIHRoZSB2YWx1ZSBvZiB0aGUgZXZlbnQgYXQgdGhlIGdpdmVuIHRpbWUgd2lsbCBiZSBzZXQgdG8gaXQuXG4gICAgICovXG4gICAgYXQodGltZSwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgdGltZUluVGlja3MgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpO1xuICAgICAgICBjb25zdCB0aWNrVGltZSA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgMSkudG9TZWNvbmRzKCk7XG4gICAgICAgIGNvbnN0IGl0ZXJhdG9yID0gdGhpcy5fZXZlbnRzLnZhbHVlcygpO1xuICAgICAgICBsZXQgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICB3aGlsZSAoIXJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyh0aW1lSW5UaWNrcyAtIGV2ZW50LnN0YXJ0T2Zmc2V0KSA8IHRpY2tUaW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHRoZXJlIHdhcyBubyBldmVudCBhdCB0aGF0IHRpbWUsIGNyZWF0ZSBvbmVcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkKHRpbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIC8vIHJldHVybiB0aGUgbmV3IGV2ZW50XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hdCh0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZCh0aW1lLCB2YWx1ZSkge1xuICAgICAgICAvLyBleHRyYWN0IHRoZSBwYXJhbWV0ZXJzXG4gICAgICAgIGlmICh0aW1lIGluc3RhbmNlb2YgT2JqZWN0ICYmIFJlZmxlY3QuaGFzKHRpbWUsIFwidGltZVwiKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aW1lO1xuICAgICAgICAgICAgdGltZSA9IHZhbHVlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGxldCBldmVudDtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgVG9uZUV2ZW50KSB7XG4gICAgICAgICAgICBldmVudCA9IHZhbHVlO1xuICAgICAgICAgICAgZXZlbnQuY2FsbGJhY2sgPSB0aGlzLl90aWNrLmJpbmQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBldmVudCA9IG5ldyBUb25lRXZlbnQoe1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlIHN0YXJ0IG9mZnNldFxuICAgICAgICBldmVudC5zdGFydE9mZnNldCA9IHRpY2tzO1xuICAgICAgICAvLyBpbml0aWFsaXplIHRoZSB2YWx1ZXNcbiAgICAgICAgZXZlbnQuc2V0KHtcbiAgICAgICAgICAgIGh1bWFuaXplOiB0aGlzLmh1bWFuaXplLFxuICAgICAgICAgICAgbG9vcDogdGhpcy5sb29wLFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5sb29wRW5kLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiB0aGlzLmxvb3BTdGFydCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogdGhpcy5wbGF5YmFja1JhdGUsXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogdGhpcy5wcm9iYWJpbGl0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoZXZlbnQpO1xuICAgICAgICAvLyBzdGFydCB0aGUgbm90ZSBpZiBpdCBzaG91bGQgYmUgcGxheWVkIHJpZ2h0IG5vd1xuICAgICAgICB0aGlzLl9yZXN0YXJ0RXZlbnQoZXZlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzdGFydCB0aGUgZ2l2ZW4gZXZlbnRcbiAgICAgKi9cbiAgICBfcmVzdGFydEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2goKHN0YXRlRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0Tm90ZShldmVudCwgc3RhdGVFdmVudC50aW1lLCBzdGF0ZUV2ZW50Lm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBzdG9wIHRoZSBub3RlXG4gICAgICAgICAgICAgICAgZXZlbnQuc3RvcChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXRlRXZlbnQudGltZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIC8vIGV4dHJhY3QgdGhlIHBhcmFtZXRlcnNcbiAgICAgICAgaWYgKGlzT2JqZWN0KHRpbWUpICYmIHRpbWUuaGFzT3duUHJvcGVydHkoXCJ0aW1lXCIpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRpbWU7XG4gICAgICAgICAgICB0aW1lID0gdmFsdWUudGltZTtcbiAgICAgICAgfVxuICAgICAgICB0aW1lID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPT09IHRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNVbmRlZih2YWx1ZSkgfHwgKGlzRGVmaW5lZCh2YWx1ZSkgJiYgZXZlbnQudmFsdWUgPT09IHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuZGVsZXRlKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYWxsIG9mIHRoZSBub3RlcyBmcm9tIHRoZSBncm91cC5cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiBldmVudC5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9ldmVudHMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBzY2hlZHVsZWQgc3RhdGUgY2hhbmdlIGV2ZW50czogaS5lLiBcInN0YXJ0XCIgYW5kIFwic3RvcFwiLlxuICAgICAqIEBwYXJhbSBhZnRlciBUaGUgdGltZSBhZnRlciB3aGljaCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBldmVudHMuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4gZXZlbnQuY2FuY2VsKGFmdGVyKSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aGlzLnRvVGlja3MoYWZ0ZXIpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIF9mb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBQYXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Ll9mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBhdHRyaWJ1dGUgb2YgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgKiBAcGFyYW0gIGF0dHIgIHRoZSBhdHRyaWJ1dGUgdG8gc2V0XG4gICAgICogQHBhcmFtICB2YWx1ZSAgICAgIFRoZSB2YWx1ZSB0byBzZXQgaXQgdG9cbiAgICAgKi9cbiAgICBfc2V0QWxsKGF0dHIsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnRbYXR0cl0gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHRpY2sgbWV0aG9kXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBvZiB0aGUgZXZlbnQgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGlmICghdGhpcy5tdXRlKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGV2ZW50IHNob3VsZCBiZSBjdXJyZW50bHkgbG9vcGluZ1xuICAgICAqIGdpdmVuIHRoZSBsb29wIGJvdW5kcmllcyBvZiB0aGlzIFBhcnQuXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIHRlc3RcbiAgICAgKi9cbiAgICBfdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AgJiYgKGV2ZW50LnN0YXJ0T2Zmc2V0IDwgdGhpcy5fbG9vcFN0YXJ0IHx8IGV2ZW50LnN0YXJ0T2Zmc2V0ID49IHRoaXMuX2xvb3BFbmQpKSB7XG4gICAgICAgICAgICBldmVudC5jYW5jZWwoMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXZlbnQuc3RhdGUgPT09IFwic3RvcHBlZFwiKSB7XG4gICAgICAgICAgICAvLyByZXNjaGVkdWxlIGl0IGlmIGl0J3Mgc3RvcHBlZFxuICAgICAgICAgICAgdGhpcy5fcmVzdGFydEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgICAgICB0aGlzLl9zZXRBbGwoXCJwcm9iYWJpbGl0eVwiLCBwcm9iKTtcbiAgICB9XG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faHVtYW5pemU7XG4gICAgfVxuICAgIHNldCBodW1hbml6ZSh2YXJpYXRpb24pIHtcbiAgICAgICAgdGhpcy5faHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgICAgIHRoaXMuX3NldEFsbChcImh1bWFuaXplXCIsIHZhcmlhdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBwYXJ0IHNob3VsZCBsb29wIG9yIG5vdFxuICAgICAqIGJldHdlZW4gUGFydC5sb29wU3RhcnQgYW5kXG4gICAgICogUGFydC5sb29wRW5kLiBJZiBzZXQgdG8gdHJ1ZSxcbiAgICAgKiB0aGUgcGFydCB3aWxsIGxvb3AgaW5kZWZpbml0ZWx5LFxuICAgICAqIGlmIHNldCB0byBhIG51bWJlciBncmVhdGVyIHRoYW4gMVxuICAgICAqIGl0IHdpbGwgcGxheSBhIHNwZWNpZmljIG51bWJlciBvZlxuICAgICAqIHRpbWVzLCBpZiBzZXQgdG8gZmFsc2UsIDAgb3IgMSwgdGhlXG4gICAgICogcGFydCB3aWxsIG9ubHkgcGxheSBvbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKTtcbiAgICAgKiAvLyBsb29wIHRoZSBwYXJ0IDggdGltZXNcbiAgICAgKiBwYXJ0Lmxvb3AgPSA4O1xuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBldmVudC5sb29wU3RhcnQgPSB0aGlzLmxvb3BTdGFydDtcbiAgICAgICAgICAgIGV2ZW50Lmxvb3BFbmQgPSB0aGlzLmxvb3BFbmQ7XG4gICAgICAgICAgICBldmVudC5sb29wID0gbG9vcDtcbiAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wRW5kIHBvaW50IGRldGVybWluZXMgd2hlbiBpdCB3aWxsXG4gICAgICogbG9vcCBpZiBQYXJ0Lmxvb3AgaXMgdHJ1ZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcEVuZCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhsb29wRW5kKTtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wU3RhcnQgcG9pbnQgZGV0ZXJtaW5lcyB3aGVuIGl0IHdpbGxcbiAgICAgKiBsb29wIGlmIFBhcnQubG9vcCBpcyB0cnVlLlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhsb29wU3RhcnQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQubG9vcFN0YXJ0ID0gdGhpcy5sb29wU3RhcnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIHBhcnRcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgdGhpcy5fc2V0QWxsKFwicGxheWJhY2tSYXRlXCIsIHJhdGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNjaGVkdWxlZCBub3RlcyBpbiB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzLnNpemU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXJ0LmpzLm1hcCIsImltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIFN0YXJ0IGF0IHRoZSBmaXJzdCB2YWx1ZSBhbmQgZ28gdXAgdG8gdGhlIGxhc3RcbiAqL1xuZnVuY3Rpb24qIHVwUGF0dGVybkdlbih2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIHdoaWxlIChpbmRleCA8IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpbmRleCsrO1xuICAgIH1cbn1cbi8qKlxuICogU3RhcnQgYXQgdGhlIGxhc3QgdmFsdWUgYW5kIGdvIGRvd24gdG8gMFxuICovXG5mdW5jdGlvbiogZG93blBhdHRlcm5HZW4odmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKGluZGV4ID49IDApIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpbmRleC0tO1xuICAgIH1cbn1cbi8qKlxuICogSW5maW5pdGVseSB5aWVsZCB0aGUgZ2VuZXJhdG9yXG4gKi9cbmZ1bmN0aW9uKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGdlbikge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHlpZWxkKiBnZW4odmFsdWVzKTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBpbmRleCBpcyBpbiB0aGUgZ2l2ZW4gcmFuZ2VcbiAqL1xuZnVuY3Rpb24gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKSB7XG4gICAgcmV0dXJuIGNsYW1wKGluZGV4LCAwLCB2YWx1ZXMubGVuZ3RoIC0gMSk7XG59XG4vKipcbiAqIEFsdGVybmF0ZSBiZXR3ZWVuIHR3byBnZW5lcmF0b3JzXG4gKi9cbmZ1bmN0aW9uKiBhbHRlcm5hdGluZ0dlbmVyYXRvcih2YWx1ZXMsIGRpcmVjdGlvblVwKSB7XG4gICAgbGV0IGluZGV4ID0gZGlyZWN0aW9uVXAgPyAwIDogdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpZiAoZGlyZWN0aW9uVXApIHtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICBpZiAoaW5kZXggPj0gdmFsdWVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb25VcCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXgtLTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8PSAwKSB7XG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uVXAgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBTdGFydGluZyBmcm9tIHRoZSBib3R0b20gbW92ZSB1cCAyLCBkb3duIDFcbiAqL1xuZnVuY3Rpb24qIGp1bXBVcCh2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGxldCBzdGVwSW5kZXggPSAwO1xuICAgIHdoaWxlIChpbmRleCA8IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBzdGVwSW5kZXgrKztcbiAgICAgICAgaW5kZXggKz0gKHN0ZXBJbmRleCAlIDIgPyAyIDogLTEpO1xuICAgIH1cbn1cbi8qKlxuICogU3RhcnRpbmcgZnJvbSB0aGUgdG9wIG1vdmUgZG93biAyLCB1cCAxXG4gKi9cbmZ1bmN0aW9uKiBqdW1wRG93bih2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSB2YWx1ZXMubGVuZ3RoIC0gMTtcbiAgICBsZXQgc3RlcEluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5kZXggPj0gMCkge1xuICAgICAgICBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgICAgIHN0ZXBJbmRleCsrO1xuICAgICAgICBpbmRleCArPSAoc3RlcEluZGV4ICUgMiA/IC0yIDogMSk7XG4gICAgfVxufVxuLyoqXG4gKiBDaG9vc2UgYSByYW5kb20gaW5kZXggZWFjaCB0aW1lXG4gKi9cbmZ1bmN0aW9uKiByYW5kb21HZW4odmFsdWVzKSB7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgY29uc3QgcmFuZG9tSW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB2YWx1ZXMubGVuZ3RoKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW3JhbmRvbUluZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFJhbmRvbWx5IGdvIHRocm91Z2ggYWxsIG9mIHRoZSB2YWx1ZXMgb25jZSBiZWZvcmUgY2hvb3NpbmcgYSBuZXcgcmFuZG9tIG9yZGVyXG4gKi9cbmZ1bmN0aW9uKiByYW5kb21PbmNlKHZhbHVlcykge1xuICAgIC8vIGNyZWF0ZSBhbiBhcnJheSBvZiBpbmRpY2VzXG4gICAgY29uc3QgY29weSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvcHkucHVzaChpKTtcbiAgICB9XG4gICAgd2hpbGUgKGNvcHkubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyByYW5kb20gY2hvb3NlIGFuIGluZGV4LCBhbmQgdGhlbiByZW1vdmUgaXQgc28gaXQncyBub3QgY2hvc2VuIGFnYWluXG4gICAgICAgIGNvbnN0IHJhbmRWYWwgPSBjb3B5LnNwbGljZShNYXRoLmZsb29yKGNvcHkubGVuZ3RoICogTWF0aC5yYW5kb20oKSksIDEpO1xuICAgICAgICBjb25zdCBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUocmFuZFZhbFswXSwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFJhbmRvbWx5IGNob29zZSB0byB3YWxrIHVwIG9yIGRvd24gMSBpbmRleCBpbiB0aGUgdmFsdWVzIGFycmF5XG4gKi9cbmZ1bmN0aW9uKiByYW5kb21XYWxrKHZhbHVlcykge1xuICAgIC8vIHJhbmRvbWx5IGNob29zZSBhIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB2YWx1ZXMgYXJyYXlcbiAgICBsZXQgaW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB2YWx1ZXMubGVuZ3RoKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIGluZGV4Kys7IC8vIGF0IGJvdHRvbSBvZiBhcnJheSwgc28gZm9yY2UgdXB3YXJkIHN0ZXBcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PT0gdmFsdWVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGluZGV4LS07IC8vIGF0IHRvcCBvZiBhcnJheSwgc28gZm9yY2UgZG93bndhcmQgc3RlcFxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKE1hdGgucmFuZG9tKCkgPCAwLjUpIHsgLy8gZWxzZSBjaG9vc2UgcmFuZG9tIGRvd253YXJkIG9yIHVwd2FyZCBzdGVwXG4gICAgICAgICAgICBpbmRleC0tO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgIH1cbn1cbi8qKlxuICogUGF0dGVybkdlbmVyYXRvciByZXR1cm5zIGEgZ2VuZXJhdG9yIHdoaWNoIHdpbGwgaXRlcmF0ZSBvdmVyIHRoZSBnaXZlbiBhcnJheVxuICogb2YgdmFsdWVzIGFuZCB5aWVsZCB0aGUgaXRlbXMgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgaW4gcGF0dGVyblxuICogQHBhcmFtIHZhbHVlcyBBbiBhcnJheSBvZiB2YWx1ZXMgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0gcGF0dGVybiBUaGUgbmFtZSBvZiB0aGUgcGF0dGVybiB1c2Ugd2hlbiBpdGVyYXRpbmcgb3ZlclxuICogQHBhcmFtIGluZGV4IFdoZXJlIHRvIHN0YXJ0IGluIHRoZSBvZmZzZXQgb2YgdGhlIHZhbHVlcyBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24qIFBhdHRlcm5HZW5lcmF0b3IodmFsdWVzLCBwYXR0ZXJuID0gXCJ1cFwiLCBpbmRleCA9IDApIHtcbiAgICAvLyBzYWZlZ3VhcmRzXG4gICAgYXNzZXJ0KHZhbHVlcy5sZW5ndGggPiAwLCBcIlRoZSBhcnJheSBtdXN0IGhhdmUgbW9yZSB0aGFuIG9uZSB2YWx1ZSBpbiBpdFwiKTtcbiAgICBzd2l0Y2ggKHBhdHRlcm4pIHtcbiAgICAgICAgY2FzZSBcInVwXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCB1cFBhdHRlcm5HZW4pO1xuICAgICAgICBjYXNlIFwiZG93blwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywgZG93blBhdHRlcm5HZW4pO1xuICAgICAgICBjYXNlIFwidXBEb3duXCI6XG4gICAgICAgICAgICB5aWVsZCogYWx0ZXJuYXRpbmdHZW5lcmF0b3IodmFsdWVzLCB0cnVlKTtcbiAgICAgICAgY2FzZSBcImRvd25VcFwiOlxuICAgICAgICAgICAgeWllbGQqIGFsdGVybmF0aW5nR2VuZXJhdG9yKHZhbHVlcywgZmFsc2UpO1xuICAgICAgICBjYXNlIFwiYWx0ZXJuYXRlVXBcIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGp1bXBVcCk7XG4gICAgICAgIGNhc2UgXCJhbHRlcm5hdGVEb3duXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCBqdW1wRG93bik7XG4gICAgICAgIGNhc2UgXCJyYW5kb21cIjpcbiAgICAgICAgICAgIHlpZWxkKiByYW5kb21HZW4odmFsdWVzKTtcbiAgICAgICAgY2FzZSBcInJhbmRvbU9uY2VcIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIHJhbmRvbU9uY2UpO1xuICAgICAgICBjYXNlIFwicmFuZG9tV2Fsa1wiOlxuICAgICAgICAgICAgeWllbGQqIHJhbmRvbVdhbGsodmFsdWVzKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXR0ZXJuR2VuZXJhdG9yLmpzLm1hcCIsImltcG9ydCB7IExvb3AgfSBmcm9tIFwiLi9Mb29wXCI7XG5pbXBvcnQgeyBQYXR0ZXJuR2VuZXJhdG9yIH0gZnJvbSBcIi4vUGF0dGVybkdlbmVyYXRvclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogUGF0dGVybiBhcnBlZ2dpYXRlcyBiZXR3ZWVuIHRoZSBnaXZlbiBub3Rlc1xuICogaW4gYSBudW1iZXIgb2YgcGF0dGVybnMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGF0dGVybiA9IG5ldyBUb25lLlBhdHRlcm4oKHRpbWUsIG5vdGUpID0+IHtcbiAqIFx0Ly8gdGhlIG9yZGVyIG9mIHRoZSBub3RlcyBwYXNzZWQgaW4gZGVwZW5kcyBvbiB0aGUgcGF0dGVyblxuICogfSwgW1wiQzJcIiwgXCJENFwiLCBcIkU1XCIsIFwiQTZcIl0sIFwidXBEb3duXCIpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYXR0ZXJuIGV4dGVuZHMgTG9vcCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhdHRlcm4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcInZhbHVlc1wiLCBcInBhdHRlcm5cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXR0ZXJuXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXR0ZXJuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZXNcIiwgXCJwYXR0ZXJuXCJdKTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3ZhbHVlcyA9IG9wdGlvbnMudmFsdWVzO1xuICAgICAgICB0aGlzLl9wYXR0ZXJuID0gUGF0dGVybkdlbmVyYXRvcihvcHRpb25zLnZhbHVlcywgb3B0aW9ucy5wYXR0ZXJuKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMucGF0dGVybjtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMb29wLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhdHRlcm46IFwidXBcIixcbiAgICAgICAgICAgIHZhbHVlczogW10sXG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIHRoZSBub3RlcyBzaG91bGQgYmUgY2FsbGVkXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3BhdHRlcm4ubmV4dCgpO1xuICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlLnZhbHVlO1xuICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRoaXMuX3ZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFycmF5IG9mIGV2ZW50cy5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWVzO1xuICAgIH1cbiAgICBzZXQgdmFsdWVzKHZhbCkge1xuICAgICAgICB0aGlzLl92YWx1ZXMgPSB2YWw7XG4gICAgICAgIC8vIHJlc2V0IHRoZSBwYXR0ZXJuXG4gICAgICAgIHRoaXMucGF0dGVybiA9IHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwYXR0ZXJuLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0dGVybiB0eXBlLiBTZWUgVG9uZS5DdHJsUGF0dGVybiBmb3IgdGhlIGZ1bGwgbGlzdCBvZiBwYXR0ZXJucy5cbiAgICAgKi9cbiAgICBnZXQgcGF0dGVybigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCBwYXR0ZXJuKHBhdHRlcm4pIHtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHBhdHRlcm47XG4gICAgICAgIHRoaXMuX3BhdHRlcm4gPSBQYXR0ZXJuR2VuZXJhdG9yKHRoaXMuX3ZhbHVlcywgdGhpcy5fdHlwZSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGF0dGVybi5qcy5tYXAiLCJpbXBvcnQgeyBUaWNrc0NsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgUGFydCB9IGZyb20gXCIuL1BhcnRcIjtcbmltcG9ydCB7IFRvbmVFdmVudCB9IGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLyoqXG4gKiBBIHNlcXVlbmNlIGlzIGFuIGFsdGVybmF0ZSBub3RhdGlvbiBvZiBhIHBhcnQuIEluc3RlYWRcbiAqIG9mIHBhc3NpbmcgaW4gYW4gYXJyYXkgb2YgW3RpbWUsIGV2ZW50XSBwYWlycywgcGFzc1xuICogaW4gYW4gYXJyYXkgb2YgZXZlbnRzIHdoaWNoIHdpbGwgYmUgc3BhY2VkIGF0IHRoZVxuICogZ2l2ZW4gc3ViZGl2aXNpb24uIFN1Yi1hcnJheXMgd2lsbCBzdWJkaXZpZGUgdGhhdCBiZWF0XG4gKiBieSB0aGUgbnVtYmVyIG9mIGl0ZW1zIGFyZSBpbiB0aGUgYXJyYXkuXG4gKiBTZXF1ZW5jZSBub3RhdGlvbiBpbnNwaXJhdGlvbiBmcm9tIFtUaWRhbF0oaHR0cDovL3lheHUub3JnL3RpZGFsLylcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgc2VxID0gbmV3IFRvbmUuU2VxdWVuY2UoKHRpbWUsIG5vdGUpID0+IHtcbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgMC4xLCB0aW1lKTtcbiAqIFx0Ly8gc3ViZGl2aXNpb25zIGFyZSBnaXZlbiBhcyBzdWJhcnJheXNcbiAqIH0sIFtcIkM0XCIsIFtcIkU0XCIsIFwiRDRcIiwgXCJFNFwiXSwgXCJHNFwiLCBbXCJBNFwiLCBcIkc0XCJdXSkuc3RhcnQoMCk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTZXF1ZW5jZSBleHRlbmRzIFRvbmVFdmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNlcXVlbmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIiwgXCJzdWJkaXZpc2lvblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNlcXVlbmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb2JqZWN0IHJlc3BvbnNpYmxlIGZvciBzY2hlZHVsaW5nIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wYXJ0ID0gbmV3IFBhcnQoe1xuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3NlcUNhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogcHJpdmF0ZSByZWZlcmVuY2UgdG8gYWxsIG9mIHRoZSBzZXF1ZW5jZSBwcm94aWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwcm94aWVkIGFycmF5XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHNBcnJheSA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2VxdWVuY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiLCBcInN1YmRpdmlzaW9uXCJdKTtcbiAgICAgICAgdGhpcy5fc3ViZGl2aXNpb24gPSB0aGlzLnRvVGlja3Mob3B0aW9ucy5zdWJkaXZpc2lvbik7XG4gICAgICAgIHRoaXMuZXZlbnRzID0gb3B0aW9ucy5ldmVudHM7XG4gICAgICAgIC8vIHNldCBhbGwgb2YgdGhlIHZhbHVlc1xuICAgICAgICB0aGlzLmxvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5wcm9iYWJpbGl0eSA9IG9wdGlvbnMucHJvYmFiaWxpdHk7XG4gICAgICAgIHRoaXMuaHVtYW5pemUgPSBvcHRpb25zLmh1bWFuaXplO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIFtcInZhbHVlXCJdKSwge1xuICAgICAgICAgICAgZXZlbnRzOiBbXSxcbiAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgc3ViZGl2aXNpb246IFwiOG5cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlcm5hbCBjYWxsYmFjayBmb3Igd2hlbiBhbiBldmVudCBpcyBpbnZva2VkXG4gICAgICovXG4gICAgX3NlcUNhbGxiYWNrKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNlcXVlbmNlXG4gICAgICovXG4gICAgZ2V0IGV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cztcbiAgICB9XG4gICAgc2V0IGV2ZW50cyhzKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQXJyYXkgPSBzO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSB0aGlzLl9jcmVhdGVTZXF1ZW5jZSh0aGlzLl9ldmVudHNBcnJheSk7XG4gICAgICAgIHRoaXMuX2V2ZW50c1VwZGF0ZWQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICAgIFdoZW4gdG8gc3RhcnQgdGhlIHBhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgIFRoZSBvZmZzZXQgaW5kZXggdG8gc3RhcnQgYXRcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdGFydCh0aW1lLCBvZmZzZXQgPyB0aGlzLl9pbmRleFRpbWUob2Zmc2V0KSA6IG9mZnNldCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdG9wIHRoZSBwYXJ0LlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJ0LnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3ViZGl2aXNpb24gb2YgdGhlIHNlcXVlbmNlLiBUaGlzIGNhbiBvbmx5IGJlXG4gICAgICogc2V0IGluIHRoZSBjb25zdHJ1Y3Rvci4gVGhlIHN1YmRpdmlzaW9uIGlzIHRoZVxuICAgICAqIGludGVydmFsIGJldHdlZW4gc3VjY2Vzc2l2ZSBzdGVwcy5cbiAgICAgKi9cbiAgICBnZXQgc3ViZGl2aXNpb24oKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N1YmRpdmlzaW9uKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgc2VxdWVuY2UgcHJveHkgd2hpY2ggY2FuIGJlIG1vbml0b3JlZCB0byBjcmVhdGUgc3Vic2VxdWVuY2VzXG4gICAgICovXG4gICAgX2NyZWF0ZVNlcXVlbmNlKGFycmF5KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoYXJyYXksIHtcbiAgICAgICAgICAgIGdldDogKHRhcmdldCwgcHJvcGVydHkpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBwcm9wZXJ0eSBpcyBpbmRleCBpbiB0aGlzIGNhc2VcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0W3Byb3BlcnR5XTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6ICh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc1N0cmluZyhwcm9wZXJ0eSkgJiYgaXNGaW5pdGUocGFyc2VJbnQocHJvcGVydHksIDEwKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcGVydHldID0gdGhpcy5fY3JlYXRlU2VxdWVuY2UodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1VwZGF0ZWQoKTtcbiAgICAgICAgICAgICAgICAvLyByZXR1cm4gdHJ1ZSB0byBhY2NlcHQgdGhlIGNoYW5nZXNcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBzZXF1ZW5jZSBoYXMgY2hhbmdlZCwgYWxsIG9mIHRoZSBldmVudHMgbmVlZCB0byBiZSByZWNyZWF0ZWRcbiAgICAgKi9cbiAgICBfZXZlbnRzVXBkYXRlZCgpIHtcbiAgICAgICAgdGhpcy5fcGFydC5jbGVhcigpO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlU2VxdWVuY2UodGhpcy5fZXZlbnRzQXJyYXksIHRoaXMuX3N1YmRpdmlzaW9uLCB0aGlzLnN0YXJ0T2Zmc2V0KTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBsb29wRW5kXG4gICAgICAgIHRoaXMubG9vcEVuZCA9IHRoaXMubG9vcEVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogcmVzY2hlZHVsZSBhbGwgb2YgdGhlIGV2ZW50cyB0aGF0IG5lZWQgdG8gYmUgcmVzY2hlZHVsZWRcbiAgICAgKi9cbiAgICBfcmVzY2hlZHVsZVNlcXVlbmNlKHNlcXVlbmNlLCBzdWJkaXZpc2lvbiwgc3RhcnRPZmZzZXQpIHtcbiAgICAgICAgc2VxdWVuY2UuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBldmVudE9mZnNldCA9IGluZGV4ICogKHN1YmRpdmlzaW9uKSArIHN0YXJ0T2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZVNlcXVlbmNlKHZhbHVlLCBzdWJkaXZpc2lvbiAvIHZhbHVlLmxlbmd0aCwgZXZlbnRPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBldmVudE9mZnNldCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnQuYWRkKHN0YXJ0VGltZSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBpbmRleCBnaXZlbiB0aGUgU2VxdWVuY2UncyBzdWJkaXZpc2lvblxuICAgICAqIEBwYXJhbSAgaW5kZXhcbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIG9mIHRoYXQgaW5kZXhcbiAgICAgKi9cbiAgICBfaW5kZXhUaW1lKGluZGV4KSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIGluZGV4ICogKHRoaXMuX3N1YmRpdmlzaW9uKSArIHRoaXMuc3RhcnRPZmZzZXQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhciBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9wYXJ0LmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcnQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gUFJPWFkgQ0FMTFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQubG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobCkge1xuICAgICAgICB0aGlzLl9wYXJ0Lmxvb3AgPSBsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIHNlcXVlbmNlIHNob3VsZCBzdGFydCBsb29waW5nXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChpbmRleCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBpbmRleDtcbiAgICAgICAgdGhpcy5fcGFydC5sb29wU3RhcnQgPSB0aGlzLl9pbmRleFRpbWUoaW5kZXgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIHNlcXVlbmNlIHNob3VsZCBlbmQgbG9vcGluZ1xuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQoaW5kZXgpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IGluZGV4O1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnQubG9vcEVuZCA9IHRoaXMuX2luZGV4VGltZSh0aGlzLl9ldmVudHNBcnJheS5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcGFydC5sb29wRW5kID0gdGhpcy5faW5kZXhUaW1lKGluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgc3RhcnRPZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnN0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQoc3RhcnQpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdGFydE9mZnNldCA9IHN0YXJ0O1xuICAgIH1cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wYXJ0LnBsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgfVxuICAgIGdldCBwcm9iYWJpbGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQucHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX3BhcnQucHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgIH1cbiAgICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnByb2dyZXNzO1xuICAgIH1cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmh1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3BhcnQuaHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygc2NoZWR1bGVkIGV2ZW50c1xuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmxlbmd0aDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TZXF1ZW5jZS5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9Mb29wXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QYXJ0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QYXR0ZXJuXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TZXF1ZW5jZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vVG9uZUV2ZW50XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0LCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEdhaW5Ub0F1ZGlvIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9HYWluVG9BdWRpb1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbi8qKlxuICogVG9uZS5Dcm9zc2ZhZGUgcHJvdmlkZXMgZXF1YWwgcG93ZXIgZmFkaW5nIGJldHdlZW4gdHdvIGlucHV0cy5cbiAqIE1vcmUgb24gY3Jvc3NmYWRpbmcgdGVjaG5pcXVlIFtoZXJlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GYWRlXyhhdWRpb19lbmdpbmVlcmluZykjQ3Jvc3NmYWRpbmcpLlxuICogYGBgXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0rXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKz4gaW5wdXQgYSArPi0tK1xuICogKy0tLS0tLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0rICAgICB8ICAgICAgICAgfCAgIHxcbiAqIHwgMXMgc2lnbmFsICs+LS0+IHN0ZXJlb1Bhbm5lck5vZGUgIEwgKz4tLS0tPiBnYWluICAgIHwgICB8XG4gKiArLS0tLS0tLS0tLS0rICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICstLS0tLS0tLS0rICAgfFxuICogICAgICAgICAgICAgICArLT4gcGFuICAgICAgICAgICAgICAgUiArPi0rICAgICAgICAgICAgICAgIHwgICArLS0tLS0tLS0rXG4gKiAgICAgICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgIHwgICAgICAgICAgICAgICAgKy0tLT4gb3V0cHV0ICs+XG4gKiAgKy0tLS0tLSsgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICstLS0tLS0tLS0rICAgfCAgICstLS0tLS0tLStcbiAqICB8IGZhZGUgKz4tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgfCArPiBpbnB1dCBiICs+LS0rXG4gKiAgKy0tLS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIHwgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLT4gZ2FpbiAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjcm9zc0ZhZGUgPSBuZXcgVG9uZS5Dcm9zc0ZhZGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBjb25uZWN0IHR3byBpbnB1dHMgVG9uZS50byBhL2JcbiAqIGNvbnN0IGlucHV0QSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoNDQwLCBcInNxdWFyZVwiKS5jb25uZWN0KGNyb3NzRmFkZS5hKS5zdGFydCgpO1xuICogY29uc3QgaW5wdXRCID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic2luZVwiKS5jb25uZWN0KGNyb3NzRmFkZS5iKS5zdGFydCgpO1xuICogLy8gdXNlIHRoZSBmYWRlIHRvIGNvbnRyb2wgdGhlIG1peCBiZXR3ZWVuIHRoZSB0d29cbiAqIGNyb3NzRmFkZS5mYWRlLnZhbHVlID0gMC41O1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ3Jvc3NGYWRlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ3Jvc3NGYWRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZmFkZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDcm9zc0ZhZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjcm9zc2ZhZGluZyBpcyBkb25lIGJ5IGEgU3RlcmVvUGFubmVyTm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogU3BsaXQgdGhlIG91dHB1dCBvZiB0aGUgcGFubmVyIG5vZGUgaW50byB0d28gdmFsdWVzIHVzZWQgdG8gY29udHJvbCB0aGUgZ2FpbnMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zcGxpdCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIoMik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0IHRoZSBmYWRlIHZhbHVlIGludG8gYW4gYXVkaW8gcmFuZ2UgdmFsdWUgc28gaXQgY2FuIGJlIGNvbm5lY3RlZFxuICAgICAgICAgKiB0byB0aGUgcGFubmVyLnBhbiBBdWRpb1BhcmFtXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nMmEgPSBuZXcgR2FpblRvQXVkaW8oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgd2hpY2ggaXMgYXQgZnVsbCBsZXZlbCB3aGVuIGZhZGUgPSAwXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmEgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnB1dCB3aGljaCBpcyBhdCBmdWxsIGxldmVsIHdoZW4gZmFkZSA9IDFcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBpcyBhIG1peCBiZXR3ZWVuIGBhYCBhbmQgYGJgIGF0IHRoZSByYXRpbyBvZiBgZmFkZWBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5hLCB0aGlzLmJdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ3Jvc3NGYWRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZmFkZVwiXSk7XG4gICAgICAgIHRoaXMuZmFkZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZhZGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZhZGVcIik7XG4gICAgICAgIHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgxKS5jb25uZWN0KHRoaXMuX3Bhbm5lcik7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIHN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XG4gICAgICAgIC8vIGRvZXNuJ3QgbWFrZSBhbnkgZGlmZmVyZW5jZSBmb3IgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NocmlzZ3V0dGFuZGluL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2lzc3Vlcy82NDdcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NwbGl0LCB0aGlzLmEuZ2FpbiwgMCk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc3BsaXQsIHRoaXMuYi5nYWluLCAxKTtcbiAgICAgICAgdGhpcy5mYWRlLmNoYWluKHRoaXMuX2cyYSwgdGhpcy5fcGFubmVyLnBhbik7XG4gICAgICAgIHRoaXMuYS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5iLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmFkZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmFkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2cyYS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q3Jvc3NGYWRlLmpzLm1hcCIsImltcG9ydCB7IENyb3NzRmFkZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogRWZmZWN0IGlzIHRoZSBiYXNlIGNsYXNzIGZvciBlZmZlY3RzLiBDb25uZWN0IHRoZSBlZmZlY3QgYmV0d2VlblxuICogdGhlIGVmZmVjdFNlbmQgYW5kIGVmZmVjdFJldHVybiBHYWluTm9kZXMsIHRoZW4gY29udHJvbCB0aGUgYW1vdW50IG9mXG4gKiBlZmZlY3Qgd2hpY2ggZ29lcyB0byB0aGUgb3V0cHV0IHVzaW5nIHRoZSB3ZXQgY29udHJvbC5cbiAqL1xuZXhwb3J0IGNsYXNzIEVmZmVjdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRWZmZWN0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgZHJ5d2V0IGtub2IgdG8gY29udHJvbCB0aGUgYW1vdW50IG9mIGVmZmVjdFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZHJ5V2V0ID0gbmV3IENyb3NzRmFkZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB3ZXQgY29udHJvbCBpcyBob3cgbXVjaCBvZiB0aGUgZWZmZWN0ZWRcbiAgICAgICAgICogd2lsbCBwYXNzIHRocm91Z2ggdG8gdGhlIG91dHB1dC4gMSA9IDEwMCUgZWZmZWN0ZWRcbiAgICAgICAgICogc2lnbmFsLCAwID0gMTAwJSBkcnkgc2lnbmFsLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy53ZXQgPSB0aGlzLl9kcnlXZXQuZmFkZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNvbm5lY3QgdGhlIGVmZmVjdFNlbmQgdG8gdGhlIGlucHV0IG9mIGh0ZSBlZmZlY3RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogY29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoZSBlZmZlY3QgdG8gdGhlIGVmZmVjdFJldHVyblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBlZmZlY3QgaW5wdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGVmZmVjdCBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZHJ5V2V0O1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmZhbih0aGlzLl9kcnlXZXQuYSwgdGhpcy5lZmZlY3RTZW5kKTtcbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY29ubmVjdCh0aGlzLl9kcnlXZXQuYik7XG4gICAgICAgIHRoaXMud2V0LnNldFZhbHVlQXRUaW1lKG9wdGlvbnMud2V0LCAwKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLmVmZmVjdFJldHVybiwgdGhpcy5lZmZlY3RTZW5kXTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ3ZXRcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB3ZXQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFpbnMgdGhlIGVmZmVjdCBpbiBiZXR3ZWVuIHRoZSBlZmZlY3RTZW5kIGFuZCBlZmZlY3RSZXR1cm5cbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0KGVmZmVjdCkge1xuICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGludGVybmFsIGNoYW5uZWxzXG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMucHVzaChlZmZlY3QpO1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4oZWZmZWN0LCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RyeVdldC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53ZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9FZmZlY3RcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgTEZPLWJhc2VkIGVmZmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBMRk9FZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTEZPRWZmZWN0XCI7XG4gICAgICAgIHRoaXMuX2xmbyA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGFtcGxpdHVkZTogb3B0aW9ucy5kZXB0aCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9sZm8uYW1wbGl0dWRlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmby5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIGRlcHRoOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGVmZmVjdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmby5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGxmb1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9sZm8uc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGZpbHRlciB0byB0aGUgdHJhbnNwb3J0LiBTZWUgW1tMRk8uc3luY11dXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvLnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgZmlsdGVyIGZyb20gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmby51bnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBMRk8ncyBvc2NpbGxhdG9yOiBTZWUgW1tPc2NpbGxhdG9yLnR5cGVdXVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgYXV0b0ZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBub2lzZSA9IG5ldyBUb25lLk5vaXNlKCkuc3RhcnQoKS5jb25uZWN0KGF1dG9GaWx0ZXIpO1xuICAgICAqIGF1dG9GaWx0ZXIudHlwZSA9IFwic3F1YXJlXCI7XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm8udHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm8udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlcHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TEZPRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZpbHRlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk9FZmZlY3QgfSBmcm9tIFwiLi9MRk9FZmZlY3RcIjtcbi8qKlxuICogQXV0b0ZpbHRlciBpcyBhIFRvbmUuRmlsdGVyIHdpdGggYSBUb25lLkxGTyBjb25uZWN0ZWQgdG8gdGhlIGZpbHRlciBjdXRvZmYgZnJlcXVlbmN5LlxuICogU2V0dGluZyB0aGUgTEZPIHJhdGUgYW5kIGRlcHRoIGFsbG93cyBmb3IgY29udHJvbCBvdmVyIHRoZSBmaWx0ZXIgbW9kdWxhdGlvbiByYXRlXG4gKiBhbmQgZGVwdGguXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhbiBhdXRvZmlsdGVyIGFuZCBzdGFydCBpdCdzIExGT1xuICogY29uc3QgYXV0b0ZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoXCI0blwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIHJvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgZmlsdGVyIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGF1dG9GaWx0ZXIpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvRmlsdGVyIGV4dGVuZHMgTEZPRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b0ZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0b0ZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b0ZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCJdKTtcbiAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXIsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSkpO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5maWx0ZXIpO1xuICAgICAgICB0aGlzLl9sZm8uY29ubmVjdCh0aGlzLmZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMuYmFzZUZyZXF1ZW5jeSA9IG9wdGlvbnMuYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMRk9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgb2N0YXZlczogMi42LFxuICAgICAgICAgICAgZmlsdGVyOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICAgICAgcm9sbG9mZjogLTEyLFxuICAgICAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmby5taW47XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KGZyZXEpIHtcbiAgICAgICAgdGhpcy5fbGZvLm1pbiA9IHRoaXMudG9GcmVxdWVuY3koZnJlcSk7XG4gICAgICAgIC8vIGFuZCBzZXQgdGhlIG1heFxuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSBvZiB0aGUgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdCkge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0O1xuICAgICAgICB0aGlzLl9sZm8ubWF4ID0gdGhpcy5fbGZvLm1pbiAqIE1hdGgucG93KDIsIG9jdCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdXRvRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBhbm5lciBpcyBhbiBlcXVhbCBwb3dlciBMZWZ0L1JpZ2h0IFBhbm5lci4gSXQgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgU3RlcmVvUGFubmVyTm9kZS5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIC8vIG1vdmUgdGhlIGlucHV0IHNpZ25hbCBmcm9tIHJpZ2h0IHRvIGxlZnRcbiAqIFx0Y29uc3QgcGFubmVyID0gbmV3IFRvbmUuUGFubmVyKDEpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0cGFubmVyLnBhbi5yYW1wVG8oLTEsIDAuNSk7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMTAwKS5jb25uZWN0KHBhbm5lcikuc3RhcnQoKTtcbiAqIH0sIDAuNSwgMik7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5uZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFubmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgcGFubmVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuY29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3Bhbm5lcjtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9wYW5uZXI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIl0pO1xuICAgICAgICB0aGlzLnBhbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBhbixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBhbixcbiAgICAgICAgICAgIG1pblZhbHVlOiAtMSxcbiAgICAgICAgICAgIG1heFZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIHN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XG4gICAgICAgIC8vIGRvZXNuJ3QgbWFrZSBhbnkgZGlmZmVyZW5jZSBmb3IgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NocmlzZ3V0dGFuZGluL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2lzc3Vlcy82NDdcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudCA9IG9wdGlvbnMuY2hhbm5lbENvdW50O1xuICAgICAgICB0aGlzLl9wYW5uZXIuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgLy8gaW5pdGlhbCB2YWx1ZVxuICAgICAgICByZWFkT25seSh0aGlzLCBcInBhblwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhbjogMCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5wYW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5uZXIuanMubWFwIiwiaW1wb3J0IHsgUGFubmVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1Bhbm5lclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk9FZmZlY3QgfSBmcm9tIFwiLi9MRk9FZmZlY3RcIjtcbi8qKlxuICogQXV0b1Bhbm5lciBpcyBhIFtbUGFubmVyXV0gd2l0aCBhbiBbW0xGT11dIGNvbm5lY3RlZCB0byB0aGUgcGFuIGFtb3VudC5cbiAqIFtSZWxhdGVkIFJlYWRpbmddKGh0dHBzOi8vd3d3LmFibGV0b24uY29tL2VuL2Jsb2cvYXV0b3Bhbi1jaG9wcGVyLWVmZmVjdC1hbmQtbW9yZS1saXZlc2Nob29sLykuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhbiBhdXRvcGFubmVyIGFuZCBzdGFydCBpdFxuICogY29uc3QgYXV0b1Bhbm5lciA9IG5ldyBUb25lLkF1dG9QYW5uZXIoXCI0blwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIHJvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgcGFubmVyIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGF1dG9QYW5uZXIpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvUGFubmVyIGV4dGVuZHMgTEZPRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1Bhbm5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dG9QYW5uZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9QYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSBuZXcgUGFubmVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9wYW5uZXIpO1xuICAgICAgICB0aGlzLl9sZm8uY29ubmVjdCh0aGlzLl9wYW5uZXIucGFuKTtcbiAgICAgICAgdGhpcy5fbGZvLm1pbiA9IC0xO1xuICAgICAgICB0aGlzLl9sZm8ubWF4ID0gMTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMRk9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1dG9QYW5uZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBPbmVQb2xlRmlsdGVyIH0gZnJvbSBcIi4uL2ZpbHRlci9PbmVQb2xlRmlsdGVyXCI7XG5pbXBvcnQgeyBBYnMgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0Fic1wiO1xuLyoqXG4gKiBGb2xsb3dlciBpcyBhIHNpbXBsZSBlbnZlbG9wZSBmb2xsb3dlci5cbiAqIEl0J3MgaW1wbGVtZW50ZWQgYnkgYXBwbHlpbmcgYSBsb3dwYXNzIGZpbHRlciB0byB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIGBgYFxuICogICAgICAgICAgKy0tLS0tKyAgICArLS0tLS0tLS0tLS0tLS0tK1xuICogSW5wdXQgKy0tPiBBYnMgKy0tLS0+IE9uZVBvbGVGaWx0ZXIgKy0tPiBPdXRwdXRcbiAqICAgICAgICAgICstLS0tLSsgICAgKy0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRm9sbG93ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRm9sbG93ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGb2xsb3dlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRm9sbG93ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pO1xuICAgICAgICB0aGlzLl9hYnMgPSB0aGlzLmlucHV0ID0gbmV3IEFicyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbG93cGFzcyA9IHRoaXMub3V0cHV0ID0gbmV3IE9uZVBvbGVGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAxIC8gdGhpcy50b1NlY29uZHMob3B0aW9ucy5zbW9vdGhpbmcpLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Ficy5jb25uZWN0KHRoaXMuX2xvd3Bhc3MpO1xuICAgICAgICB0aGlzLl9zbW9vdGhpbmcgPSBvcHRpb25zLnNtb290aGluZztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC4wNVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiB0aW1lIGl0IHRha2VzIGEgdmFsdWUgY2hhbmdlIHRvIGFycml2ZSBhdCB0aGUgdXBkYXRlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHNtb290aGluZykge1xuICAgICAgICB0aGlzLl9zbW9vdGhpbmcgPSBzbW9vdGhpbmc7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MuZnJlcXVlbmN5ID0gMSAvIHRoaXMudG9TZWNvbmRzKHRoaXMuc21vb3RoaW5nKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hYnMuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Rm9sbG93ZXIuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IEZvbGxvd2VyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9hbmFseXNpcy9Gb2xsb3dlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBTY2FsZUV4cCB9IGZyb20gXCIuLi9zaWduYWwvU2NhbGVFeHBcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQXV0b1dhaCBjb25uZWN0cyBhIFtbRm9sbG93ZXJdXSB0byBhIFtbRmlsdGVyXV0uXG4gKiBUaGUgZnJlcXVlbmN5IG9mIHRoZSBmaWx0ZXIsIGZvbGxvd3MgdGhlIGlucHV0IGFtcGxpdHVkZSBjdXJ2ZS5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgYXV0b1dhaCA9IG5ldyBUb25lLkF1dG9XYWgoNTAsIDYsIC0zMCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gaW5pdGlhbGl6ZSB0aGUgc3ludGggYW5kIGNvbm5lY3QgdG8gYXV0b3dhaFxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLmNvbm5lY3QoYXV0b1dhaCk7XG4gKiAvLyBRIHZhbHVlIGluZmx1ZW5jZXMgdGhlIGVmZmVjdCBvZiB0aGUgd2FoIC0gZGVmYXVsdCBpcyAyXG4gKiBhdXRvV2FoLlEudmFsdWUgPSA2O1xuICogLy8gbW9yZSBhdWRpYmxlIG9uIGhpZ2hlciBub3Rlc1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQXV0b1dhaCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9XYWguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcInNlbnNpdGl2aXR5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0b1dhaFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1dhaC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwic2Vuc2l0aXZpdHlcIl0pO1xuICAgICAgICB0aGlzLl9mb2xsb3dlciA9IG5ldyBGb2xsb3dlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzbW9vdGhpbmc6IG9wdGlvbnMuZm9sbG93ZXIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlID0gbmV3IFNjYWxlRXhwKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIGV4cG9uZW50OiAwLjUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLmJhc2VGcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2JhbmRwYXNzID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICByb2xsb2ZmOiAtNDgsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICBROiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wZWFraW5nID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcInBlYWtpbmdcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGVha2luZy5nYWluLnZhbHVlID0gb3B0aW9ucy5nYWluO1xuICAgICAgICB0aGlzLmdhaW4gPSB0aGlzLl9wZWFraW5nLmdhaW47XG4gICAgICAgIHRoaXMuUSA9IHRoaXMuX2JhbmRwYXNzLlE7XG4gICAgICAgIC8vIHRoZSBjb250cm9sIHNpZ25hbCBwYXRoXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbih0aGlzLl9pbnB1dEJvb3N0LCB0aGlzLl9mb2xsb3dlciwgdGhpcy5fc3dlZXBSYW5nZSk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UuY29ubmVjdCh0aGlzLl9iYW5kcGFzcy5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmNvbm5lY3QodGhpcy5fcGVha2luZy5mcmVxdWVuY3kpO1xuICAgICAgICAvLyB0aGUgZmlsdGVyZWQgcGF0aFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4odGhpcy5fYmFuZHBhc3MsIHRoaXMuX3BlYWtpbmcsIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHZhbHVlXG4gICAgICAgIHRoaXMuX3NldFN3ZWVwUmFuZ2UoKTtcbiAgICAgICAgdGhpcy5zZW5zaXRpdml0eSA9IG9wdGlvbnMuc2Vuc2l0aXZpdHk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImdhaW5cIiwgXCJRXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMTAwLFxuICAgICAgICAgICAgb2N0YXZlczogNixcbiAgICAgICAgICAgIHNlbnNpdGl2aXR5OiAwLFxuICAgICAgICAgICAgUTogMixcbiAgICAgICAgICAgIGdhaW46IDIsXG4gICAgICAgICAgICBmb2xsb3dlcjogMC4yLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIHRoYXQgdGhlIGZpbHRlciB3aWxsIHN3ZWVwIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5LlxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0YXZlcykge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcbiAgICAgICAgdGhpcy5fc2V0U3dlZXBSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZm9sbG93ZXIncyBzbW9vdGhpbmcgdGltZVxuICAgICAqL1xuICAgIGdldCBmb2xsb3dlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IGZvbGxvd2VyKGZvbGxvd2VyKSB7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZyA9IGZvbGxvd2VyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBmcmVxdWVuY3kgZnJvbSB3aGljaCB0aGUgc3dlZXAgd2lsbCBzdGFydCBmcm9tLlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3koYmFzZUZyZXEpIHtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3koYmFzZUZyZXEpO1xuICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzZW5zaXRpdml0eSB0byBjb250cm9sIGhvdyByZXNwb25zaXZlIHRvIHRoZSBpbnB1dCBzaWduYWwgdGhlIGZpbHRlciBpcy5cbiAgICAgKi9cbiAgICBnZXQgc2Vuc2l0aXZpdHkoKSB7XG4gICAgICAgIHJldHVybiBnYWluVG9EYigxIC8gdGhpcy5faW5wdXRCb29zdC5nYWluLnZhbHVlKTtcbiAgICB9XG4gICAgc2V0IHNlbnNpdGl2aXR5KHNlbnNpdGl2aXR5KSB7XG4gICAgICAgIHRoaXMuX2lucHV0Qm9vc3QuZ2Fpbi52YWx1ZSA9IDEgLyBkYlRvR2FpbihzZW5zaXRpdml0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHNldHMgdGhlIHN3ZWVwIHJhbmdlIG9mIHRoZSBzY2FsZXJcbiAgICAgKi9cbiAgICBfc2V0U3dlZXBSYW5nZSgpIHtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5taW4gPSB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLm1heCA9IE1hdGgubWluKHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCB0aGlzLl9vY3RhdmVzKSwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAyKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9iYW5kcGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BlYWtpbmcuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXV0b1dhaC5qcy5tYXAiLCJpbXBvcnQgXCIuLi9jb3JlL3dvcmtsZXQvU2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldFwiO1xuaW1wb3J0IHsgcmVnaXN0ZXJQcm9jZXNzb3IgfSBmcm9tIFwiLi4vY29yZS93b3JrbGV0L1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNvbnN0IHdvcmtsZXROYW1lID0gXCJiaXQtY3J1c2hlclwiO1xuZXhwb3J0IGNvbnN0IGJpdENydXNoZXJXb3JrbGV0ID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdGNsYXNzIEJpdENydXNoZXJXb3JrbGV0IGV4dGVuZHMgU2luZ2xlSU9Qcm9jZXNzb3Ige1xuXG5cdFx0c3RhdGljIGdldCBwYXJhbWV0ZXJEZXNjcmlwdG9ycygpIHtcblx0XHRcdHJldHVybiBbe1xuXHRcdFx0XHRuYW1lOiBcImJpdHNcIixcblx0XHRcdFx0ZGVmYXVsdFZhbHVlOiAxMixcblx0XHRcdFx0bWluVmFsdWU6IDEsXG5cdFx0XHRcdG1heFZhbHVlOiAxNixcblx0XHRcdFx0YXV0b21hdGlvblJhdGU6ICdrLXJhdGUnXG5cdFx0XHR9XTtcblx0XHR9XG5cblx0XHRnZW5lcmF0ZShpbnB1dCwgX2NoYW5uZWwsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IHN0ZXAgPSBNYXRoLnBvdygwLjUsIHBhcmFtZXRlcnMuYml0cyAtIDEpO1xuXHRcdFx0Y29uc3QgdmFsID0gc3RlcCAqIE1hdGguZmxvb3IoaW5wdXQgLyBzdGVwICsgMC41KTtcblx0XHRcdHJldHVybiB2YWw7XG5cdFx0fVxuXHR9XG5gO1xucmVnaXN0ZXJQcm9jZXNzb3Iod29ya2xldE5hbWUsIGJpdENydXNoZXJXb3JrbGV0KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpdENydXNoZXIud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Xb3JrbGV0IH0gZnJvbSBcIi4uL2NvcmUvd29ya2xldC9Ub25lQXVkaW9Xb3JrbGV0XCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyB3b3JrbGV0TmFtZSB9IGZyb20gXCIuL0JpdENydXNoZXIud29ya2xldFwiO1xuLyoqXG4gKiBCaXRDcnVzaGVyIGRvd24tc2FtcGxlcyB0aGUgaW5jb21pbmcgc2lnbmFsIHRvIGEgZGlmZmVyZW50IGJpdCBkZXB0aC5cbiAqIExvd2VyaW5nIHRoZSBiaXQgZGVwdGggb2YgdGhlIHNpZ25hbCBjcmVhdGVzIGRpc3RvcnRpb24uIFJlYWQgbW9yZSBhYm91dCBCaXRDcnVzaGluZ1xuICogb24gW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQml0Y3J1c2hlcikuXG4gKiBAZXhhbXBsZVxuICogLy8gaW5pdGlhbGl6ZSBjcnVzaGVyIGFuZCByb3V0ZSBhIHN5bnRoIHRocm91Z2ggaXRcbiAqIGNvbnN0IGNydXNoZXIgPSBuZXcgVG9uZS5CaXRDcnVzaGVyKDQpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS5jb25uZWN0KGNydXNoZXIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDMlwiLCAyKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBCaXRDcnVzaGVyIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJpdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJCaXRDcnVzaGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXRDcnVzaGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYml0c1wiXSk7XG4gICAgICAgIHRoaXMuX2JpdENydXNoZXJXb3JrbGV0ID0gbmV3IEJpdENydXNoZXJXb3JrbGV0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGJpdHM6IG9wdGlvbnMuYml0cyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX2JpdENydXNoZXJXb3JrbGV0KTtcbiAgICAgICAgdGhpcy5iaXRzID0gdGhpcy5fYml0Q3J1c2hlcldvcmtsZXQuYml0cztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYml0czogNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYml0Q3J1c2hlcldvcmtsZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEludGVybmFsIGNsYXNzIHdoaWNoIGNyZWF0ZXMgYW4gQXVkaW9Xb3JrbGV0IHRvIGRvIHRoZSBiaXQgY3J1c2hpbmdcbiAqL1xuY2xhc3MgQml0Q3J1c2hlcldvcmtsZXQgZXh0ZW5kcyBUb25lQXVkaW9Xb3JrbGV0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlcldvcmtsZXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQml0Q3J1c2hlcldvcmtsZXRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXJXb3JrbGV0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5iaXRzID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmJpdHMsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgbWluVmFsdWU6IDEsXG4gICAgICAgICAgICBtYXhWYWx1ZTogMTYsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZHVtbXlQYXJhbSxcbiAgICAgICAgICAgIHN3YXBwYWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvV29ya2xldC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiaXRzOiAxMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9hdWRpb1dvcmtsZXROYW1lKCkge1xuICAgICAgICByZXR1cm4gd29ya2xldE5hbWU7XG4gICAgfVxuICAgIG9uUmVhZHkobm9kZSkge1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIG5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29uc3QgYml0cyA9IG5vZGUucGFyYW1ldGVycy5nZXQoXCJiaXRzXCIpO1xuICAgICAgICB0aGlzLmJpdHMuc2V0UGFyYW0oYml0cyk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5iaXRzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Qml0Q3J1c2hlci5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuLi9zaWduYWwvV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBDaGVieXNoZXYgaXMgYSB3YXZlc2hhcGVyIHdoaWNoIGlzIGdvb2RcbiAqIGZvciBtYWtpbmcgZGlmZmVyZW50IHR5cGVzIG9mIGRpc3RvcnRpb24gc291bmRzLlxuICogTm90ZSB0aGF0IG9kZCBvcmRlcnMgc291bmQgdmVyeSBkaWZmZXJlbnQgZnJvbSBldmVuIG9uZXMsXG4gKiBhbmQgb3JkZXIgPSAxIGlzIG5vIGNoYW5nZS5cbiAqIFJlYWQgbW9yZSBhdCBbbXVzaWMuY29sdW1iaWEuZWR1XShodHRwOi8vbXVzaWMuY29sdW1iaWEuZWR1L2NtYy9tdXNpY2FuZGNvbXB1dGVycy9jaGFwdGVyNC8wNF8wNi5waHApLlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhIG5ldyBjaGVieVxuICogY29uc3QgY2hlYnkgPSBuZXcgVG9uZS5DaGVieXNoZXYoNTApLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIGNyZWF0ZSBhIG1vbm9zeW50aCBjb25uZWN0ZWQgdG8gb3VyIGNoZWJ5XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk1vbm9TeW50aCgpLmNvbm5lY3QoY2hlYnkpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDMlwiLCAwLjQpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQ2hlYnlzaGV2IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hlYnlzaGV2LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib3JkZXJcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDaGVieXNoZXZcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENoZWJ5c2hldi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9yZGVyXCJdKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbGVuZ3RoOiA0MDk2XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9vcmRlciA9IG9wdGlvbnMub3JkZXI7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9zaGFwZXIpO1xuICAgICAgICB0aGlzLm9yZGVyID0gb3B0aW9ucy5vcmRlcjtcbiAgICAgICAgdGhpcy5vdmVyc2FtcGxlID0gb3B0aW9ucy5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBvcmRlcjogMSxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6IFwibm9uZVwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIGNvZWZmaWNpZW50IGZvciB0aGF0IGRlZ3JlZVxuICAgICAqIEBwYXJhbSAgeCB0aGUgeCB2YWx1ZVxuICAgICAqIEBwYXJhbSAgZGVncmVlXG4gICAgICogQHBhcmFtICBtZW1vIG1lbW9pemUgdGhlIGNvbXB1dGVkIHZhbHVlLiB0aGlzIHNwZWVkcyB1cCBjb21wdXRhdGlvbiBncmVhdGx5LlxuICAgICAqL1xuICAgIF9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUsIG1lbW8pIHtcbiAgICAgICAgaWYgKG1lbW8uaGFzKGRlZ3JlZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBtZW1vLmdldChkZWdyZWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRlZ3JlZSA9PT0gMCkge1xuICAgICAgICAgICAgbWVtby5zZXQoZGVncmVlLCAwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkZWdyZWUgPT09IDEpIHtcbiAgICAgICAgICAgIG1lbW8uc2V0KGRlZ3JlZSwgeCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtZW1vLnNldChkZWdyZWUsIDIgKiB4ICogdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlIC0gMSwgbWVtbykgLSB0aGlzLl9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUgLSAyLCBtZW1vKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW8uZ2V0KGRlZ3JlZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvcmRlciBvZiB0aGUgQ2hlYnlzaGV2IHBvbHlub21pYWwgd2hpY2ggY3JlYXRlcyB0aGUgZXF1YXRpb24gd2hpY2ggaXMgYXBwbGllZCB0byB0aGUgaW5jb21pbmdcbiAgICAgKiBzaWduYWwgdGhyb3VnaCBhIFRvbmUuV2F2ZVNoYXBlci4gVGhlIGVxdWF0aW9ucyBhcmUgaW4gdGhlIGZvcm06XG4gICAgICogYGBgXG4gICAgICogb3JkZXIgMjogMnheMiArIDFcbiAgICAgKiBvcmRlciAzOiA0eF4zICsgM3hcbiAgICAgKiBgYGBcbiAgICAgKiBAbWluIDFcbiAgICAgKiBAbWF4IDEwMFxuICAgICAqL1xuICAgIGdldCBvcmRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29yZGVyO1xuICAgIH1cbiAgICBzZXQgb3JkZXIob3JkZXIpIHtcbiAgICAgICAgdGhpcy5fb3JkZXIgPSBvcmRlcjtcbiAgICAgICAgdGhpcy5fc2hhcGVyLnNldE1hcCgoeCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgb3JkZXIsIG5ldyBNYXAoKSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG92ZXJzYW1wbGluZyBvZiB0aGUgZWZmZWN0LiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaGVieXNoZXYuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIFNwbGl0IHNwbGl0cyBhbiBpbmNvbWluZyBzaWduYWwgaW50byB0aGUgbnVtYmVyIG9mIGdpdmVuIGNoYW5uZWxzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzcGxpdCA9IG5ldyBUb25lLlNwbGl0KCk7XG4gKiAvLyBzdGVyZW9TaWduYWwuY29ubmVjdChzcGxpdCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3BsaXRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2hhbm5lbHNcIl0pO1xuICAgICAgICB0aGlzLl9zcGxpdHRlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIob3B0aW9ucy5jaGFubmVscyk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fc3BsaXR0ZXJdO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIE1lcmdlIGJyaW5ncyBtdWx0aXBsZSBtb25vIGlucHV0IGNoYW5uZWxzIGludG8gYSBzaW5nbGUgbXVsdGljaGFubmVsIG91dHB1dCBjaGFubmVsLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXJnZSA9IG5ldyBUb25lLk1lcmdlKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcm91dGluZyBhIHNpbmUgdG9uZSBpbiB0aGUgbGVmdCBjaGFubmVsXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChtZXJnZSwgMCwgMCkuc3RhcnQoKTtcbiAqIC8vIGFuZCBub2lzZSBpbiB0aGUgcmlnaHQgY2hhbm5lbFxuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLmNvbm5lY3QobWVyZ2UsIDAsIDEpLnN0YXJ0KCk7O1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWVyZ2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1lcmdlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXJnZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKTtcbiAgICAgICAgdGhpcy5fbWVyZ2VyID0gdGhpcy5vdXRwdXQgPSB0aGlzLmlucHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIob3B0aW9ucy5jaGFubmVscyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2VyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWVyZ2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCwgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ3Jvc3NGYWRlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIFN0ZXJlbyBlZmZlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvRWZmZWN0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGVyZW9FZmZlY3RcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvLyBmb3JjZSBtb25vIHNvdXJjZXMgdG8gYmUgc3RlcmVvXG4gICAgICAgIHRoaXMuaW5wdXQuY2hhbm5lbENvdW50ID0gMjtcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICB0aGlzLl9kcnlXZXQgPSB0aGlzLm91dHB1dCA9IG5ldyBDcm9zc0ZhZGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZmFkZTogb3B0aW9ucy53ZXRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMud2V0ID0gdGhpcy5fZHJ5V2V0LmZhZGU7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gbmV3IFNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSBuZXcgTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQsIGNoYW5uZWxzOiAyIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fc3BsaXQpO1xuICAgICAgICAvLyBkcnkgd2V0IGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9kcnlXZXQuYSk7XG4gICAgICAgIHRoaXMuX21lcmdlLmNvbm5lY3QodGhpcy5fZHJ5V2V0LmIpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3ZXRcIl0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBsZWZ0IHBhcnQgb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RMZWZ0KC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3Qobm9kZXNbMF0sIDAsIDApO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLm5vZGVzKTtcbiAgICAgICAgY29ubmVjdChub2Rlc1tub2Rlcy5sZW5ndGggLSAxXSwgdGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSByaWdodCBwYXJ0IG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0UmlnaHQoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdChub2Rlc1swXSwgMSwgMCk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXMoLi4ubm9kZXMpO1xuICAgICAgICBjb25uZWN0KG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdLCB0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB3ZXQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RyeVdldC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9FZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHN0ZXJlbyBmZWVkYmFjayBlZmZlY3RzIHdoZXJlIHRoZSBlZmZlY3RSZXR1cm4gaXMgZmVkIGJhY2sgaW50byB0aGUgc2FtZSBjaGFubmVsLlxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2sgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZlZWRiYWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0ID0gbmV3IFNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tNZXJnZSA9IG5ldyBNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tTcGxpdCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTWVyZ2UuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIGxlZnQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTCwgMCwgMCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDApO1xuICAgICAgICAvLyB0aGUgcmlnaHQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgcmlnaHQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrUiwgMSwgMCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDEpO1xuICAgICAgICAvLyB0aGUgZmVlZGJhY2sgY29udHJvbFxuICAgICAgICB0aGlzLmZlZWRiYWNrLmZhbih0aGlzLl9mZWVkYmFja0wuZ2FpbiwgdGhpcy5fZmVlZGJhY2tSLmdhaW4pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmZWVkYmFja1wiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZlZWRiYWNrOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0ZXJlb0ZlZWRiYWNrRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9TdGVyZW9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQ2hvcnVzIGlzIGEgc3RlcmVvIGNob3J1cyBlZmZlY3QgY29tcG9zZWQgb2YgYSBsZWZ0IGFuZCByaWdodCBkZWxheSB3aXRoIGFuIFtbTEZPXV0gYXBwbGllZCB0byB0aGUgZGVsYXlUaW1lIG9mIGVhY2ggY2hhbm5lbC5cbiAqIFdoZW4gW1tmZWVkYmFja11dIGlzIHNldCB0byBhIHZhbHVlIGxhcmdlciB0aGFuIDAsIHlvdSBhbHNvIGdldCBGbGFuZ2VyLXR5cGUgZWZmZWN0cy5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hL2Jsb2IvbWFzdGVyL3R1bmEuanMpLlxuICogUmVhZCBtb3JlIG9uIHRoZSBjaG9ydXMgZWZmZWN0IG9uIFtTb3VuZE9uU291bmRdKGh0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvanVuMDQvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmh0bSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNob3J1cyA9IG5ldyBUb25lLkNob3J1cyg0LCAyLjUsIDAuNSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aCgpLmNvbm5lY3QoY2hvcnVzKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkMzXCIsIFwiRTNcIiwgXCJHM1wiXSwgXCI4blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBDaG9ydXMgZXh0ZW5kcyBTdGVyZW9GZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENob3J1cy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlbGF5VGltZVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hvcnVzXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDaG9ydXMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZWxheVRpbWVcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuX2RlcHRoID0gb3B0aW9ucy5kZXB0aDtcbiAgICAgICAgdGhpcy5fZGVsYXlUaW1lID0gb3B0aW9ucy5kZWxheVRpbWUgLyAxMDAwO1xuICAgICAgICB0aGlzLl9sZm9MID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvUiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIHBoYXNlOiAxODBcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZUwgPSBuZXcgRGVsYXkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZVIgPSBuZXcgRGVsYXkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvTC5mcmVxdWVuY3k7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIC8vIGhhdmUgb25lIExGTyBmcmVxdWVuY3kgY29udHJvbCB0aGUgb3RoZXJcbiAgICAgICAgdGhpcy5fbGZvTC5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQodGhpcy5fZGVsYXlOb2RlTCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KHRoaXMuX2RlbGF5Tm9kZVIpO1xuICAgICAgICAvLyBsZm8gc2V0dXBcbiAgICAgICAgdGhpcy5fbGZvTC5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZUwuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZVIuZGVsYXlUaW1lKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHZhbHVlc1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fZGVwdGg7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9GZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEuNSxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMy41LFxuICAgICAgICAgICAgZGVwdGg6IDAuNyxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgc3ByZWFkOiAxODAsXG4gICAgICAgICAgICBmZWVkYmFjazogMCxcbiAgICAgICAgICAgIHdldDogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRlcHRoIG9mIHRoZSBlZmZlY3QuIEEgZGVwdGggb2YgMSBtYWtlcyB0aGUgZGVsYXlUaW1lXG4gICAgICogbW9kdWxhdGUgYmV0d2VlbiAwIGFuZCAyKmRlbGF5VGltZSAoY2VudGVyZWQgYXJvdW5kIHRoZSBkZWxheVRpbWUpLlxuICAgICAqL1xuICAgIGdldCBkZXB0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlcHRoO1xuICAgIH1cbiAgICBzZXQgZGVwdGgoZGVwdGgpIHtcbiAgICAgICAgdGhpcy5fZGVwdGggPSBkZXB0aDtcbiAgICAgICAgY29uc3QgZGV2aWF0aW9uID0gdGhpcy5fZGVsYXlUaW1lICogZGVwdGg7XG4gICAgICAgIHRoaXMuX2xmb0wubWluID0gTWF0aC5tYXgodGhpcy5fZGVsYXlUaW1lIC0gZGV2aWF0aW9uLCAwKTtcbiAgICAgICAgdGhpcy5fbGZvTC5tYXggPSB0aGlzLl9kZWxheVRpbWUgKyBkZXZpYXRpb247XG4gICAgICAgIHRoaXMuX2xmb1IubWluID0gTWF0aC5tYXgodGhpcy5fZGVsYXlUaW1lIC0gZGV2aWF0aW9uLCAwKTtcbiAgICAgICAgdGhpcy5fbGZvUi5tYXggPSB0aGlzLl9kZWxheVRpbWUgKyBkZXZpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZWxheVRpbWUgaW4gbWlsbGlzZWNvbmRzIG9mIHRoZSBjaG9ydXMuIEEgbGFyZ2VyIGRlbGF5VGltZVxuICAgICAqIHdpbGwgZ2l2ZSBhIG1vcmUgcHJvbm91bmNlZCBlZmZlY3QuIE5vbWluYWwgcmFuZ2UgYSBkZWxheVRpbWVcbiAgICAgKiBpcyBiZXR3ZWVuIDIgYW5kIDIwbXMuXG4gICAgICovXG4gICAgZ2V0IGRlbGF5VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlbGF5VGltZSAqIDEwMDA7XG4gICAgfVxuICAgIHNldCBkZWxheVRpbWUoZGVsYXlUaW1lKSB7XG4gICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IGRlbGF5VGltZSAvIDEwMDA7XG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9kZXB0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IgdHlwZSBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvTC50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2xmb1IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFtb3VudCBvZiBzdGVyZW8gc3ByZWFkLiBXaGVuIHNldCB0byAwLCBib3RoIExGTydzIHdpbGwgYmUgcGFubmVkIGNlbnRyYWxseS5cbiAgICAgKiBXaGVuIHNldCB0byAxODAsIExGTydzIHdpbGwgYmUgcGFubmVkIGhhcmQgbGVmdCBhbmQgcmlnaHQgcmVzcGVjdGl2ZWx5LlxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTtcbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5waGFzZSA9IDkwIC0gKHNwcmVhZCAvIDIpO1xuICAgICAgICB0aGlzLl9sZm9SLnBoYXNlID0gKHNwcmVhZCAvIDIpICsgOTA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBlZmZlY3QuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgbGZvXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgZmlsdGVyIHRvIHRoZSB0cmFuc3BvcnQuIFNlZSBbW0xGTy5zeW5jXV1cbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGZpbHRlciBmcm9tIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnVuc3luYygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZUwuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVSLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaG9ydXMuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4uL3NpZ25hbC9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbi8qKlxuICogQSBzaW1wbGUgZGlzdG9ydGlvbiBlZmZlY3QgdXNpbmcgVG9uZS5XYXZlU2hhcGVyLlxuICogQWxnb3JpdGhtIGZyb20gW3RoaXMgc3RhY2tvdmVyZmxvdyBhbnN3ZXJdKGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyMzEzNDA4KS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZGlzdCA9IG5ldyBUb25lLkRpc3RvcnRpb24oMC44KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBmbSA9IG5ldyBUb25lLkZNU3ludGgoKS5jb25uZWN0KGRpc3QpO1xuICogZm0udHJpZ2dlckF0dGFja1JlbGVhc2UoXCJBMVwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRGlzdG9ydGlvbiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKERpc3RvcnRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkaXN0b3J0aW9uXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGlzdG9ydGlvblwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRGlzdG9ydGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRpc3RvcnRpb25cIl0pO1xuICAgICAgICB0aGlzLl9zaGFwZXIgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsZW5ndGg6IDQwOTYsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9kaXN0b3J0aW9uID0gb3B0aW9ucy5kaXN0b3J0aW9uO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fc2hhcGVyKTtcbiAgICAgICAgdGhpcy5kaXN0b3J0aW9uID0gb3B0aW9ucy5kaXN0b3J0aW9uO1xuICAgICAgICB0aGlzLm92ZXJzYW1wbGUgPSBvcHRpb25zLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRpc3RvcnRpb246IDAuNCxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6IFwibm9uZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiBkaXN0b3J0aW9uLiBOb21pbmFsIHJhbmdlIGlzIGJldHdlZW4gMCBhbmQgMS5cbiAgICAgKi9cbiAgICBnZXQgZGlzdG9ydGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3RvcnRpb247XG4gICAgfVxuICAgIHNldCBkaXN0b3J0aW9uKGFtb3VudCkge1xuICAgICAgICB0aGlzLl9kaXN0b3J0aW9uID0gYW1vdW50O1xuICAgICAgICBjb25zdCBrID0gYW1vdW50ICogMTAwO1xuICAgICAgICBjb25zdCBkZWcgPSBNYXRoLlBJIC8gMTgwO1xuICAgICAgICB0aGlzLl9zaGFwZXIuc2V0TWFwKCh4KSA9PiB7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoeCkgPCAwLjAwMSkge1xuICAgICAgICAgICAgICAgIC8vIHNob3VsZCBvdXRwdXQgMCB3aGVuIGlucHV0IGlzIDBcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAoMyArIGspICogeCAqIDIwICogZGVnIC8gKE1hdGguUEkgKyBrICogTWF0aC5hYnMoeCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG92ZXJzYW1wbGluZyBvZiB0aGUgZWZmZWN0LiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EaXN0b3J0aW9uLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuLyoqXG4gKiBGZWVkYmFja0VmZmVjdCBwcm92aWRlcyBhIGxvb3AgYmV0d2VlbiBhbiBhdWRpbyBzb3VyY2UgYW5kIGl0cyBvd24gb3V0cHV0LlxuICogVGhpcyBpcyBhIGJhc2UtY2xhc3MgZm9yIGZlZWRiYWNrIGVmZmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZWVkYmFja0VmZmVjdCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0VmZmVjdFwiO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0dhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmZlZWRiYWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2sgPSB0aGlzLl9mZWVkYmFja0dhaW4uZ2FpbjtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmZWVkYmFja1wiKTtcbiAgICAgICAgLy8gdGhlIGZlZWRiYWNrIGxvb3BcbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY2hhaW4odGhpcy5fZmVlZGJhY2tHYWluLCB0aGlzLmVmZmVjdFNlbmQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmZWVkYmFjazogMC4xMjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2suZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9GZWVkYmFja0VmZmVjdFwiO1xuLyoqXG4gKiBGZWVkYmFja0RlbGF5IGlzIGEgRGVsYXlOb2RlIGluIHdoaWNoIHBhcnQgb2Ygb3V0cHV0IHNpZ25hbCBpcyBmZWQgYmFjayBpbnRvIHRoZSBkZWxheS5cbiAqXG4gKiBAcGFyYW0gZGVsYXlUaW1lIFRoZSBkZWxheSBhcHBsaWVkIHRvIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBAcGFyYW0gZmVlZGJhY2sgVGhlIGFtb3VudCBvZiB0aGUgZWZmZWN0ZWQgc2lnbmFsIHdoaWNoIGlzIGZlZCBiYWNrIHRocm91Z2ggdGhlIGRlbGF5LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZlZWRiYWNrRGVsYXkgPSBuZXcgVG9uZS5GZWVkYmFja0RlbGF5KFwiOG5cIiwgMC41KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCB0b20gPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKHtcbiAqIFx0b2N0YXZlczogNCxcbiAqIFx0cGl0Y2hEZWNheTogMC4xXG4gKiB9KS5jb25uZWN0KGZlZWRiYWNrRGVsYXkpO1xuICogdG9tLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTJcIiwgXCIzMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBGZWVkYmFja0RlbGF5IGV4dGVuZHMgRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0RlbGF5XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9kZWxheU5vZGUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMjUsXG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0RlbGF5LmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogUGhhc2VTaGlmdEFsbHBhc3MgaXMgYW4gdmVyeSBlZmZpY2llbnQgaW1wbGVtZW50YXRpb24gb2YgYSBIaWxiZXJ0IFRyYW5zZm9ybVxuICogdXNpbmcgdHdvIEFsbHBhc3MgZmlsdGVyIGJhbmtzIHdob3NlIG91dHB1dHMgaGF2ZSBhIHBoYXNlIGRpZmZlcmVuY2Ugb2YgOTDCsC5cbiAqIEhlcmUgdGhlIGBvZmZzZXQ5MGAgcGhhc2UgaXMgb2Zmc2V0IGJ5ICs5MMKwIGluIHJlbGF0aW9uIHRvIGBvdXRwdXRgLlxuICogQ29lZmZpY2llbnRzIGFuZCBzdHJ1Y3R1cmUgd2FzIGRldmVsb3BlZCBieSBPbGxpIE5pZW1pdGFsby5cbiAqIEZvciBtb3JlIGRldGFpbHMgc2VlOiBodHRwOi8veWVoYXIuY29tL2Jsb2cvP3A9MzY4XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQaGFzZVNoaWZ0QWxscGFzcyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGhhc2VTaGlmdEFsbHBhc3NcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBoYXNlIHNoaWZ0ZWQgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIFBoYXNlU2hpZnRlZCBhbGxwYXNzIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vZmZzZXQ5MCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICBjb25zdCBhbGxwYXNzQmFuazFWYWx1ZXMgPSBbMC42OTIzODc4LCAwLjkzNjA2NTQzMjI5NTksIDAuOTg4MjI5NTIyNjg2MCwgMC45OTg3NDg4NDUyNzM3XTtcbiAgICAgICAgY29uc3QgYWxscGFzc0JhbmsyVmFsdWVzID0gWzAuNDAyMTkyMTE2MjQyNiwgMC44NTYxNzEwODgyNDIwLCAwLjk3MjI5MDk1NDU2NTEsIDAuOTk1Mjg4NDc5MTI3OF07XG4gICAgICAgIHRoaXMuX2JhbmswID0gdGhpcy5fY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYWxscGFzc0JhbmsxVmFsdWVzKTtcbiAgICAgICAgdGhpcy5fYmFuazEgPSB0aGlzLl9jcmVhdGVBbGxQYXNzRmlsdGVyQmFuayhhbGxwYXNzQmFuazJWYWx1ZXMpO1xuICAgICAgICB0aGlzLl9vbmVTYW1wbGVEZWxheSA9IHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoWzAuMCwgMS4wXSwgWzEuMCwgMC4wXSk7XG4gICAgICAgIC8vIGNvbm5lY3QgQWxscGFzcyBmaWx0ZXIgYmFua3NcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9iYW5rMCwgdGhpcy5fb25lU2FtcGxlRGVsYXksIHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9iYW5rMSwgdGhpcy5vZmZzZXQ5MCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbGwgb2YgdGhlIElJUiBmaWx0ZXJzIGZyb20gYW4gYXJyYXkgb2YgdmFsdWVzIHVzaW5nIHRoZSBjb2VmZmljaWVudCBjYWxjdWxhdGlvbi5cbiAgICAgKi9cbiAgICBfY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYmFua1ZhbHVlcykge1xuICAgICAgICBjb25zdCBub2RlcyA9IGJhbmtWYWx1ZXMubWFwKHZhbHVlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvZWZmaWNpZW50cyA9IFtbdmFsdWUgKiB2YWx1ZSwgMCwgLTFdLCBbMSwgMCwgLSh2YWx1ZSAqIHZhbHVlKV1dO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoY29lZmZpY2llbnRzWzBdLCBjb2VmZmljaWVudHNbMV0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub2Zmc2V0OTAuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9iYW5rMC5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9iYW5rMS5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9vbmVTYW1wbGVEZWxheS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBoYXNlU2hpZnRBbGxwYXNzLmpzLm1hcCIsImltcG9ydCB7IFBoYXNlU2hpZnRBbGxwYXNzIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvUGhhc2VTaGlmdEFsbHBhc3NcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9FZmZlY3RcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuLi9zaWduYWwvQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IE5lZ2F0ZSB9IGZyb20gXCIuLi9zaWduYWwvTmVnYXRlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBUb25lT3NjaWxsYXRvck5vZGUgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG4vKipcbiAqIEZyZXF1ZW5jeVNoaWZ0ZXIgY2FuIGJlIHVzZWQgdG8gc2hpZnQgYWxsIGZyZXF1ZW5jaWVzIG9mIGEgc2lnbmFsIGJ5IGEgZml4ZWQgYW1vdW50LlxuICogVGhlIGFtb3VudCBjYW4gYmUgY2hhbmdlZCBhdCBhdWRpbyByYXRlIGFuZCB0aGUgZWZmZWN0IGlzIGFwcGxpZWQgaW4gcmVhbCB0aW1lLlxuICogVGhlIGZyZXF1ZW5jeSBzaGlmdGluZyBpcyBpbXBsZW1lbnRlZCB3aXRoIGEgdGVjaG5pcXVlIGNhbGxlZCBzaW5nbGUgc2lkZSBiYW5kIG1vZHVsYXRpb24gdXNpbmcgYSByaW5nIG1vZHVsYXRvci5cbiAqIE5vdGU6IENvbnRyYXJ5IHRvIHBpdGNoIHNoaWZ0aW5nLCBhbGwgZnJlcXVlbmNpZXMgYXJlIHNoaWZ0ZWQgYnkgdGhlIHNhbWUgYW1vdW50LFxuICogZGVzdHJveWluZyB0aGUgaGFybW9uaWMgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlbS4gVGhpcyBsZWFkcyB0byB0aGUgY2xhc3NpYyByaW5nIG1vZHVsYXRvciB0aW1icmUgZGlzdG9ydGlvbi5cbiAqIFRoZSBhbGdvcml0aG0gd2lsbCBwcm9kdWNlcyBzb21lIGFsaWFzaW5nIHRvd2FyZHMgdGhlIGhpZ2ggZW5kLCBlc3BlY2lhbGx5IGlmIHlvdXIgc291cmNlIG1hdGVyaWFsXG4gKiBjb250YWlucyBhIGxvdCBvZiBoaWdoIGZyZXF1ZW5jaWVzLiBVbmZvcnR1bmF0ZWxseSB0aGUgd2ViYXVkaW8gQVBJIGRvZXMgbm90IHN1cHBvcnQgcmVzYW1wbGluZ1xuICogYnVmZmVycyBpbiByZWFsIHRpbWUsIHNvIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBmaXggaXQgcHJvcGVybHkuIERlcGVuZGluZyBvbiB0aGUgdXNlIGNhc2UgaXQgbWlnaHRcbiAqIGJlIGFuIG9wdGlvbiB0byBsb3cgcGFzcyBmaWx0ZXIgeW91ciBpbnB1dCBiZWZvcmUgZnJlcXVlbmN5IHNoaWZ0aW5nIGl0IHRvIGdldCByaWRlIG9mIHRoZSBhbGlhc2luZy5cbiAqIFlvdSBjYW4gZmluZCBhIHZlcnkgZGV0YWlsZWQgZGVzY3JpcHRpb24gb2YgdGhlIGFsZ29yaXRobSBoZXJlOiBodHRwczovL2xhcnplaXRsaW4uZ2l0aHViLmlvL1JNRlMvXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGlucHV0ID0gbmV3IFRvbmUuT3NjaWxsYXRvcigyMzAsIFwic2F3dG9vdGhcIikuc3RhcnQoKTtcbiAqIGNvbnN0IHNoaWZ0ID0gbmV3IFRvbmUuRnJlcXVlbmN5U2hpZnRlcig0MikudG9EZXN0aW5hdGlvbigpO1xuICogaW5wdXQuY29ubmVjdChzaGlmdCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBGcmVxdWVuY3lTaGlmdGVyIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlcXVlbmN5U2hpZnRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZXF1ZW5jeVNoaWZ0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeVNoaWZ0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW5WYWx1ZTogLXRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gMixcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zaW5lID0gbmV3IFRvbmVPc2NpbGxhdG9yTm9kZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZSA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBoYXNlOiAtOTAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseSA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fY29zaW5lTXVsdGlwbHkgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX25lZ2F0ZSA9IG5ldyBOZWdhdGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2FkZCA9IG5ldyBBZGQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlciA9IG5ldyBQaGFzZVNoaWZ0QWxscGFzcyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNvbm5lY3QodGhpcy5fcGhhc2VTaGlmdGVyKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgY2FycmllciBmcmVxdWVuY3kgc2lnbmFsIHRvIHRoZSB0d28gb3NjaWxsYXRvcnNcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZmFuKHRoaXMuX3NpbmUuZnJlcXVlbmN5LCB0aGlzLl9jb3NpbmUuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLm9mZnNldDkwLmNvbm5lY3QodGhpcy5fY29zaW5lTXVsdGlwbHkpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuY29ubmVjdCh0aGlzLl9jb3NpbmVNdWx0aXBseS5mYWN0b3IpO1xuICAgICAgICB0aGlzLl9waGFzZVNoaWZ0ZXIuY29ubmVjdCh0aGlzLl9zaW5lTXVsdGlwbHkpO1xuICAgICAgICB0aGlzLl9zaW5lLmNvbm5lY3QodGhpcy5fc2luZU11bHRpcGx5LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseS5jb25uZWN0KHRoaXMuX25lZ2F0ZSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5LmNvbm5lY3QodGhpcy5fYWRkKTtcbiAgICAgICAgdGhpcy5fbmVnYXRlLmNvbm5lY3QodGhpcy5fYWRkLmFkZGVuZCk7XG4gICAgICAgIHRoaXMuX2FkZC5jb25uZWN0KHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIG9zY2lsbGF0b3JzIGF0IHRoZSBzYW1lIHRpbWVcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5pbW1lZGlhdGUoKTtcbiAgICAgICAgdGhpcy5fc2luZS5zdGFydChub3cpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuc3RhcnQobm93KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nvc2luZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbmVnYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2luZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZXF1ZW5jeVNoaWZ0ZXIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBMb3dwYXNzQ29tYkZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0xvd3Bhc3NDb21iRmlsdGVyXCI7XG4vKipcbiAqIEFuIGFycmF5IG9mIGNvbWIgZmlsdGVyIGRlbGF5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJUdW5pbmdzID0gWzE1NTcgLyA0NDEwMCwgMTYxNyAvIDQ0MTAwLCAxNDkxIC8gNDQxMDAsIDE0MjIgLyA0NDEwMCwgMTI3NyAvIDQ0MTAwLCAxMzU2IC8gNDQxMDAsIDExODggLyA0NDEwMCwgMTExNiAvIDQ0MTAwXTtcbi8qKlxuICogQW4gYXJyYXkgb2YgYWxscGFzcyBmaWx0ZXIgZnJlcXVlbmN5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG4gKi9cbmNvbnN0IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcyA9IFsyMjUsIDU1NiwgNDQxLCAzNDFdO1xuLyoqXG4gKiBGcmVldmVyYiBpcyBhIHJldmVyYiBiYXNlZCBvbiBbRnJlZXZlcmJdKGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L35qb3MvcGFzcC9GcmVldmVyYi5odG1sKS5cbiAqIFJlYWQgbW9yZSBvbiByZXZlcmIgb24gW1NvdW5kIE9uIFNvdW5kXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDQwODM5MDIvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tOjgwL3Nvcy9mZWIwMS9hcnRpY2xlcy9zeW50aHNlY3JldHMuYXNwKS5cbiAqIEZyZWV2ZXJiIGlzIG5vdyBpbXBsZW1lbnRlZCB3aXRoIGFuIEF1ZGlvV29ya2xldE5vZGUgd2hpY2ggbWF5IHJlc3VsdCBvbiBwZXJmb3JtYW5jZSBkZWdyYWRhdGlvbiBvbiBzb21lIHBsYXRmb3Jtcy4gQ29uc2lkZXIgdXNpbmcgW1tSZXZlcmJdXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmcmVldmVyYiA9IG5ldyBUb25lLkZyZWV2ZXJiKCkudG9EZXN0aW5hdGlvbigpO1xuICogZnJlZXZlcmIuZGFtcGVuaW5nID0gMTAwMDtcbiAqIC8vIHJvdXRpbmcgc3ludGggdGhyb3VnaCB0aGUgcmV2ZXJiXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS5jb25uZWN0KGZyZWV2ZXJiKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuMDUpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRnJlZXZlcmIgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCIsIFwiZGFtcGVuaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRnJlZXZlcmJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBjb21iIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSBsZWZ0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0wgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIHJpZ2h0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc1IgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZWV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIiwgXCJkYW1wZW5pbmdcIl0pO1xuICAgICAgICB0aGlzLnJvb21TaXplID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yb29tU2l6ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIHJpZ2h0XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTCA9IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzTCA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGFsbHBhc3NMLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIGFsbHBhc3NMLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzc0w7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIGxlZnRcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSID0gYWxscGFzc0ZpbHRlckZyZXF1ZW5jaWVzLm1hcChmcmVxID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFsbHBhc3NSID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgYWxscGFzc1IudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgYWxscGFzc1IuZnJlcXVlbmN5LnZhbHVlID0gZnJlcTtcbiAgICAgICAgICAgIHJldHVybiBhbGxwYXNzUjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGNvbWIgZmlsdGVyc1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVycyA9IGNvbWJGaWx0ZXJUdW5pbmdzLm1hcCgoZGVsYXlUaW1lLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGZwZiA9IG5ldyBMb3dwYXNzQ29tYkZpbHRlcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGRhbXBlbmluZzogb3B0aW9ucy5kYW1wZW5pbmcsXG4gICAgICAgICAgICAgICAgZGVsYXlUaW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggPCBjb21iRmlsdGVyVHVuaW5ncy5sZW5ndGggLyAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdChsZnBmLCAuLi50aGlzLl9hbGxwYXNzRmlsdGVyc0wpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQobGZwZiwgLi4udGhpcy5fYWxscGFzc0ZpbHRlcnNSKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucm9vbVNpemUuY29ubmVjdChsZnBmLnJlc29uYW5jZSk7XG4gICAgICAgICAgICByZXR1cm4gbGZwZjtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInJvb21TaXplXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcm9vbVNpemU6IDAuNyxcbiAgICAgICAgICAgIGRhbXBlbmluZzogMzAwMFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiBkYW1wZW5pbmcgb2YgdGhlIHJldmVyYmVyYW50IHNpZ25hbC5cbiAgICAgKi9cbiAgICBnZXQgZGFtcGVuaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29tYkZpbHRlcnNbMF0uZGFtcGVuaW5nO1xuICAgIH1cbiAgICBzZXQgZGFtcGVuaW5nKGQpIHtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMuZm9yRWFjaChjID0+IGMuZGFtcGVuaW5nID0gZCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNMLmZvckVhY2goYWwgPT4gYWwuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSLmZvckVhY2goYXIgPT4gYXIuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMuZm9yRWFjaChjZiA9PiBjZi5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLnJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RnJlZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZlZWRiYWNrQ29tYkZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBhbiBhcnJheSBvZiB0aGUgY29tYiBmaWx0ZXIgZGVsYXkgdGltZSB2YWx1ZXNcbiAqL1xuY29uc3QgY29tYkZpbHRlckRlbGF5VGltZXMgPSBbMTY4NyAvIDI1MDAwLCAxNjAxIC8gMjUwMDAsIDIwNTMgLyAyNTAwMCwgMjI1MSAvIDI1MDAwXTtcbi8qKlxuICogdGhlIHJlc29uYW5jZXMgb2YgZWFjaCBvZiB0aGUgY29tYiBmaWx0ZXJzXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJSZXNvbmFuY2VzID0gWzAuNzczLCAwLjgwMiwgMC43NTMsIDAuNzMzXTtcbi8qKlxuICogdGhlIGFsbHBhc3MgZmlsdGVyIGZyZXF1ZW5jaWVzXG4gKi9cbmNvbnN0IGFsbHBhc3NGaWx0ZXJGcmVxcyA9IFszNDcsIDExMywgMzddO1xuLyoqXG4gKiBKQ1JldmVyYiBpcyBhIHNpbXBsZSBbU2Nocm9lZGVyIFJldmVyYmVyYXRvcl0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL1NjaHJvZWRlcl9SZXZlcmJlcmF0b3JzLmh0bWwpXG4gKiB0dW5lZCBieSBKb2huIENob3duaW5nIGluIDE5NzAuXG4gKiBJdCBpcyBtYWRlIHVwIG9mIHRocmVlIGFsbHBhc3MgZmlsdGVycyBhbmQgZm91ciBbW0ZlZWRiYWNrQ29tYkZpbHRlcl1dLlxuICogSkNSZXZlcmIgaXMgbm93IGltcGxlbWVudGVkIHdpdGggYW4gQXVkaW9Xb3JrbGV0Tm9kZSB3aGljaCBtYXkgcmVzdWx0IG9uIHBlcmZvcm1hbmNlIGRlZ3JhZGF0aW9uIG9uIHNvbWUgcGxhdGZvcm1zLiBDb25zaWRlciB1c2luZyBbW1JldmVyYl1dLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHJldmVyYiA9IG5ldyBUb25lLkpDUmV2ZXJiKDAuNCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgZGVsYXkgPSBuZXcgVG9uZS5GZWVkYmFja0RlbGF5KDAuNSk7XG4gKiAvLyBjb25uZWN0aW5nIHRoZSBzeW50aCB0byByZXZlcmIgdGhyb3VnaCBkZWxheVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5EdW9TeW50aCgpLmNoYWluKGRlbGF5LCByZXZlcmIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJBNFwiLCBcIjhuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEpDUmV2ZXJiIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoSkNSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJyb29tU2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkpDUmV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBhIHNlcmllcyBvZiBhbGxwYXNzIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBwYXJhbGxlbCBmZWVkYmFjayBjb21iIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEpDUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIl0pO1xuICAgICAgICB0aGlzLnJvb21TaXplID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yb29tU2l6ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogLTAuNzMzLFxuICAgICAgICAgICAgbWF4OiAwLjE5NyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGFsbHBhc3MgZmlsdGVyc1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycyA9IGFsbHBhc3NGaWx0ZXJGcmVxcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgYWxscGFzcy50eXBlID0gXCJhbGxwYXNzXCI7XG4gICAgICAgICAgICBhbGxwYXNzLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzcztcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGFuZCB0aGUgY29tYiBmaWx0ZXJzXG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMgPSBjb21iRmlsdGVyRGVsYXlUaW1lcy5tYXAoKGRlbGF5VGltZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZiY2YgPSBuZXcgRmVlZGJhY2tDb21iRmlsdGVyKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgZGVsYXlUaW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmNvbm5lY3QoZmJjZi5yZXNvbmFuY2UpO1xuICAgICAgICAgICAgZmJjZi5yZXNvbmFuY2UudmFsdWUgPSBjb21iRmlsdGVyUmVzb25hbmNlc1tpbmRleF07XG4gICAgICAgICAgICBpZiAoaW5kZXggPCBjb21iRmlsdGVyRGVsYXlUaW1lcy5sZW5ndGggLyAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCguLi50aGlzLl9hbGxwYXNzRmlsdGVycywgZmJjZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCguLi50aGlzLl9hbGxwYXNzRmlsdGVycywgZmJjZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmJjZjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNoYWluIHRoZSBhbGxwYXNzIGZpbHRlcnMgdG9nZXRoZXJcbiAgICAgICAgdGhpcy5yb29tU2l6ZS5jb25uZWN0KHRoaXMuX3NjYWxlUm9vbVNpemUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyb29tU2l6ZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHJvb21TaXplOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzLmZvckVhY2goYXBmID0+IGFwZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzLmZvckVhY2goZmJjZiA9PiBmYmNmLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMucm9vbVNpemUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SkNSZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBKdXN0IGxpa2UgYSBbW1N0ZXJlb0ZlZWRiYWNrRWZmZWN0XV0sIGJ1dCB0aGUgZmVlZGJhY2sgaXMgcm91dGVkIGZyb20gbGVmdCB0byByaWdodFxuICogYW5kIHJpZ2h0IHRvIGxlZnQgaW5zdGVhZCBvZiBvbiB0aGUgc2FtZSBjaGFubmVsLlxuICogYGBgXG4gKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIGZlZWRiYWNrTCA8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiArLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0+ICAgICAgICArLS0tLT4gICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLStcbiAqICAgICAgZmVlZGJhY2tNZXJnZSArLS0+IHNwbGl0ICAgICAgICAoRUZGRUNUKSAgICAgICBtZXJnZSArLS0+IGZlZWRiYWNrU3BsaXQgICAgIHwgfFxuICogKy0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tPiAgICAgICAgKy0tLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tKyB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgZmVlZGJhY2tSIDwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9YRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBTdGVyZW9GZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLy8gdGhlIGxlZnQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgcmlnaHQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tNZXJnZSwgMCwgMSk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIHJpZ2h0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDApO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmZWVkYmFja1wiXSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvWEZlZWRiYWNrRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb1hGZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb1hGZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBpbmdQb25nRGVsYXkgaXMgYSBmZWVkYmFjayBkZWxheSBlZmZlY3Qgd2hlcmUgdGhlIGVjaG8gaXMgaGVhcmRcbiAqIGZpcnN0IGluIG9uZSBjaGFubmVsIGFuZCBuZXh0IGluIHRoZSBvcHBvc2l0ZSBjaGFubmVsLiBJbiBhIHN0ZXJlb1xuICogc3lzdGVtIHRoZXNlIGFyZSB0aGUgcmlnaHQgYW5kIGxlZnQgY2hhbm5lbHMuXG4gKiBQaW5nUG9uZ0RlbGF5IGluIG1vcmUgc2ltcGxpZmllZCB0ZXJtcyBpcyB0d28gVG9uZS5GZWVkYmFja0RlbGF5c1xuICogd2l0aCBpbmRlcGVuZGVudCBkZWxheSB2YWx1ZXMuIEVhY2ggZGVsYXkgaXMgcm91dGVkIHRvIG9uZSBjaGFubmVsXG4gKiAobGVmdCBvciByaWdodCksIGFuZCB0aGUgY2hhbm5lbCB0cmlnZ2VyZWQgc2Vjb25kIHdpbGwgYWx3YXlzXG4gKiB0cmlnZ2VyIGF0IHRoZSBzYW1lIGludGVydmFsIGFmdGVyIHRoZSBmaXJzdC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwaW5nUG9uZyA9IG5ldyBUb25lLlBpbmdQb25nRGVsYXkoXCI0blwiLCAwLjIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGRydW0gPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKCkuY29ubmVjdChwaW5nUG9uZyk7XG4gKiBkcnVtLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCIzMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaW5nUG9uZ0RlbGF5IGV4dGVuZHMgU3RlcmVvWEZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGluZ1BvbmdEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGluZ1BvbmdEZWxheVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGluZ1BvbmdEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKTtcbiAgICAgICAgdGhpcy5fbGVmdERlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHREZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCh0aGlzLl9sZWZ0RGVsYXkpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCh0aGlzLl9yaWdodFByZURlbGF5LCB0aGlzLl9yaWdodERlbGF5KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZmFuKHRoaXMuX2xlZnREZWxheS5kZWxheVRpbWUsIHRoaXMuX3JpZ2h0RGVsYXkuZGVsYXlUaW1lLCB0aGlzLl9yaWdodFByZURlbGF5LmRlbGF5VGltZSk7XG4gICAgICAgIC8vIHJlYXJyYW5nZWQgdGhlIGZlZWRiYWNrIHRvIGJlIGFmdGVyIHRoZSByaWdodFByZURlbGF5XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX3JpZ2h0RGVsYXkpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJkZWxheVRpbWVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb1hGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMjUsXG4gICAgICAgICAgICBtYXhEZWxheTogMVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0RGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodERlbGF5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGluZ1BvbmdEZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBGZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL0ZlZWRiYWNrRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IERlbGF5IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9EZWxheVwiO1xuaW1wb3J0IHsgQ3Jvc3NGYWRlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbi8qKlxuICogUGl0Y2hTaGlmdCBkb2VzIG5lYXItcmVhbHRpbWUgcGl0Y2ggc2hpZnRpbmcgdG8gdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIFRoZSBlZmZlY3QgaXMgYWNoaWV2ZWQgYnkgc3BlZWRpbmcgdXAgb3Igc2xvd2luZyBkb3duIHRoZSBkZWxheVRpbWVcbiAqIG9mIGEgRGVsYXlOb2RlIHVzaW5nIGEgc2F3dG9vdGggd2F2ZS5cbiAqIEFsZ29yaXRobSBmb3VuZCBpbiBbdGhpcyBwZGZdKGh0dHA6Ly9kc3AtYm9vay5uYXJvZC5ydS9zb3VuZHByb2MucGRmKS5cbiAqIEFkZGl0aW9uYWwgcmVmZXJlbmNlIGJ5IFtNaWxsZXIgUHVja2V0XShodHRwOi8vbXNwLnVjc2QuZWR1L3RlY2huaXF1ZXMvdjAuMTEvYm9vay1odG1sL25vZGUxMTUuaHRtbCkuXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaXRjaFNoaWZ0IGV4dGVuZHMgRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQaXRjaFNoaWZ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGl0Y2hcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQaXRjaFNoaWZ0XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQaXRjaFNoaWZ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGl0Y2hcIl0pO1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9kZWxheUEgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb0EgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fZGVsYXlBLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2RlbGF5QiA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvQiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAwLjEsXG4gICAgICAgICAgICB0eXBlOiBcInNhd3Rvb3RoXCIsXG4gICAgICAgICAgICBwaGFzZTogMTgwXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fZGVsYXlCLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZSA9IG5ldyBDcm9zc0ZhZGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTyA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgdHlwZTogXCJ0cmlhbmdsZVwiLFxuICAgICAgICAgICAgcGhhc2U6IDkwXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmZhZGUpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0RlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IHRoaXMuX2ZlZWRiYWNrRGVsYXkuZGVsYXlUaW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICAgICAgdGhpcy5fcGl0Y2ggPSBvcHRpb25zLnBpdGNoO1xuICAgICAgICB0aGlzLl93aW5kb3dTaXplID0gb3B0aW9ucy53aW5kb3dTaXplO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSB0d28gZGVsYXkgbGluZXMgdXBcbiAgICAgICAgdGhpcy5fZGVsYXlBLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmEpO1xuICAgICAgICB0aGlzLl9kZWxheUIuY29ubmVjdCh0aGlzLl9jcm9zc0ZhZGUuYik7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLl9mcmVxdWVuY3kuZmFuKHRoaXMuX2xmb0EuZnJlcXVlbmN5LCB0aGlzLl9sZm9CLmZyZXF1ZW5jeSwgdGhpcy5fY3Jvc3NGYWRlTEZPLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHJvdXRlIHRoZSBpbnB1dFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuZmFuKHRoaXMuX2RlbGF5QSwgdGhpcy5fZGVsYXlCKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlLmNoYWluKHRoaXMuX2ZlZWRiYWNrRGVsYXksIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIExGT3MgYXQgdGhlIHNhbWUgdGltZVxuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICB0aGlzLl9sZm9BLnN0YXJ0KG5vdyk7XG4gICAgICAgIHRoaXMuX2xmb0Iuc3RhcnQobm93KTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlTEZPLnN0YXJ0KG5vdyk7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCB2YWx1ZVxuICAgICAgICB0aGlzLndpbmRvd1NpemUgPSB0aGlzLl93aW5kb3dTaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEZlZWRiYWNrRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBpdGNoOiAwLFxuICAgICAgICAgICAgd2luZG93U2l6ZTogMC4xLFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLFxuICAgICAgICAgICAgZmVlZGJhY2s6IDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcGl0Y2ggdGhlIGluY29taW5nIHNpZ25hbCBieSBzb21lIGludGVydmFsIChtZWFzdXJlZCBpbiBzZW1pLXRvbmVzKS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBpdGNoU2hpZnQgPSBuZXcgVG9uZS5QaXRjaFNoaWZ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHBpdGNoU2hpZnQpLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBpdGNoU2hpZnQucGl0Y2ggPSAtMTI7IC8vIGRvd24gb25lIG9jdGF2ZVxuICAgICAqIHBpdGNoU2hpZnQucGl0Y2ggPSA3OyAvLyB1cCBhIGZpZnRoXG4gICAgICovXG4gICAgZ2V0IHBpdGNoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGl0Y2g7XG4gICAgfVxuICAgIHNldCBwaXRjaChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl9waXRjaCA9IGludGVydmFsO1xuICAgICAgICBsZXQgZmFjdG9yID0gMDtcbiAgICAgICAgaWYgKGludGVydmFsIDwgMCkge1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5taW4gPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5tYXggPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5taW4gPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5tYXggPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgZmFjdG9yID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsIC0gMSkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5taW4gPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5tYXggPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5taW4gPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5tYXggPSAwO1xuICAgICAgICAgICAgZmFjdG9yID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5LnZhbHVlID0gZmFjdG9yICogKDEuMiAvIHRoaXMuX3dpbmRvd1NpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgd2luZG93IHNpemUgY29ycmVzcG9uZHMgcm91Z2hseSB0byB0aGUgc2FtcGxlIGxlbmd0aCBpbiBhIGxvb3Bpbmcgc2FtcGxlci5cbiAgICAgKiBTbWFsbGVyIHZhbHVlcyBhcmUgZGVzaXJhYmxlIGZvciBhIGxlc3Mgbm90aWNlYWJsZSBkZWxheSB0aW1lIG9mIHRoZSBwaXRjaCBzaGlmdGVkXG4gICAgICogc2lnbmFsLCBidXQgbGFyZ2VyIHZhbHVlcyB3aWxsIHJlc3VsdCBpbiBzbW9vdGhlciBwaXRjaCBzaGlmdGluZyBmb3IgbGFyZ2VyIGludGVydmFscy5cbiAgICAgKiBBIG5vbWluYWwgcmFuZ2Ugb2YgMC4wMyB0byAwLjEgaXMgcmVjb21tZW5kZWQuXG4gICAgICovXG4gICAgZ2V0IHdpbmRvd1NpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93aW5kb3dTaXplO1xuICAgIH1cbiAgICBzZXQgd2luZG93U2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX3dpbmRvd1NpemUgPSB0aGlzLnRvU2Vjb25kcyhzaXplKTtcbiAgICAgICAgdGhpcy5waXRjaCA9IHRoaXMuX3BpdGNoO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5QS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Qi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0EuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9CLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlTEZPLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tEZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBpdGNoU2hpZnQuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBoYXNlciBpcyBhIHBoYXNlciBlZmZlY3QuIFBoYXNlcnMgd29yayBieSBjaGFuZ2luZyB0aGUgcGhhc2VcbiAqIG9mIGRpZmZlcmVudCBmcmVxdWVuY3kgY29tcG9uZW50cyBvZiBhbiBpbmNvbWluZyBzaWduYWwuIFJlYWQgbW9yZSBvblxuICogW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUGhhc2VyXyhlZmZlY3QpKS5cbiAqIEluc3BpcmF0aW9uIGZvciB0aGlzIHBoYXNlciBjb21lcyBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYS8pLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBoYXNlciA9IG5ldyBUb25lLlBoYXNlcih7XG4gKiBcdGZyZXF1ZW5jeTogMTUsXG4gKiBcdG9jdGF2ZXM6IDUsXG4gKiBcdGJhc2VGcmVxdWVuY3k6IDEwMDBcbiAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLmNvbm5lY3QocGhhc2VyKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiRTNcIiwgXCIyblwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFBoYXNlciBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBoYXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIiwgXCJiYXNlRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGhhc2VyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQaGFzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwiYmFzZUZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX2xmb0wgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDFcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBwaGFzZTogMTgwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5iYXNlRnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5RID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNMID0gdGhpcy5fbWFrZUZpbHRlcnMob3B0aW9ucy5zdGFnZXMsIHRoaXMuX2xmb0wpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzUiA9IHRoaXMuX21ha2VGaWx0ZXJzKG9wdGlvbnMuc3RhZ2VzLCB0aGlzLl9sZm9SKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm9MLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kudmFsdWUgPSBvcHRpb25zLmZyZXF1ZW5jeTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGVtIHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQoLi4udGhpcy5fZmlsdGVyc0wpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCguLi50aGlzLl9maWx0ZXJzUik7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIGZyZXF1ZW5jeSB3aXRoIG9uZSBMRk9cbiAgICAgICAgdGhpcy5fbGZvTC5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHNldCB0aGUgb3B0aW9uc1xuICAgICAgICB0aGlzLmJhc2VGcmVxdWVuY3kgPSBvcHRpb25zLmJhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgLy8gc3RhcnQgdGhlIGxmb1xuICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RhcnQoKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiUVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMC41LFxuICAgICAgICAgICAgb2N0YXZlczogMyxcbiAgICAgICAgICAgIHN0YWdlczogMTAsXG4gICAgICAgICAgICBROiAxMCxcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9tYWtlRmlsdGVycyhzdGFnZXMsIGNvbm5lY3RUb0ZyZXEpIHtcbiAgICAgICAgY29uc3QgZmlsdGVycyA9IFtdO1xuICAgICAgICAvLyBtYWtlIGFsbCB0aGUgZmlsdGVyc1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0YWdlczsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgICAgICBmaWx0ZXIudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgdGhpcy5RLmNvbm5lY3QoZmlsdGVyLlEpO1xuICAgICAgICAgICAgY29ubmVjdFRvRnJlcS5jb25uZWN0KGZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgZmlsdGVycy5wdXNoKGZpbHRlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbHRlcnM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyB0aGUgcGhhc2UgZ29lcyBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeVxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0YXZlcykge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcbiAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIG9jdGF2ZXMpO1xuICAgICAgICB0aGlzLl9sZm9MLm1heCA9IG1heDtcbiAgICAgICAgdGhpcy5fbGZvUi5tYXggPSBtYXg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aGUgYmFzZSBmcmVxdWVuY3kgb2YgdGhlIGZpbHRlcnMuXG4gICAgICovXG4gICAgZ2V0IGJhc2VGcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgIH1cbiAgICBzZXQgYmFzZUZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KGZyZXEpO1xuICAgICAgICB0aGlzLl9sZm9MLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX2xmb1IubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNMLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNSLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGhhc2VyLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWVyZ2VcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTm9pc2UgfSBmcm9tIFwiLi4vc291cmNlL05vaXNlXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogU2ltcGxlIGNvbnZvbHV0aW9uIGNyZWF0ZWQgd2l0aCBkZWNheWluZyBub2lzZS5cbiAqIEdlbmVyYXRlcyBhbiBJbXB1bHNlIFJlc3BvbnNlIEJ1ZmZlclxuICogd2l0aCBUb25lLk9mZmxpbmUgdGhlbiBmZWVkcyB0aGUgSVIgaW50byBDb252b2x2ZXJOb2RlLlxuICogVGhlIGltcHVsc2UgcmVzcG9uc2UgZ2VuZXJhdGlvbiBpcyBhc3luYywgc28geW91IGhhdmVcbiAqIHRvIHdhaXQgdW50aWwgW1tyZWFkeV1dIHJlc29sdmVzIGJlZm9yZSBpdCB3aWxsIG1ha2UgYSBzb3VuZC5cbiAqXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtSZXZlcmJHZW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9hZGVsZXNwaW5hc3NlL3JldmVyYkdlbikuXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgQWxhbiBkZUxlc3BpbmFzc2UgQXBhY2hlIDIuMCBMaWNlbnNlLlxuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFJldmVyYiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFJldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlY2F5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUmV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252b2x2ZXIgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVzb2x2ZXMgd2hlbiB0aGUgcmV2ZXJiIGJ1ZmZlciBpcyBnZW5lcmF0ZWQuIFdoZW5ldmVyIGVpdGhlciBbW2RlY2F5XV1cbiAgICAgICAgICogb3IgW1twcmVEZWxheV1dIGFyZSBzZXQsIHlvdSBoYXZlIHRvIHdhaXQgdW50aWwgW1tyZWFkeV1dIHJlc29sdmVzXG4gICAgICAgICAqIGJlZm9yZSB0aGUgSVIgaXMgZ2VuZXJhdGVkIHdpdGggdGhlIGxhdGVzdCB2YWx1ZXMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlYWR5ID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWNheVwiXSk7XG4gICAgICAgIHRoaXMuX2RlY2F5ID0gb3B0aW9ucy5kZWNheTtcbiAgICAgICAgdGhpcy5fcHJlRGVsYXkgPSBvcHRpb25zLnByZURlbGF5O1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9jb252b2x2ZXIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWNheTogMS41LFxuICAgICAgICAgICAgcHJlRGVsYXk6IDAuMDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHVyYXRpb24gb2YgdGhlIHJldmVyYi5cbiAgICAgKi9cbiAgICBnZXQgZGVjYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNheTtcbiAgICB9XG4gICAgc2V0IGRlY2F5KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZSh0aW1lLCAwLjAwMSk7XG4gICAgICAgIHRoaXMuX2RlY2F5ID0gdGltZTtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgYmVmb3JlIHRoZSByZXZlcmIgaXMgZnVsbHkgcmFtcGVkIGluLlxuICAgICAqL1xuICAgIGdldCBwcmVEZWxheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ByZURlbGF5O1xuICAgIH1cbiAgICBzZXQgcHJlRGVsYXkodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGFzc2VydFJhbmdlKHRpbWUsIDApO1xuICAgICAgICB0aGlzLl9wcmVEZWxheSA9IHRpbWU7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgdGhlIEltcHVsc2UgUmVzcG9uc2UuIFJldHVybnMgYSBwcm9taXNlIHdoaWxlIHRoZSBJUiBpcyBiZWluZyBnZW5lcmF0ZWQuXG4gICAgICogQHJldHVybiBQcm9taXNlIHdoaWNoIHJldHVybnMgdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgZ2VuZXJhdGUoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c1JlYWR5ID0gdGhpcy5yZWFkeTtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5vaXNlIGJ1cnN0IHdoaWNoIGRlY2F5cyBvdmVyIHRoZSBkdXJhdGlvbiBpbiBlYWNoIGNoYW5uZWxcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoMiwgdGhpcy5fZGVjYXkgKyB0aGlzLl9wcmVEZWxheSwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgY29uc3Qgbm9pc2VMID0gbmV3IE5vaXNlKHsgY29udGV4dCB9KTtcbiAgICAgICAgICAgIGNvbnN0IG5vaXNlUiA9IG5ldyBOb2lzZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZSA9IG5ldyBNZXJnZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBub2lzZUwuY29ubmVjdChtZXJnZSwgMCwgMCk7XG4gICAgICAgICAgICBub2lzZVIuY29ubmVjdChtZXJnZSwgMCwgMSk7XG4gICAgICAgICAgICBjb25zdCBnYWluTm9kZSA9IG5ldyBHYWluKHsgY29udGV4dCB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAgICBtZXJnZS5jb25uZWN0KGdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5vaXNlTC5zdGFydCgwKTtcbiAgICAgICAgICAgIG5vaXNlUi5zdGFydCgwKTtcbiAgICAgICAgICAgIC8vIHByZWRlbGF5XG4gICAgICAgICAgICBnYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIDApO1xuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aGlzLl9wcmVEZWxheSk7XG4gICAgICAgICAgICAvLyBkZWNheVxuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUoMCwgdGhpcy5fcHJlRGVsYXksIHRoaXMuZGVjYXkpO1xuICAgICAgICAgICAgLy8gcmVuZGVyIHRoZSBidWZmZXJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlclByb21pc2UgPSBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5yZWFkeSA9IHJlbmRlclByb21pc2UudGhlbihub09wKTtcbiAgICAgICAgICAgIC8vIHdhaXQgZm9yIHRoZSBwcmV2aW91cyBgcmVhZHlgIHRvIHJlc29sdmVcbiAgICAgICAgICAgIHlpZWxkIHByZXZpb3VzUmVhZHk7XG4gICAgICAgICAgICAvLyBzZXQgdGhlIGJ1ZmZlclxuICAgICAgICAgICAgdGhpcy5fY29udm9sdmVyLmJ1ZmZlciA9ICh5aWVsZCByZW5kZXJQcm9taXNlKS5nZXQoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1SZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi9TcGxpdFwiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogTWlkL1NpZGUgcHJvY2Vzc2luZyBzZXBhcmF0ZXMgdGhlIHRoZSAnbWlkJyBzaWduYWwgKHdoaWNoIGNvbWVzIG91dCBvZiBib3RoIHRoZSBsZWZ0IGFuZCB0aGUgcmlnaHQgY2hhbm5lbClcbiAqIGFuZCB0aGUgJ3NpZGUnICh3aGljaCBvbmx5IGNvbWVzIG91dCBvZiB0aGUgdGhlIHNpZGUgY2hhbm5lbHMpLlxuICogYGBgXG4gKiBNaWQgPSAoTGVmdCtSaWdodCkvc3FydCgyKTsgICAvLyBvYnRhaW4gbWlkLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBTaWRlID0gKExlZnQtUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIHNpZGUtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHRcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWlkU2lkZVNwbGl0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1pZFNpZGVTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRTaWRlU3BsaXRcIjtcbiAgICAgICAgdGhpcy5fc3BsaXQgPSB0aGlzLmlucHV0ID0gbmV3IFNwbGl0KHtcbiAgICAgICAgICAgIGNoYW5uZWxzOiAyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taWRBZGQgPSBuZXcgQWRkKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0ID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLnNpZGUgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fbWlkQWRkLCAwKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9taWRBZGQuYWRkZW5kLCAxKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9zaWRlU3VidHJhY3QsIDApO1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX3NpZGVTdWJ0cmFjdC5zdWJ0cmFoZW5kLCAxKTtcbiAgICAgICAgdGhpcy5fbWlkQWRkLmNvbm5lY3QodGhpcy5taWQpO1xuICAgICAgICB0aGlzLl9zaWRlU3VidHJhY3QuY29ubmVjdCh0aGlzLnNpZGUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkQWRkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlU3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi9NZXJnZVwiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogTWlkU2lkZU1lcmdlIG1lcmdlcyB0aGUgbWlkIGFuZCBzaWRlIHNpZ25hbCBhZnRlciB0aGV5J3ZlIGJlZW4gc2VwYXJhdGVkIGJ5IFtbTWlkU2lkZVNwbGl0XV1cbiAqIGBgYFxuICogTWlkID0gKExlZnQrUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIG1pZC1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogU2lkZSA9IChMZWZ0LVJpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBzaWRlLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVNZXJnZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZU1lcmdlXCI7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuc2lkZSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9sZWZ0ID0gbmV3IEFkZCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbGVmdE11bHQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHQgPSBuZXcgU3VidHJhY3QoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TXVsdCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IE1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZC5mYW4odGhpcy5fbGVmdCk7XG4gICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX2xlZnQuYWRkZW5kKTtcbiAgICAgICAgdGhpcy5taWQuY29ubmVjdCh0aGlzLl9yaWdodCk7XG4gICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX3JpZ2h0LnN1YnRyYWhlbmQpO1xuICAgICAgICB0aGlzLl9sZWZ0LmNvbm5lY3QodGhpcy5fbGVmdE11bHQpO1xuICAgICAgICB0aGlzLl9yaWdodC5jb25uZWN0KHRoaXMuX3JpZ2h0TXVsdCk7XG4gICAgICAgIHRoaXMuX2xlZnRNdWx0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgICAgICB0aGlzLl9yaWdodE11bHQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnNpZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0TXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xlZnQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZFNpZGVNZXJnZS5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IE1pZFNpZGVTcGxpdCB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlU3BsaXRcIjtcbmltcG9ydCB7IE1pZFNpZGVNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbi8qKlxuICogTWlkL1NpZGUgcHJvY2Vzc2luZyBzZXBhcmF0ZXMgdGhlIHRoZSAnbWlkJyBzaWduYWxcbiAqICh3aGljaCBjb21lcyBvdXQgb2YgYm90aCB0aGUgbGVmdCBhbmQgdGhlIHJpZ2h0IGNoYW5uZWwpXG4gKiBhbmQgdGhlICdzaWRlJyAod2hpY2ggb25seSBjb21lcyBvdXQgb2YgdGhlIHRoZSBzaWRlIGNoYW5uZWxzKVxuICogYW5kIGVmZmVjdHMgdGhlbSBzZXBhcmF0ZWx5IGJlZm9yZSBiZWluZyByZWNvbWJpbmVkLlxuICogQXBwbGllcyBhIE1pZC9TaWRlIHNlcGVyYXRpb24gYW5kIHJlY29tYmluYXRpb24uXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW2t2cmF1ZGlvIGZvcnVtc10oaHR0cDovL3d3dy5rdnJhdWRpby5jb20vZm9ydW0vdmlld3RvcGljLnBocD90PTIxMjU4NykuXG4gKiBUaGlzIGlzIGEgYmFzZS1jbGFzcyBmb3IgTWlkL1NpZGUgRWZmZWN0cy5cbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVFZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZUVmZmVjdFwiO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UgPSBuZXcgTWlkU2lkZU1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSBuZXcgTWlkU2lkZVNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9taWRTZW5kID0gdGhpcy5fbWlkU2lkZVNwbGl0Lm1pZDtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQgPSB0aGlzLl9taWRTaWRlU3BsaXQuc2lkZTtcbiAgICAgICAgdGhpcy5fbWlkUmV0dXJuID0gdGhpcy5fbWlkU2lkZU1lcmdlLm1pZDtcbiAgICAgICAgdGhpcy5fc2lkZVJldHVybiA9IHRoaXMuX21pZFNpZGVNZXJnZS5zaWRlO1xuICAgICAgICAvLyB0aGUgY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNvbm5lY3QodGhpcy5fbWlkU2lkZVNwbGl0KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBtaWQgY2hhaW4gb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RNaWQoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fbWlkU2VuZC5jaGFpbiguLi5ub2RlcywgdGhpcy5fbWlkUmV0dXJuKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgc2lkZSBjaGFpbiBvZiB0aGUgZWZmZWN0XG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdFNpZGUoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQuY2hhaW4oLi4ubm9kZXMsIHRoaXMuX3NpZGVSZXR1cm4pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNlbmQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlU2VuZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFJldHVybi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZGVSZXR1cm4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IE1pZFNpZGVFZmZlY3QgfSBmcm9tIFwiLi4vZWZmZWN0L01pZFNpZGVFZmZlY3RcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4uL3NpZ25hbC9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIEFwcGxpZXMgYSB3aWR0aCBmYWN0b3IgdG8gdGhlIG1pZC9zaWRlIHNlcGVyYXRpb24uXG4gKiAwIGlzIGFsbCBtaWQgYW5kIDEgaXMgYWxsIHNpZGUuXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW2t2cmF1ZGlvIGZvcnVtc10oaHR0cDovL3d3dy5rdnJhdWRpby5jb20vZm9ydW0vdmlld3RvcGljLnBocD90PTIxMjU4NykuXG4gKiBgYGBcbiAqIE1pZCAqPSAyKigxLXdpZHRoKTxicj5cbiAqIFNpZGUgKj0gMip3aWR0aFxuICogYGBgXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9XaWRlbmVyIGV4dGVuZHMgTWlkU2lkZUVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFN0ZXJlb1dpZGVuZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ3aWR0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN0ZXJlb1dpZGVuZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFN0ZXJlb1dpZGVuZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLndpZHRoLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIndpZHRoXCJdKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkTXVsdCA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZC5jb25uZWN0KHRoaXMuX21pZE11bHQuZmFjdG9yKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TWlkKHRoaXMuX21pZE11bHQpO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoLmNvbm5lY3QodGhpcy5fdHdvVGltZXNXaWR0aE1pZCk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5jb250ZXh0LmdldENvbnN0YW50KDEpLCB0aGlzLl9vbmVNaW51c1dpZHRoKTtcbiAgICAgICAgdGhpcy53aWR0aC5jb25uZWN0KHRoaXMuX29uZU1pbnVzV2lkdGguc3VidHJhaGVuZCk7XG4gICAgICAgIHRoaXMuX3NpZGVNdWx0ID0gbmV3IE11bHRpcGx5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLndpZHRoLmNvbm5lY3QodGhpcy5fdHdvVGltZXNXaWR0aFNpZGUpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZS5jb25uZWN0KHRoaXMuX3NpZGVNdWx0LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFNpZGUodGhpcy5fc2lkZU11bHQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1pZFNpZGVFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgd2lkdGg6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53aWR0aC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZE11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlTXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29uZU1pbnVzV2lkdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9XaWRlbmVyLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBUcmVtb2xvIG1vZHVsYXRlcyB0aGUgYW1wbGl0dWRlIG9mIGFuIGluY29taW5nIHNpZ25hbCB1c2luZyBhbiBbW0xGT11dLlxuICogVGhlIGVmZmVjdCBpcyBhIHN0ZXJlbyBlZmZlY3Qgd2hlcmUgdGhlIG1vZHVsYXRpb24gcGhhc2UgaXMgaW52ZXJ0ZWQgaW4gZWFjaCBjaGFubmVsLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYSB0cmVtb2xvIGFuZCBzdGFydCBpdCdzIExGT1xuICogY29uc3QgdHJlbW9sbyA9IG5ldyBUb25lLlRyZW1vbG8oOSwgMC43NSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyByb3V0ZSBhbiBvc2NpbGxhdG9yIHRocm91Z2ggdGhlIHRyZW1vbG8gYW5kIHN0YXJ0IGl0XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QodHJlbW9sbykuc3RhcnQoKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBUcmVtb2xvIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJlbW9sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJlbW9sb1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJlbW9sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICAgICAgbWluOiAxLFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvUiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICAgICAgbWluOiAxLFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlTCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVSID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVwdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlcHRoLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCh0aGlzLl9hbXBsaXR1ZGVMKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQodGhpcy5fYW1wbGl0dWRlUik7XG4gICAgICAgIHRoaXMuX2xmb0wuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGVMLmdhaW4pO1xuICAgICAgICB0aGlzLl9sZm9SLmNvbm5lY3QodGhpcy5fYW1wbGl0dWRlUi5nYWluKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZmFuKHRoaXMuX2xmb0wuZnJlcXVlbmN5LCB0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZGVwdGguZmFuKHRoaXMuX2xmb1IuYW1wbGl0dWRlLCB0aGlzLl9sZm9MLmFtcGxpdHVkZSk7XG4gICAgICAgIHRoaXMuc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMTAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIGRlcHRoOiAwLjUsXG4gICAgICAgICAgICBzcHJlYWQ6IDE4MCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSB0cmVtb2xvLlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHRyZW1vbG8uXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgZWZmZWN0IHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zeW5jKCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3luYygpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBmaWx0ZXIgZnJvbSB0aGUgdHJhbnNwb3J0XG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnVuc3luYygpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnVuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvciB0eXBlLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvTC50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2xmb1IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFtb3VudCBvZiBzdGVyZW8gc3ByZWFkLiBXaGVuIHNldCB0byAwLCBib3RoIExGTydzIHdpbGwgYmUgcGFubmVkIGNlbnRyYWxseS5cbiAgICAgKiBXaGVuIHNldCB0byAxODAsIExGTydzIHdpbGwgYmUgcGFubmVkIGhhcmQgbGVmdCBhbmQgcmlnaHQgcmVzcGVjdGl2ZWx5LlxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTsgLy8gMTgwXG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX2xmb0wucGhhc2UgPSA5MCAtIChzcHJlYWQgLyAyKTtcbiAgICAgICAgdGhpcy5fbGZvUi5waGFzZSA9IChzcHJlYWQgLyAyKSArIDkwO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9SLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZVIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVwdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmVtb2xvLmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQSBWaWJyYXRvIGVmZmVjdCBjb21wb3NlZCBvZiBhIFRvbmUuRGVsYXkgYW5kIGEgVG9uZS5MRk8uIFRoZSBMRk9cbiAqIG1vZHVsYXRlcyB0aGUgZGVsYXlUaW1lIG9mIHRoZSBkZWxheSwgY2F1c2luZyB0aGUgcGl0Y2ggdG8gcmlzZSBhbmQgZmFsbC5cbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFZpYnJhdG8gZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhWaWJyYXRvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJWaWJyYXRvXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhWaWJyYXRvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBwaGFzZTogLTkwIC8vIG9mZnNlIHRoZSBwaGFzZSBzbyB0aGUgcmVzdGluZyBwb3NpdGlvbiBpcyBpbiB0aGUgY2VudGVyXG4gICAgICAgIH0pLnN0YXJ0KCkuY29ubmVjdCh0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fbGZvLmFtcGxpdHVkZTtcbiAgICAgICAgdGhpcy5kZXB0aC52YWx1ZSA9IG9wdGlvbnMuZGVwdGg7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKHRoaXMuX2RlbGF5Tm9kZSwgdGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtYXhEZWxheTogMC4wMDUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDUsXG4gICAgICAgICAgICBkZXB0aDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFR5cGUgb2Ygb3NjaWxsYXRvciBhdHRhY2hlZCB0byB0aGUgVmlicmF0by5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmby50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmby50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVwdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1WaWJyYXRvLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0F1dG9GaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1dG9QYW5uZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1dG9XYWhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0JpdENydXNoZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0NoZWJ5c2hldlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQ2hvcnVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EaXN0b3J0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GZWVkYmFja0RlbGF5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GcmVxdWVuY3lTaGlmdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GcmVldmVyYlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vSkNSZXZlcmJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BpbmdQb25nRGVsYXlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BpdGNoU2hpZnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BoYXNlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUmV2ZXJiXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TdGVyZW9XaWRlbmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9UcmVtb2xvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9WaWJyYXRvXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgV2ViIEF1ZGlvJ3MgW0FuYWx5c2VyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyNpZGwtZGVmLUFuYWx5c2VyTm9kZSkuXG4gKiBFeHRyYWN0cyBGRlQgb3IgV2F2ZWZvcm0gZGF0YSBmcm9tIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBBbmFseXNlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBbmFseXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIiwgXCJzaXplXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQW5hbHlzZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhbmFseXNlciBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYnVmZmVyIHRoYXQgdGhlIEZGVCBkYXRhIGlzIHdyaXR0ZW4gdG9cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEFuYWx5c2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiLCBcInNpemVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gbmV3IFNwbGl0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNoYW5uZWxzOiBvcHRpb25zLmNoYW5uZWxzLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgYXNzZXJ0UmFuZ2Uob3B0aW9ucy5jaGFubmVscywgMSk7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgYW5hbHlzZXJzXG4gICAgICAgIGZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgb3B0aW9ucy5jaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICB0aGlzLl9hbmFseXNlcnNbY2hhbm5lbF0gPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICAgICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fYW5hbHlzZXJzW2NoYW5uZWxdLCBjaGFubmVsLCAwKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHZhbHVlcyBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzaXplOiAxMDI0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjgsXG4gICAgICAgICAgICB0eXBlOiBcImZmdFwiLFxuICAgICAgICAgICAgY2hhbm5lbHM6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSdW4gdGhlIGFuYWx5c2lzIGdpdmVuIHRoZSBjdXJyZW50IHNldHRpbmdzLiBJZiBbW2NoYW5uZWxzXV0gPSAxLFxuICAgICAqIGl0IHdpbGwgcmV0dXJuIGEgRmxvYXQzMkFycmF5LiBJZiBbW2NoYW5uZWxzXV0gPiAxLCBpdCB3aWxsXG4gICAgICogcmV0dXJuIGFuIGFycmF5IG9mIEZsb2F0MzJBcnJheXMgd2hlcmUgZWFjaCBpbmRleCBpbiB0aGUgYXJyYXlcbiAgICAgKiByZXByZXNlbnRzIHRoZSBhbmFseXNpcyBkb25lIG9uIGEgY2hhbm5lbC5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goKGFuYWx5c2VyLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fYnVmZmVyc1tpbmRleF07XG4gICAgICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJmZnRcIikge1xuICAgICAgICAgICAgICAgIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShidWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3YXZlZm9ybVwiKSB7XG4gICAgICAgICAgICAgICAgYW5hbHlzZXIuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YShidWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlcnNbMF0uZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgfVxuICAgIHNldCBzaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goKGFuYWx5c2VyLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgYW5hbHlzZXIuZmZ0U2l6ZSA9IHNpemUgKiAyO1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVyc1tpbmRleF0gPSBuZXcgRmxvYXQzMkFycmF5KHNpemUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBjaGFubmVscyB0aGUgYW5hbHlzZXIgZG9lcyB0aGUgYW5hbHlzaXMgb24uIENoYW5uZWxcbiAgICAgKiBzZXBhcmF0aW9uIGlzIGRvbmUgdXNpbmcgW1tTcGxpdF1dXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXJzLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuYWx5c2lzIGZ1bmN0aW9uIHJldHVybmVkIGJ5IGFuYWx5c2VyLmdldFZhbHVlKCksIGVpdGhlciBcImZmdFwiIG9yIFwid2F2ZWZvcm1cIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgYXNzZXJ0KHR5cGUgPT09IFwid2F2ZWZvcm1cIiB8fCB0eXBlID09PSBcImZmdFwiLCBgQW5hbHlzZXI6IGludmFsaWQgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogMCByZXByZXNlbnRzIG5vIHRpbWUgYXZlcmFnaW5nIHdpdGggdGhlIGxhc3QgYW5hbHlzaXMgZnJhbWUuXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2Vyc1swXS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQ7XG4gICAgfVxuICAgIHNldCBzbW9vdGhpbmcodmFsKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKGEgPT4gYS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSB2YWwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKGEgPT4gYS5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BbmFseXNlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEFuYWx5c2VyIH0gZnJvbSBcIi4vQW5hbHlzZXJcIjtcbi8qKlxuICogVGhlIGJhc2UgY2xhc3MgZm9yIE1ldGVyaW5nIGNsYXNzZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRlckJhc2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0ZXJCYXNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1ldGVyQmFzZVwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9hbmFseXNlciA9IG5ldyBBbmFseXNlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzaXplOiAyNTYsXG4gICAgICAgICAgICB0eXBlOiBcIndhdmVmb3JtXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0ZXJCYXNlLmpzLm1hcCIsImltcG9ydCB7IGdhaW5Ub0RiIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXRlckJhc2UgfSBmcm9tIFwiLi9NZXRlckJhc2VcIjtcbmltcG9ydCB7IHdhcm4gfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBBbmFseXNlciB9IGZyb20gXCIuL0FuYWx5c2VyXCI7XG4vKipcbiAqIE1ldGVyIGdldHMgdGhlIFtSTVNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1Jvb3RfbWVhbl9zcXVhcmUpXG4gKiBvZiBhbiBpbnB1dCBzaWduYWwuIEl0IGNhbiBhbHNvIGdldCB0aGUgcmF3IHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuTWV0ZXIoKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpO1xuICogbWljLm9wZW4oKTtcbiAqIC8vIGNvbm5lY3QgbWljIHRvIHRoZSBtZXRlclxuICogbWljLmNvbm5lY3QobWV0ZXIpO1xuICogLy8gdGhlIGN1cnJlbnQgbGV2ZWwgb2YgdGhlIG1pY1xuICogc2V0SW50ZXJ2YWwoKCkgPT4gY29uc29sZS5sb2cobWV0ZXIuZ2V0VmFsdWUoKSksIDEwMCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRlciBleHRlbmRzIE1ldGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWV0ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwcmV2aW91cyBmcmFtZSdzIHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ybXMgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9hbmFseXNlciA9IG5ldyBBbmFseXNlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzaXplOiAyNTYsXG4gICAgICAgICAgICB0eXBlOiBcIndhdmVmb3JtXCIsXG4gICAgICAgICAgICBjaGFubmVsczogb3B0aW9ucy5jaGFubmVscyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc21vb3RoaW5nID0gb3B0aW9ucy5zbW9vdGhpbmcsXG4gICAgICAgICAgICB0aGlzLm5vcm1hbFJhbmdlID0gb3B0aW9ucy5ub3JtYWxSYW5nZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNZXRlckJhc2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjgsXG4gICAgICAgICAgICBub3JtYWxSYW5nZTogZmFsc2UsXG4gICAgICAgICAgICBjaGFubmVsczogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVzZSBbW2dldFZhbHVlXV0gaW5zdGVhZC4gRm9yIHRoZSBwcmV2aW91cyBnZXRWYWx1ZSBiZWhhdmlvciwgdXNlIERDTWV0ZXIuXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXRMZXZlbCgpIHtcbiAgICAgICAgd2FybihcIidnZXRMZXZlbCcgaGFzIGJlZW4gY2hhbmdlZCB0byAnZ2V0VmFsdWUnXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbC5cbiAgICAgKiBPdXRwdXQgaXMgaW4gZGVjaWJlbHMgd2hlbiBbW25vcm1hbFJhbmdlXV0gaXMgYGZhbHNlYC5cbiAgICAgKiBJZiBbW2NoYW5uZWxzXV0gPSAxLCB0aGVuIHRoZSBvdXRwdXQgaXMgYSBzaW5nbGUgbnVtYmVyXG4gICAgICogcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUgaW5wdXQgc2lnbmFsLiBXaGVuIFtbY2hhbm5lbHNdXSA+IDEsXG4gICAgICogdGhlbiBlYWNoIGNoYW5uZWwgaXMgcmV0dXJuZWQgYXMgYSB2YWx1ZSBpbiBhIG51bWJlciBhcnJheS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgYVZhbHVlcyA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxWYWx1ZXMgPSB0aGlzLmNoYW5uZWxzID09PSAxID8gW2FWYWx1ZXNdIDogYVZhbHVlcztcbiAgICAgICAgY29uc3QgdmFscyA9IGNoYW5uZWxWYWx1ZXMubWFwKHZhbHVlcyA9PiB7XG4gICAgICAgICAgICBjb25zdCB0b3RhbFNxdWFyZWQgPSB2YWx1ZXMucmVkdWNlKCh0b3RhbCwgY3VycmVudCkgPT4gdG90YWwgKyBjdXJyZW50ICogY3VycmVudCwgMCk7XG4gICAgICAgICAgICBjb25zdCBybXMgPSBNYXRoLnNxcnQodG90YWxTcXVhcmVkIC8gdmFsdWVzLmxlbmd0aCk7XG4gICAgICAgICAgICAvLyB0aGUgcm1zIGNhbiBvbmx5IGZhbGwgYXQgdGhlIHJhdGUgb2YgdGhlIHNtb290aGluZ1xuICAgICAgICAgICAgLy8gYnV0IGNhbiBqdW1wIHVwIGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy5fcm1zID0gTWF0aC5tYXgocm1zLCB0aGlzLl9ybXMgKiB0aGlzLnNtb290aGluZyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxSYW5nZSA/IHRoaXMuX3JtcyA6IGdhaW5Ub0RiKHRoaXMuX3Jtcyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5jaGFubmVscyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdmFscztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIGFuYWx5c2lzLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLmNoYW5uZWxzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgZGJUb0dhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgZnJlcXVlbmN5IGRhdGEgb2YgdGhlIGNvbm5lY3RlZCBhdWRpbyBzb3VyY2UgdXNpbmcgYSBmYXN0IEZvdXJpZXIgdHJhbnNmb3JtLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRkZUIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRkZULmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZGVFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRkZULmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSk7XG4gICAgICAgIHRoaXMubm9ybWFsUmFuZ2UgPSBvcHRpb25zLm5vcm1hbFJhbmdlO1xuICAgICAgICB0aGlzLl9hbmFseXNlci50eXBlID0gXCJmZnRcIjtcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbm9ybWFsUmFuZ2U6IGZhbHNlLFxuICAgICAgICAgICAgc2l6ZTogMTAyNCxcbiAgICAgICAgICAgIHNtb290aGluZzogMC44LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgY3VycmVudCBmcmVxdWVuY3kgZGF0YSBmcm9tIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuICAgICAqIFJldHVybnMgdGhlIGZyZXF1ZW5jeSBkYXRhIG9mIGxlbmd0aCBbW3NpemVdXSBhcyBhIEZsb2F0MzJBcnJheSBvZiBkZWNpYmVsIHZhbHVlcy5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5tYXAodiA9PiB0aGlzLm5vcm1hbFJhbmdlID8gZGJUb0dhaW4odikgOiB2KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICogRGV0ZXJtaW5lcyB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgcmV0dXJuZWQgYnkgW1tnZXRWYWx1ZV1dIChpLmUuIHRoZSBudW1iZXIgb2ZcbiAgICAgKiBmcmVxdWVuY3kgYmlucykuIExhcmdlIEZGVCBzaXplcyBtYXkgYmUgY29zdGx5IHRvIGNvbXB1dGUuXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5zaXplO1xuICAgIH1cbiAgICBzZXQgc2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnNpemUgPSBzaXplO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAwIHJlcHJlc2VudHMgbm8gdGltZSBhdmVyYWdpbmcgd2l0aCB0aGUgbGFzdCBhbmFseXNpcyBmcmFtZS5cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHZhbCkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zbW9vdGhpbmcgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGZyZXF1ZW5jeSB2YWx1ZSBpbiBoZXJ0eiBvZiBlYWNoIG9mIHRoZSBpbmRpY2VzIG9mIHRoZSBGRlQncyBbW2dldFZhbHVlXV0gcmVzcG9uc2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmZnQgPSBuZXcgVG9uZS5GRlQoMzIpO1xuICAgICAqIGNvbnNvbGUubG9nKFswLCAxLCAyLCAzLCA0XS5tYXAoaW5kZXggPT4gZmZ0LmdldEZyZXF1ZW5jeU9mSW5kZXgoaW5kZXgpKSk7XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5T2ZJbmRleChpbmRleCkge1xuICAgICAgICBhc3NlcnQoMCA8PSBpbmRleCAmJiBpbmRleCA8IHRoaXMuc2l6ZSwgYGluZGV4IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MgdGhhbiAke3RoaXMuc2l6ZX1gKTtcbiAgICAgICAgcmV0dXJuIGluZGV4ICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAodGhpcy5zaXplICogMik7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RkZULmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG4vKipcbiAqIERDTWV0ZXIgZ2V0cyB0aGUgcmF3IHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwgYXQgdGhlIGN1cnJlbnQgdGltZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWV0ZXIgPSBuZXcgVG9uZS5EQ01ldGVyKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAqIG1pYy5vcGVuKCk7XG4gKiAvLyBjb25uZWN0IG1pYyB0byB0aGUgbWV0ZXJcbiAqIG1pYy5jb25uZWN0KG1ldGVyKTtcbiAqIC8vIHRoZSBjdXJyZW50IGxldmVsIG9mIHRoZSBtaWNcbiAqIGNvbnN0IGxldmVsID0gbWV0ZXIuZ2V0VmFsdWUoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIERDTWV0ZXIgZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEQ01ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRDTWV0ZXJcIjtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwid2F2ZWZvcm1cIjtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc2l6ZSA9IDI1NjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzaWduYWwgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbFxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIHJldHVybiB2YWx1ZVswXTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EQ01ldGVyLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG4vKipcbiAqIEdldCB0aGUgY3VycmVudCB3YXZlZm9ybSBkYXRhIG9mIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgV2F2ZWZvcm0gZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlZm9ybS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJXYXZlZm9ybVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZWZvcm0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzaXplXCJdKTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwid2F2ZWZvcm1cIjtcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1ldGVyQmFzZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzaXplOiAxMDI0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB3YXZlZm9ybSBmb3IgdGhlIGN1cnJlbnQgdGltZSBhcyBhIEZsb2F0MzJBcnJheSB3aGVyZSBlYWNoIHZhbHVlIGluIHRoZSBhcnJheVxuICAgICAqIHJlcHJlc2VudHMgYSBzYW1wbGUgaW4gdGhlIHdhdmVmb3JtLlxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICogRGV0ZXJtaW5lcyB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgcmV0dXJuZWQgYnkgW1tnZXRWYWx1ZV1dLlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc2l6ZTtcbiAgICB9XG4gICAgc2V0IHNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zaXplID0gc2l6ZTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1XYXZlZm9ybS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogU29sbyBsZXRzIHlvdSBpc29sYXRlIGEgc3BlY2lmaWMgYXVkaW8gc3RyZWFtLiBXaGVuIGFuIGluc3RhbmNlIGlzIHNldCB0byBgc29sbz10cnVlYCxcbiAqIGl0IHdpbGwgbXV0ZSBhbGwgb3RoZXIgaW5zdGFuY2VzIG9mIFNvbG8uXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc29sb0EgPSBuZXcgVG9uZS5Tb2xvKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjQSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJDNFwiLCBcInNhd3Rvb3RoXCIpLmNvbm5lY3Qoc29sb0EpO1xuICogY29uc3Qgc29sb0IgPSBuZXcgVG9uZS5Tb2xvKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjQiA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJFNFwiLCBcInNxdWFyZVwiKS5jb25uZWN0KHNvbG9CKTtcbiAqIHNvbG9BLnNvbG8gPSB0cnVlO1xuICogLy8gbm8gYXVkaW8gd2lsbCBwYXNzIHRocm91Z2ggc29sb0JcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNvbG8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU29sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNvbG9cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTb2xvXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTb2xvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic29sb1wiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghU29sby5fYWxsU29sb3MuaGFzKHRoaXMuY29udGV4dCkpIHtcbiAgICAgICAgICAgIFNvbG8uX2FsbFNvbG9zLnNldCh0aGlzLmNvbnRleHQsIG5ldyBTZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgU29sby5fYWxsU29sb3MuZ2V0KHRoaXMuY29udGV4dCkuYWRkKHRoaXMpO1xuICAgICAgICAvLyBzZXQgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMuc29sbyA9IG9wdGlvbnMuc29sbztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNvbG86IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXNvbGF0ZXMgdGhpcyBpbnN0YW5jZSBhbmQgbXV0ZXMgYWxsIG90aGVyIGluc3RhbmNlcyBvZiBTb2xvLlxuICAgICAqIE9ubHkgb25lIGluc3RhbmNlIGNhbiBiZSBzb2xvZWQgYXQgYSB0aW1lLiBBIHNvbG9lZFxuICAgICAqIGluc3RhbmNlIHdpbGwgcmVwb3J0IGBzb2xvPWZhbHNlYCB3aGVuIGFub3RoZXIgaW5zdGFuY2UgaXMgc29sb2VkLlxuICAgICAqL1xuICAgIGdldCBzb2xvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNTb2xvZWQoKTtcbiAgICB9XG4gICAgc2V0IHNvbG8oc29sbykge1xuICAgICAgICBpZiAoc29sbykge1xuICAgICAgICAgICAgdGhpcy5fYWRkU29sbygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuICAgICAgICB9XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmZvckVhY2goaW5zdGFuY2UgPT4gaW5zdGFuY2UuX3VwZGF0ZVNvbG8oKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBjdXJyZW50IGluc3RhbmNlIGlzIG11dGVkLCBpLmUuIGFub3RoZXIgaW5zdGFuY2UgaXMgc29sb2VkXG4gICAgICovXG4gICAgZ2V0IG11dGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dC5nYWluLnZhbHVlID09PSAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgdGhpcyB0byB0aGUgc29sb2VkIGFycmF5XG4gICAgICovXG4gICAgX2FkZFNvbG8oKSB7XG4gICAgICAgIGlmICghU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICBTb2xvLl9zb2xvZWQuc2V0KHRoaXMuY29udGV4dCwgbmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICBTb2xvLl9zb2xvZWQuZ2V0KHRoaXMuY29udGV4dCkuYWRkKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhpcyBmcm9tIHRoZSBzb2xvZWQgYXJyYXlcbiAgICAgKi9cbiAgICBfcmVtb3ZlU29sbygpIHtcbiAgICAgICAgaWYgKFNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmRlbGV0ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJcyB0aGlzIG9uIHRoZSBzb2xvZWQgYXJyYXlcbiAgICAgKi9cbiAgICBfaXNTb2xvZWQoKSB7XG4gICAgICAgIHJldHVybiBTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgJiYgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmhhcyh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIG5vIG9uZSBpcyBzb2xvZWRcbiAgICAgKi9cbiAgICBfbm9Tb2xvcygpIHtcbiAgICAgICAgLy8gZWl0aGVyIGRvZXMgbm90IGhhdmUgYW55IHNvbG9lZCBhZGRlZFxuICAgICAgICByZXR1cm4gIVNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSB8fFxuICAgICAgICAgICAgLy8gb3IgaGFzIGEgc29sbyBzZXQgYnV0IGRvZXNuJ3QgaW5jbHVkZSBhbnkgaXRlbXNcbiAgICAgICAgICAgIChTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgJiYgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLnNpemUgPT09IDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTb2xvIHRoZSBjdXJyZW50IGluc3RhbmNlIGFuZCB1bnNvbG8gYWxsIG90aGVyIGluc3RhbmNlcy5cbiAgICAgKi9cbiAgICBfdXBkYXRlU29sbygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzU29sb2VkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fbm9Tb2xvcygpKSB7XG4gICAgICAgICAgICAvLyBubyBvbmUgaXMgc29sb2VkXG4gICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5nYWluLnZhbHVlID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmRlbGV0ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEhvbGQgYWxsIG9mIHRoZSBzb2xvJ2VkIHRyYWNrcyBiZWxvbmdpbmcgdG8gYSBzcGVjaWZpYyBjb250ZXh0XG4gKi9cblNvbG8uX2FsbFNvbG9zID0gbmV3IE1hcCgpO1xuLyoqXG4gKiBIb2xkIHRoZSBjdXJyZW50bHkgc29sbydlZCBpbnN0YW5jZShzKVxuICovXG5Tb2xvLl9zb2xvZWQgPSBuZXcgTWFwKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Tb2xvLmpzLm1hcCIsImltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgUGFubmVyIH0gZnJvbSBcIi4vUGFubmVyXCI7XG5pbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi9Wb2x1bWVcIjtcbi8qKlxuICogUGFuVm9sIGlzIGEgVG9uZS5QYW5uZXIgYW5kIFRvbmUuVm9sdW1lIGluIG9uZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBwYW4gdGhlIGluY29taW5nIHNpZ25hbCBsZWZ0IGFuZCBkcm9wIHRoZSB2b2x1bWVcbiAqIGNvbnN0IHBhblZvbCA9IG5ldyBUb25lLlBhblZvbCgtMC4yNSwgLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChwYW5Wb2wpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5Wb2wgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFuVm9sLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCIsIFwidm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFuVm9sXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5Wb2wuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSB0aGlzLmlucHV0ID0gbmV3IFBhbm5lcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYW46IG9wdGlvbnMucGFuLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGFuID0gdGhpcy5fcGFubmVyLnBhbjtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25uZWN0KHRoaXMuX3ZvbHVtZSk7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicGFuXCIsIFwidm9sdW1lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgcGFuOiAwLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZS91bm11dGUgdGhlIHZvbHVtZVxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGFuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5Wb2wuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTb2xvIH0gZnJvbSBcIi4vU29sb1wiO1xuaW1wb3J0IHsgUGFuVm9sIH0gZnJvbSBcIi4vUGFuVm9sXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG4vKipcbiAqIENoYW5uZWwgcHJvdmlkZXMgYSBjaGFubmVsIHN0cmlwIGludGVyZmFjZSB3aXRoIHZvbHVtZSwgcGFuLCBzb2xvIGFuZCBtdXRlIGNvbnRyb2xzLlxuICogU2VlIFtbUGFuVm9sXV0gYW5kIFtbU29sb11dXG4gKiBAZXhhbXBsZVxuICogLy8gcGFuIHRoZSBpbmNvbWluZyBzaWduYWwgbGVmdCBhbmQgZHJvcCB0aGUgdm9sdW1lIDEyZGJcbiAqIGNvbnN0IGNoYW5uZWwgPSBuZXcgVG9uZS5DaGFubmVsKC0wLjI1LCAtMTIpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ2hhbm5lbCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDaGFubmVsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCIsIFwicGFuXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hhbm5lbFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hhbm5lbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiLCBcInBhblwiXSk7XG4gICAgICAgIHRoaXMuX3NvbG8gPSB0aGlzLmlucHV0ID0gbmV3IFNvbG8oe1xuICAgICAgICAgICAgc29sbzogb3B0aW9ucy5zb2xvLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFuVm9sID0gdGhpcy5vdXRwdXQgPSBuZXcgUGFuVm9sKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhbjogb3B0aW9ucy5wYW4sXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICAgICAgbXV0ZTogb3B0aW9ucy5tdXRlLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wYW4gPSB0aGlzLl9wYW5Wb2wucGFuO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3BhblZvbC52b2x1bWU7XG4gICAgICAgIHRoaXMuX3NvbG8uY29ubmVjdCh0aGlzLl9wYW5Wb2wpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcGFuOiAwLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBzb2xvOiBmYWxzZSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNvbG8vdW5zb2xvIHRoZSBjaGFubmVsLiBTb2xvaW5nIGlzIG9ubHkgcmVsYXRpdmUgdG8gb3RoZXIgW1tDaGFubmVsc11dIGFuZCBbW1NvbG9dXSBpbnN0YW5jZXNcbiAgICAgKi9cbiAgICBnZXQgc29sbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvbG8uc29sbztcbiAgICB9XG4gICAgc2V0IHNvbG8oc29sbykge1xuICAgICAgICB0aGlzLl9zb2xvLnNvbG8gPSBzb2xvO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgY3VycmVudCBpbnN0YW5jZSBpcyBtdXRlZCwgaS5lLiBhbm90aGVyIGluc3RhbmNlIGlzIHNvbG9lZCxcbiAgICAgKiBvciB0aGUgY2hhbm5lbCBpcyBtdXRlZFxuICAgICAqL1xuICAgIGdldCBtdXRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvbG8ubXV0ZWQgfHwgdGhpcy5tdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlL3VubXV0ZSB0aGUgdm9sdW1lXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5Wb2wubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl9wYW5Wb2wubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZ2FpbiBub2RlIGJlbG9uZ2luZyB0byB0aGUgYnVzIG5hbWUuIENyZWF0ZSBpdCBpZlxuICAgICAqIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYnVzIG5hbWVcbiAgICAgKi9cbiAgICBfZ2V0QnVzKG5hbWUpIHtcbiAgICAgICAgaWYgKCFDaGFubmVsLmJ1c2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgQ2hhbm5lbC5idXNlcy5zZXQobmFtZSwgbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDaGFubmVsLmJ1c2VzLmdldChuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZCBhdWRpbyB0byBhbm90aGVyIGNoYW5uZWwgdXNpbmcgYSBzdHJpbmcuIGBzZW5kYCBpcyBhIGxvdCBsaWtlXG4gICAgICogW1tjb25uZWN0XV0sIGV4Y2VwdCBpdCB1c2VzIGEgc3RyaW5nIGluc3RlYWQgb2YgYW4gb2JqZWN0LiBUaGlzIGNhblxuICAgICAqIGJlIHVzZWZ1bCBpbiBsYXJnZSBhcHBsaWNhdGlvbnMgdG8gZGVjb3VwbGUgc2VjdGlvbnMgc2luY2UgW1tzZW5kXV1cbiAgICAgKiBhbmQgW1tyZWNlaXZlXV0gY2FuIGJlIGludm9rZWQgc2VwYXJhdGVseSBpbiBvcmRlciB0byBjb25uZWN0IGFuIG9iamVjdFxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBjaGFubmVsIG5hbWUgdG8gc2VuZCB0aGUgYXVkaW9cbiAgICAgKiBAcGFyYW0gdm9sdW1lIFRoZSBhbW91bnQgb2YgdGhlIHNpZ25hbCB0byBzZW5kLlxuICAgICAqIFx0RGVmYXVsdHMgdG8gMGRiLCBpLmUuIHNlbmQgdGhlIGVudGlyZSBzaWduYWxcbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIHRoZSBnYWluIG5vZGUgb2YgdGhpcyBjb25uZWN0aW9uLlxuICAgICAqL1xuICAgIHNlbmQobmFtZSwgdm9sdW1lID0gMCkge1xuICAgICAgICBjb25zdCBidXMgPSB0aGlzLl9nZXRCdXMobmFtZSk7XG4gICAgICAgIGNvbnN0IHNlbmRLbm9iID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIGdhaW46IHZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY29ubmVjdChzZW5kS25vYik7XG4gICAgICAgIHNlbmRLbm9iLmNvbm5lY3QoYnVzKTtcbiAgICAgICAgcmV0dXJuIHNlbmRLbm9iO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWNlaXZlIGF1ZGlvIGZyb20gYSBjaGFubmVsIHdoaWNoIHdhcyBjb25uZWN0ZWQgd2l0aCBbW3NlbmRdXS5cbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgY2hhbm5lbCBuYW1lIHRvIHJlY2VpdmUgYXVkaW8gZnJvbS5cbiAgICAgKi9cbiAgICByZWNlaXZlKG5hbWUpIHtcbiAgICAgICAgY29uc3QgYnVzID0gdGhpcy5fZ2V0QnVzKG5hbWUpO1xuICAgICAgICBidXMuY29ubmVjdCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFuVm9sLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wYW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NvbG8uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIFN0b3JlIHRoZSBzZW5kL3JlY2VpdmUgY2hhbm5lbHMgYnkgbmFtZS5cbiAqL1xuQ2hhbm5lbC5idXNlcyA9IG5ldyBNYXAoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNoYW5uZWwuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuL01lcmdlXCI7XG4vKipcbiAqIE1vbm8gY29lcmNlcyB0aGUgaW5jb21pbmcgbW9ubyBvciBzdGVyZW8gc2lnbmFsIGludG8gYSBtb25vIHNpZ25hbFxuICogd2hlcmUgYm90aCBsZWZ0IGFuZCByaWdodCBjaGFubmVscyBoYXZlIHRoZSBzYW1lIHZhbHVlLiBUaGlzIGNhbiBiZSB1c2VmdWxcbiAqIGZvciBbc3RlcmVvIGltYWdpbmddKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N0ZXJlb19pbWFnaW5nKS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1vbm8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9uby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb25vXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBNZXJnZSh7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMCk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9uby5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2ZpbHRlci9GaWx0ZXJcIjtcbi8qKlxuICogU3BsaXQgdGhlIGluY29taW5nIHNpZ25hbCBpbnRvIHRocmVlIGJhbmRzIChsb3csIG1pZCwgaGlnaClcbiAqIHdpdGggdHdvIGNyb3Nzb3ZlciBmcmVxdWVuY3kgY29udHJvbHMuXG4gKiBgYGBcbiAqICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICArLT4gaW5wdXQgPCBsb3dGcmVxdWVuY3kgKy0tLS0tLS0tLS0tLS0tLS0tLT4gbG93XG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgfFxuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBpbnB1dCAtLS0rLT4gbG93RnJlcXVlbmN5IDwgaW5wdXQgPCBoaWdoRnJlcXVlbmN5ICstLT4gbWlkXG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgIHxcbiAqICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgKy0+IGhpZ2hGcmVxdWVuY3kgPCBpbnB1dCArLS0tLS0tLS0tLS0tLS0tLS0+IGhpZ2hcbiAqICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNdWx0aWJhbmRTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNdWx0aWJhbmRTcGxpdFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBubyBvdXRwdXQgbm9kZSwgdXNlIGVpdGhlciBsb3csIG1pZCBvciBoaWdoIG91dHB1dHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvdyBiYW5kLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sb3cgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBsb3dlciBmaWx0ZXIgb2YgdGhlIG1pZCBiYW5kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwiaGlnaHBhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWlkIGJhbmQgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5taWQgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBoaWdoIGJhbmQgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oaWdoID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImhpZ2hwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMubG93LCB0aGlzLm1pZCwgdGhpcy5oaWdoXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpYmFuZFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmxvd0ZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oaWdoRnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5RID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuUSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuZmFuKHRoaXMubG93LCB0aGlzLmhpZ2gpO1xuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2xvd01pZEZpbHRlciwgdGhpcy5taWQpO1xuICAgICAgICAvLyB0aGUgZnJlcXVlbmN5IGNvbnRyb2wgc2lnbmFsXG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmZhbih0aGlzLmxvdy5mcmVxdWVuY3ksIHRoaXMuX2xvd01pZEZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kuZmFuKHRoaXMubWlkLmZyZXF1ZW5jeSwgdGhpcy5oaWdoLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHRoZSBRIHZhbHVlXG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMubG93LlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLl9sb3dNaWRGaWx0ZXIuUSk7XG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMubWlkLlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLmhpZ2guUSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyNTAwLFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiA0MDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHdyaXRhYmxlKHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5sb3cuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGliYW5kU3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4vUGFyYW1cIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG4vKipcbiAqIFRvbmUuTGlzdGVuZXIgaXMgYSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBBdWRpb0xpc3RlbmVyLiBMaXN0ZW5lciBjb21iaW5lZFxuICogd2l0aCBbW1Bhbm5lcjNEXV0gbWFrZXMgdXAgdGhlIFdlYiBBdWRpbyBBUEkncyAzRCBwYW5uaW5nIHN5c3RlbS4gUGFubmVyM0QgYWxsb3dzIHlvdVxuICogdG8gcGxhY2Ugc291bmRzIGluIDNEIGFuZCBMaXN0ZW5lciBhbGxvd3MgeW91IHRvIG5hdmlnYXRlIHRoZSAzRCBzb3VuZCBlbnZpcm9ubWVudCBmcm9tXG4gKiBhIGZpcnN0LXBlcnNvbiBwZXJzcGVjdGl2ZS4gVGhlcmUgaXMgb25seSBvbmUgbGlzdGVuZXIgcGVyIGF1ZGlvIGNvbnRleHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMaXN0ZW5lciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxpc3RlbmVyXCI7XG4gICAgICAgIHRoaXMucG9zaXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5wb3NpdGlvblgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIucG9zaXRpb25ZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFggPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRYLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIuZm9yd2FyZFksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZvcndhcmRaID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5mb3J3YXJkWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBYID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci51cFgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIudXBZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cFogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnVwWixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwb3NpdGlvblg6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblk6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblo6IDAsXG4gICAgICAgICAgICBmb3J3YXJkWDogMCxcbiAgICAgICAgICAgIGZvcndhcmRZOiAwLFxuICAgICAgICAgICAgZm9yd2FyZFo6IC0xLFxuICAgICAgICAgICAgdXBYOiAwLFxuICAgICAgICAgICAgdXBZOiAxLFxuICAgICAgICAgICAgdXBaOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZvcndhcmRYLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVwWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudXBZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51cFouZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0Lmxpc3RlbmVyID0gbmV3IExpc3RlbmVyKHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5saXN0ZW5lci5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxpc3RlbmVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgXCIuLi8uLi9jb3JlL2NvbnRleHQvTGlzdGVuZXJcIjtcbi8qKlxuICogQSBzcGF0aWFsaXplZCBwYW5uZXIgbm9kZSB3aGljaCBzdXBwb3J0cyBlcXVhbHBvd2VyIG9yIEhSVEYgcGFubmluZy5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhbm5lcjNEIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lcjNELmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicG9zaXRpb25YXCIsIFwicG9zaXRpb25ZXCIsIFwicG9zaXRpb25aXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFubmVyM0RcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lcjNELmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicG9zaXRpb25YXCIsIFwicG9zaXRpb25ZXCIsIFwicG9zaXRpb25aXCJdKTtcbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgICAgICAvLyBzZXQgc29tZSB2YWx1ZXNcbiAgICAgICAgdGhpcy5wYW5uaW5nTW9kZWwgPSBvcHRpb25zLnBhbm5pbmdNb2RlbDtcbiAgICAgICAgdGhpcy5tYXhEaXN0YW5jZSA9IG9wdGlvbnMubWF4RGlzdGFuY2U7XG4gICAgICAgIHRoaXMuZGlzdGFuY2VNb2RlbCA9IG9wdGlvbnMuZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgdGhpcy5jb25lT3V0ZXJHYWluID0gb3B0aW9ucy5jb25lT3V0ZXJHYWluO1xuICAgICAgICB0aGlzLmNvbmVPdXRlckFuZ2xlID0gb3B0aW9ucy5jb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgdGhpcy5jb25lSW5uZXJBbmdsZSA9IG9wdGlvbnMuY29uZUlubmVyQW5nbGU7XG4gICAgICAgIHRoaXMucmVmRGlzdGFuY2UgPSBvcHRpb25zLnJlZkRpc3RhbmNlO1xuICAgICAgICB0aGlzLnJvbGxvZmZGYWN0b3IgPSBvcHRpb25zLnJvbGxvZmZGYWN0b3I7XG4gICAgICAgIHRoaXMucG9zaXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIucG9zaXRpb25YLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucG9zaXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wb3NpdGlvblksXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wb3NpdGlvblksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBvc2l0aW9uWixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBvc2l0aW9uWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIub3JpZW50YXRpb25YLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub3JpZW50YXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblksXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5vcmllbnRhdGlvblksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLm9yaWVudGF0aW9uWixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9yaWVudGF0aW9uWixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb25lSW5uZXJBbmdsZTogMzYwLFxuICAgICAgICAgICAgY29uZU91dGVyQW5nbGU6IDM2MCxcbiAgICAgICAgICAgIGNvbmVPdXRlckdhaW46IDAsXG4gICAgICAgICAgICBkaXN0YW5jZU1vZGVsOiBcImludmVyc2VcIixcbiAgICAgICAgICAgIG1heERpc3RhbmNlOiAxMDAwMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWDogMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWTogMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWjogMCxcbiAgICAgICAgICAgIHBhbm5pbmdNb2RlbDogXCJlcXVhbHBvd2VyXCIsXG4gICAgICAgICAgICBwb3NpdGlvblg6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblk6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblo6IDAsXG4gICAgICAgICAgICByZWZEaXN0YW5jZTogMSxcbiAgICAgICAgICAgIHJvbGxvZmZGYWN0b3I6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc291cmNlIGluIDNkIHNwYWNlLlxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uKHgsIHksIHopIHtcbiAgICAgICAgdGhpcy5wb3NpdGlvblgudmFsdWUgPSB4O1xuICAgICAgICB0aGlzLnBvc2l0aW9uWS52YWx1ZSA9IHk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aLnZhbHVlID0gejtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBzb3VyY2UgaW4gM2Qgc3BhY2UuXG4gICAgICovXG4gICAgc2V0T3JpZW50YXRpb24oeCwgeSwgeikge1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWC52YWx1ZSA9IHg7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZLnZhbHVlID0geTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbloudmFsdWUgPSB6O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhbm5pbmcgbW9kZWwuIEVpdGhlciBcImVxdWFscG93ZXJcIiBvciBcIkhSVEZcIi5cbiAgICAgKi9cbiAgICBnZXQgcGFubmluZ01vZGVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnBhbm5pbmdNb2RlbDtcbiAgICB9XG4gICAgc2V0IHBhbm5pbmdNb2RlbCh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLnBhbm5pbmdNb2RlbCA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWZlcmVuY2UgZGlzdGFuY2UgZm9yIHJlZHVjaW5nIHZvbHVtZSBhcyBzb3VyY2UgbW92ZSBmdXJ0aGVyIGZyb20gdGhlIGxpc3RlbmVyXG4gICAgICovXG4gICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnJlZkRpc3RhbmNlO1xuICAgIH1cbiAgICBzZXQgcmVmRGlzdGFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5yZWZEaXN0YW5jZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzY3JpYmVzIGhvdyBxdWlja2x5IHRoZSB2b2x1bWUgaXMgcmVkdWNlZCBhcyBzb3VyY2UgbW92ZXMgYXdheSBmcm9tIGxpc3RlbmVyLlxuICAgICAqL1xuICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnJvbGxvZmZGYWN0b3I7XG4gICAgfVxuICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIucm9sbG9mZkZhY3RvciA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRpc3RhbmNlIG1vZGVsIHVzZWQgYnksICBcImxpbmVhclwiLCBcImludmVyc2VcIiwgb3IgXCJleHBvbmVudGlhbFwiLlxuICAgICAqL1xuICAgIGdldCBkaXN0YW5jZU1vZGVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmRpc3RhbmNlTW9kZWw7XG4gICAgfVxuICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzdGFuY2VNb2RlbCA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuZ2xlLCBpbiBkZWdyZWVzLCBpbnNpZGUgb2Ygd2hpY2ggdGhlcmUgd2lsbCBiZSBubyB2b2x1bWUgcmVkdWN0aW9uXG4gICAgICovXG4gICAgZ2V0IGNvbmVJbm5lckFuZ2xlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmNvbmVJbm5lckFuZ2xlO1xuICAgIH1cbiAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lSW5uZXJBbmdsZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuZ2xlLCBpbiBkZWdyZWVzLCBvdXRzaWRlIG9mIHdoaWNoIHRoZSB2b2x1bWUgd2lsbCBiZSByZWR1Y2VkXG4gICAgICogdG8gYSBjb25zdGFudCB2YWx1ZSBvZiBjb25lT3V0ZXJHYWluXG4gICAgICovXG4gICAgZ2V0IGNvbmVPdXRlckFuZ2xlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmNvbmVPdXRlckFuZ2xlO1xuICAgIH1cbiAgICBzZXQgY29uZU91dGVyQW5nbGUodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJBbmdsZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGdhaW4gb3V0c2lkZSBvZiB0aGUgY29uZU91dGVyQW5nbGVcbiAgICAgKi9cbiAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJHYWluO1xuICAgIH1cbiAgICBzZXQgY29uZU91dGVyR2Fpbih2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNvbmVPdXRlckdhaW4gPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIGRpc3RhbmNlIGJldHdlZW4gc291cmNlIGFuZCBsaXN0ZW5lcixcbiAgICAgKiBhZnRlciB3aGljaCB0aGUgdm9sdW1lIHdpbGwgbm90IGJlIHJlZHVjZWQgYW55IGZ1cnRoZXIuXG4gICAgICovXG4gICAgZ2V0IG1heERpc3RhbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLm1heERpc3RhbmNlO1xuICAgIH1cbiAgICBzZXQgbWF4RGlzdGFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5tYXhEaXN0YW5jZSA9IHZhbDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblouZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5uZXIzRC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHRoZVdpbmRvdyB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogQSB3cmFwcGVyIGFyb3VuZCB0aGUgTWVkaWFSZWNvcmRlciBBUEkuIFVubGlrZSB0aGUgcmVzdCBvZiBUb25lLmpzLCB0aGlzIG1vZHVsZSBkb2VzIG5vdCBvZmZlclxuICogYW55IHNhbXBsZS1hY2N1cmF0ZSBzY2hlZHVsaW5nIGJlY2F1c2UgaXQgaXMgbm90IGEgZmVhdHVyZSBvZiB0aGUgTWVkaWFSZWNvcmRlciBBUEkuXG4gKiBUaGlzIGlzIG9ubHkgbmF0aXZlbHkgc3VwcG9ydGVkIGluIENocm9tZSBhbmQgRmlyZWZveC5cbiAqIEZvciBhIGNyb3NzLWJyb3dzZXIgc2hpbSwgaW5zdGFsbCAoYXVkaW8tcmVjb3JkZXItcG9seWZpbGwpW2h0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2F1ZGlvLXJlY29yZGVyLXBvbHlmaWxsXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCByZWNvcmRlciA9IG5ldyBUb25lLlJlY29yZGVyKCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkuY29ubmVjdChyZWNvcmRlcik7XG4gKiAvLyBzdGFydCByZWNvcmRpbmdcbiAqIHJlY29yZGVyLnN0YXJ0KCk7XG4gKiAvLyBnZW5lcmF0ZSBhIGZldyBub3Rlc1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDM1wiLCAwLjUpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCAwLjUsIFwiKzFcIik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM1XCIsIDAuNSwgXCIrMlwiKTtcbiAqIC8vIHdhaXQgZm9yIHRoZSBub3RlcyB0byBlbmQgYW5kIHN0b3AgdGhlIHJlY29yZGluZ1xuICogc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gKiBcdC8vIHRoZSByZWNvcmRlZCBhdWRpbyBpcyByZXR1cm5lZCBhcyBhIGJsb2JcbiAqIFx0Y29uc3QgcmVjb3JkaW5nID0gYXdhaXQgcmVjb3JkZXIuc3RvcCgpO1xuICogXHQvLyBkb3dubG9hZCB0aGUgcmVjb3JkaW5nIGJ5IGNyZWF0aW5nIGFuIGFuY2hvciBlbGVtZW50IGFuZCBibG9iIHVybFxuICogXHRjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHJlY29yZGluZyk7XG4gKiBcdGNvbnN0IGFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuICogXHRhbmNob3IuZG93bmxvYWQgPSBcInJlY29yZGluZy53ZWJtXCI7XG4gKiBcdGFuY2hvci5ocmVmID0gdXJsO1xuICogXHRhbmNob3IuY2xpY2soKTtcbiAqIH0sIDQwMDApO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUmVjb3JkZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUmVjb3JkZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFJlY29yZGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydChSZWNvcmRlci5zdXBwb3J0ZWQsIFwiTWVkaWEgUmVjb3JkZXIgQVBJIGlzIG5vdCBhdmFpbGFibGVcIik7XG4gICAgICAgIHRoaXMuX3N0cmVhbSA9IHRoaXMuY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9zdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuX3N0cmVhbS5zdHJlYW0sIHtcbiAgICAgICAgICAgIG1pbWVUeXBlOiBvcHRpb25zLm1pbWVUeXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW1lIHR5cGUgaXMgdGhlIGZvcm1hdCB0aGF0IHRoZSBhdWRpbyBpcyBlbmNvZGVkIGluLiBGb3IgQ2hyb21lXG4gICAgICogdGhhdCBpcyB0eXBpY2FsbHkgd2VibSBlbmNvZGVkIGFzIFwidm9yYmlzXCIuXG4gICAgICovXG4gICAgZ2V0IG1pbWVUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVjb3JkZXIubWltZVR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlc3QgaWYgeW91ciBwbGF0Zm9ybSBzdXBwb3J0cyB0aGUgTWVkaWEgUmVjb3JkZXIgQVBJLiBJZiBpdCdzIG5vdCBhdmFpbGFibGUsXG4gICAgICogdHJ5IGluc3RhbGxpbmcgdGhpcyAocG9seWZpbGwpW2h0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2F1ZGlvLXJlY29yZGVyLXBvbHlmaWxsXS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHN1cHBvcnRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoZVdpbmRvdyAhPT0gbnVsbCAmJiBSZWZsZWN0Lmhhcyh0aGVXaW5kb3csIFwiTWVkaWFSZWNvcmRlclwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgUmVjb3JkZXIsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIgb3IgXCJwYXVzZWRcIlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3JlY29yZGVyLnN0YXRlID09PSBcImluYWN0aXZlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBcInN0b3BwZWRcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9yZWNvcmRlci5zdGF0ZSA9PT0gXCJwYXVzZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIFwicGF1c2VkXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gXCJzdGFydGVkXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIFJlY29yZGVyLiBSZXR1cm5zIGEgcHJvbWlzZSB3aGljaCByZXNvbHZlc1xuICAgICAqIHdoZW4gdGhlIHJlY29yZGVyIGhhcyBzdGFydGVkLlxuICAgICAqL1xuICAgIHN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KHRoaXMuc3RhdGUgIT09IFwic3RhcnRlZFwiLCBcIlJlY29yZGVyIGlzIGFscmVhZHkgc3RhcnRlZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ldyBQcm9taXNlKGRvbmUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZVN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5yZW1vdmVFdmVudExpc3RlbmVyKFwic3RhcnRcIiwgaGFuZGxlU3RhcnQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuYWRkRXZlbnRMaXN0ZW5lcihcInN0YXJ0XCIsIGhhbmRsZVN0YXJ0LCBmYWxzZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnN0YXJ0KCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgc3RhcnRQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcmVjb3JkZXIuIFJldHVybnMgYSBwcm9taXNlIHdpdGggdGhlIHJlY29yZGVkIGNvbnRlbnQgdW50aWwgdGhpcyBwb2ludFxuICAgICAqIGVuY29kZWQgYXMgW1ttaW1lVHlwZV1dXG4gICAgICovXG4gICAgc3RvcCgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLnN0YXRlICE9PSBcInN0b3BwZWRcIiwgXCJSZWNvcmRlciBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFQcm9taXNlID0gbmV3IFByb21pc2UoZG9uZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlRGF0YSA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJkYXRhYXZhaWxhYmxlXCIsIGhhbmRsZURhdGEsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShlLmRhdGEpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuYWRkRXZlbnRMaXN0ZW5lcihcImRhdGFhdmFpbGFibGVcIiwgaGFuZGxlRGF0YSwgZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgZGF0YVByb21pc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgcmVjb3JkZXJcbiAgICAgKi9cbiAgICBwYXVzZSgpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiLCBcIlJlY29yZGVyIG11c3QgYmUgc3RhcnRlZFwiKTtcbiAgICAgICAgdGhpcy5fcmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0cmVhbS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVJlY29yZGVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIENvbXByZXNzb3IgaXMgYSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBXZWIgQXVkaW9cbiAqIFtEeW5hbWljc0NvbXByZXNzb3JOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1keW5hbWljc2NvbXByZXNzb3Jub2RlLWludGVyZmFjZSkuXG4gKiBDb21wcmVzc2lvbiByZWR1Y2VzIHRoZSB2b2x1bWUgb2YgbG91ZCBzb3VuZHMgb3IgYW1wbGlmaWVzIHF1aWV0IHNvdW5kc1xuICogYnkgbmFycm93aW5nIG9yIFwiY29tcHJlc3NpbmdcIiBhbiBhdWRpbyBzaWduYWwncyBkeW5hbWljIHJhbmdlLlxuICogUmVhZCBtb3JlIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0R5bmFtaWNfcmFuZ2VfY29tcHJlc3Npb24pLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvbXAgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIiwgXCJyYXRpb1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbXByZXNzb3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBjb21wcmVzc29yIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSB0aGlzLmNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9jb21wcmVzc29yO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2NvbXByZXNzb3I7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwicmF0aW9cIl0pO1xuICAgICAgICB0aGlzLnRocmVzaG9sZCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy50aHJlc2hvbGQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFjayA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2subWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2subWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2ssXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5hdHRhY2ssXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IucmVsZWFzZS5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJlbGVhc2UubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5yZWxlYXNlLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmVsZWFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMua25lZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5rbmVlLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3Iua25lZS5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3Iua25lZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5rbmVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yYXRpbyA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yYXRpby5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJhdGlvLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5yYXRpbyxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yYXRpbyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNldCB0aGUgZGVmYXVsdHNcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wia25lZVwiLCBcInJlbGVhc2VcIiwgXCJhdHRhY2tcIiwgXCJyYXRpb1wiLCBcInRocmVzaG9sZFwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2s6IDAuMDAzLFxuICAgICAgICAgICAga25lZTogMzAsXG4gICAgICAgICAgICByYXRpbzogMTIsXG4gICAgICAgICAgICByZWxlYXNlOiAwLjI1LFxuICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlYWQtb25seSBkZWNpYmVsIHZhbHVlIGZvciBtZXRlcmluZyBwdXJwb3NlcywgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IGFtb3VudCBvZiBnYWluXG4gICAgICogcmVkdWN0aW9uIHRoYXQgdGhlIGNvbXByZXNzb3IgaXMgYXBwbHlpbmcgdG8gdGhlIHNpZ25hbC4gSWYgZmVkIG5vIHNpZ25hbCB0aGUgdmFsdWUgd2lsbCBiZSAwIChubyBnYWluIHJlZHVjdGlvbikuXG4gICAgICovXG4gICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXByZXNzb3IucmVkdWN0aW9uO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmF0dGFjay5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmVsZWFzZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudGhyZXNob2xkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5yYXRpby5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMua25lZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbXByZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR3JlYXRlclRoYW4gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0dyZWF0ZXJUaGFuXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBGb2xsb3dlciB9IGZyb20gXCIuLi9hbmFseXNpcy9Gb2xsb3dlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG4vKipcbiAqIEdhdGUgb25seSBwYXNzZXMgYSBzaWduYWwgdGhyb3VnaCB3aGVuIHRoZSBpbmNvbWluZ1xuICogc2lnbmFsIGV4Y2VlZHMgYSBzcGVjaWZpZWQgdGhyZXNob2xkLiBJdCB1c2VzIFtbRm9sbG93ZXJdXSB0byBmb2xsb3cgdGhlIGFtcGx0aXVkZVxuICogb2YgdGhlIGluY29taW5nIHNpZ25hbCBhbmQgY29tcGFyZXMgaXQgdG8gdGhlIFtbdGhyZXNob2xkXV0gdmFsdWUgdXNpbmcgW1tHcmVhdGVyVGhhbl1dLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBnYXRlID0gbmV3IFRvbmUuR2F0ZSgtMzAsIDAuMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCkuY29ubmVjdChnYXRlKTtcbiAqIC8vIHRoZSBnYXRlIHdpbGwgb25seSBwYXNzIHRocm91Z2ggdGhlIGluY29taW5nXG4gKiAvLyBzaWduYWwgd2hlbiBpdCdzIGxvdWRlciB0aGFuIC0zMGRiXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoR2F0ZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInNtb290aGluZ1wiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYXRlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHYXRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwic21vb3RoaW5nXCJdKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIgPSBuZXcgRm9sbG93ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiBvcHRpb25zLnNtb290aGluZyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2d0ID0gbmV3IEdyZWF0ZXJUaGFuKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBkYlRvR2FpbihvcHRpb25zLnRocmVzaG9sZCksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2dhdGUgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fZ2F0ZSk7XG4gICAgICAgIC8vIHRoZSBjb250cm9sIHNpZ25hbFxuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2ZvbGxvd2VyLCB0aGlzLl9ndCwgdGhpcy5fZ2F0ZS5nYWluKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC4xLFxuICAgICAgICAgICAgdGhyZXNob2xkOiAtNDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aHJlc2hvbGQgb2YgdGhlIGdhdGUgaW4gZGVjaWJlbHNcbiAgICAgKi9cbiAgICBnZXQgdGhyZXNob2xkKCkge1xuICAgICAgICByZXR1cm4gZ2FpblRvRGIodGhpcy5fZ3QudmFsdWUpO1xuICAgIH1cbiAgICBzZXQgdGhyZXNob2xkKHRocmVzaCkge1xuICAgICAgICB0aGlzLl9ndC52YWx1ZSA9IGRiVG9HYWluKHRocmVzaCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdHRhY2svZGVjYXkgc3BlZWQgb2YgdGhlIGdhdGUuIFNlZSBbW0ZvbGxvd2VyLnNtb290aGluZ11dXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyhzbW9vdGhpbmdUaW1lKSB7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZyA9IHNtb290aGluZ1RpbWU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ3QuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2F0ZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IENvbXByZXNzb3IgfSBmcm9tIFwiLi9Db21wcmVzc29yXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG47XG4vKipcbiAqIExpbWl0ZXIgd2lsbCBsaW1pdCB0aGUgbG91ZG5lc3Mgb2YgYW4gaW5jb21pbmcgc2lnbmFsLlxuICogVW5kZXIgdGhlIGhvb2QgaXQncyBjb21wb3NlZCBvZiBhIFtbQ29tcHJlc3Nvcl1dIHdpdGggYSBmYXN0IGF0dGFja1xuICogYW5kIHJlbGVhc2UgYW5kIG1heCBjb21wcmVzc2lvbiByYXRpby5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbGltaXRlciA9IG5ldyBUb25lLkxpbWl0ZXIoLTIwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QobGltaXRlcik7XG4gKiBvc2NpbGxhdG9yLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBMaW1pdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTGltaXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMaW1pdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMaW1pdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCJdKTtcbiAgICAgICAgdGhpcy5fY29tcHJlc3NvciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBDb21wcmVzc29yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHJhdGlvOiAyMCxcbiAgICAgICAgICAgIGF0dGFjazogMC4wMDMsXG4gICAgICAgICAgICByZWxlYXNlOiAwLjAxLFxuICAgICAgICAgICAgdGhyZXNob2xkOiBvcHRpb25zLnRocmVzaG9sZFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQgPSB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ0aHJlc2hvbGRcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB0aHJlc2hvbGQ6IC0xMlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWFkLW9ubHkgZGVjaWJlbCB2YWx1ZSBmb3IgbWV0ZXJpbmcgcHVycG9zZXMsIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBhbW91bnQgb2YgZ2FpblxuICAgICAqIHJlZHVjdGlvbiB0aGF0IHRoZSBjb21wcmVzc29yIGlzIGFwcGx5aW5nIHRvIHRoZSBzaWduYWwuXG4gICAgICovXG4gICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXByZXNzb3IucmVkdWN0aW9uO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRocmVzaG9sZC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxpbWl0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ29tcHJlc3NvciB9IGZyb20gXCIuL0NvbXByZXNzb3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWlkU2lkZVNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5pbXBvcnQgeyBNaWRTaWRlTWVyZ2UgfSBmcm9tIFwiLi4vY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogTWlkU2lkZUNvbXByZXNzb3IgYXBwbGllcyB0d28gZGlmZmVyZW50IGNvbXByZXNzb3JzIHRvIHRoZSBbW21pZF1dXG4gKiBhbmQgW1tzaWRlXV0gc2lnbmFsIGNvbXBvbmVudHMgb2YgdGhlIGlucHV0LiBTZWUgW1tNaWRTaWRlU3BsaXRdXSBhbmQgW1tNaWRTaWRlTWVyZ2VdXS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZUNvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVDb21wcmVzc29yXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSB0aGlzLmlucHV0ID0gbmV3IE1pZFNpZGVTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlID0gdGhpcy5vdXRwdXQgPSBuZXcgTWlkU2lkZU1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5taWQsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5zaWRlID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLnNpZGUsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0Lm1pZC5jaGFpbih0aGlzLm1pZCwgdGhpcy5fbWlkU2lkZU1lcmdlLm1pZCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5zaWRlLmNoYWluKHRoaXMuc2lkZSwgdGhpcy5fbWlkU2lkZU1lcmdlLnNpZGUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJtaWRcIiwgXCJzaWRlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1pZDoge1xuICAgICAgICAgICAgICAgIHJhdGlvOiAzLFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTI0LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMDMsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAyLFxuICAgICAgICAgICAgICAgIGtuZWU6IDE2XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2lkZToge1xuICAgICAgICAgICAgICAgIHJhdGlvOiA2LFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTMwLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAzLFxuICAgICAgICAgICAgICAgIGtuZWU6IDEwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZUNvbXByZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ29tcHJlc3NvciB9IGZyb20gXCIuL0NvbXByZXNzb3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGliYW5kU3BsaXQgfSBmcm9tIFwiLi4vY2hhbm5lbC9NdWx0aWJhbmRTcGxpdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuLyoqXG4gKiBBIGNvbXByZXNzb3Igd2l0aCBzZXBhcmF0ZSBjb250cm9scyBvdmVyIGxvdy9taWQvaGlnaCBkeW5hbWljcy4gU2VlIFtbQ29tcHJlc3Nvcl1dIGFuZCBbW011bHRpYmFuZFNwbGl0XV1cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbXVsdGliYW5kID0gbmV3IFRvbmUuTXVsdGliYW5kQ29tcHJlc3Nvcih7XG4gKiBcdGxvd0ZyZXF1ZW5jeTogMjAwLFxuICogXHRoaWdoRnJlcXVlbmN5OiAxMzAwLFxuICogXHRsb3c6IHtcbiAqIFx0XHR0aHJlc2hvbGQ6IC0xMlxuICogXHR9XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE11bHRpYmFuZENvbXByZXNzb3IgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNdWx0aWJhbmRDb21wcmVzc29yXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyID0gdGhpcy5pbnB1dCA9IG5ldyBNdWx0aWJhbmRTcGxpdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogb3B0aW9ucy5oaWdoRnJlcXVlbmN5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IHRoaXMuX3NwbGl0dGVyLmxvd0ZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5ID0gdGhpcy5fc3BsaXR0ZXIuaGlnaEZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5sb3cgPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMubG93LCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLm1pZCwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmhpZ2ggPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMuaGlnaCwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBjb21wcmVzc29yXG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmxvdy5jaGFpbih0aGlzLmxvdywgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlci5taWQuY2hhaW4odGhpcy5taWQsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIuaGlnaC5jaGFpbih0aGlzLmhpZ2gsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiaGlnaFwiLCBcIm1pZFwiLCBcImxvd1wiLCBcImhpZ2hGcmVxdWVuY3lcIiwgXCJsb3dGcmVxdWVuY3lcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiAyNTAsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyMDAwLFxuICAgICAgICAgICAgbG93OiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDYsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMzAsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4yNSxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDMsXG4gICAgICAgICAgICAgICAga25lZTogMTBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtaWQ6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhpZ2g6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvdy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NdWx0aWJhbmRDb21wcmVzc29yLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpYmFuZFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbi8qKlxuICogRVEzIHByb3ZpZGVzIDMgZXF1YWxpemVyIGJpbnM6IExvdy9NaWQvSGlnaC5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEVRMyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhFUTMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRVEzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhFUTMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX211bHRpYmFuZFNwbGl0ID0gbmV3IE11bHRpYmFuZFNwbGl0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogb3B0aW9ucy5sb3dGcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sb3dHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5sb3csXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMubWlkLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2hpZ2hHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5oaWdoLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG93ID0gdGhpcy5fbG93R2Fpbi5nYWluO1xuICAgICAgICB0aGlzLm1pZCA9IHRoaXMuX21pZEdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5oaWdoID0gdGhpcy5faGlnaEdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5RID0gdGhpcy5fbXVsdGliYW5kU3BsaXQuUTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdC5sb3dGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IHRoaXMuX211bHRpYmFuZFNwbGl0LmhpZ2hGcmVxdWVuY3k7XG4gICAgICAgIC8vIHRoZSBmcmVxdWVuY3kgYmFuZHNcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQubG93LmNoYWluKHRoaXMuX2xvd0dhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQubWlkLmNoYWluKHRoaXMuX21pZEdhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQuaGlnaC5jaGFpbih0aGlzLl9oaWdoR2FpbiwgdGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCIsIFwibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fbXVsdGliYW5kU3BsaXRdO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGlnaDogMCxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IDI1MDAsXG4gICAgICAgICAgICBsb3c6IDAsXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IDQwMCxcbiAgICAgICAgICAgIG1pZDogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiLCBcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0aWJhbmRTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93R2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZEdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9oaWdoR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2guZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FUTMuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQ29udm9sdmVyIGlzIGEgd3JhcHBlciBhcm91bmQgdGhlIE5hdGl2ZSBXZWIgQXVkaW9cbiAqIFtDb252b2x2ZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1jb252b2x2ZXJub2RlLWludGVyZmFjZSkuXG4gKiBDb252b2x1dGlvbiBpcyB1c2VmdWwgZm9yIHJldmVyYiBhbmQgZmlsdGVyIGVtdWxhdGlvbi4gUmVhZCBtb3JlIGFib3V0IGNvbnZvbHV0aW9uIHJldmVyYiBvblxuICogW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29udm9sdXRpb25fcmV2ZXJiKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gaW5pdGlhbGl6aW5nIHRoZSBjb252b2x2ZXIgd2l0aCBhbiBpbXB1bHNlIHJlc3BvbnNlXG4gKiBjb25zdCBjb252b2x2ZXIgPSBuZXcgVG9uZS5Db252b2x2ZXIoXCIuL3BhdGgvdG8vaXIud2F2XCIpLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENvbnZvbHZlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDb252b2x2ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb252b2x2ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYXRpdmUgQ29udm9sdmVyTm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29udm9sdmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcihvcHRpb25zLnVybCwgYnVmZmVyID0+IHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICAgICAgb3B0aW9ucy5vbmxvYWQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLy8gc2V0IGlmIGl0J3MgYWxyZWFkeSBsb2FkZWQsIHNldCBpdCBpbW1lZGlhdGVseVxuICAgICAgICBpZiAodGhpcy5fYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSB0aGlzLl9idWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW5pdGlhbGx5IHNldCBub3JtYWxpemF0aW9uXG4gICAgICAgIHRoaXMubm9ybWFsaXplID0gb3B0aW9ucy5ub3JtYWxpemU7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9jb252b2x2ZXIsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZTogdHJ1ZSxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvYWQgYW4gaW1wdWxzZSByZXNwb25zZSB1cmwgYXMgYW4gYXVkaW8gYnVmZmVyLlxuICAgICAqIERlY29kZXMgdGhlIGF1ZGlvIGFzeW5jaHJvbm91c2x5IGFuZCBpbnZva2VzXG4gICAgICogdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGF1ZGlvIGJ1ZmZlciBsb2Fkcy5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIGJ1ZmZlciB0byBsb2FkLiBmaWxldHlwZSBzdXBwb3J0IGRlcGVuZHMgb24gdGhlIGJyb3dzZXIuXG4gICAgICovXG4gICAgbG9hZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0geWllbGQgdGhpcy5fYnVmZmVyLmxvYWQodXJsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjb252b2x2ZXIncyBidWZmZXJcbiAgICAgKi9cbiAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBidWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiBpdCdzIGFscmVhZHkgZ290IGEgYnVmZmVyLCBjcmVhdGUgYSBuZXcgb25lXG4gICAgICAgIGlmICh0aGlzLl9jb252b2x2ZXIuYnVmZmVyKSB7XG4gICAgICAgICAgICAvLyBkaXNjb25uZWN0IHRoZSBvbGQgb25lXG4gICAgICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYW5kIGNvbm5lY3QgYSBuZXcgb25lXG4gICAgICAgICAgICB0aGlzLl9jb252b2x2ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2NvbnZvbHZlciwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ1ZmYgPSB0aGlzLl9idWZmZXIuZ2V0KCk7XG4gICAgICAgIHRoaXMuX2NvbnZvbHZlci5idWZmZXIgPSBidWZmID8gYnVmZiA6IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBub3JtYWxpemUgcHJvcGVydHkgb2YgdGhlIENvbnZvbHZlck5vZGUgaW50ZXJmYWNlIGlzIGEgYm9vbGVhbiB0aGF0XG4gICAgICogY29udHJvbHMgd2hldGhlciB0aGUgaW1wdWxzZSByZXNwb25zZSBmcm9tIHRoZSBidWZmZXIgd2lsbCBiZSBzY2FsZWQgYnlcbiAgICAgKiBhbiBlcXVhbC1wb3dlciBub3JtYWxpemF0aW9uIHdoZW4gdGhlIGJ1ZmZlciBhdHRyaWJ1dGUgaXMgc2V0LCBvciBub3QuXG4gICAgICovXG4gICAgZ2V0IG5vcm1hbGl6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZvbHZlci5ub3JtYWxpemU7XG4gICAgfVxuICAgIHNldCBub3JtYWxpemUobm9ybSkge1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIubm9ybWFsaXplID0gbm9ybTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db252b2x2ZXIuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvQW5hbHlzZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL01ldGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9GRlRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL0RDTWV0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL1dhdmVmb3JtXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9Gb2xsb3dlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9DaGFubmVsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NZXJnZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL01vbm9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvUGFubmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1Bhbm5lcjNEXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1BhblZvbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9SZWNvcmRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Tb2xvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1NwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1ZvbHVtZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvQ29tcHJlc3NvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvR2F0ZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvTGltaXRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvTWlkU2lkZUNvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL011bHRpYmFuZENvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52ZWxvcGUvRnJlcXVlbmN5RW52ZWxvcGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9FUTNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9GaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9PbmVQb2xlRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvRmVlZGJhY2tDb21iRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvTG93cGFzc0NvbWJGaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9Db252b2x2ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9CaXF1YWRGaWx0ZXJcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL2NvcmUvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NvdXJjZS9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vc2lnbmFsL2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pbnN0cnVtZW50L2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9ldmVudC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZWZmZWN0L2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb21wb25lbnQvaW5kZXhcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsYXNzZXMuanMubWFwIiwiZXhwb3J0IHsgZ2V0Q29udGV4dCwgc2V0Q29udGV4dCB9IGZyb20gXCIuL2NvcmUvR2xvYmFsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jbGFzc2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi92ZXJzaW9uXCI7XG5pbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4vY29yZS9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmV4cG9ydCB7IHN0YXJ0IH0gZnJvbSBcIi4vY29yZS9HbG9iYWxcIjtcbmV4cG9ydCB7IHN1cHBvcnRlZCB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbi8qKlxuICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIG9mIHRoZSBnbG9iYWwgW1tDb250ZXh0XV0uXG4gKiBTZWUgW1tDb250ZXh0Lm5vd11dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm93KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkubm93KCk7XG59XG4vKipcbiAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSBvZiB0aGUgZ2xvYmFsIFtbQ29udGV4dF1dIHdpdGhvdXQgdGhlIFtbQ29udGV4dC5sb29rQWhlYWRdXVxuICogU2VlIFtbQ29udGV4dC5pbW1lZGlhdGVdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGltbWVkaWF0ZSgpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmltbWVkaWF0ZSgpO1xufVxuLyoqXG4gKiBUaGUgVHJhbnNwb3J0IG9iamVjdCBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tUcmFuc3BvcnRdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRyYW5zcG9ydCA9IGdldENvbnRleHQoKS50cmFuc3BvcnQ7XG4vKipcbiAqIFRoZSBUcmFuc3BvcnQgb2JqZWN0IGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIFNlZSBbW1RyYW5zcG9ydF1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNwb3J0KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkudHJhbnNwb3J0O1xufVxuLyoqXG4gKiBUaGUgRGVzdGluYXRpb24gKG91dHB1dCkgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbRGVzdGluYXRpb25dXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IERlc3RpbmF0aW9uID0gZ2V0Q29udGV4dCgpLmRlc3RpbmF0aW9uO1xuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgW1tEZXN0aW5hdGlvbl1dXG4gKi9cbmV4cG9ydCBjb25zdCBNYXN0ZXIgPSBnZXRDb250ZXh0KCkuZGVzdGluYXRpb247XG4vKipcbiAqIFRoZSBEZXN0aW5hdGlvbiAob3V0cHV0KSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tEZXN0aW5hdGlvbl1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVzdGluYXRpb24oKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5kZXN0aW5hdGlvbjtcbn1cbi8qKlxuICogVGhlIFtbTGlzdGVuZXJdXSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY29uc3QgTGlzdGVuZXIgPSBnZXRDb250ZXh0KCkubGlzdGVuZXI7XG4vKipcbiAqIFRoZSBbW0xpc3RlbmVyXV0gYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExpc3RlbmVyKCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkubGlzdGVuZXI7XG59XG4vKipcbiAqIERyYXcgaXMgdXNlZCB0byBzeW5jaHJvbml6ZSB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUcmFuc3BvcnQncyBjYWxsYmFja3MuXG4gKiBTZWUgW1tEcmF3XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBEcmF3ID0gZ2V0Q29udGV4dCgpLmRyYXc7XG4vKipcbiAqIEdldCB0aGUgc2luZ2xldG9uIGF0dGFjaGVkIHRvIHRoZSBnbG9iYWwgY29udGV4dC5cbiAqIERyYXcgaXMgdXNlZCB0byBzeW5jaHJvbml6ZSB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUcmFuc3BvcnQncyBjYWxsYmFja3MuXG4gKiBTZWUgW1tEcmF3XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREcmF3KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkuZHJhdztcbn1cbi8qKlxuICogQSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBjb250ZXh0XG4gKiBTZWUgW1tDb250ZXh0XV1cbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4vKipcbiAqIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIGxvYWRpbmcgcHJvbWlzZXMgYXJlIHJlc29sdmVkLlxuICogQWxpYXMgZm9yIHN0YXRpYyBbW1RvbmVBdWRpb0J1ZmZlci5sb2FkZWRdXSBtZXRob2QuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZGVkKCkge1xuICAgIHJldHVybiBUb25lQXVkaW9CdWZmZXIubG9hZGVkKCk7XG59XG4vLyB0aGlzIGZpbGxzIGluIG5hbWUgY2hhbmdlcyBmcm9tIDEzLnggdG8gMTQueFxuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVycyB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vc291cmNlL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG5leHBvcnQgY29uc3QgQnVmZmVyID0gVG9uZUF1ZGlvQnVmZmVyO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlcnMgPSBUb25lQXVkaW9CdWZmZXJzO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlclNvdXJjZSA9IFRvbmVCdWZmZXJTb3VyY2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgU3RhcnRBdWRpb0NvbnRleHQgZnJvbSBcIi4vc3RhcnRBdWRpb0NvbnRleHRcIjtcblxuY29uc3QgaXNJcGhvbmUgPVxuICBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmUvaSkgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBvZC9pKTtcbmNvbnN0IGlzSXBhZCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQYWQvaSk7XG5jb25zdCBpc0FuZHJvaWQgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpO1xuY29uc3QgaXNNb2JpbGUgPSBpc0lwaG9uZSB8fCBpc0lwYWQgfHwgaXNBbmRyb2lkO1xuY29uc3QgaXNEZXNrdG9wID0gIWlzTW9iaWxlO1xuXG5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCIpO1xuXG5leHBvcnQgY29uc3QgYnJvd3NlciA9IHsgaXNJcGhvbmUsIGlzSXBhZCwgaXNNb2JpbGUsIGlzRGVza3RvcCB9O1xuZXhwb3J0IGNvbnN0IGNob2ljZSA9IChhKSA9PiBhW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGEubGVuZ3RoKV07XG5leHBvcnQgY29uc3QgbW9kID0gKG4sIG0pID0+IG4gLSBtICogTWF0aC5mbG9vcihuIC8gbSk7XG5leHBvcnQgY29uc3QgcmFuZG9tID0gKCkgPT4gTWF0aC5yYW5kb20oKTtcbmV4cG9ydCBjb25zdCByYW5kID0gKG4pID0+IE1hdGgucmFuZG9tKCkgKiBuO1xuZXhwb3J0IGNvbnN0IHJhbmRpbnQgPSAobikgPT4gcmFuZChuKSB8IDA7XG5leHBvcnQgY29uc3QgcmFuZHJhbmdlID0gKGEsIGIpID0+IGEgKyByYW5kKGIgLSBhKTtcbmV4cG9ydCBjb25zdCByYW5kc2lnbiA9ICgpID0+IChyYW5kb20oKSA+PSAwLjUgPyAtMSA6IDEpO1xuZXhwb3J0IGNvbnN0IHJhbmRudWxsc2lnbiA9ICgpID0+IHtcbiAgdmFyIHIgPSByYW5kb20oKTtcbiAgcmV0dXJuIHIgPCAwLjMzMyA/IC0xIDogciA8IDAuNjY2ID8gMCA6IDE7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcmVxdWVzdEF1ZGlvQ29udGV4dChmbikge1xuICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBidXR0b24uaW5uZXJIVE1MID0gXCJUYXAgdG8gc3RhcnQgLSBwbGVhc2UgdW5tdXRlIHlvdXIgZGV2aWNlXCI7XG4gIE9iamVjdC5hc3NpZ24oY29udGFpbmVyLnN0eWxlLCB7XG4gICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgd2lkdGg6IFwiMTAwJVwiLFxuICAgIGhlaWdodDogXCIxMDAlXCIsXG4gICAgekluZGV4OiBcIjEwMDAwXCIsXG4gICAgdG9wOiBcIjBweFwiLFxuICAgIGxlZnQ6IFwiMHB4XCIsXG4gICAgYmFja2dyb3VuZENvbG9yOiBcInJnYmEoMCwgMCwgMCwgMC44KVwiLFxuICB9KTtcbiAgT2JqZWN0LmFzc2lnbihidXR0b24uc3R5bGUsIHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gICAgcG9zaXRpb246IFwiYWJzb2x1dGVcIixcbiAgICBsZWZ0OiBcIjUwJVwiLFxuICAgIHRvcDogXCI1MCVcIixcbiAgICBwYWRkaW5nOiBcIjIwcHhcIixcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IFwiIzdGMzNFRFwiLFxuICAgIGNvbG9yOiBcIndoaXRlXCIsXG4gICAgZm9udEZhbWlseTogXCInTWVubG8nLCBtb25vc3BhY2VcIixcbiAgICBib3JkZXJSYWRpdXM6IFwiM3B4XCIsXG4gICAgdHJhbnNmb3JtOiBcInRyYW5zbGF0ZTNEKC01MCUsLTUwJSwwKVwiLFxuICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcbiAgICBsaW5lSGVpZ2h0OiBcIjEuNVwiLFxuICAgIHdpZHRoOiBcIjE1MHB4XCIsXG4gICAgY3Vyc29yOiBcInBvaW50ZXJcIixcbiAgfSk7XG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChidXR0b24pO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gIFN0YXJ0QXVkaW9Db250ZXh0LnNldENvbnRleHQoVG9uZS5jb250ZXh0KTtcbiAgU3RhcnRBdWRpb0NvbnRleHQub24oYnV0dG9uKTtcbiAgU3RhcnRBdWRpb0NvbnRleHQub25TdGFydGVkKChfKSA9PiB7XG4gICAgY29udGFpbmVyLnJlbW92ZSgpO1xuICAgIGZuKCk7XG4gIH0pO1xufVxuIiwiLyoqXG4gKiBSZWxhYmkgd2F2ZWZvcm0gZGlzcGxheVxuICogQG1vZHVsZSBzcmMvcmVsYWJpL2NhbnZhcy5qcztcbiAqL1xuXG5jb25zdCBOT1RFX1JBRElVUyA9IDc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbGFiaUNhbnZhcyB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHJlbGFiaSB3YXZlIHJlbmRlcmVyXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7IHJlbGFiaSwgcGFyZW50IH0pIHtcbiAgICB0aGlzLnJlbGFiaSA9IHJlbGFiaTtcbiAgICB0aGlzLmhlaWdodCA9IDQwMDtcbiAgICB0aGlzLmxhc3RGcmFtZSA9IDA7XG4gICAgdGhpcy5sYXN0QXBwZW5kVGltZSA9IDA7XG4gICAgdGhpcy5sYXN0QXBwZW5kRnJhbWUgPSAwO1xuXG4gICAgLy8gU3BlZWQgb2YgdGhlIHdhdmUgaW4gcGl4ZWxzIHBlciBzZWNvbmRcbiAgICB0aGlzLnNwZWVkID0gMSAvIDU7XG5cbiAgICAvLyBQb3NpdGlvbiBvZiBjdXJyZW50IHRpbWUgb24gdGhlIHNjcmVlbiwgZnJvbSB0aGUgbGVmdFxuICAgIHRoaXMudFplcm9PZmZzZXQgPSAyMDtcblxuICAgIC8vIEF0dGFjaCB0byB0aGUgRE9NXG4gICAgdGhpcy5hcHBlbmRDYW52YXMocGFyZW50KTtcbiAgICAvLyBJbml0aWFsaXplIGFycmF5XG4gICAgdGhpcy52YWx1ZXMgPSBuZXcgQXJyYXkod2luZG93LmlubmVyV2lkdGgpLmZpbGwoMCk7XG4gICAgdGhpcy5ub3RlcyA9IFtdO1xuICAgIHRoaXMuYXBwZW5kKFtdKTtcblxuICAgIC8vIENsZWFyIHRoZSBjYW52YXNcbiAgICB0aGlzLnJlc2l6ZSgpO1xuXG4gICAgLy8gU3RhcnQgZHJhd2luZ1xuICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lKDApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZCB0aGUgY2FudmFzXG4gICAqL1xuICBhcHBlbmRDYW52YXMocGFyZW50KSB7XG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQgfHwgZG9jdW1lbnQuYm9keTtcbiAgICB0aGlzLmNhbnZhcyA9IHRoaXMuY2FudmFzIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgdGhpcy5jdHggPSB0aGlzLmN0eCB8fCB0aGlzLmNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5jYW52YXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIG5leHQgZnJhbWVcbiAgICovXG4gIHJlcXVlc3RBbmltYXRpb25GcmFtZShmcmFtZSkge1xuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoZnJhbWUpID0+IHtcbiAgICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZyYW1lKTtcbiAgICB9KTtcbiAgICB0aGlzLnBhaW50KGZyYW1lKTtcbiAgICB0aGlzLmxhc3RGcmFtZSA9IGZyYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSB3aW5kb3cgcmVzaXplXG4gICAqL1xuICByZXNpemUoKSB7XG4gICAgdGhpcy5jYW52YXMud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICB0aGlzLmNhbnZhcy5oZWlnaHQgPSB0aGlzLmhlaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciB0aGUgY2FudmFzXG4gICAqL1xuICBjbGVhcigpIHtcbiAgICB0aGlzLmN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy5jYW52YXMud2lkdGgsIHRoaXMuY2FudmFzLmhlaWdodCk7XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kIHZhbHVlc1xuICAgKi9cbiAgYXBwZW5kKHRpbWUsIHZhbHVlcywgbm90ZXMpIHtcbiAgICB0aGlzLmxhc3RBcHBlbmRUaW1lID0gdGltZTtcbiAgICB0aGlzLmxhc3RBcHBlbmRGcmFtZSA9IHRoaXMubGFzdEZyYW1lO1xuICAgIHRoaXMudmFsdWVzID0gdGhpcy52YWx1ZXNcbiAgICAgIC5maWx0ZXIoKHZhbHVlKSA9PiB2YWx1ZSAmJiB2YWx1ZVswXSA8IHRpbWUpXG4gICAgICAuY29uY2F0KHZhbHVlcylcbiAgICAgIC5zbGljZSgtdGhpcy5jYW52YXMud2lkdGgpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYVswXSAtIGJbMF0pO1xuXG4gICAgaWYgKG5vdGVzPy5sZW5ndGgpIHtcbiAgICAgIHRoaXMubm90ZXMgPSB0aGlzLm5vdGVzXG4gICAgICAgIC5jb25jYXQobm90ZXMpXG4gICAgICAgIC5zbGljZSgtNTApXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhWzBdIC0gYlswXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhaW50IHRoZSBjYW52YXNcbiAgICovXG4gIHBhaW50KGZyYW1lKSB7XG4gICAgdGhpcy5jbGVhcigpO1xuICAgIHRoaXMuZHJhd1JlbGFiaVdhdmUoZnJhbWUpO1xuICAgIHRoaXMuZHJhd0JvdW5kcygpO1xuICAgIHRoaXMuZHJhd05vdGVzKGZyYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcmF3IHRoZSBib3VuZHNcbiAgICovXG4gIGRyYXdCb3VuZHMoKSB7XG4gICAgY29uc3QgeyBjYW52YXMsIGN0eCB9ID0gdGhpcztcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNhbnZhcztcblxuICAgIC8vIERyYXcgZGFzaGVkIGxpbmVzIGZvciBhbGwgYm91bmRzXG4gICAgZm9yIChjb25zdCBib3VuZCBvZiB0aGlzLnJlbGFiaS5ib3VuZHMpIHtcbiAgICAgIGNvbnN0IHkgPSBnZXRXYXZlSGVpZ2h0KGJvdW5kLmxldmVsLCBoZWlnaHQpO1xuXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHguc2V0TGluZURhc2goWzQsIDRdKTtcbiAgICAgIGN0eC5saW5lV2lkdGggPSAxO1xuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gYm91bmQuY29sb3IgfHwgXCIjODg4XCI7XG4gICAgICBjdHgubW92ZVRvKDAsIHkpO1xuICAgICAgY3R4LmxpbmVUbyh3aWR0aCwgeSk7XG4gICAgICBjdHguc3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgLy8gRHJhdyB0aGUgemVybyBwb3NpdGlvblxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHguc2V0TGluZURhc2goWzEsIDFdKTtcbiAgICBjdHgubGluZVdpZHRoID0gMjtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBcIiM2NjZcIjtcbiAgICBjdHgubW92ZVRvKHdpZHRoIC0gdGhpcy50WmVyb09mZnNldCwgMCk7XG4gICAgY3R4LmxpbmVUbyh3aWR0aCAtIHRoaXMudFplcm9PZmZzZXQsIGhlaWdodCk7XG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIHJlbGFiaSB3YXZlXG4gICAqL1xuICBkcmF3UmVsYWJpV2F2ZShmcmFtZSkge1xuICAgIGNvbnN0IHsgY2FudmFzLCBjdHggfSA9IHRoaXM7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBjYW52YXM7XG5cbiAgICBjb25zdCBwb2ludENvdW50ID0gdGhpcy52YWx1ZXMubGVuZ3RoO1xuICAgIGxldCBpbmRleCA9IDA7XG5cbiAgICAvLyBTdGFydCB0aGUgcGF0aFxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBcIiNkZmZcIjtcbiAgICBjdHgubGluZVdpZHRoID0gMS4xO1xuICAgIGN0eC5zZXRMaW5lRGFzaChbXSk7XG5cbiAgICAvLyBUaGlzIGlzIHRoZSBvZmZzZXQgaW4gc2Vjb25kcyBmcm9tIHRoZSBsYXN0IGZyYW1lIHdlIGNvbXB1dGVkXG4gICAgY29uc3QgZnJhbWVPZmZzZXQgPSAoZnJhbWUgLSB0aGlzLmxhc3RBcHBlbmRGcmFtZSkgLyAxMDAwO1xuXG4gICAgLy8gTWFrZSBhIHBhdGggY29ubmVjdGluZyBhbGwgdmFsdWVzXG4gICAgZm9yIChjb25zdCBwb2ludCBvZiB0aGlzLnZhbHVlcykge1xuICAgICAgaWYgKCFwb2ludCkge1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgW3RpbWUsIHZhbHVlXSA9IHBvaW50O1xuXG4gICAgICAvLyBUaGlzIGlzIHRoZSBvZmZzZXQgb2YgdGhpcyB0aW1lIGZyb20gY3VycmVudCB0aW1lXG4gICAgICAvLyBJZiB0aGlzIGlzIGluIHRoZSBmdXR1cmUsIGl0IHdpbGwgYmUgcG9zaXRpdmUuXG4gICAgICAvLyBTdWJ0cmFjdGluZyB0aGUgZnJhbWUgb2Zmc2V0IHB1bGxzIGl0IG5lZ2F0aXZlLlxuICAgICAgY29uc3QgdGltZU9mZnNldCA9IHRoaXMubGFzdEFwcGVuZFRpbWUgKyBmcmFtZU9mZnNldCAtIHRpbWU7XG5cbiAgICAgIGNvbnN0IHggPSB3aWR0aCAtIHRpbWVPZmZzZXQgKiB0aGlzLnNwZWVkICogd2lkdGggLSB0aGlzLnRaZXJvT2Zmc2V0O1xuICAgICAgY29uc3QgeSA9IGdldFdhdmVIZWlnaHQodmFsdWUsIGhlaWdodCk7XG5cbiAgICAgIGlmICh4IDwgMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgIGN0eC5tb3ZlVG8oeCwgeSk7XG4gICAgICB9XG4gICAgICBjdHgubGluZVRvKHgsIHkpO1xuICAgICAgaW5kZXggKz0gMTtcbiAgICB9XG5cbiAgICAvLyBQYWludCB0aGUgbGluZVxuICAgIGN0eC5zdHJva2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcmF3IHRoZSBub3Rlc1xuICAgKi9cbiAgZHJhd05vdGVzKGZyYW1lKSB7XG4gICAgY29uc3QgeyBjYW52YXMsIGN0eCB9ID0gdGhpcztcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNhbnZhcztcblxuICAgIC8vIFRoaXMgaXMgdGhlIG9mZnNldCBpbiBzZWNvbmRzIGZyb20gdGhlIGxhc3QgZnJhbWUgd2UgY29tcHV0ZWRcbiAgICBjb25zdCBmcmFtZU9mZnNldCA9IChmcmFtZSAtIHRoaXMubGFzdEFwcGVuZEZyYW1lKSAvIDEwMDA7XG5cbiAgICAvLyBNYWtlIGEgcGF0aCBjb25uZWN0aW5nIGFsbCB2YWx1ZXNcbiAgICBmb3IgKGNvbnN0IG5vdGUgb2YgdGhpcy5ub3Rlcykge1xuICAgICAgY29uc3QgW3RpbWUsIHZhbHVlLCBkaXJlY3Rpb25dID0gbm90ZTtcbiAgICAgIGNvbnN0IHRpbWVPZmZzZXQgPSB0aGlzLmxhc3RBcHBlbmRUaW1lICsgZnJhbWVPZmZzZXQgLSB0aW1lO1xuICAgICAgY29uc3QgeCA9IHdpZHRoIC0gdGltZU9mZnNldCAqIHRoaXMuc3BlZWQgKiB3aWR0aCAtIHRoaXMudFplcm9PZmZzZXQ7XG4gICAgICBjb25zdCB5ID0gZ2V0V2F2ZUhlaWdodCh2YWx1ZSwgaGVpZ2h0KTtcblxuICAgICAgLy8gRG9uJ3QgZHJhdyBub3RlcyB0aGF0IGhhdmVuJ3QgcGxheWVkIHlldFxuICAgICAgaWYgKHggPiB3aWR0aCAtIHRoaXMudFplcm9PZmZzZXQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIERyYXcgbm90ZXMgYXMgYSBkb3QgdGhhdCBmYWRlcyBvdXRcbiAgICAgIGNvbnN0IG9wYWNpdHkgPSAxIC0gKHRpbWVPZmZzZXQgKiB0aGlzLnNwZWVkICogd2lkdGgpIC8gMTAwMDtcbiAgICAgIGlmIChvcGFjaXR5IDwgMC4wMDEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHguYXJjKHgsIHksIE5PVEVfUkFESVVTLCAwLCAyICogTWF0aC5QSSk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gZGlyZWN0aW9uXG4gICAgICAgID8gYHJnYmEoMjU1LDk2LDEyOCwke29wYWNpdHl9KWBcbiAgICAgICAgOiBgcmdiYSgxMjgsMjU1LDk2LCR7b3BhY2l0eX0pYDtcbiAgICAgIGN0eC5maWxsKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBoZWlnaHQgb2YgdGhlIHdhdmUgYXQgYSBnaXZlbiB2YWx1ZVxuICovXG5jb25zdCBnZXRXYXZlSGVpZ2h0ID0gKHZhbHVlLCBoZWlnaHQpID0+ICgodmFsdWUgKyAxKSAvIDIpICogaGVpZ2h0O1xuIiwiaW1wb3J0ICogYXMgVG9uZSBmcm9tIFwidG9uZVwiO1xuXG5jb25zdCBjb21wcmVzc29yID0gbmV3IFRvbmUuQ29tcHJlc3NvcigtMzAsIDMpO1xuY29uc3QgZ2FpbiA9IG5ldyBUb25lLkdhaW4oMC4zKTtcbmNvbXByZXNzb3IuY29ubmVjdChnYWluKTtcbmdhaW4udG9EZXN0aW5hdGlvbigpO1xuXG5leHBvcnQgZGVmYXVsdCBjb21wcmVzc29yO1xuIiwiaW1wb3J0ICogYXMgVG9uZSBmcm9tIFwidG9uZVwiO1xuaW1wb3J0IHsgY2hvaWNlLCByYW5kcmFuZ2UgfSBmcm9tIFwiLi91dGlsXCI7XG5pbXBvcnQgb3V0cHV0IGZyb20gXCIuL291dHB1dFwiO1xuXG5jb25zdCBQTEFZRVJfQ09VTlQgPSA0O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTYW1wbGVyIHtcbiAgY29uc3RydWN0b3IoeyBzYW1wbGVzLCB0b25hbCB9KSB7XG4gICAgdGhpcy50b25hbCA9IHRvbmFsO1xuICAgIHRoaXMuc2FtcGxlcyA9IHNhbXBsZXMubWFwKCh7IC4uLnNhbXBsZSB9KSA9PiB7XG4gICAgICBzYW1wbGUucGxheWVycyA9IFtdO1xuICAgICAgc2FtcGxlLmluZGV4ID0gLTE7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IFBMQVlFUl9DT1VOVDsgaSsrKSB7XG4gICAgICAgIGxldCBmbiA9IHNhbXBsZS5mbjtcbiAgICAgICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5ocmVmLm1hdGNoKC9hc2RmLnVzLykpIHtcbiAgICAgICAgICBmbiA9IFwiLy9hc2RmLnVzL2thbGltYmEvXCIgKyBmbjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKHtcbiAgICAgICAgICB1cmw6IGZuLFxuICAgICAgICAgIHJldHJpZ2dlcjogdHJ1ZSxcbiAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgIH0pO1xuICAgICAgICBwbGF5ZXIuY29ubmVjdChvdXRwdXQpO1xuICAgICAgICBzYW1wbGUucGxheWVycy5wdXNoKHBsYXllcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2FtcGxlO1xuICAgIH0pO1xuICB9XG5cbiAgcGxheSh0aW1lLCBvcHRpb25zKSB7XG4gICAgY29uc3Qgc291bmQgPSBvcHRpb25zLmluZGV4XG4gICAgICA/IHRoaXMuc2FtcGxlc1tvcHRpb25zLmluZGV4XVxuICAgICAgOiBjaG9pY2UodGhpcy5zYW1wbGVzKTtcblxuICAgIHNvdW5kLmluZGV4ID0gKHNvdW5kLmluZGV4ICsgMSkgJSBQTEFZRVJfQ09VTlQ7XG5cbiAgICBjb25zdCBwbGF5ZXIgPSBzb3VuZC5wbGF5ZXJzW3NvdW5kLmluZGV4XTtcblxuICAgIGlmICh0aGlzLnRvbmFsKSB7XG4gICAgICBwbGF5ZXIucGxheWJhY2tSYXRlID1cbiAgICAgICAgKG9wdGlvbnMuZnJlcXVlbmN5ICogY2hvaWNlKFswLjUsIDFdKSArIHJhbmRyYW5nZSgwLCAxMCkpIC8gc291bmQucm9vdDtcbiAgICB9XG5cbiAgICBwbGF5ZXIuc3RhcnQodGltZSB8fCAwKTtcbiAgfVxufVxuIiwiaW1wb3J0IFNhbXBsZXIgZnJvbSBcIi4vc2FtcGxlclwiO1xuXG5leHBvcnQgY29uc3QgS2FsaW1iYSA9IG5ldyBTYW1wbGVyKHtcbiAgdG9uYWw6IHRydWUsXG4gIHNhbXBsZXM6IFtcbiAgICB7IHJvb3Q6IDIyNiwgZm46IFwic2FtcGxlcy8zODA3MzdfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAxLWEtcmF3Lm1wM1wiIH0sXG4gICAgeyByb290OiAyNjcsIGZuOiBcInNhbXBsZXMvMzgwNzM2X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMi1jLXJhdy5tcDNcIiB9LFxuICAgIHsgcm9vdDogMzQwLCBmbjogXCJzYW1wbGVzLzM4MDczNV9fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDMtZS1yYXcubXAzXCIgfSxcbiAgICB7IHJvb3Q6IDQ1MiwgZm46IFwic2FtcGxlcy8zODA3MzNfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTA2LWEtMDItcmF3Lm1wM1wiIH0sXG4gIF0sXG59KTtcblxuZXhwb3J0IGNvbnN0IERydW1zID0gbmV3IFNhbXBsZXIoe1xuICBzYW1wbGVzOiBbXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19iZC5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfY2xhcC5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfY2gubXAzXCIgfSxcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X3JpbS5tcDNcIiB9LFxuICBdLFxufSk7XG5cbmV4cG9ydCBjb25zdCBLaWNrID0gbmV3IFNhbXBsZXIoe1xuICBzYW1wbGVzOiBbeyBmbjogXCJzYW1wbGVzLzcwN19iZC5tcDNcIiB9LCB7IGZuOiBcInNhbXBsZXMvNzA3X2JkMi5tcDNcIiB9XSxcbn0pO1xuXG5leHBvcnQgY29uc3QgU25hcmUgPSBuZXcgU2FtcGxlcih7XG4gIHNhbXBsZXM6IFt7IGZuOiBcInNhbXBsZXMvNzA3X3NuYXJlMS5tcDNcIiB9LCB7IGZuOiBcInNhbXBsZXMvNzA3X3NuYXJlMi5tcDNcIiB9XSxcbn0pO1xuXG5leHBvcnQgY29uc3QgSGF0ID0gbmV3IFNhbXBsZXIoe1xuICBzYW1wbGVzOiBbXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19jaC5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfY2gubXAzXCIgfSxcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X2NoLm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19vaC5tcDNcIiB9LFxuICBdLFxufSk7XG5cbmV4cG9ydCBjb25zdCBQZXJjID0gbmV3IFNhbXBsZXIoe1xuICBzYW1wbGVzOiBbeyBmbjogXCJzYW1wbGVzLzcwN19yaW0ubXAzXCIgfSwgeyBmbjogXCJzYW1wbGVzLzcwN190YW1iLm1wM1wiIH1dLFxufSk7XG5cbmV4cG9ydCBjb25zdCBDeW1iYWwgPSBuZXcgU2FtcGxlcih7XG4gIHNhbXBsZXM6IFt7IGZuOiBcInNhbXBsZXMvNzA3X2NyYXNoLm1wM1wiIH0sIHsgZm46IFwic2FtcGxlcy83MDdfcmlkZS5tcDNcIiB9XSxcbn0pO1xuXG5leHBvcnQgY29uc3QgVG9tID0gbmV3IFNhbXBsZXIoe1xuICBzYW1wbGVzOiBbeyBmbjogXCJzYW1wbGVzLzcwN190b20xLm1wM1wiIH0sIHsgZm46IFwic2FtcGxlcy83MDdfdG9tMi5tcDNcIiB9XSxcbn0pO1xuIiwiLyoqXG4gKiBSZWxhYmkgZXZlbnQgZ2VuZXJhdG9yXG4gKi9cblxuaW1wb3J0ICogYXMgVG9uZSBmcm9tIFwidG9uZVwiO1xuaW1wb3J0IFJlbGFiaUNhbnZhcyBmcm9tIFwiLi9jYW52YXNcIjtcbmltcG9ydCAqIGFzIEluc3RydW1lbnRzIGZyb20gXCIuLi9saWIvaW5zdHJ1bWVudHNcIjtcblxuY29uc3QgVFdPX1BJID0gMiAqIE1hdGguUEk7XG5cbi8qKlxuICogV2F2ZSBmdW5jdGlvbnNcbiAqL1xuY29uc3QgV0FWRV9TSEFQRVMgPSB7XG4gIHNpbmU6IE1hdGguY29zLFxuICB0cmlhbmdsZTogKHRpbWUpID0+XG4gICAgKDQgLyBUV09fUEkpICpcbiAgICAgIE1hdGguYWJzKFxuICAgICAgICAoKCgodGltZSAtIFRXT19QSSAvIDQpICUgVFdPX1BJKSArIFRXT19QSSkgJSBUV09fUEkpIC0gVFdPX1BJIC8gMlxuICAgICAgKSAtXG4gICAgMSxcbiAgc3F1YXJlOiAodGltZSkgPT4gKHRpbWUgJSBUV09fUEkgPCBNYXRoLlBJID8gMSA6IC0xKSxcbiAgc2F3OiAodGltZSkgPT4gKHRpbWUgJSBUV09fUEkpIC8gTWF0aC5QSSAtIDEsXG4gIHJldmVyc2Vfc2F3OiAodGltZSkgPT4gMSAtICh0aW1lICUgVFdPX1BJKSAvIE1hdGguUEksXG4gIG5vaXNlOiAodGltZSkgPT4gTWF0aC5yYW5kb20oKSAqIE1hdGgucmFuZG9tKCkgKiAyIC0gMSxcbn07XG5cbi8qKlxuICogUmVsYWJpIGdlbmVyYXRvclxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWxhYmkge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSBnZW5lcmF0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKHsgd2F2ZXMsIGJvdW5kcywgc2V0dGluZ3MsIHBhcmVudCB9KSB7XG4gICAgdGhpcy51cGRhdGVUaW1lID0gMTtcbiAgICB0aGlzLnN0ZXBzID0gNTA7XG4gICAgdGhpcy53YXZlcyA9IHdhdmVzO1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICAgIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBudWxsO1xuICAgIHRoaXMuY2FudmFzID0gbmV3IFJlbGFiaUNhbnZhcyh7IHJlbGFiaTogdGhpcywgcGFyZW50IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBnZW5lcmF0b3JcbiAgICovXG4gIHN0YXJ0KCkge1xuICAgIGNvbnNvbGUubG9nKFwiU3RhcnQgUmVsYWJpXCIpO1xuICAgIHRoaXMuc3RvcCgpO1xuICAgIHRoaXMuY2xvY2sgPSBuZXcgVG9uZS5DbG9jaygodGltZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWVzID0gdGhpcy5nZW5lcmF0ZSh0aW1lKTtcbiAgICAgIGNvbnN0IG5vdGVzID0gdGhpcy5wbGF5KHZhbHVlcyk7XG4gICAgICB0aGlzLmNhbnZhcy5hcHBlbmQodGltZSwgdmFsdWVzLCBub3Rlcyk7XG4gICAgfSwgdGhpcy51cGRhdGVUaW1lKTtcbiAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gIH1cblxuICAvKipcbiAgICogU3RvcCB0aGUgZ2VuZXJhdG9yIGFuZCByZXNldCBpdFxuICAgKi9cbiAgc3RvcCgpIHtcbiAgICBpZiAodGhpcy5jbG9jaykge1xuICAgICAgdGhpcy5jbG9jay5zdG9wKCk7XG4gICAgICB0aGlzLmNsb2NrLmRpc3Bvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgcmVsYWJpIGV2ZW50c1xuICAgKi9cbiAgZ2VuZXJhdGUodGltZSkge1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgdmFsdWU7XG4gICAgbGV0IHZhbHVlcyA9IFtdO1xuICAgIGxldCBwcmV2aW91c1dhdmVWYWx1ZSA9IHRoaXMucHJldmlvdXNXYXZlVmFsdWUgfHwgMDtcblxuICAgIC8vIFdlaWdodCBpbmRpdmlkdWFsIHdhdmVzIHJhdGhlciB0aGFuIHNpbXBseSBhdmVyYWdpbmcgdGhlbVxuICAgIGxldCB0b3RhbFdlaWdodCA9IHRoaXMud2F2ZXMucmVkdWNlKChzdW0sIHdhdmUpID0+IHN1bSArIHdhdmUud2VpZ2h0LCAwLjApO1xuXG4gICAgLy8gT3ZlcnNob290IHRoZSBsaW5lIHNsaWdodGx5IGVhY2ggdGltZVxuICAgIGxldCBzdGVwQ291bnQgPSB0aGlzLnN0ZXBzO1xuXG4gICAgLy8gR2VuZXJhdGUgc2V2ZXJhbCBldmVudHMgcGVyIHNlY29uZFxuICAgIGZvciAoc3RlcCA9IDA7IHN0ZXAgPCBzdGVwQ291bnQ7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gVGltZSBvZmZzZXQgZm9yIHRoaXMgZXZlbnRcbiAgICAgIGNvbnN0IHRpbWVPZmZzZXQgPSB0aW1lICsgKHN0ZXAgKiB0aGlzLnVwZGF0ZVRpbWUpIC8gdGhpcy5zdGVwcztcblxuICAgICAgLy8gSW5pdGlhbGl6ZSB2YWx1ZVxuICAgICAgdmFsdWUgPSAwO1xuXG4gICAgICAvLyBDb21wdXRlIHRoZSB3YXZlIGZ1bmN0aW9ucyBmb3IgdGhpcyBldmVudFxuICAgICAgZm9yIChjb25zdCB3YXZlIG9mIHRoaXMud2F2ZXMpIHtcbiAgICAgICAgY29uc3Qgd2F2ZU9mZnNldCA9XG4gICAgICAgICAgKHdhdmUub2Zmc2V0IHx8IDApICtcbiAgICAgICAgICAod2F2ZS5mcmVxdWVuY3kgKiB0aGlzLnNldHRpbmdzLnNwZWVkKSAvIHRoaXMuc3RlcHMgK1xuICAgICAgICAgIHByZXZpb3VzV2F2ZVZhbHVlICogdGhpcy5zZXR0aW5ncy5jaGFvcztcblxuICAgICAgICBjb25zdCB3YXZlVmFsdWUgPSBXQVZFX1NIQVBFU1t3YXZlLnNoYXBlXSh3YXZlT2Zmc2V0KTtcbiAgICAgICAgdmFsdWUgKz0gd2F2ZVZhbHVlICogd2F2ZS53ZWlnaHQ7XG4gICAgICAgIHByZXZpb3VzV2F2ZVZhbHVlID0gd2F2ZVZhbHVlO1xuICAgICAgICB3YXZlLm9mZnNldCA9IHdhdmVPZmZzZXQ7XG4gICAgICB9XG5cbiAgICAgIC8vIFNjYWxlIHRvIFstMSwgMV1cbiAgICAgIHZhbHVlIC89IHRvdGFsV2VpZ2h0O1xuICAgICAgcHJldmlvdXNXYXZlVmFsdWUgPSB2YWx1ZTtcblxuICAgICAgdmFsdWVzLnB1c2goW3RpbWVPZmZzZXQsIHZhbHVlXSk7XG4gICAgfVxuXG4gICAgdGhpcy5wcmV2aW91c1dhdmVWYWx1ZSA9IHByZXZpb3VzV2F2ZVZhbHVlO1xuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2hlZHVsZSByZWxhYmkgZXZlbnRzXG4gICAqL1xuICBwbGF5KHZhbHVlcykge1xuICAgIGNvbnN0IGJvdW5kc0NvdW50ID0gdGhpcy5ib3VuZHMubGVuZ3RoO1xuICAgIGxldCBwcmV2aW91c1ZhbHVlID0gdGhpcy5wcmV2aW91c1ZhbHVlO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgbm90ZUNvdW50ID0gMDtcbiAgICBjb25zdCBub3RlcyA9IFtdO1xuXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gR2V0IHRoZSBuZXh0IHZhbHVlXG4gICAgICBjb25zdCBbdGltZSwgdmFsdWVdID0gdmFsdWVzW3N0ZXBdO1xuXG4gICAgICAvLyBDb21wdXRlIHdoZXRoZXIgd2UgY3Jvc3NlZCBhIGJvdW5kYXJ5LCBhbmQgd2hpY2ggZGlyZWN0aW9uXG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBib3VuZHNDb3VudDsgaW5kZXggKz0gMSkge1xuICAgICAgICBjb25zdCBib3VuZCA9IHRoaXMuYm91bmRzW2luZGV4XTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHZhbHVlIDwgYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA8IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIGRvd25cbiAgICAgICAgICB0aGlzLnRyaWdnZXIodGltZSwgYm91bmQuc291bmRzWzBdKTtcbiAgICAgICAgICBub3Rlcy5wdXNoKFt0aW1lLCBib3VuZC5sZXZlbCwgdHJ1ZV0pO1xuICAgICAgICAgIG5vdGVDb3VudCArPSAxO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIHZhbHVlID4gYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA+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/IHt9IDogX3Byb3BzJGFsaWduLFxuICAgIF9wcm9wcyRkZXN0cm95VG9vbHRpcCA9IHByb3BzLmRlc3Ryb3lUb29sdGlwT25IaWRlLFxuICAgIGRlc3Ryb3lUb29sdGlwT25IaWRlID0gX3Byb3BzJGRlc3Ryb3lUb29sdGlwID09PSB2b2lkIDAgPyBmYWxzZSA6IF9wcm9wcyRkZXN0cm95VG9vbHRpcCxcbiAgICBkZWZhdWx0VmlzaWJsZSA9IHByb3BzLmRlZmF1bHRWaXNpYmxlLFxuICAgIGdldFRvb2x0aXBDb250YWluZXIgPSBwcm9wcy5nZXRUb29sdGlwQ29udGFpbmVyLFxuICAgIG92ZXJsYXlJbm5lclN0eWxlID0gcHJvcHMub3ZlcmxheUlubmVyU3R5bGUsXG4gICAgYXJyb3dDb250ZW50ID0gcHJvcHMuYXJyb3dDb250ZW50LFxuICAgIG92ZXJsYXkgPSBwcm9wcy5vdmVybGF5LFxuICAgIGlkID0gcHJvcHMuaWQsXG4gICAgX3Byb3BzJHNob3dBcnJvdyA9IHByb3BzLnNob3dBcnJvdyxcbiAgICBzaG93QXJyb3cgPSBfcHJvcHMkc2hvd0Fycm93ID09PSB2b2lkIDAgPyB0cnVlIDogX3Byb3BzJHNob3dBcnJvdyxcbiAgICByZXN0UHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMocHJvcHMsIF9leGNsdWRlZCk7XG4gIHZhciB0cmlnZ2VyUmVmID0gdXNlUmVmKG51bGwpO1xuICB1c2VJbXBlcmF0aXZlSGFuZGxlKHJlZiwgZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0cmlnZ2VyUmVmLmN1cnJlbnQ7XG4gIH0pO1xuICB2YXIgZXh0cmFQcm9wcyA9IF9vYmplY3RTcHJlYWQoe30sIHJlc3RQcm9wcyk7XG4gIGlmICgndmlzaWJsZScgaW4gcHJvcHMpIHtcbiAgICBleHRyYVByb3BzLnBvcHVwVmlzaWJsZSA9IHByb3BzLnZpc2libGU7XG4gIH1cbiAgdmFyIGdldFBvcHVwRWxlbWVudCA9IGZ1bmN0aW9uIGdldFBvcHVwRWxlbWVudCgpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUG9wdXAsIHtcbiAgICAgIGtleTogXCJjb250ZW50XCIsXG4gICAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICAgIGlkOiBpZCxcbiAgICAgIG92ZXJsYXlJbm5lclN0eWxlOiBvdmVybGF5SW5uZXJTdHlsZVxuICAgIH0sIG92ZXJsYXkpO1xuICB9O1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoVHJpZ2dlciwgX2V4dGVuZHMoe1xuICAgIHBvcHVwQ2xhc3NOYW1lOiBvdmVybGF5Q2xhc3NOYW1lLFxuICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgIHBvcHVwOiBnZXRQb3B1cEVsZW1lbnQsXG4gICAgYWN0aW9uOiB0cmlnZ2VyLFxuICAgIGJ1aWx0aW5QbGFjZW1lbnRzOiBwbGFjZW1lbnRzLFxuICAgIHBvcHVwUGxhY2VtZW50OiBwbGFjZW1lbnQsXG4gICAgcmVmOiB0cmlnZ2VyUmVmLFxuICAgIHBvcHVwQWxpZ246IGFsaWduLFxuICAgIGdldFBvcHVwQ29udGFpbmVyOiBnZXRUb29sdGlwQ29udGFpbmVyLFxuICAgIG9uUG9wdXBWaXNpYmxlQ2hhbmdlOiBvblZpc2libGVDaGFuZ2UsXG4gICAgYWZ0ZXJQb3B1cFZpc2libGVDaGFuZ2U6IGFmdGVyVmlzaWJsZUNoYW5nZSxcbiAgICBwb3B1cFRyYW5zaXRpb25OYW1lOiB0cmFuc2l0aW9uTmFtZSxcbiAgICBwb3B1cEFuaW1hdGlvbjogYW5pbWF0aW9uLFxuICAgIHBvcHVwTW90aW9uOiBtb3Rpb24sXG4gICAgZGVmYXVsdFBvcHVwVmlzaWJsZTogZGVmYXVsdFZpc2libGUsXG4gICAgYXV0b0Rlc3Ryb3k6IGRlc3Ryb3lUb29sdGlwT25IaWRlLFxuICAgIG1vdXNlTGVhdmVEZWxheTogbW91c2VMZWF2ZURlbGF5LFxuICAgIHBvcHVwU3R5bGU6IG92ZXJsYXlTdHlsZSxcbiAgICBtb3VzZUVudGVyRGVsYXk6IG1vdXNlRW50ZXJEZWxheSxcbiAgICBhcnJvdzogc2hvd0Fycm93XG4gIH0sIGV4dHJhUHJvcHMpLCBjaGlsZHJlbik7XG59O1xuZXhwb3J0IGRlZmF1bHQgLyojX19QVVJFX18qL2ZvcndhcmRSZWYoVG9vbHRpcCk7IiwiaW1wb3J0IFRvb2x0aXAgZnJvbSBcIi4vVG9vbHRpcFwiO1xuaW1wb3J0IFBvcHVwIGZyb20gXCIuL1BvcHVwXCI7XG5leHBvcnQgeyBQb3B1cCB9O1xuZXhwb3J0IGRlZmF1bHQgVG9vbHRpcDsiLCIvKipcbiAqIHJjLXRvb2x0aXAgdG9vbHRpcCBzbGlkZXJcbiAqL1xudmFyIF9fYXNzaWduID0gKHRoaXMgJiYgdGhpcy5fX2Fzc2lnbikgfHwgZnVuY3Rpb24gKCkge1xuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbih0KSB7XG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSlcbiAgICAgICAgICAgICAgICB0W3BdID0gc1twXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufTtcbnZhciBfX3Jlc3QgPSAodGhpcyAmJiB0aGlzLl9fcmVzdCkgfHwgZnVuY3Rpb24gKHMsIGUpIHtcbiAgICB2YXIgdCA9IHt9O1xuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxuICAgICAgICB0W3BdID0gc1twXTtcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcbiAgICAgICAgfVxuICAgIHJldHVybiB0O1xufTtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IFwicmMtdG9vbHRpcC9hc3NldHMvYm9vdHN0cmFwLmNzc1wiO1xuaW1wb3J0IFNsaWRlciBmcm9tIFwicmMtc2xpZGVyXCI7XG5pbXBvcnQgcmFmIGZyb20gXCJyYy11dGlsL2xpYi9yYWZcIjtcbmltcG9ydCBUb29sdGlwIGZyb20gXCJyYy10b29sdGlwXCI7XG52YXIgSGFuZGxlVG9vbHRpcCA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgIHZhciB2YWx1ZSA9IHByb3BzLnZhbHVlLCBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLCB2aXNpYmxlID0gcHJvcHMudmlzaWJsZSwgX2EgPSBwcm9wcy50aXBGb3JtYXR0ZXIsIHRpcEZvcm1hdHRlciA9IF9hID09PSB2b2lkIDAgPyBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBcIlwiLmNvbmNhdCh2YWwsIFwiICVcIik7IH0gOiBfYSwgcmVzdFByb3BzID0gX19yZXN0KHByb3BzLCBbXCJ2YWx1ZVwiLCBcImNoaWxkcmVuXCIsIFwidmlzaWJsZVwiLCBcInRpcEZvcm1hdHRlclwiXSk7XG4gICAgdmFyIHRvb2x0aXBSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgICB2YXIgcmFmUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICAgIGZ1bmN0aW9uIGNhbmNlbEtlZXBBbGlnbigpIHtcbiAgICAgICAgcmFmLmNhbmNlbChyYWZSZWYuY3VycmVudCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGtlZXBBbGlnbigpIHtcbiAgICAgICAgcmFmUmVmLmN1cnJlbnQgPSByYWYoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gdG9vbHRpcFJlZi5jdXJyZW50Py5mb3JjZVBvcHVwQWxpZ24oKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh2aXNpYmxlKSB7XG4gICAgICAgICAgICBrZWVwQWxpZ24oKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNhbmNlbEtlZXBBbGlnbigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxLZWVwQWxpZ247XG4gICAgfSwgW3ZhbHVlLCB2aXNpYmxlXSk7XG4gICAgcmV0dXJuIChSZWFjdC5jcmVhdGVFbGVtZW50KFRvb2x0aXAsIF9fYXNzaWduKHsgcGxhY2VtZW50OiBcInRvcFwiLCBvdmVybGF5OiB0aXBGb3JtYXR0ZXIodmFsdWUpLCBvdmVybGF5SW5uZXJTdHlsZTogeyBtaW5IZWlnaHQ6IFwiYXV0b1wiIH0sIHJlZjogdG9vbHRpcFJlZiwgdmlzaWJsZTogdmlzaWJsZSB9LCByZXN0UHJvcHMpLCBjaGlsZHJlbikpO1xufTtcbmV4cG9ydCB2YXIgaGFuZGxlUmVuZGVyID0gZnVuY3Rpb24gKG5vZGUsIHByb3BzKSB7XG4gICAgcmV0dXJuIChSZWFjdC5jcmVhdGVFbGVtZW50KEhhbmRsZVRvb2x0aXAsIHsgdmFsdWU6IHByb3BzLnZhbHVlLCB2aXNpYmxlOiBwcm9wcy5kcmFnZ2luZyB9LCBub2RlKSk7XG59O1xudmFyIFRvb2x0aXBTbGlkZXIgPSBmdW5jdGlvbiAoX2EpIHtcbiAgICB2YXIgdGlwRm9ybWF0dGVyID0gX2EudGlwRm9ybWF0dGVyLCB0aXBQcm9wcyA9IF9hLnRpcFByb3BzLCBwcm9wcyA9IF9fcmVzdChfYSwgW1widGlwRm9ybWF0dGVyXCIsIFwidGlwUHJvcHNcIl0pO1xuICAgIHZhciB0aXBIYW5kbGVSZW5kZXIgPSBmdW5jdGlvbiAobm9kZSwgaGFuZGxlUHJvcHMpIHtcbiAgICAgICAgcmV0dXJuIChSZWFjdC5jcmVhdGVFbGVtZW50KEhhbmRsZVRvb2x0aXAsIF9fYXNzaWduKHsgdmFsdWU6IGhhbmRsZVByb3BzLnZhbHVlLCB2aXNpYmxlOiBoYW5kbGVQcm9wcy5kcmFnZ2luZywgdGlwRm9ybWF0dGVyOiB0aXBGb3JtYXR0ZXIgfSwgdGlwUHJvcHMpLCBub2RlKSk7XG4gICAgfTtcbiAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChTbGlkZXIsIF9fYXNzaWduKHt9LCBwcm9wcywgeyBoYW5kbGVSZW5kZXI6IHRpcEhhbmRsZVJlbmRlciB9KSk7XG59O1xuZXhwb3J0IGRlZmF1bHQgVG9vbHRpcFNsaWRlcjtcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2luZGV4LmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xuXG4gICAgICBvcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xuICAgIFxub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9pbmRleC5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCIvKipcbiAqIFJlbGFiaSBjb250cm9sc1xuICogQG1vZHVsZSBzcmMvdWkvQ29udHJvbHMuanN4O1xuICovXG5cbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZVJlZiB9IGZyb20gXCJyZWFjdFwiO1xuXG5pbXBvcnQgU2xpZGVyIGZyb20gXCJyYy1zbGlkZXJcIjtcbmltcG9ydCBUb29sdGlwU2xpZGVyLCB7IGhhbmRsZVJlbmRlciB9IGZyb20gXCIuL1Rvb2x0aXBTbGlkZXIudHN4XCI7XG5pbXBvcnQgXCJyYy1zbGlkZXIvYXNzZXRzL2luZGV4LmNzc1wiO1xuXG5jb25zdCBXQVZFX1NIQVBFX05BTUVTID0gW1xuICBcInNpbmVcIixcbiAgXCJ0cmlhbmdsZVwiLFxuICBcInNhd1wiLFxuICBcInJldmVyc2Vfc2F3XCIsXG4gIFwic3F1YXJlXCIsXG4gIFwibm9pc2VcIixcbl07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvbnRyb2xzKHsgcmVsYWJpIH0pIHtcbiAgLyoqXG4gICAqIEhhbmRsZSB1cGRhdGluZyBhIHNsaWRlclxuICAgKi9cbiAgY29uc3Qgb25DaGFuZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAodHlwZSwgaW5kZXgpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKHR5cGUgPT09IFwiYm91bmRcIikge1xuICAgICAgICByZWxhYmkuYm91bmRzW2luZGV4XS5sZXZlbCA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGUgPT09IFwic2hhcGVcIikge1xuICAgICAgICByZWxhYmkud2F2ZXNbaW5kZXhdLnNoYXBlID0gV0FWRV9TSEFQRV9OQU1FU1t2YWx1ZV07XG4gICAgICB9XG4gICAgICBpZiAodHlwZSA9PT0gXCJmcmVxdWVuY3lcIikge1xuICAgICAgICByZWxhYmkud2F2ZXNbaW5kZXhdLmZyZXF1ZW5jeSA9IE1hdGguZXhwKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlID09PSBcIndlaWdodFwiKSB7XG4gICAgICAgIHJlbGFiaS53YXZlc1tpbmRleF0ud2VpZ2h0ID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAodHlwZSA9PT0gXCJzZXR0aW5nc1wiKSB7XG4gICAgICAgIHJlbGFiaS5zZXR0aW5nc1tpbmRleF0gPSBpbmRleCA9PT0gXCJzcGVlZFwiID8gTWF0aC5leHAodmFsdWUpIDogdmFsdWU7XG4gICAgICB9XG4gICAgfSxcbiAgICBbcmVsYWJpXVxuICApO1xuXG4gIGlmICghcmVsYWJpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxDb250cm9sUm93PlxuICAgICAgPENvbnRyb2xCb3g+XG4gICAgICAgIDxMYWJlbD5Cb3VuZHM8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIHtyZWxhYmk/LmJvdW5kcy5tYXAoKGJvdW5kLCBpbmRleCkgPT4gKFxuICAgICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgICAgcmVsPXtgYm91bmRfJHtpbmRleH1gfVxuICAgICAgICAgICAgICB0eXBlPVwiYm91bmRcIlxuICAgICAgICAgICAgICBpbmRleD17aW5kZXh9XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgbWluPXstMX1cbiAgICAgICAgICAgICAgbWF4PXsxfVxuICAgICAgICAgICAgICBzdGVwPXswLjAxfVxuICAgICAgICAgICAgICB0aXBGb3JtYXR0ZXI9eyh2YWx1ZSkgPT4gLXZhbHVlfVxuICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU9e2JvdW5kLmxldmVsfVxuICAgICAgICAgICAgICBjb2xvcj17Ym91bmQuY29sb3J9XG4gICAgICAgICAgICAgIHJldmVyc2VcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSl9XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuXG4gICAgICA8Q29udHJvbEJveD5cbiAgICAgICAgPExhYmVsPldhdmUgZnJlcXVlbmNpZXM8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIHtyZWxhYmk/LndhdmVzLm1hcCgod2F2ZSwgaW5kZXgpID0+IChcbiAgICAgICAgICAgIDxDb250cm9sU2xpZGVyXG4gICAgICAgICAgICAgIHJlbD17YGZyZXF1ZW5jeV8ke2luZGV4fWB9XG4gICAgICAgICAgICAgIHR5cGU9XCJmcmVxdWVuY3lcIlxuICAgICAgICAgICAgICBpbmRleD17aW5kZXh9XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgbWluPXstMn1cbiAgICAgICAgICAgICAgbWF4PXszfVxuICAgICAgICAgICAgICBzdGVwPXswLjAwMX1cbiAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlPXtNYXRoLmxvZyh3YXZlLmZyZXF1ZW5jeSl9XG4gICAgICAgICAgICAgIHRpcEZvcm1hdHRlcj17KHZhbHVlKSA9PiBNYXRoLmV4cCh2YWx1ZSkudG9GaXhlZCgxKX1cbiAgICAgICAgICAgICAgY29sb3I9e1wiIzhhOFwifVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9TbGlkZXJSb3c+XG4gICAgICA8L0NvbnRyb2xCb3g+XG5cbiAgICAgIDxDb250cm9sQm94PlxuICAgICAgICA8TGFiZWw+V2F2ZSBzaGFwZXM8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIHtyZWxhYmk/LndhdmVzLm1hcCgod2F2ZSwgaW5kZXgpID0+IChcbiAgICAgICAgICAgIDxDb250cm9sU2xpZGVyXG4gICAgICAgICAgICAgIHJlbD17YHNoYXBlXyR7aW5kZXh9YH1cbiAgICAgICAgICAgICAgdHlwZT1cInNoYXBlXCJcbiAgICAgICAgICAgICAgaW5kZXg9e2luZGV4fVxuICAgICAgICAgICAgICBvbkNoYW5nZT17b25DaGFuZ2V9XG4gICAgICAgICAgICAgIG1pbj17MH1cbiAgICAgICAgICAgICAgbWF4PXtXQVZFX1NIQVBFX05BTUVTLmxlbmd0aCAtIDF9XG4gICAgICAgICAgICAgIHN0ZXA9ezF9XG4gICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17V0FWRV9TSEFQRV9OQU1FUy5pbmRleE9mKHdhdmUuc2hhcGUpfVxuICAgICAgICAgICAgICBjb2xvcj17XCIjYWE4XCJ9XG4gICAgICAgICAgICAgIHRpcEZvcm1hdHRlcj17KHZhbHVlKSA9PiBXQVZFX1NIQVBFX05BTUVTW3ZhbHVlXX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSl9XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuXG4gICAgICA8Q29udHJvbEJveD5cbiAgICAgICAgPExhYmVsPldhdmUgd2VpZ2h0czwvTGFiZWw+XG4gICAgICAgIDxTbGlkZXJSb3c+XG4gICAgICAgICAge3JlbGFiaT8ud2F2ZXMubWFwKCh3YXZlLCBpbmRleCkgPT4gKFxuICAgICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgICAgcmVsPXtgd2VpZ2h0XyR7aW5kZXh9YH1cbiAgICAgICAgICAgICAgdHlwZT1cIndlaWdodFwiXG4gICAgICAgICAgICAgIGluZGV4PXtpbmRleH1cbiAgICAgICAgICAgICAgb25DaGFuZ2U9e29uQ2hhbmdlfVxuICAgICAgICAgICAgICBtaW49ezB9XG4gICAgICAgICAgICAgIG1heD17Mn1cbiAgICAgICAgICAgICAgc3RlcD17MC4wMX1cbiAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlPXt3YXZlLndlaWdodH1cbiAgICAgICAgICAgICAgY29sb3I9e1wiIzk5YlwifVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9TbGlkZXJSb3c+XG4gICAgICA8L0NvbnRyb2xCb3g+XG5cbiAgICAgIDxDb250cm9sQm94PlxuICAgICAgICA8TGFiZWw+U3BlZWQ8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIDxDb250cm9sU2xpZGVyXG4gICAgICAgICAgICB0eXBlPVwic2V0dGluZ3NcIlxuICAgICAgICAgICAgaW5kZXg9XCJzcGVlZFwiXG4gICAgICAgICAgICBvbkNoYW5nZT17b25DaGFuZ2V9XG4gICAgICAgICAgICBtaW49ey0zfVxuICAgICAgICAgICAgbWF4PXszfVxuICAgICAgICAgICAgc3RlcD17MC4wMX1cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17TWF0aC5sb2cocmVsYWJpLnNldHRpbmdzLnNwZWVkKX1cbiAgICAgICAgICAgIHRpcEZvcm1hdHRlcj17KHZhbHVlKSA9PiBNYXRoLmV4cCh2YWx1ZSkudG9GaXhlZCgxKX1cbiAgICAgICAgICAgIGNvbG9yPXtcIiNhODhcIn1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1NsaWRlclJvdz5cbiAgICAgIDwvQ29udHJvbEJveD5cblxuICAgICAgPENvbnRyb2xCb3g+XG4gICAgICAgIDxMYWJlbD5DaGFvczwvTGFiZWw+XG4gICAgICAgIDxTbGlkZXJSb3c+XG4gICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgIHR5cGU9XCJzZXR0aW5nc1wiXG4gICAgICAgICAgICBpbmRleD1cImNoYW9zXCJcbiAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgIG1pbj17MH1cbiAgICAgICAgICAgIG1heD17MC41fVxuICAgICAgICAgICAgc3RlcD17MC4wMX1cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17cmVsYWJpLnNldHRpbmdzLmNoYW9zfVxuICAgICAgICAgICAgY29sb3I9e1wiI2E4OFwifVxuICAgICAgICAgIC8+XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuICAgIDwvQ29udHJvbFJvdz5cbiAgKTtcbn1cblxuLyoqXG4gKiBVSSBFbGVtZW50c1xuICovXG5jb25zdCBDb250cm9sUm93ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgZmxleERpcmVjdGlvbjogXCJyb3dcIixcbiAgICAgIG1hcmdpblRvcDogXCIxcmVtXCIsXG4gICAgfX1cbiAgPlxuICAgIHtjaGlsZHJlbn1cbiAgPC9kaXY+XG4pO1xuXG5jb25zdCBDb250cm9sQm94ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIG1hcmdpbkxlZnQ6IFwiMXJlbVwiLFxuICAgIH19XG4gID5cbiAgICB7Y2hpbGRyZW59XG4gIDwvZGl2PlxuKTtcblxuY29uc3QgU2xpZGVyUm93ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgZmxleERpcmVjaXRvbjogXCJyb3dcIixcbiAgICAgIGhlaWdodDogXCIxMHJlbVwiLFxuICAgICAgbWFyZ2luVG9wOiBcIjAuNXJlbVwiLFxuICAgIH19XG4gID5cbiAgICB7Y2hpbGRyZW59XG4gIDwvZGl2PlxuKTtcblxuY29uc3QgTGFiZWwgPSAoeyBjaGlsZHJlbiB9KSA9PiAoXG4gIDxkaXYgc3R5bGU9e3sgZm9udFNpemU6IFwiMC43NXJlbVwiIH19PntjaGlsZHJlbn08L2Rpdj5cbik7XG5cbmNvbnN0IENvbnRyb2xTbGlkZXIgPSAoe1xuICB0eXBlLFxuICBpbmRleCxcbiAgbWluLFxuICBtYXgsXG4gIHN0ZXAsXG4gIHJldmVyc2UsXG4gIGRlZmF1bHRWYWx1ZSxcbiAgY29sb3IsXG4gIG9uQ2hhbmdlLFxuICB0aXBGb3JtYXR0ZXIsXG59KSA9PiAoXG4gIDxkaXYgc3R5bGU9e3sgbWFyZ2luUmlnaHQ6IFwiMC41cmVtXCIgfX0+XG4gICAgPFRvb2x0aXBTbGlkZXJcbiAgICAgIHZlcnRpY2FsXG4gICAgICBtaW49e21pbn1cbiAgICAgIG1heD17bWF4fVxuICAgICAgc3RlcD17c3RlcH1cbiAgICAgIHJldmVyc2U9e3JldmVyc2V9XG4gICAgICBkZWZhdWx0VmFsdWU9e2RlZmF1bHRWYWx1ZX1cbiAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZSh0eXBlLCBpbmRleCl9XG4gICAgICBoYW5kbGVTdHlsZT17e1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9yLFxuICAgICAgICBib3JkZXJDb2xvcjogY29sb3IsXG4gICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICB9fVxuICAgICAgdHJhY2tTdHlsZT17eyBiYWNrZ3JvdW5kQ29sb3I6IFwiIzg4OFwiLCB3aWR0aDogXCIycHhcIiB9fVxuICAgICAgcmFpbFN0eWxlPXt7IGJhY2tncm91bmRDb2xvcjogXCIjODg4XCIsIHdpZHRoOiBcIjJweFwiIH19XG4gICAgICB0aXBGb3JtYXR0ZXI9e3RpcEZvcm1hdHRlciB8fCAoKHZhbHVlKSA9PiB2YWx1ZSl9XG4gICAgLz5cbiAgPC9kaXY+XG4pO1xuIiwiLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yIFVJXG4gKiBAbW9kdWxlIHNyYy91aS9BcHAuanM7XG4gKi9cblxuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBSZWxhYmkgZnJvbSBcIi4uL3JlbGFiaVwiO1xuaW1wb3J0IENvbnRyb2xzIGZyb20gXCIuL0NvbnRyb2xzLmpzeFwiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7XG4gIGNvbnN0IFtyZWxhYmksIHNldFJlbGFiaV0gPSB1c2VTdGF0ZSgpO1xuICBjb25zdCByZWxhYmlSZWYgPSB1c2VSZWYoKTtcblxuICAvKipcbiAgICogSW5zdGFudGlhdGUgdGhlIFJlbGFiaSBnZW5lcmF0b3JcbiAgICovXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFyZWxhYmkpIHtcbiAgICAgIGNvbnN0IHJlbGFiaUdlbmVyYXRvciA9IG5ldyBSZWxhYmkoe1xuICAgICAgICBzZXR0aW5nczoge1xuICAgICAgICAgIHNwZWVkOiAxLjAsXG4gICAgICAgICAgY2hhb3M6IDAuMixcbiAgICAgICAgfSxcbiAgICAgICAgd2F2ZXM6IFtcbiAgICAgICAgICB7IHNoYXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAwLjUsIHdlaWdodDogMSB9LFxuICAgICAgICAgIHsgc2hhcGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IDEuMCwgd2VpZ2h0OiAxIH0sXG4gICAgICAgICAgeyBzaGFwZTogXCJzaW5lXCIsIGZyZXF1ZW5jeTogMS41LCB3ZWlnaHQ6IDEgfSxcbiAgICAgICAgICB7IHNoYXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAyLjAsIHdlaWdodDogMSB9LFxuICAgICAgICBdLFxuICAgICAgICBib3VuZHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogLTAuMjUsXG4gICAgICAgICAgICBjb2xvcjogXCIjZjMzXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFt7IGluc3RydW1lbnQ6IFwiS2lja1wiIH0sIHsgaW5zdHJ1bWVudDogXCJTbmFyZVwiIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGV2ZWw6IDAuMjUsXG4gICAgICAgICAgICBjb2xvcjogXCIjZjgzXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFt7IGluc3RydW1lbnQ6IFwiSGF0XCIgfSwgeyBpbnN0cnVtZW50OiBcIlBlcmNcIiB9XSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIC8vIHtcbiAgICAgICAgICAvLyAgIGxldmVsOiAtMC4yNSxcbiAgICAgICAgICAvLyAgIGNvbG9yOiBcIiMzYjhcIixcbiAgICAgICAgICAvLyAgIHNvdW5kczogW1xuICAgICAgICAgIC8vICAgICB7IGluc3RydW1lbnQ6IEthbGltYmEsIGZyZXF1ZW5jeTogNDQwIH0sXG4gICAgICAgICAgLy8gICAgIHsgaW5zdHJ1bWVudDogS2FsaW1iYSwgZnJlcXVlbmN5OiAoNDQwICogMykgLyAyIH0sXG4gICAgICAgICAgLy8gICBdLFxuICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgLy8ge1xuICAgICAgICAgIC8vICAgbGV2ZWw6IDAuMjUsXG4gICAgICAgICAgLy8gICBjb2xvcjogXCIjMzZmXCIsXG4gICAgICAgICAgLy8gICBzb3VuZHM6IFtcbiAgICAgICAgICAvLyAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDUgfSxcbiAgICAgICAgICAvLyAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDcgfSxcbiAgICAgICAgICAvLyAgIF0sXG4gICAgICAgICAgLy8gfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgICAgcmVsYWJpR2VuZXJhdG9yLnN0YXJ0KCk7XG4gICAgICBzZXRSZWxhYmkocmVsYWJpR2VuZXJhdG9yKTtcbiAgICB9XG4gIH0sIFtyZWxhYmldKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChyZWxhYmkgJiYgcmVsYWJpUmVmLmN1cnJlbnQpIHtcbiAgICAgIHJlbGFiaS5jYW52YXMuYXBwZW5kQ2FudmFzKHJlbGFiaVJlZi5jdXJyZW50KTtcbiAgICB9XG4gIH0sIFtyZWxhYmksIHJlbGFiaVJlZi5jdXJyZW50XSk7XG5cbiAgLyoqXG4gICAqIFJlbmRlclxuICAgKi9cbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBzdHlsZT17e1xuICAgICAgICBoZWlnaHQ6IFwiMTAwJVwiLFxuICAgICAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgICAgIHBhZGRpbmc6IDAsXG4gICAgICAgIG1hcmdpbjogMCxcbiAgICAgICAgZGlzcGxheTogXCJmbGV4XCIsXG4gICAgICAgIGZsZXhEaXJlY3Rpb246IFwiY29sdW1uXCIsXG4gICAgICAgIGp1c3RpZnlDb250ZW50OiBcImNlbnRlclwiLFxuICAgICAgfX1cbiAgICA+XG4gICAgICA8ZGl2IHJlZj17cmVsYWJpUmVmfSAvPlxuICAgICAgPENvbnRyb2xzIHJlbGFiaT17cmVsYWJpfSAvPlxuICAgIDwvZGl2PlxuICApO1xufVxuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBjcmVhdGVSb290IH0gZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIjtcbmltcG9ydCB7IHJlcXVlc3RBdWRpb0NvbnRleHQsIHJhbmRyYW5nZSB9IGZyb20gXCIuL2xpYi91dGlsXCI7XG5cbmltcG9ydCBBcHAgZnJvbSBcIi4vdWkvQXBwLmpzeFwiO1xuXG5kb2N1bWVudC5ib2R5LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwiIzExMVwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5jb2xvciA9IFwiI2ZmZlwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW4gPSAwO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nID0gMDtcbmRvY3VtZW50LmJvZHkuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLmZvbnRGYW1pbHkgPSBcIkhlbHZldGljYSwgQXJpYWxcIjtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS5tYXJnaW4gPSAwO1xuZG9jdW1lbnQuYm9keS5wYXJlbnROb2RlLnN0eWxlLnBhZGRpbmcgPSAwO1xuZG9jdW1lbnQuYm9keS5wYXJlbnROb2RlLnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuZG9jdW1lbnQuYm9keS5wYXJlbnROb2RlLnN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG5cbnJlcXVlc3RBdWRpb0NvbnRleHQoKCkgPT4ge1xuICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBjb250YWluZXIuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG4gIGNvbnRhaW5lci5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuICBkb2N1bWVudC5ib2R5LmlubmVySFRNTCA9IFwiXCI7XG4gIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgY29uc3Qgcm9vdCA9IGNyZWF0ZVJvb3QoY29udGFpbmVyKTtcbiAgcm9vdC5yZW5kZXIoPEFwcCAvPik7XG59KTtcbiJdLCJuYW1lcyI6WyJUb25lIiwiU3RhcnRBdWRpb0NvbnRleHQiLCJpc0lwaG9uZSIsIm5hdmlnYXRvciIsInVzZXJBZ2VudCIsIm1hdGNoIiwiaXNJcGFkIiwiaXNBbmRyb2lkIiwiaXNNb2JpbGUiLCJpc0Rlc2t0b3AiLCJkb2N1bWVudCIsImJvZHkiLCJjbGFzc0xpc3QiLCJhZGQiLCJicm93c2VyIiwiY2hvaWNlIiwiYSIsIk1hdGgiLCJmbG9vciIsInJhbmRvbSIsImxlbmd0aCIsIm1vZCIsIm4iLCJtIiwicmFuZCIsInJhbmRpbnQiLCJyYW5kcmFuZ2UiLCJiIiwicmFuZHNpZ24iLCJyYW5kbnVsbHNpZ24iLCJyIiwicmVxdWVzdEF1ZGlvQ29udGV4dCIsImZuIiwiY29udGFpbmVyIiwiY3JlYXRlRWxlbWVudCIsImJ1dHRvbiIsImlubmVySFRNTCIsIk9iamVjdCIsImFzc2lnbiIsInN0eWxlIiwiZGlzcGxheSIsInBvc2l0aW9uIiwid2lkdGgiLCJoZWlnaHQiLCJ6SW5kZXgiLCJ0b3AiLCJsZWZ0IiwiYmFja2dyb3VuZENvbG9yIiwicGFkZGluZyIsImNvbG9yIiwiZm9udEZhbWlseSIsImJvcmRlclJhZGl1cyIsInRyYW5zZm9ybSIsInRleHRBbGlnbiIsImxpbmVIZWlnaHQiLCJjdXJzb3IiLCJhcHBlbmRDaGlsZCIsInNldENvbnRleHQiLCJjb250ZXh0Iiwib24iLCJvblN0YXJ0ZWQiLCJfIiwicmVtb3ZlIiwiTk9URV9SQURJVVMiLCJSZWxhYmlDYW52YXMiLCJfcmVmIiwicmVsYWJpIiwicGFyZW50IiwiX2NsYXNzQ2FsbENoZWNrIiwibGFzdEZyYW1lIiwibGFzdEFwcGVuZFRpbWUiLCJsYXN0QXBwZW5kRnJhbWUiLCJzcGVlZCIsInRaZXJvT2Zmc2V0IiwiYXBwZW5kQ2FudmFzIiwidmFsdWVzIiwiQXJyYXkiLCJ3aW5kb3ciLCJpbm5lcldpZHRoIiwiZmlsbCIsIm5vdGVzIiwiYXBwZW5kIiwicmVzaXplIiwicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiX2NyZWF0ZUNsYXNzIiwia2V5IiwidmFsdWUiLCJjYW52YXMiLCJjdHgiLCJnZXRDb250ZXh0IiwiX3JlcXVlc3RBbmltYXRpb25GcmFtZSIsIl94IiwiYXBwbHkiLCJhcmd1bWVudHMiLCJ0b1N0cmluZyIsImZyYW1lIiwiX3RoaXMiLCJwYWludCIsImNsZWFyIiwiY2xlYXJSZWN0IiwidGltZSIsImZpbHRlciIsImNvbmNhdCIsInNsaWNlIiwic29ydCIsImRyYXdSZWxhYmlXYXZlIiwiZHJhd0JvdW5kcyIsImRyYXdOb3RlcyIsIl9pdGVyYXRvciIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiYm91bmRzIiwiX3N0ZXAiLCJzIiwiZG9uZSIsImJvdW5kIiwieSIsImdldFdhdmVIZWlnaHQiLCJsZXZlbCIsImJlZ2luUGF0aCIsInNldExpbmVEYXNoIiwibGluZVdpZHRoIiwic3Ryb2tlU3R5bGUiLCJtb3ZlVG8iLCJsaW5lVG8iLCJzdHJva2UiLCJlcnIiLCJlIiwiZiIsInBvaW50Q291bnQiLCJpbmRleCIsImZyYW1lT2Zmc2V0IiwiX2l0ZXJhdG9yMiIsIl9zdGVwMiIsInBvaW50IiwiX3BvaW50IiwiX3NsaWNlZFRvQXJyYXkiLCJ0aW1lT2Zmc2V0IiwieCIsIl9pdGVyYXRvcjMiLCJfc3RlcDMiLCJub3RlIiwiX25vdGUiLCJkaXJlY3Rpb24iLCJvcGFjaXR5IiwiYXJjIiwiUEkiLCJmaWxsU3R5bGUiLCJkZWZhdWx0IiwiY29tcHJlc3NvciIsIkNvbXByZXNzb3IiLCJnYWluIiwiR2FpbiIsImNvbm5lY3QiLCJ0b0Rlc3RpbmF0aW9uIiwib3V0cHV0IiwiUExBWUVSX0NPVU5UIiwiU2FtcGxlciIsInNhbXBsZXMiLCJ0b25hbCIsIm1hcCIsIl9yZWYyIiwic2FtcGxlIiwiX2V4dGVuZHMiLCJfb2JqZWN0RGVzdHJ1Y3R1cmluZ0VtcHR5IiwicGxheWVycyIsImkiLCJsb2NhdGlvbiIsImhyZWYiLCJwbGF5ZXIiLCJQbGF5ZXIiLCJ1cmwiLCJyZXRyaWdnZXIiLCJwbGF5YmFja1JhdGUiLCJwdXNoIiwicGxheSIsIm9wdGlvbnMiLCJzb3VuZCIsImZyZXF1ZW5jeSIsInJvb3QiLCJzdGFydCIsIkthbGltYmEiLCJEcnVtcyIsIktpY2siLCJTbmFyZSIsIkhhdCIsIlBlcmMiLCJDeW1iYWwiLCJUb20iLCJJbnN0cnVtZW50cyIsIlRXT19QSSIsIldBVkVfU0hBUEVTIiwic2luZSIsImNvcyIsInRyaWFuZ2xlIiwiYWJzIiwic3F1YXJlIiwic2F3IiwicmV2ZXJzZV9zYXciLCJub2lzZSIsIlJlbGFiaSIsIndhdmVzIiwic2V0dGluZ3MiLCJ1cGRhdGVUaW1lIiwic3RlcHMiLCJwcmV2aW91c1ZhbHVlIiwiY29uc29sZSIsImxvZyIsInN0b3AiLCJjbG9jayIsIkNsb2NrIiwiZ2VuZXJhdGUiLCJkaXNwb3NlIiwic3RlcCIsInByZXZpb3VzV2F2ZVZhbHVlIiwidG90YWxXZWlnaHQiLCJyZWR1Y2UiLCJzdW0iLCJ3YXZlIiwid2VpZ2h0Iiwic3RlcENvdW50Iiwid2F2ZU9mZnNldCIsIm9mZnNldCIsImNoYW9zIiwid2F2ZVZhbHVlIiwic2hhcGUiLCJib3VuZHNDb3VudCIsIm5vdGVDb3VudCIsIl92YWx1ZXMkc3RlcCIsInRyaWdnZXIiLCJzb3VuZHMiLCJpbnN0cnVtZW50IiwiUmVhY3QiLCJ1c2VDYWxsYmFjayIsInVzZVJlZiIsIlNsaWRlciIsIlRvb2x0aXBTbGlkZXIiLCJoYW5kbGVSZW5kZXIiLCJXQVZFX1NIQVBFX05BTUVTIiwiQ29udHJvbHMiLCJvbkNoYW5nZSIsInR5cGUiLCJleHAiLCJDb250cm9sUm93IiwiQ29udHJvbEJveCIsIkxhYmVsIiwiU2xpZGVyUm93IiwiQ29udHJvbFNsaWRlciIsInJlbCIsIm1pbiIsIm1heCIsInRpcEZvcm1hdHRlciIsImRlZmF1bHRWYWx1ZSIsInJldmVyc2UiLCJ0b0ZpeGVkIiwiaW5kZXhPZiIsImNoaWxkcmVuIiwiZmxleERpcmVjdGlvbiIsIm1hcmdpblRvcCIsIl9yZWYzIiwibWFyZ2luTGVmdCIsIl9yZWY0IiwiZmxleERpcmVjaXRvbiIsIl9yZWY1IiwiZm9udFNpemUiLCJfcmVmNiIsIm1hcmdpblJpZ2h0IiwidmVydGljYWwiLCJoYW5kbGVTdHlsZSIsImJvcmRlckNvbG9yIiwidHJhY2tTdHlsZSIsInJhaWxTdHlsZSIsInVzZVN0YXRlIiwidXNlRWZmZWN0IiwiQXBwIiwiX3VzZVN0YXRlIiwiX3VzZVN0YXRlMiIsInNldFJlbGFiaSIsInJlbGFiaVJlZiIsInJlbGFiaUdlbmVyYXRvciIsImN1cnJlbnQiLCJtYXJnaW4iLCJqdXN0aWZ5Q29udGVudCIsInJlZiIsImNyZWF0ZVJvb3QiLCJwYXJlbnROb2RlIiwicmVuZGVyIl0sInNvdXJjZVJvb3QiOiIifQ==\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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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)})();