UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

302 lines (296 loc) 55.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = EffectTimeConfiguratorFactory; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); var _react = _interopRequireWildcard(require("react")); var _reactIntl = require("react-intl"); var _styledComponents = _interopRequireDefault(require("styled-components")); var _momentTimezone = _interopRequireDefault(require("moment-timezone")); var _suncalc = _interopRequireDefault(require("suncalc")); var _localization = require("@kepler.gl/localization"); var _utils = require("@kepler.gl/utils"); var _constants = require("@kepler.gl/constants"); var _reducers = require("@kepler.gl/reducers"); var _injector = require("../injector"); var _styledComponents2 = require("../common/styled-components"); var _checkbox = _interopRequireDefault(require("../common/checkbox")); var _button = _interopRequireDefault(require("../common/data-table/button")); var _icons = require("../common/icons"); var _timezoneSelector = _interopRequireDefault(require("./timezone-selector")); var _effectTimeSlider = _interopRequireDefault(require("./effect-time-slider")); var _effectTimeSelector = _interopRequireDefault(require("./effect-time-selector")); var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9; // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } var DAY_MILISECONDS = 1000 * 60 * 60 * 24; var StyledWrapper = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: ", "px;\n ", "\n"])), function (props) { var _props$marginBottom; return (_props$marginBottom = props.marginBottom) !== null && _props$marginBottom !== void 0 ? _props$marginBottom : 9; }, function (props) { return props.hidden ? 'display: none;' : ''; }); var SliderWrapper = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n margin-top: 13px;\n margin-bottom: 12px;\n ", "\n"])), function (props) { return props.hidden ? 'display: none;' : ''; }); var StyledButton = (0, _styledComponents["default"])(_button["default"])(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n color: ", ";\n background-color: ", ";\n height: 32px;\n width: 32px;\n padding: 5px;\n border-radius: 4px;\n justify-content: center;\n &:hover {\n color: ", ";\n background-color: ", ";\n }\n"])), function (props) { return props.theme.effectPanelTextSecondary2; }, function (props) { return props.theme.inputBgd; }, function (props) { return props.theme.effectPanelTextMain; }, function (props) { return props.theme.inputBgdHover; }); var StyledRadio = (0, _styledComponents["default"])(_checkbox["default"])(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n .kg-checkbox__label {\n font-family: ", ";\n font-size: ", ";\n }\n .kg-checkbox__label:before {\n background: transparent;\n border-color: ", ";\n }\n input:checked + .kg-checkbox__label:before {\n border-color: ", ";\n }\n .kg-checkbox__label:after {\n background-color: ", ";\n }\n"])), function (props) { return props.theme.fontFamily; }, function (props) { return props.theme.inputFontSize; }, function (props) { return props.theme.effectPanelTextSecondary2; }, function (props) { return props.theme.activeColor; }, function (props) { return props.theme.activeColor; }); var StyledEffectTimeConfigurator = _styledComponents["default"].div(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n margin-bottom: 8px;\n margin-top: 3px;\n"]))); var StyledDatePicker = _styledComponents["default"].div(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n .react-date-picker--open .react-date-picker__wrapper .react-date-picker__inputGroup {\n border: 1px solid ", ";\n border-radius: 4px 4px 0px 0px !important;\n }\n .react-calendar__navigation__prev2-button,\n .react-calendar__navigation__next2-button {\n display: none;\n }\n .react-calendar__navigation__label {\n position: absolute;\n top: 20px;\n }\n .react-calendar__navigation__arrow {\n position: absolute;\n top: 18px;\n font-size: 16px;\n }\n .react-calendar__navigation__prev-button {\n right: 36px;\n }\n .react-calendar__navigation__next-button {\n right: 12px;\n }\n"])), function (props) { return props.theme.activeColor; }); var WithIconWrapper = _styledComponents["default"].div(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n position: relative;\n ", "\n"])), function (props) { return props.width ? "width: ".concat(props.width) : ''; }); var StyledExtraIcon = _styledComponents["default"].div(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2["default"])(["\n position: absolute;\n top: 0px;\n left: 8px;\n width: 0px;\n height: 32px;\n color: ", ";\n pointer-events: none;\n"])), function (props) { return props.theme.effectPanelTextSecondary2; }); var TextBlock = _styledComponents["default"].div(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2["default"])(["\n color: ", ";\n width: ", ";\n font-size: ", ";\n"])), function (props) { return props.theme.effectPanelTextSecondary2; }, function (props) { return props.width; }, function (props) { return props.theme.inputFontSize; }); /** * Converts date, time and timezone into a UTC timestamp. * @param dateStr Date string in YYYY-MM-DD format. * @param timeStr Time string in HH:MM format. * @param timezone Timezone name. * @returns Timestamp or null if case of bad inputs. */ var getTimestamp = function getTimestamp(dateStr, timeStr, timezone) { var timestamp = null; var curr = _momentTimezone["default"].tz("".concat(dateStr, "T").concat(timeStr, ":00"), timezone); if (curr.isValid()) { timestamp = curr.utc().valueOf(); } return timestamp; }; /** * Converts time of the day into [0, 1] range * @param date * @returns */ var getDayRatio = function getDayRatio(date) { return (date.hours() * 60 + date.minutes()) * 60 * 1000 / DAY_MILISECONDS; }; EffectTimeConfiguratorFactory.deps = [_timezoneSelector["default"], _effectTimeSlider["default"], _effectTimeSelector["default"]]; function EffectTimeConfiguratorFactory(TimezoneSelector, EffectTimeSlider, EffectTimeSelector) { var EffectTimeConfigurator = function EffectTimeConfigurator(_ref) { var timestamp = _ref.timestamp, _timezone = _ref.timezone, timeMode = _ref.timeMode, onTimeParametersChanged = _ref.onChange, mapState = _ref.mapState, intl = _ref.intl; var timezone = (0, _react.useMemo)(function () { return _momentTimezone["default"].tz.names().includes(_timezone) ? _timezone : _constants.DEFAULT_TIMEZONE; }, [_timezone]); var _useMemo = (0, _react.useMemo)(function () { var currentMoment = _momentTimezone["default"].tz(timestamp, timezone); // Slider value from 0 to 1 var dayProgress = getDayRatio(currentMoment); // Date picker always renders Date in local timezone var date = new Date(); date.setFullYear(currentMoment.year(), currentMoment.month(), currentMoment.date()); date.setHours(0, 0, 0, 0); return [date, currentMoment.toDate(), currentMoment.format('HH:mm'), currentMoment.format('YYYY-MM-DD'), dayProgress]; }, [timestamp, timezone]), _useMemo2 = (0, _slicedToArray2["default"])(_useMemo, 5), datePickerDate = _useMemo2[0], fullDate = _useMemo2[1], formattedTime = _useMemo2[2], formattedDate = _useMemo2[3], dayTimeProgress = _useMemo2[4]; var timeSliderConfig = (0, _react.useMemo)(function () { var times = _suncalc["default"].getTimes(fullDate, mapState.latitude, mapState.longitude); var dawn = times.dawn, sunrise = times.sunrise, sunset = times.sunset, dusk = times.dusk; return { dawn: getDayRatio(_momentTimezone["default"].tz(dawn.valueOf(), timezone)), sunrise: getDayRatio(_momentTimezone["default"].tz(sunrise.valueOf(), timezone)), sunset: getDayRatio(_momentTimezone["default"].tz(sunset.valueOf(), timezone)), dusk: getDayRatio(_momentTimezone["default"].tz(dusk.valueOf(), timezone)), sunriseTime: _momentTimezone["default"].tz(sunrise.valueOf(), timezone).format('hh:mm A'), sunsetTime: _momentTimezone["default"].tz(sunset.valueOf(), timezone).format('hh:mm A') }; }, [fullDate, timezone, mapState.latitude, mapState.longitude]); var onTimeSliderChange = (0, _react.useCallback)(function (value) { var hours = (0, _utils.clamp)([0, 23], Math.floor(value[1] * 24)); var minutes = (0, _utils.clamp)([0, 59], Math.floor((value[1] * 24 - hours) * 60)); var newFormattedTime = "".concat(hours < 10 ? "0".concat(hours) : hours, ":").concat(minutes < 10 ? "0".concat(minutes) : minutes); var newTimestamp = getTimestamp(formattedDate, newFormattedTime, timezone); onTimeParametersChanged({ timestamp: newTimestamp }); }, [formattedDate, timezone, onTimeParametersChanged]); var setDate = (0, _react.useCallback)(function (newDate) { if (!newDate) return; var newFormattedDate = (0, _momentTimezone["default"])(newDate).format('YYYY-MM-DD'); var newTimestamp = getTimestamp(newFormattedDate, formattedTime, timezone); onTimeParametersChanged({ timestamp: newTimestamp }); }, [formattedTime, timezone, onTimeParametersChanged]); var setTime = (0, _react.useCallback)(function (newTime) { if (!newTime) return; var newTimestamp = getTimestamp(formattedDate, newTime, timezone); onTimeParametersChanged({ timestamp: newTimestamp }); }, [formattedDate, timezone, onTimeParametersChanged]); var setTimezone = (0, _react.useCallback)(function (newTimezone) { if (!newTimezone) return; var newTimestamp = getTimestamp(formattedDate, formattedTime, newTimezone); // date and time are adjusted to have the same value but in the new timezone onTimeParametersChanged({ timestamp: newTimestamp, timezone: newTimezone }); }, [formattedDate, formattedTime, onTimeParametersChanged]); var setCurrentDateTime = (0, _react.useCallback)(function () { onTimeParametersChanged({ timestamp: new Date().valueOf() }); }, [onTimeParametersChanged]); var formatShortWeekday = (0, _react.useCallback)(function (locale, date) { return ['S', 'M', 'T', 'W', 'T', 'F', 'S'][date.getDay()]; }, []); var disableDateTimePick = timeMode !== _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.pick; return /*#__PURE__*/_react["default"].createElement(StyledEffectTimeConfigurator, null, /*#__PURE__*/_react["default"].createElement(StyledWrapper, { marginBottom: 16 }, /*#__PURE__*/_react["default"].createElement(StyledRadio, { type: "radio", checked: timeMode === _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.pick, id: "effect-time-toggle-use-pick-time", label: intl.formatMessage({ id: 'effectManager.pickDateTime' }), onChange: function onChange() { onTimeParametersChanged({ timeMode: _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.pick }); } })), /*#__PURE__*/_react["default"].createElement(SliderWrapper, { hidden: disableDateTimePick }, /*#__PURE__*/_react["default"].createElement(EffectTimeSlider, { value: dayTimeProgress, onChange: onTimeSliderChange, config: timeSliderConfig })), /*#__PURE__*/_react["default"].createElement(StyledWrapper, { hidden: disableDateTimePick, marginBottom: 2 }, /*#__PURE__*/_react["default"].createElement(TextBlock, { width: "32px" }), /*#__PURE__*/_react["default"].createElement(TextBlock, { width: "110px" }, /*#__PURE__*/_react["default"].createElement(_localization.FormattedMessage, { id: 'effectManager.date' })), /*#__PURE__*/_react["default"].createElement(TextBlock, { width: "110px" }, /*#__PURE__*/_react["default"].createElement(_localization.FormattedMessage, { id: 'effectManager.time' }))), /*#__PURE__*/_react["default"].createElement(StyledWrapper, { hidden: disableDateTimePick, marginBottom: 16 }, /*#__PURE__*/_react["default"].createElement(StyledButton, { onClick: setCurrentDateTime, "data-for": "pick-time-button", "data-tip": true }, /*#__PURE__*/_react["default"].createElement(_icons.LocationMarker, { height: "16px" }), /*#__PURE__*/_react["default"].createElement(_styledComponents2.Tooltip, { id: "pick-time-button", effect: "solid", place: "top", delayShow: 500 }, /*#__PURE__*/_react["default"].createElement(_localization.FormattedMessage, { id: 'effectManager.pickCurrrentTime' }))), /*#__PURE__*/_react["default"].createElement(WithIconWrapper, null, /*#__PURE__*/_react["default"].createElement(StyledDatePicker, null, /*#__PURE__*/_react["default"].createElement(_styledComponents2.StyledDatePicker, { value: datePickerDate, onChange: setDate, minDetail: 'month', formatShortWeekday: formatShortWeekday })), /*#__PURE__*/_react["default"].createElement(StyledExtraIcon, null, /*#__PURE__*/_react["default"].createElement(_icons.Calendar, { width: "16px", height: "32px" }))), /*#__PURE__*/_react["default"].createElement(WithIconWrapper, null, /*#__PURE__*/_react["default"].createElement(EffectTimeSelector, { value: formattedTime, onChange: setTime }), /*#__PURE__*/_react["default"].createElement(StyledExtraIcon, null, /*#__PURE__*/_react["default"].createElement(_icons.Clock, { width: "16px", height: "32px" })))), /*#__PURE__*/_react["default"].createElement(StyledWrapper, { hidden: disableDateTimePick, marginBottom: 2 }, /*#__PURE__*/_react["default"].createElement(TextBlock, null, /*#__PURE__*/_react["default"].createElement(_localization.FormattedMessage, { id: 'effectManager.timezone' }))), /*#__PURE__*/_react["default"].createElement(StyledWrapper, { hidden: disableDateTimePick, marginBottom: 24 }, /*#__PURE__*/_react["default"].createElement(WithIconWrapper, { width: '100%' }, /*#__PURE__*/_react["default"].createElement(TimezoneSelector, { selected: timezone, onSelect: setTimezone }), /*#__PURE__*/_react["default"].createElement(StyledExtraIcon, null, /*#__PURE__*/_react["default"].createElement(_icons.Globe, { width: "16px", height: "32px" })))), /*#__PURE__*/_react["default"].createElement(StyledWrapper, { marginBottom: 16 }, /*#__PURE__*/_react["default"].createElement(StyledRadio, { type: "radio", checked: timeMode === _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.current, id: "effect-time-toggle-use-current-time", label: intl.formatMessage({ id: 'effectManager.currentTime' }), onChange: function onChange() { onTimeParametersChanged({ timeMode: _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.current }); } })), /*#__PURE__*/_react["default"].createElement(StyledWrapper, { marginBottom: 16 }, /*#__PURE__*/_react["default"].createElement(StyledRadio, { type: "radio", checked: timeMode === _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.animation, id: "effect-time-toggle-use-animation-time", label: 'Animation time', onChange: function onChange() { onTimeParametersChanged({ timeMode: _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.animation }); } }))); }; // @ts-expect-error how to properly type? return (0, _injector.withState)([_reducers.mapStateLens])((0, _reactIntl.injectIntl)(EffectTimeConfigurator)); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcmVhY3RJbnRsIiwiX3N0eWxlZENvbXBvbmVudHMiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX21vbWVudFRpbWV6b25lIiwiX3N1bmNhbGMiLCJfbG9jYWxpemF0aW9uIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIl9yZWR1Y2VycyIsIl9pbmplY3RvciIsIl9zdHlsZWRDb21wb25lbnRzMiIsIl9jaGVja2JveCIsIl9idXR0b24iLCJfaWNvbnMiLCJfdGltZXpvbmVTZWxlY3RvciIsIl9lZmZlY3RUaW1lU2xpZGVyIiwiX2VmZmVjdFRpbWVTZWxlY3RvciIsIl90ZW1wbGF0ZU9iamVjdCIsIl90ZW1wbGF0ZU9iamVjdDIiLCJfdGVtcGxhdGVPYmplY3QzIiwiX3RlbXBsYXRlT2JqZWN0NCIsIl90ZW1wbGF0ZU9iamVjdDUiLCJfdGVtcGxhdGVPYmplY3Q2IiwiX3RlbXBsYXRlT2JqZWN0NyIsIl90ZW1wbGF0ZU9iamVjdDgiLCJfdGVtcGxhdGVPYmplY3Q5IiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJfdHlwZW9mIiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiREFZX01JTElTRUNPTkRTIiwiU3R5bGVkV3JhcHBlciIsInN0eWxlZCIsImRpdiIsIl90YWdnZWRUZW1wbGF0ZUxpdGVyYWwyIiwicHJvcHMiLCJfcHJvcHMkbWFyZ2luQm90dG9tIiwibWFyZ2luQm90dG9tIiwiaGlkZGVuIiwiU2xpZGVyV3JhcHBlciIsIlN0eWxlZEJ1dHRvbiIsIkJ1dHRvbiIsInRoZW1lIiwiZWZmZWN0UGFuZWxUZXh0U2Vjb25kYXJ5MiIsImlucHV0QmdkIiwiZWZmZWN0UGFuZWxUZXh0TWFpbiIsImlucHV0QmdkSG92ZXIiLCJTdHlsZWRSYWRpbyIsIkNoZWNrYm94IiwiZm9udEZhbWlseSIsImlucHV0Rm9udFNpemUiLCJhY3RpdmVDb2xvciIsIlN0eWxlZEVmZmVjdFRpbWVDb25maWd1cmF0b3IiLCJTdHlsZWREYXRlUGlja2VyIiwiV2l0aEljb25XcmFwcGVyIiwid2lkdGgiLCJjb25jYXQiLCJTdHlsZWRFeHRyYUljb24iLCJUZXh0QmxvY2siLCJnZXRUaW1lc3RhbXAiLCJkYXRlU3RyIiwidGltZVN0ciIsInRpbWV6b25lIiwidGltZXN0YW1wIiwiY3VyciIsIm1vbWVudCIsInR6IiwiaXNWYWxpZCIsInV0YyIsInZhbHVlT2YiLCJnZXREYXlSYXRpbyIsImRhdGUiLCJob3VycyIsIm1pbnV0ZXMiLCJFZmZlY3RUaW1lQ29uZmlndXJhdG9yRmFjdG9yeSIsImRlcHMiLCJUaW1lem9uZVNlbGVjdG9yRmFjdG9yeSIsIkVmZmVjdFRpbWVTbGlkZXJGYWN0b3J5IiwiRWZmZWN0VGltZVNlbGVjdG9yRmFjdG9yeSIsIlRpbWV6b25lU2VsZWN0b3IiLCJFZmZlY3RUaW1lU2xpZGVyIiwiRWZmZWN0VGltZVNlbGVjdG9yIiwiRWZmZWN0VGltZUNvbmZpZ3VyYXRvciIsIl9yZWYiLCJfdGltZXpvbmUiLCJ0aW1lTW9kZSIsIm9uVGltZVBhcmFtZXRlcnNDaGFuZ2VkIiwib25DaGFuZ2UiLCJtYXBTdGF0ZSIsImludGwiLCJ1c2VNZW1vIiwibmFtZXMiLCJpbmNsdWRlcyIsIkRFRkFVTFRfVElNRVpPTkUiLCJfdXNlTWVtbyIsImN1cnJlbnRNb21lbnQiLCJkYXlQcm9ncmVzcyIsIkRhdGUiLCJzZXRGdWxsWWVhciIsInllYXIiLCJtb250aCIsInNldEhvdXJzIiwidG9EYXRlIiwiZm9ybWF0IiwiX3VzZU1lbW8yIiwiX3NsaWNlZFRvQXJyYXkyIiwiZGF0ZVBpY2tlckRhdGUiLCJmdWxsRGF0ZSIsImZvcm1hdHRlZFRpbWUiLCJmb3JtYXR0ZWREYXRlIiwiZGF5VGltZVByb2dyZXNzIiwidGltZVNsaWRlckNvbmZpZyIsInRpbWVzIiwiU3VuQ2FsYyIsImdldFRpbWVzIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJkYXduIiwic3VucmlzZSIsInN1bnNldCIsImR1c2siLCJzdW5yaXNlVGltZSIsInN1bnNldFRpbWUiLCJvblRpbWVTbGlkZXJDaGFuZ2UiLCJ1c2VDYWxsYmFjayIsInZhbHVlIiwiY2xhbXAiLCJNYXRoIiwiZmxvb3IiLCJuZXdGb3JtYXR0ZWRUaW1lIiwibmV3VGltZXN0YW1wIiwic2V0RGF0ZSIsIm5ld0RhdGUiLCJuZXdGb3JtYXR0ZWREYXRlIiwic2V0VGltZSIsIm5ld1RpbWUiLCJzZXRUaW1lem9uZSIsIm5ld1RpbWV6b25lIiwic2V0Q3VycmVudERhdGVUaW1lIiwiZm9ybWF0U2hvcnRXZWVrZGF5IiwibG9jYWxlIiwiZ2V0RGF5IiwiZGlzYWJsZURhdGVUaW1lUGljayIsIkxJR0hUX0FORF9TSEFET1dfRUZGRUNUX1RJTUVfTU9ERVMiLCJwaWNrIiwiY3JlYXRlRWxlbWVudCIsInR5cGUiLCJjaGVja2VkIiwiaWQiLCJsYWJlbCIsImZvcm1hdE1lc3NhZ2UiLCJjb25maWciLCJGb3JtYXR0ZWRNZXNzYWdlIiwib25DbGljayIsIkxvY2F0aW9uTWFya2VyIiwiaGVpZ2h0IiwiVG9vbHRpcCIsImVmZmVjdCIsInBsYWNlIiwiZGVsYXlTaG93IiwibWluRGV0YWlsIiwiQ2FsZW5kYXIiLCJDbG9jayIsInNlbGVjdGVkIiwib25TZWxlY3QiLCJHbG9iZSIsImN1cnJlbnQiLCJhbmltYXRpb24iLCJ3aXRoU3RhdGUiLCJtYXBTdGF0ZUxlbnMiLCJpbmplY3RJbnRsIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VmZmVjdHMvZWZmZWN0LXRpbWUtY29uZmlndXJhdG9yLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgUmVhY3QsIHt1c2VDYWxsYmFjaywgdXNlTWVtb30gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHtpbmplY3RJbnRsLCBJbnRsU2hhcGV9IGZyb20gJ3JlYWN0LWludGwnO1xuaW1wb3J0IHN0eWxlZCBmcm9tICdzdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudC10aW1lem9uZSc7XG5pbXBvcnQgU3VuQ2FsYyBmcm9tICdzdW5jYWxjJztcblxuaW1wb3J0IHtNYXBTdGF0ZX0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge0Zvcm1hdHRlZE1lc3NhZ2V9IGZyb20gJ0BrZXBsZXIuZ2wvbG9jYWxpemF0aW9uJztcbmltcG9ydCB7Y2xhbXB9IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuaW1wb3J0IHtcbiAgTElHSFRfQU5EX1NIQURPV19FRkZFQ1RfVElNRV9NT0RFUyxcbiAgTGlnaHRBbmRTaGFkb3dFZmZlY3RUaW1lTW9kZSxcbiAgREVGQVVMVF9USU1FWk9ORVxufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge21hcFN0YXRlTGVuc30gZnJvbSAnQGtlcGxlci5nbC9yZWR1Y2Vycyc7XG5cbmltcG9ydCB7d2l0aFN0YXRlfSBmcm9tICcuLi9pbmplY3Rvcic7XG5pbXBvcnQge1N0eWxlZERhdGVQaWNrZXIgYXMgRGF0ZVBpY2tlciwgVG9vbHRpcH0gZnJvbSAnLi4vY29tbW9uL3N0eWxlZC1jb21wb25lbnRzJztcbmltcG9ydCBDaGVja2JveCBmcm9tICcuLi9jb21tb24vY2hlY2tib3gnO1xuaW1wb3J0IEJ1dHRvbiBmcm9tICcuLi9jb21tb24vZGF0YS10YWJsZS9idXR0b24nO1xuaW1wb3J0IHtMb2NhdGlvbk1hcmtlciwgQ2FsZW5kYXIsIENsb2NrLCBHbG9iZX0gZnJvbSAnLi4vY29tbW9uL2ljb25zJztcbmltcG9ydCBUaW1lem9uZVNlbGVjdG9yRmFjdG9yeSBmcm9tICcuL3RpbWV6b25lLXNlbGVjdG9yJztcbmltcG9ydCBFZmZlY3RUaW1lU2xpZGVyRmFjdG9yeSBmcm9tICcuL2VmZmVjdC10aW1lLXNsaWRlcic7XG5pbXBvcnQgRWZmZWN0VGltZVNlbGVjdG9yRmFjdG9yeSBmcm9tICcuL2VmZmVjdC10aW1lLXNlbGVjdG9yJztcblxuY29uc3QgREFZX01JTElTRUNPTkRTID0gMTAwMCAqIDYwICogNjAgKiAyNDtcblxuZXhwb3J0IHR5cGUgRWZmZWN0VGltZUNvbmZpZ3VyYXRvclByb3BzID0ge1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgdGltZXpvbmU6IHN0cmluZztcbiAgdGltZU1vZGU6IExpZ2h0QW5kU2hhZG93RWZmZWN0VGltZU1vZGU7XG4gIG9uQ2hhbmdlOiAocGFyYW1ldGVyczoge1xuICAgIHRpbWVzdGFtcD86IG51bWJlciB8IG51bGw7XG4gICAgdGltZXpvbmU/OiBzdHJpbmc7XG4gICAgdGltZU1vZGU/OiBMaWdodEFuZFNoYWRvd0VmZmVjdFRpbWVNb2RlO1xuICB9KSA9PiB2b2lkO1xufTtcblxudHlwZSBTdHlsZWRXcmFwcGVyUHJvcHMgPSB7ZGlzYWJsZWQ/OiBib29sZWFuOyBtYXJnaW5Cb3R0b20/OiBudW1iZXJ9O1xuY29uc3QgU3R5bGVkV3JhcHBlciA9IHN0eWxlZC5kaXY8U3R5bGVkV3JhcHBlclByb3BzPmBcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBtYXJnaW4tYm90dG9tOiAke3Byb3BzID0+IHByb3BzLm1hcmdpbkJvdHRvbSA/PyA5fXB4O1xuICAke3Byb3BzID0+IChwcm9wcy5oaWRkZW4gPyAnZGlzcGxheTogbm9uZTsnIDogJycpfVxuYDtcblxudHlwZSBTbGlkZXJXcmFwcGVyUHJvcHMgPSB7ZGlzYWJsZWQ/OiBib29sZWFufTtcbmNvbnN0IFNsaWRlcldyYXBwZXIgPSBzdHlsZWQuZGl2PFNsaWRlcldyYXBwZXJQcm9wcz5gXG4gIG1hcmdpbi10b3A6IDEzcHg7XG4gIG1hcmdpbi1ib3R0b206IDEycHg7XG4gICR7cHJvcHMgPT4gKHByb3BzLmhpZGRlbiA/ICdkaXNwbGF5OiBub25lOycgOiAnJyl9XG5gO1xuXG5jb25zdCBTdHlsZWRCdXR0b24gPSBzdHlsZWQoQnV0dG9uKWBcbiAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZWZmZWN0UGFuZWxUZXh0U2Vjb25kYXJ5Mn07XG4gIGJhY2tncm91bmQtY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuaW5wdXRCZ2R9O1xuICBoZWlnaHQ6IDMycHg7XG4gIHdpZHRoOiAzMnB4O1xuICBwYWRkaW5nOiA1cHg7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICY6aG92ZXIge1xuICAgIGNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmVmZmVjdFBhbmVsVGV4dE1haW59O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuaW5wdXRCZ2RIb3Zlcn07XG4gIH1cbmA7XG5cbmNvbnN0IFN0eWxlZFJhZGlvID0gc3R5bGVkKENoZWNrYm94KWBcbiAgLmtnLWNoZWNrYm94X19sYWJlbCB7XG4gICAgZm9udC1mYW1pbHk6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZm9udEZhbWlseX07XG4gICAgZm9udC1zaXplOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmlucHV0Rm9udFNpemV9O1xuICB9XG4gIC5rZy1jaGVja2JveF9fbGFiZWw6YmVmb3JlIHtcbiAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICBib3JkZXItY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZWZmZWN0UGFuZWxUZXh0U2Vjb25kYXJ5Mn07XG4gIH1cbiAgaW5wdXQ6Y2hlY2tlZCArIC5rZy1jaGVja2JveF9fbGFiZWw6YmVmb3JlIHtcbiAgICBib3JkZXItY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuYWN0aXZlQ29sb3J9O1xuICB9XG4gIC5rZy1jaGVja2JveF9fbGFiZWw6YWZ0ZXIge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuYWN0aXZlQ29sb3J9O1xuICB9XG5gO1xuXG5jb25zdCBTdHlsZWRFZmZlY3RUaW1lQ29uZmlndXJhdG9yID0gc3R5bGVkLmRpdmBcbiAgbWFyZ2luLWJvdHRvbTogOHB4O1xuICBtYXJnaW4tdG9wOiAzcHg7XG5gO1xuXG5jb25zdCBTdHlsZWREYXRlUGlja2VyID0gc3R5bGVkLmRpdmBcbiAgLnJlYWN0LWRhdGUtcGlja2VyLS1vcGVuIC5yZWFjdC1kYXRlLXBpY2tlcl9fd3JhcHBlciAucmVhY3QtZGF0ZS1waWNrZXJfX2lucHV0R3JvdXAge1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuYWN0aXZlQ29sb3J9O1xuICAgIGJvcmRlci1yYWRpdXM6IDRweCA0cHggMHB4IDBweCAhaW1wb3J0YW50O1xuICB9XG4gIC5yZWFjdC1jYWxlbmRhcl9fbmF2aWdhdGlvbl9fcHJldjItYnV0dG9uLFxuICAucmVhY3QtY2FsZW5kYXJfX25hdmlnYXRpb25fX25leHQyLWJ1dHRvbiB7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgfVxuICAucmVhY3QtY2FsZW5kYXJfX25hdmlnYXRpb25fX2xhYmVsIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAyMHB4O1xuICB9XG4gIC5yZWFjdC1jYWxlbmRhcl9fbmF2aWdhdGlvbl9fYXJyb3cge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDE4cHg7XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICB9XG4gIC5yZWFjdC1jYWxlbmRhcl9fbmF2aWdhdGlvbl9fcHJldi1idXR0b24ge1xuICAgIHJpZ2h0OiAzNnB4O1xuICB9XG4gIC5yZWFjdC1jYWxlbmRhcl9fbmF2aWdhdGlvbl9fbmV4dC1idXR0b24ge1xuICAgIHJpZ2h0OiAxMnB4O1xuICB9XG5gO1xuXG50eXBlIFdpdGhJY29uV3JhcHBlclByb3BzID0ge3dpZHRoPzogc3RyaW5nfTtcbmNvbnN0IFdpdGhJY29uV3JhcHBlciA9IHN0eWxlZC5kaXY8V2l0aEljb25XcmFwcGVyUHJvcHM+YFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICR7cHJvcHMgPT4gKHByb3BzLndpZHRoID8gYHdpZHRoOiAke3Byb3BzLndpZHRofWAgOiAnJyl9XG5gO1xuXG5jb25zdCBTdHlsZWRFeHRyYUljb24gPSBzdHlsZWQuZGl2YFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMHB4O1xuICBsZWZ0OiA4cHg7XG4gIHdpZHRoOiAwcHg7XG4gIGhlaWdodDogMzJweDtcbiAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZWZmZWN0UGFuZWxUZXh0U2Vjb25kYXJ5Mn07XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuYDtcblxudHlwZSBUZXh0QmxvY2tQcm9wcyA9IHtcbiAgd2lkdGg/OiBzdHJpbmc7XG59O1xuY29uc3QgVGV4dEJsb2NrID0gc3R5bGVkLmRpdjxUZXh0QmxvY2tQcm9wcz5gXG4gIGNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmVmZmVjdFBhbmVsVGV4dFNlY29uZGFyeTJ9O1xuICB3aWR0aDogJHtwcm9wcyA9PiBwcm9wcy53aWR0aH07XG4gIGZvbnQtc2l6ZTogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5pbnB1dEZvbnRTaXplfTtcbmA7XG5cbi8qKlxuICogQ29udmVydHMgZGF0ZSwgdGltZSBhbmQgdGltZXpvbmUgaW50byBhIFVUQyB0aW1lc3RhbXAuXG4gKiBAcGFyYW0gZGF0ZVN0ciBEYXRlIHN0cmluZyBpbiBZWVlZLU1NLUREIGZvcm1hdC5cbiAqIEBwYXJhbSB0aW1lU3RyIFRpbWUgc3RyaW5nIGluIEhIOk1NIGZvcm1hdC5cbiAqIEBwYXJhbSB0aW1lem9uZSBUaW1lem9uZSBuYW1lLlxuICogQHJldHVybnMgVGltZXN0YW1wIG9yIG51bGwgaWYgY2FzZSBvZiBiYWQgaW5wdXRzLlxuICovXG5jb25zdCBnZXRUaW1lc3RhbXAgPSAoZGF0ZVN0cjogc3RyaW5nLCB0aW1lU3RyOiBzdHJpbmcsIHRpbWV6b25lOiBzdHJpbmcpOiBudW1iZXIgfCBudWxsID0+IHtcbiAgbGV0IHRpbWVzdGFtcDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IGN1cnIgPSBtb21lbnQudHooYCR7ZGF0ZVN0cn1UJHt0aW1lU3RyfTowMGAsIHRpbWV6b25lKTtcbiAgaWYgKGN1cnIuaXNWYWxpZCgpKSB7XG4gICAgdGltZXN0YW1wID0gY3Vyci51dGMoKS52YWx1ZU9mKCk7XG4gIH1cbiAgcmV0dXJuIHRpbWVzdGFtcDtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGltZSBvZiB0aGUgZGF5IGludG8gWzAsIDFdIHJhbmdlXG4gKiBAcGFyYW0gZGF0ZVxuICogQHJldHVybnNcbiAqL1xuY29uc3QgZ2V0RGF5UmF0aW8gPSAoZGF0ZTogbW9tZW50Lk1vbWVudCkgPT4ge1xuICByZXR1cm4gKChkYXRlLmhvdXJzKCkgKiA2MCArIGRhdGUubWludXRlcygpKSAqIDYwICogMTAwMCkgLyBEQVlfTUlMSVNFQ09ORFM7XG59O1xuXG5FZmZlY3RUaW1lQ29uZmlndXJhdG9yRmFjdG9yeS5kZXBzID0gW1xuICBUaW1lem9uZVNlbGVjdG9yRmFjdG9yeSxcbiAgRWZmZWN0VGltZVNsaWRlckZhY3RvcnksXG4gIEVmZmVjdFRpbWVTZWxlY3RvckZhY3Rvcnlcbl07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEVmZmVjdFRpbWVDb25maWd1cmF0b3JGYWN0b3J5KFxuICBUaW1lem9uZVNlbGVjdG9yOiBSZXR1cm5UeXBlPHR5cGVvZiBUaW1lem9uZVNlbGVjdG9yRmFjdG9yeT4sXG4gIEVmZmVjdFRpbWVTbGlkZXI6IFJldHVyblR5cGU8dHlwZW9mIEVmZmVjdFRpbWVTbGlkZXJGYWN0b3J5PixcbiAgRWZmZWN0VGltZVNlbGVjdG9yOiBSZXR1cm5UeXBlPHR5cGVvZiBFZmZlY3RUaW1lU2VsZWN0b3JGYWN0b3J5PlxuKTogUmVhY3QuRkM8RWZmZWN0VGltZUNvbmZpZ3VyYXRvclByb3BzPiB7XG4gIGNvbnN0IEVmZmVjdFRpbWVDb25maWd1cmF0b3IgPSAoe1xuICAgIHRpbWVzdGFtcCxcbiAgICB0aW1lem9uZTogX3RpbWV6b25lLFxuICAgIHRpbWVNb2RlLFxuICAgIG9uQ2hhbmdlOiBvblRpbWVQYXJhbWV0ZXJzQ2hhbmdlZCxcbiAgICBtYXBTdGF0ZSxcbiAgICBpbnRsXG4gIH06IEVmZmVjdFRpbWVDb25maWd1cmF0b3JQcm9wcyAmIHtpbnRsOiBJbnRsU2hhcGU7IG1hcFN0YXRlOiBNYXBTdGF0ZX0pID0+IHtcbiAgICBjb25zdCB0aW1lem9uZSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgICAgcmV0dXJuIG1vbWVudC50ei5uYW1lcygpLmluY2x1ZGVzKF90aW1lem9uZSkgPyBfdGltZXpvbmUgOiBERUZBVUxUX1RJTUVaT05FO1xuICAgIH0sIFtfdGltZXpvbmVdKTtcblxuICAgIGNvbnN0IFtkYXRlUGlja2VyRGF0ZSwgZnVsbERhdGUsIGZvcm1hdHRlZFRpbWUsIGZvcm1hdHRlZERhdGUsIGRheVRpbWVQcm9ncmVzc10gPVxuICAgICAgdXNlTWVtbygoKSA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNb21lbnQgPSBtb21lbnQudHoodGltZXN0YW1wLCB0aW1lem9uZSk7XG5cbiAgICAgICAgLy8gU2xpZGVyIHZhbHVlIGZyb20gMCB0byAxXG4gICAgICAgIGNvbnN0IGRheVByb2dyZXNzID0gZ2V0RGF5UmF0aW8oY3VycmVudE1vbWVudCk7XG5cbiAgICAgICAgLy8gRGF0ZSBwaWNrZXIgYWx3YXlzIHJlbmRlcnMgRGF0ZSBpbiBsb2NhbCB0aW1lem9uZVxuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgZGF0ZS5zZXRGdWxsWWVhcihjdXJyZW50TW9tZW50LnllYXIoKSwgY3VycmVudE1vbWVudC5tb250aCgpLCBjdXJyZW50TW9tZW50LmRhdGUoKSk7XG4gICAgICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG5cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICBkYXRlLFxuICAgICAgICAgIGN1cnJlbnRNb21lbnQudG9EYXRlKCksXG4gICAgICAgICAgY3VycmVudE1vbWVudC5mb3JtYXQoJ0hIOm1tJyksXG4gICAgICAgICAgY3VycmVudE1vbWVudC5mb3JtYXQoJ1lZWVktTU0tREQnKSxcbiAgICAgICAgICBkYXlQcm9ncmVzc1xuICAgICAgICBdO1xuICAgICAgfSwgW3RpbWVzdGFtcCwgdGltZXpvbmVdKTtcblxuICAgIGNvbnN0IHRpbWVTbGlkZXJDb25maWcgPSB1c2VNZW1vKCgpID0+IHtcbiAgICAgIGNvbnN0IHRpbWVzID0gU3VuQ2FsYy5nZXRUaW1lcyhmdWxsRGF0ZSwgbWFwU3RhdGUubGF0aXR1ZGUsIG1hcFN0YXRlLmxvbmdpdHVkZSk7XG4gICAgICBjb25zdCB7ZGF3biwgc3VucmlzZSwgc3Vuc2V0LCBkdXNrfSA9IHRpbWVzO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXduOiBnZXREYXlSYXRpbyhtb21lbnQudHooZGF3bi52YWx1ZU9mKCksIHRpbWV6b25lKSksXG4gICAgICAgIHN1bnJpc2U6IGdldERheVJhdGlvKG1vbWVudC50eihzdW5yaXNlLnZhbHVlT2YoKSwgdGltZXpvbmUpKSxcbiAgICAgICAgc3Vuc2V0OiBnZXREYXlSYXRpbyhtb21lbnQudHooc3Vuc2V0LnZhbHVlT2YoKSwgdGltZXpvbmUpKSxcbiAgICAgICAgZHVzazogZ2V0RGF5UmF0aW8obW9tZW50LnR6KGR1c2sudmFsdWVPZigpLCB0aW1lem9uZSkpLFxuICAgICAgICBzdW5yaXNlVGltZTogbW9tZW50LnR6KHN1bnJpc2UudmFsdWVPZigpLCB0aW1lem9uZSkuZm9ybWF0KCdoaDptbSBBJyksXG4gICAgICAgIHN1bnNldFRpbWU6IG1vbWVudC50eihzdW5zZXQudmFsdWVPZigpLCB0aW1lem9uZSkuZm9ybWF0KCdoaDptbSBBJylcbiAgICAgIH07XG4gICAgfSwgW2Z1bGxEYXRlLCB0aW1lem9uZSwgbWFwU3RhdGUubGF0aXR1ZGUsIG1hcFN0YXRlLmxvbmdpdHVkZV0pO1xuXG4gICAgY29uc3Qgb25UaW1lU2xpZGVyQ2hhbmdlID0gdXNlQ2FsbGJhY2soXG4gICAgICB2YWx1ZSA9PiB7XG4gICAgICAgIGNvbnN0IGhvdXJzID0gY2xhbXAoWzAsIDIzXSwgTWF0aC5mbG9vcih2YWx1ZVsxXSAqIDI0KSk7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSBjbGFtcChbMCwgNTldLCBNYXRoLmZsb29yKCh2YWx1ZVsxXSAqIDI0IC0gaG91cnMpICogNjApKTtcblxuICAgICAgICBjb25zdCBuZXdGb3JtYXR0ZWRUaW1lID0gYCR7aG91cnMgPCAxMCA/IGAwJHtob3Vyc31gIDogaG91cnN9OiR7XG4gICAgICAgICAgbWludXRlcyA8IDEwID8gYDAke21pbnV0ZXN9YCA6IG1pbnV0ZXNcbiAgICAgICAgfWA7XG4gICAgICAgIGNvbnN0IG5ld1RpbWVzdGFtcCA9IGdldFRpbWVzdGFtcChmb3JtYXR0ZWREYXRlLCBuZXdGb3JtYXR0ZWRUaW1lLCB0aW1lem9uZSk7XG4gICAgICAgIG9uVGltZVBhcmFtZXRlcnNDaGFuZ2VkKHt0aW1lc3RhbXA6IG5ld1RpbWVzdGFtcH0pO1xuICAgICAgfSxcbiAgICAgIFtmb3JtYXR0ZWREYXRlLCB0aW1lem9uZSwgb25UaW1lUGFyYW1ldGVyc0NoYW5nZWRdXG4gICAgKTtcblxuICAgIGNvbnN0IHNldERhdGUgPSB1c2VDYWxsYmFjayhcbiAgICAgIG5ld0RhdGUgPT4ge1xuICAgICAgICBpZiAoIW5ld0RhdGUpIHJldHVybjtcblxuICAgICAgICBjb25zdCBuZXdGb3JtYXR0ZWREYXRlID0gbW9tZW50KG5ld0RhdGUpLmZvcm1hdCgnWVlZWS1NTS1ERCcpO1xuICAgICAgICBjb25zdCBuZXdUaW1lc3RhbXAgPSBnZXRUaW1lc3RhbXAobmV3Rm9ybWF0dGVkRGF0ZSwgZm9ybWF0dGVkVGltZSwgdGltZXpvbmUpO1xuICAgICAgICBvblRpbWVQYXJhbWV0ZXJzQ2hhbmdlZCh7dGltZXN0YW1wOiBuZXdUaW1lc3RhbXB9KTtcbiAgICAgIH0sXG4gICAgICBbZm9ybWF0dGVkVGltZSwgdGltZXpvbmUsIG9uVGltZVBhcmFtZXRlcnNDaGFuZ2VkXVxuICAgICk7XG5cbiAgICBjb25zdCBzZXRUaW1lID0gdXNlQ2FsbGJhY2soXG4gICAgICBuZXdUaW1lID0+IHtcbiAgICAgICAgaWYgKCFuZXdUaW1lKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgbmV3VGltZXN0YW1wID0gZ2V0VGltZXN0YW1wKGZvcm1hdHRlZERhdGUsIG5ld1RpbWUsIHRpbWV6b25lKTtcbiAgICAgICAgb25UaW1lUGFyYW1ldGVyc0NoYW5nZWQoe3RpbWVzdGFtcDogbmV3VGltZXN0YW1wfSk7XG4gICAgICB9LFxuICAgICAgW2Zvcm1hdHRlZERhdGUsIHRpbWV6b25lLCBvblRpbWVQYXJhbWV0ZXJzQ2hhbmdlZF1cbiAgICApO1xuXG4gICAgY29uc3Qgc2V0VGltZXpvbmUgPSB1c2VDYWxsYmFjayhcbiAgICAgIG5ld1RpbWV6b25lID0+IHtcbiAgICAgICAgaWYgKCFuZXdUaW1lem9uZSkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IG5ld1RpbWVzdGFtcCA9IGdldFRpbWVzdGFtcChmb3JtYXR0ZWREYXRlLCBmb3JtYXR0ZWRUaW1lLCBuZXdUaW1lem9uZSk7XG4gICAgICAgIC8vIGRhdGUgYW5kIHRpbWUgYXJlIGFkanVzdGVkIHRvIGhhdmUgdGhlIHNhbWUgdmFsdWUgYnV0IGluIHRoZSBuZXcgdGltZXpvbmVcbiAgICAgICAgb25UaW1lUGFyYW1ldGVyc0NoYW5nZWQoe3RpbWVzdGFtcDogbmV3VGltZXN0YW1wLCB0aW1lem9uZTogbmV3VGltZXpvbmV9KTtcbiAgICAgIH0sXG4gICAgICBbZm9ybWF0dGVkRGF0ZSwgZm9ybWF0dGVkVGltZSwgb25UaW1lUGFyYW1ldGVyc0NoYW5nZWRdXG4gICAgKTtcblxuICAgIGNvbnN0IHNldEN1cnJlbnREYXRlVGltZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICAgIG9uVGltZVBhcmFtZXRlcnNDaGFuZ2VkKHt0aW1lc3RhbXA6IG5ldyBEYXRlKCkudmFsdWVPZigpfSk7XG4gICAgfSwgW29uVGltZVBhcmFtZXRlcnNDaGFuZ2VkXSk7XG5cbiAgICBjb25zdCBmb3JtYXRTaG9ydFdlZWtkYXkgPSB1c2VDYWxsYmFjaygobG9jYWxlLCBkYXRlKSA9PiB7XG4gICAgICByZXR1cm4gWydTJywgJ00nLCAnVCcsICdXJywgJ1QnLCAnRicsICdTJ11bZGF0ZS5nZXREYXkoKV07XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgZGlzYWJsZURhdGVUaW1lUGljayA9IHRpbWVNb2RlICE9PSBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVF9USU1FX01PREVTLnBpY2s7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPFN0eWxlZEVmZmVjdFRpbWVDb25maWd1cmF0b3I+XG4gICAgICAgIDxTdHlsZWRXcmFwcGVyIG1hcmdpbkJvdHRvbT17MTZ9PlxuICAgICAgICAgIDxTdHlsZWRSYWRpb1xuICAgICAgICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgICAgICAgIGNoZWNrZWQ9e3RpbWVNb2RlID09PSBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVF9USU1FX01PREVTLnBpY2t9XG4gICAgICAgICAgICBpZD17YGVmZmVjdC10aW1lLXRvZ2dsZS11c2UtcGljay10aW1lYH1cbiAgICAgICAgICAgIGxhYmVsPXtpbnRsLmZvcm1hdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgICBpZDogJ2VmZmVjdE1hbmFnZXIucGlja0RhdGVUaW1lJ1xuICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICBvbkNoYW5nZT17KCkgPT4ge1xuICAgICAgICAgICAgICBvblRpbWVQYXJhbWV0ZXJzQ2hhbmdlZCh7dGltZU1vZGU6IExJR0hUX0FORF9TSEFET1dfRUZGRUNUX1RJTUVfTU9ERVMucGlja30pO1xuICAgICAgICAgICAgfX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1N0eWxlZFdyYXBwZXI+XG5cbiAgICAgICAgPFNsaWRlcldyYXBwZXIgaGlkZGVuPXtkaXNhYmxlRGF0ZVRpbWVQaWNrfT5cbiAgICAgICAgICA8RWZmZWN0VGltZVNsaWRlclxuICAgICAgICAgICAgdmFsdWU9e2RheVRpbWVQcm9ncmVzc31cbiAgICAgICAgICAgIG9uQ2hhbmdlPXtvblRpbWVTbGlkZXJDaGFuZ2V9XG4gICAgICAgICAgICBjb25maWc9e3RpbWVTbGlkZXJDb25maWd9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9TbGlkZXJXcmFwcGVyPlxuXG4gICAgICAgIDxTdHlsZWRXcmFwcGVyIGhpZGRlbj17ZGlzYWJsZURhdGVUaW1lUGlja30gbWFyZ2luQm90dG9tPXsyfT5cbiAgICAgICAgICA8VGV4dEJsb2NrIHdpZHRoPVwiMzJweFwiIC8+XG4gICAgICAgICAgPFRleHRCbG9jayB3aWR0aD1cIjExMHB4XCI+XG4gICAgICAgICAgICA8Rm9ybWF0dGVkTWVzc2FnZSBpZD17J2VmZmVjdE1hbmFnZXIuZGF0ZSd9IC8+XG4gICAgICAgICAgPC9UZXh0QmxvY2s+XG4gICAgICAgICAgPFRleHRCbG9jayB3aWR0aD1cIjExMHB4XCI+XG4gICAgICAgICAgICA8Rm9ybWF0dGVkTWVzc2FnZSBpZD17J2VmZmVjdE1hbmFnZXIudGltZSd9IC8+XG4gICAgICAgICAgPC9UZXh0QmxvY2s+XG4gICAgICAgIDwvU3R5bGVkV3JhcHBlcj5cblxuICAgICAgICA8U3R5bGVkV3JhcHBlciBoaWRkZW49e2Rpc2FibGVEYXRlVGltZVBpY2t9IG1hcmdpbkJvdHRvbT17MTZ9PlxuICAgICAgICAgIDxTdHlsZWRCdXR0b24gb25DbGljaz17c2V0Q3VycmVudERhdGVUaW1lfSBkYXRhLWZvcj1cInBpY2stdGltZS1idXR0b25cIiBkYXRhLXRpcD5cbiAgICAgICAgICAgIDxMb2NhdGlvbk1hcmtlciBoZWlnaHQ9XCIxNnB4XCIgLz5cbiAgICAgICAgICAgIDxUb29sdGlwIGlkPVwicGljay10aW1lLWJ1dHRvblwiIGVmZmVjdD1cInNvbGlkXCIgcGxhY2U9XCJ0b3BcIiBkZWxheVNob3c9ezUwMH0+XG4gICAgICAgICAgICAgIDxGb3JtYXR0ZWRNZXNzYWdlIGlkPXsnZWZmZWN0TWFuYWdlci5waWNrQ3VycnJlbnRUaW1lJ30gLz5cbiAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgICA8L1N0eWxlZEJ1dHRvbj5cbiAgICAgICAgICA8V2l0aEljb25XcmFwcGVyPlxuICAgICAgICAgICAgPFN0eWxlZERhdGVQaWNrZXI+XG4gICAgICAgICAgICAgIDxEYXRlUGlja2VyXG4gICAgICAgICAgICAgICAgdmFsdWU9e2RhdGVQaWNrZXJEYXRlfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtzZXREYXRlfVxuICAgICAgICAgICAgICAgIG1pbkRldGFpbD17J21vbnRoJ31cbiAgICAgICAgICAgICAgICBmb3JtYXRTaG9ydFdlZWtkYXk9e2Zvcm1hdFNob3J0V2Vla2RheX1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvU3R5bGVkRGF0ZVBpY2tlcj5cbiAgICAgICAgICAgIDxTdHlsZWRFeHRyYUljb24+XG4gICAgICAgICAgICAgIDxDYWxlbmRhciB3aWR0aD1cIjE2cHhcIiBoZWlnaHQ9XCIzMnB4XCIgLz5cbiAgICAgICAgICAgIDwvU3R5bGVkRXh0cmFJY29uPlxuICAgICAgICAgIDwvV2l0aEljb25XcmFwcGVyPlxuICAgICAgICAgIDxXaXRoSWNvbldyYXBwZXI+XG4gICAgICAgICAgICA8RWZmZWN0VGltZVNlbGVjdG9yIHZhbHVlPXtmb3JtYXR0ZWRUaW1lfSBvbkNoYW5nZT17c2V0VGltZX0gLz5cbiAgICAgICAgICAgIDxTdHlsZWRFeHRyYUljb24+XG4gICAgICAgICAgICAgIDxDbG9jayB3aWR0aD1cIjE2cHhcIiBoZWlnaHQ9XCIzMnB4XCIgLz5cbiAgICAgICAgICAgIDwvU3R5bGVkRXh0cmFJY29uPlxuICAgICAgICAgIDwvV2l0aEljb25XcmFwcGVyPlxuICAgICAgICA8L1N0eWxlZFdyYXBwZXI+XG5cbiAgICAgICAgPFN0eWxlZFdyYXBwZXIgaGlkZGVuPXtkaXNhYmxlRGF0ZVRpbWVQaWNrfSBtYXJnaW5Cb3R0b209ezJ9PlxuICAgICAgICAgIDxUZXh0QmxvY2s+XG4gICAgICAgICAgICA8Rm9ybWF0dGVkTWVzc2FnZSBpZD17J2VmZmVjdE1hbmFnZXIudGltZXpvbmUnfSAvPlxuICAgICAgICAgIDwvVGV4dEJsb2NrPlxuICAgICAgICA8L1N0eWxlZFdyYXBwZXI+XG5cbiAgICAgICAgPFN0eWxlZFdyYXBwZXIgaGlkZGVuPXtkaXNhYmxlRGF0ZVRpbWVQaWNrfSBtYXJnaW5Cb3R0b209ezI0fT5cbiAgICAgICAgICA8V2l0aEljb25XcmFwcGVyIHdpZHRoPXsnMTAwJSd9PlxuICAgICAgICAgICAgPFRpbWV6b25lU2VsZWN0b3Igc2VsZWN0ZWQ9e3RpbWV6b25lfSBvblNlbGVjdD17c2V0VGltZXpvbmV9IC8+XG4gICAgICAgICAgICA8U3R5bGVkRXh0cmFJY29uPlxuICAgICAgICAgICAgICA8R2xvYmUgd2lkdGg9XCIxNnB4XCIgaGVpZ2h0PVwiMzJweFwiIC8+XG4gICAgICAgICAgICA8L1N0eWxlZEV4dHJhSWNvbj5cbiAgICAgICAgICA8L1dpdGhJY29uV3JhcHBlcj5cbiAgICAgICAgPC9TdHlsZWRXcmFwcGVyPlxuXG4gICAgICAgIDxTdHlsZWRXcmFwcGVyIG1hcmdpbkJvdHRvbT17MTZ9PlxuICAgICAgICAgIDxTdHlsZWRSYWRpb1xuICAgICAgICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgICAgICAgIGNoZWNrZWQ9e3RpbWVNb2RlID09PSBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVF9USU1FX01PREVTLmN1cnJlbnR9XG4gICAgICAgICAgICBpZD17YGVmZmVjdC10aW1lLXRvZ2dsZS11c2UtY3VycmVudC10aW1lYH1cbiAgICAgICAgICAgIGxhYmVsPXtpbnRsLmZvcm1hdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgICBpZDogJ2VmZmVjdE1hbmFnZXIuY3VycmVudFRpbWUnXG4gICAgICAgICAgICB9KX1cbiAgICAgICAgICAgIG9uQ2hhbmdlPXsoKSA9PiB7XG4gICAgICAgICAgICAgIG9uVGltZVBhcmFtZXRlcnNDaGFuZ2VkKHt0aW1lTW9kZTogTElHSFRfQU5EX1NIQURPV19FRkZFQ1RfVElNRV9NT0RFUy5jdXJyZW50fSk7XG4gICAgICAgICAgICB9fVxuICAgICAgICAgIC8+XG4gICAgICAgIDwvU3R5bGVkV3JhcHBlcj5cblxuICAgICAgICA8U3R5bGVkV3JhcHBlciBtYXJnaW5Cb3R0b209ezE2fT5cbiAgICAgICAgICA8U3R5bGVkUmFkaW9cbiAgICAgICAgICAgIHR5cGU9XCJyYWRpb1wiXG4gICAgICAgICAgICBjaGVja2VkPXt0aW1lTW9kZSA9PT0gTElHSFRfQU5EX1NIQURPV19FRkZFQ1RfVElNRV9NT0RFUy5hbmltYXRpb259XG4gICAgICAgICAgICBpZD17YGVmZmVjdC10aW1lLXRvZ2dsZS11c2UtYW5pbWF0aW9uLXRpbWVgfVxuICAgICAgICAgICAgbGFiZWw9eydBbmltYXRpb24gdGltZSd9XG4gICAgICAgICAgICBvbkNoYW5nZT17KCkgPT4ge1xuICAgICAgICAgICAgICBvblRpbWVQYXJhbWV0ZXJzQ2hhbmdlZCh7dGltZU1vZGU6IExJR0hUX0FORF9TSEFET1dfRUZGRUNUX1RJTUVfTU9ERVMuYW5pbWF0aW9ufSk7XG4gICAgICAgICAgICB9fVxuICAgICAgICAgIC8+XG4gICAgICAgIDwvU3R5bGVkV3JhcHBlcj5cbiAgICAgIDwvU3R5bGVkRWZmZWN0VGltZUNvbmZpZ3VyYXRvcj5cbiAgICApO1xuICB9O1xuXG4gIC8vIEB0cy1leHBlY3QtZXJyb3IgaG93IHRvIHByb3Blcmx5IHR5cGU/XG4gIHJldHVybiB3aXRoU3RhdGUoW21hcFN0YXRlTGVuc10pKGluamVjdEludGwoRWZmZWN0VGlt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