kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
304 lines (249 loc) • 33.6 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = TimeRangeSliderFactory;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _moment = _interopRequireDefault(require("moment"));
var _window = require("global/window");
var _lodash = _interopRequireDefault(require("lodash.throttle"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _reselect = require("reselect");
var _icons = require("./icons");
var _styledComponents2 = require("./styled-components");
var _rangeSlider = _interopRequireDefault(require("./range-slider"));
var _timeSliderMarker = _interopRequireDefault(require("./time-slider-marker"));
var _playbackControls = _interopRequireDefault(require("./animation-control/playback-controls"));
var _defaultSettings = require("../../constants/default-settings");
function _templateObject2() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n align-items: center;\n font-size: 11px;\n justify-content: ", ";\n\n .horizontal-bar {\n padding: 0 12px;\n color: ", ";\n }\n\n .time-value {\n display: flex;\n flex-direction: ", ";\n align-items: flex-start;\n\n span {\n color: ", ";\n }\n }\n\n .time-value:last-child {\n align-items: flex-end;\n }\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n align-items: flex-end;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n .time-range-slider__control {\n margin-bottom: 12px;\n margin-right: 30px;\n }\n\n .playback-control-button {\n padding: 9px 12px;\n }\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
var animationControlWidth = 140;
var StyledSliderContainer = _styledComponents["default"].div(_templateObject());
TimeRangeSliderFactory.deps = [_playbackControls["default"]];
function TimeRangeSliderFactory(PlaybackControls) {
var TimeRangeSlider =
/*#__PURE__*/
function (_Component) {
(0, _inherits2["default"])(TimeRangeSlider, _Component);
function TimeRangeSlider(_props) {
var _this;
(0, _classCallCheck2["default"])(this, TimeRangeSlider);
_this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(TimeRangeSlider).call(this, _props));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "timeSelector", function (props) {
return props.currentTime;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "formatSelector", function (props) {
return props.format;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "displayTimeSelector", (0, _reselect.createSelector)(_this.timeSelector, _this.formatSelector, function (currentTime, format) {
var groupTime = Array.isArray(currentTime) ? currentTime : [currentTime];
return groupTime.reduce(function (accu, curr) {
var displayDateTime = _moment["default"].utc(curr).format(format);
var _displayDateTime$spli = displayDateTime.split(' '),
_displayDateTime$spli2 = (0, _slicedToArray2["default"])(_displayDateTime$spli, 2),
displayDate = _displayDateTime$spli2[0],
displayTime = _displayDateTime$spli2[1];
if (!accu.displayDate.includes(displayDate)) {
accu.displayDate.push(displayDate);
}
accu.displayTime.push(displayTime);
return accu;
}, {
displayDate: [],
displayTime: []
});
}));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_sliderUpdate", function (args) {
_this._sliderThrottle.cancel();
_this._sliderThrottle(args);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_resetAnimation", function () {
var _this$props = _this.props,
domain = _this$props.domain,
value = _this$props.value;
var value0 = domain[0];
var value1 = value0 + value[1] - value[0];
_this.props.onChange([value0, value1]);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_startAnimation", function () {
_this._pauseAnimation();
_this.props.toggleAnimation();
_this.setState({
isAnimating: true
});
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_pauseAnimation", function () {
if (_this._animation) {
(0, _window.cancelAnimationFrame)(_this._animation);
_this.props.toggleAnimation();
_this._animation = null;
}
_this.setState({
isAnimating: false
});
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_nextFrame", function () {
_this._animation = null;
var _this$props2 = _this.props,
domain = _this$props2.domain,
value = _this$props2.value;
var speed = (domain[1] - domain[0]) / _defaultSettings.BASE_SPEED * _this.props.speed; // loop when reaches the end
var value0 = value[1] + speed > domain[1] ? domain[0] : value[0] + speed;
var value1 = value0 + value[1] - value[0];
_this.props.onChange([value0, value1]);
});
_this.state = {
isAnimating: false,
width: 288
};
_this._animation = null;
_this._sliderThrottle = (0, _lodash["default"])(function () {
var _this$props3;
return (_this$props3 = _this.props).onChange.apply(_this$props3, arguments);
}, 20);
return _this;
}
(0, _createClass2["default"])(TimeRangeSlider, [{
key: "componentDidUpdate",
value: function componentDidUpdate() {
if (!this._animation && this.state.isAnimating) {
this._animation = (0, _window.requestAnimationFrame)(this._nextFrame);
}
}
}, {
key: "render",
value: function render() {
var _this$props4 = this.props,
domain = _this$props4.domain,
value = _this$props4.value,
isEnlarged = _this$props4.isEnlarged,
hideTimeTitle = _this$props4.hideTimeTitle;
var isAnimating = this.state.isAnimating;
return _react["default"].createElement("div", {
className: "time-range-slider"
}, !hideTimeTitle ? _react["default"].createElement(TimeTitle, {
timeFormat: this.props.timeFormat,
value: value,
isEnlarged: isEnlarged
}) : null, _react["default"].createElement(StyledSliderContainer, {
className: "time-range-slider__container",
isEnlarged: isEnlarged
}, isEnlarged ? _react["default"].createElement(PlaybackControls, {
isAnimatable: this.props.isAnimatable,
isEnlarged: isEnlarged,
isAnimating: isAnimating,
pauseAnimation: this._pauseAnimation,
resetAnimation: this._resetAnimation,
startAnimation: this._startAnimation,
buttonHeight: "12px",
buttonStyle: "secondary"
}) : null, _react["default"].createElement("div", {
style: {
width: isEnlarged ? "calc(100% - ".concat(animationControlWidth, "px)") : '100%'
}
}, _react["default"].createElement(_rangeSlider["default"], {
range: domain,
value0: value[0],
value1: value[1],
histogram: this.props.histogram,
lineChart: this.props.lineChart,
plotType: this.props.plotType,
isEnlarged: isEnlarged,
showInput: false,
step: this.props.step,
onChange: this._sliderUpdate,
xAxis: _timeSliderMarker["default"]
}))));
}
}]);
return TimeRangeSlider;
}(_react.Component);
(0, _defineProperty2["default"])(TimeRangeSlider, "propTypes", {
onChange: _propTypes["default"].func.isRequired,
domain: _propTypes["default"].arrayOf(_propTypes["default"].number).isRequired,
value: _propTypes["default"].arrayOf(_propTypes["default"].number).isRequired,
step: _propTypes["default"].number.isRequired,
plotType: _propTypes["default"].string,
histogram: _propTypes["default"].arrayOf(_propTypes["default"].any),
lineChart: _propTypes["default"].object,
toggleAnimation: _propTypes["default"].func.isRequired,
isAnimatable: _propTypes["default"].bool,
isEnlarged: _propTypes["default"].bool,
speed: _propTypes["default"].number,
timeFormat: _propTypes["default"].string,
hideTimeTitle: _propTypes["default"].bool
});
TimeRangeSlider.defaultProps = {
timeFormat: _defaultSettings.DEFAULT_TIME_FORMAT
};
return TimeRangeSlider;
}
var TimeValueWrapper = _styledComponents["default"].div(_templateObject2(), function (props) {
return props.isEnlarged ? 'center' : 'space-between';
}, function (props) {
return props.theme.titleTextColor;
}, function (props) {
return props.isEnlarged ? 'row' : 'column';
}, function (props) {
return props.theme.titleTextColor;
});
var TimeTitle = function TimeTitle(_ref) {
var value = _ref.value,
isEnlarged = _ref.isEnlarged,
_ref$timeFormat = _ref.timeFormat,
timeFormat = _ref$timeFormat === void 0 ? _defaultSettings.DEFAULT_TIME_FORMAT : _ref$timeFormat;
return _react["default"].createElement(TimeValueWrapper, {
isEnlarged: isEnlarged,
className: "time-range-slider__time-title"
}, _react["default"].createElement(TimeValue, {
key: 0,
value: _moment["default"].utc(value[0]).format(timeFormat),
split: !isEnlarged
}), isEnlarged ? _react["default"].createElement("div", {
className: "horizontal-bar"
}, _react["default"].createElement(_icons.Minus, {
height: "12px"
})) : null, _react["default"].createElement(TimeValue, {
key: 1,
value: _moment["default"].utc(value[1]).format(timeFormat),
split: !isEnlarged
}));
};
var TimeValue = function TimeValue(_ref2) {
var value = _ref2.value,
split = _ref2.split;
return (// render two lines if not enlarged
_react["default"].createElement("div", {
className: "time-value"
}, split ? value.split(' ').map(function (v, i) {
return _react["default"].createElement("div", {
key: i
}, i === 0 ? _react["default"].createElement(_styledComponents2.SelectText, null, v) : _react["default"].createElement(_styledComponents2.SelectTextBold, null, v));
}) : _react["default"].createElement(_styledComponents2.SelectTextBold, null, value))
);
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2NvbW1vbi90aW1lLXJhbmdlLXNsaWRlci5qcyJdLCJuYW1lcyI6WyJhbmltYXRpb25Db250cm9sV2lkdGgiLCJTdHlsZWRTbGlkZXJDb250YWluZXIiLCJzdHlsZWQiLCJkaXYiLCJUaW1lUmFuZ2VTbGlkZXJGYWN0b3J5IiwiZGVwcyIsIlBsYXliYWNrQ29udHJvbHNGYWN0b3J5IiwiUGxheWJhY2tDb250cm9scyIsIlRpbWVSYW5nZVNsaWRlciIsInByb3BzIiwiY3VycmVudFRpbWUiLCJmb3JtYXQiLCJ0aW1lU2VsZWN0b3IiLCJmb3JtYXRTZWxlY3RvciIsImdyb3VwVGltZSIsIkFycmF5IiwiaXNBcnJheSIsInJlZHVjZSIsImFjY3UiLCJjdXJyIiwiZGlzcGxheURhdGVUaW1lIiwibW9tZW50IiwidXRjIiwic3BsaXQiLCJkaXNwbGF5RGF0ZSIsImRpc3BsYXlUaW1lIiwiaW5jbHVkZXMiLCJwdXNoIiwiYXJncyIsIl9zbGlkZXJUaHJvdHRsZSIsImNhbmNlbCIsImRvbWFpbiIsInZhbHVlIiwidmFsdWUwIiwidmFsdWUxIiwib25DaGFuZ2UiLCJfcGF1c2VBbmltYXRpb24iLCJ0b2dnbGVBbmltYXRpb24iLCJzZXRTdGF0ZSIsImlzQW5pbWF0aW5nIiwiX2FuaW1hdGlvbiIsInNwZWVkIiwiQkFTRV9TUEVFRCIsInN0YXRlIiwid2lkdGgiLCJfbmV4dEZyYW1lIiwiaXNFbmxhcmdlZCIsImhpZGVUaW1lVGl0bGUiLCJ0aW1lRm9ybWF0IiwiaXNBbmltYXRhYmxlIiwiX3Jlc2V0QW5pbWF0aW9uIiwiX3N0YXJ0QW5pbWF0aW9uIiwiaGlzdG9ncmFtIiwibGluZUNoYXJ0IiwicGxvdFR5cGUiLCJzdGVwIiwiX3NsaWRlclVwZGF0ZSIsIlRpbWVTbGlkZXJNYXJrZXIiLCJDb21wb25lbnQiLCJQcm9wVHlwZXMiLCJmdW5jIiwiaXNSZXF1aXJlZCIsImFycmF5T2YiLCJudW1iZXIiLCJzdHJpbmciLCJhbnkiLCJvYmplY3QiLCJib29sIiwiZGVmYXVsdFByb3BzIiwiREVGQVVMVF9USU1FX0ZPUk1BVCIsIlRpbWVWYWx1ZVdyYXBwZXIiLCJ0aGVtZSIsInRpdGxlVGV4dENvbG9yIiwiVGltZVRpdGxlIiwiVGltZVZhbHVlIiwibWFwIiwidiIsImkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsSUFBTUEscUJBQXFCLEdBQUcsR0FBOUI7O0FBRUEsSUFBTUMscUJBQXFCLEdBQUdDLDZCQUFPQyxHQUFWLG1CQUEzQjs7QUFnQkFDLHNCQUFzQixDQUFDQyxJQUF2QixHQUE4QixDQUFDQyw0QkFBRCxDQUE5Qjs7QUFFZSxTQUFTRixzQkFBVCxDQUFnQ0csZ0JBQWhDLEVBQWtEO0FBQUEsTUFDekRDLGVBRHlEO0FBQUE7QUFBQTtBQUFBOztBQWtCN0QsNkJBQVlDLE1BQVosRUFBbUI7QUFBQTs7QUFBQTtBQUNqQiw2SEFBTUEsTUFBTjtBQURpQix1R0FnQkosVUFBQUEsS0FBSztBQUFBLGVBQUlBLEtBQUssQ0FBQ0MsV0FBVjtBQUFBLE9BaEJEO0FBQUEseUdBaUJGLFVBQUFELEtBQUs7QUFBQSxlQUFJQSxLQUFLLENBQUNFLE1BQVY7QUFBQSxPQWpCSDtBQUFBLDhHQWtCRyw4QkFDcEIsTUFBS0MsWUFEZSxFQUVwQixNQUFLQyxjQUZlLEVBR3BCLFVBQUNILFdBQUQsRUFBY0MsTUFBZCxFQUF5QjtBQUN2QixZQUFNRyxTQUFTLEdBQUdDLEtBQUssQ0FBQ0MsT0FBTixDQUFjTixXQUFkLElBQTZCQSxXQUE3QixHQUEyQyxDQUFDQSxXQUFELENBQTdEO0FBQ0EsZUFBT0ksU0FBUyxDQUFDRyxNQUFWLENBQ0wsVUFBQ0MsSUFBRCxFQUFPQyxJQUFQLEVBQWdCO0FBQ2QsY0FBTUMsZUFBZSxHQUFHQyxt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LGFBQ0g7QUFBSyxRQUFBLEdBQUcsRUFBRUE7QUFBVixTQUNHQSxDQUFDLEtBQUssQ0FBTixHQUFVLGdDQUFDLDZCQUFELFFBQWFELENBQWIsQ0FBVixHQUF5QyxnQ0FBQyxpQ0FBRCxRQUFpQkEsQ0FBakIsQ0FENUMsQ0FERztBQUFBLEtBRlAsQ0FESSxHQVNKLGdDQUFDLGlDQUFELFFBQWlCNUMsS0FBakIsQ0FWSjtBQUZnQjtBQUFBLENBQWxCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIwIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IFJlYWN0LCB7Q29tcG9uZW50fSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHtyZXF1ZXN0QW5pbWF0aW9uRnJhbWUsIGNhbmNlbEFuaW1hdGlvbkZyYW1lfSBmcm9tICdnbG9iYWwvd2luZG93JztcbmltcG9ydCB0aHJvdHRsZSBmcm9tICdsb2Rhc2gudGhyb3R0bGUnO1xuaW1wb3J0IHN0eWxlZCBmcm9tICdzdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQge2NyZWF0ZVNlbGVjdG9yfSBmcm9tICdyZXNlbGVjdCc7XG5cbmltcG9ydCB7TWludXN9IGZyb20gJ2NvbXBvbmVudHMvY29tbW9uL2ljb25zJztcbmltcG9ydCB7U2VsZWN0VGV4dEJvbGQsIFNlbGVjdFRleHR9IGZyb20gJ2NvbXBvbmVudHMvY29tbW9uL3N0eWxlZC1jb21wb25lbnRzJztcbmltcG9ydCBSYW5nZVNsaWRlciBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9yYW5nZS1zbGlkZXInO1xuaW1wb3J0IFRpbWVTbGlkZXJNYXJrZXIgZnJvbSAnY29tcG9uZW50cy9jb21tb24vdGltZS1zbGlkZXItbWFya2VyJztcbmltcG9ydCBQbGF5YmFja0NvbnRyb2xzRmFjdG9yeSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9hbmltYXRpb24tY29udHJvbC9wbGF5YmFjay1jb250cm9scyc7XG5pbXBvcnQge0JBU0VfU1BFRUQsIERFRkFVTFRfVElNRV9GT1JNQVR9IGZyb20gJ2NvbnN0YW50cy9kZWZhdWx0LXNldHRpbmdzJztcblxuY29uc3QgYW5pbWF0aW9uQ29udHJvbFdpZHRoID0gMTQwO1xuXG5jb25zdCBTdHlsZWRTbGlkZXJDb250YWluZXIgPSBzdHlsZWQuZGl2YFxuICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcblxuICAudGltZS1yYW5nZS1zbGlkZXJfX2NvbnRyb2wge1xuICAgIG1hcmdpbi1ib3R0b206IDEycHg7XG4gICAgbWFyZ2luLXJpZ2h0OiAzMHB4O1xuICB9XG5cbiAgLnBsYXliYWNrLWNvbnRyb2wtYnV0dG9uIHtcbiAgICBwYWRkaW5nOiA5cHggMTJweDtcbiAgfVxuYDtcblxuVGltZVJhbmdlU2xpZGVyRmFjdG9yeS5kZXBzID0gW1BsYXliYWNrQ29udHJvbHNGYWN0b3J5XTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVGltZVJhbmdlU2xpZGVyRmFjdG9yeShQbGF5YmFja0NvbnRyb2xzKSB7XG4gIGNsYXNzIFRpbWVSYW5nZVNsaWRlciBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICAgIG9uQ2hhbmdlOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgZG9tYWluOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMubnVtYmVyKS5pc1JlcXVpcmVkLFxuICAgICAgdmFsdWU6IFByb3BUeXBlcy5hcnJheU9mKFByb3BUeXBlcy5udW1iZXIpLmlzUmVxdWlyZWQsXG4gICAgICBzdGVwOiBQcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWQsXG4gICAgICBwbG90VHlwZTogUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgIGhpc3RvZ3JhbTogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLmFueSksXG4gICAgICBsaW5lQ2hhcnQ6IFByb3BUeXBlcy5vYmplY3QsXG4gICAgICB0b2dnbGVBbmltYXRpb246IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICBpc0FuaW1hdGFibGU6IFByb3BUeXBlcy5ib29sLFxuICAgICAgaXNFbmxhcmdlZDogUHJvcFR5cGVzLmJvb2wsXG4gICAgICBzcGVlZDogUHJvcFR5cGVzLm51bWJlcixcbiAgICAgIHRpbWVGb3JtYXQ6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgICBoaWRlVGltZVRpdGxlOiBQcm9wVHlwZXMuYm9vbFxuICAgIH07XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgICAgc3VwZXIocHJvcHMpO1xuICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgaXNBbmltYXRpbmc6IGZhbHNlLFxuICAgICAgICB3aWR0aDogMjg4XG4gICAgICB9O1xuICAgICAgdGhpcy5fYW5pbWF0aW9uID0gbnVsbDtcbiAgICAgIHRoaXMuX3NsaWRlclRocm90dGxlID0gdGhyb3R0bGUoKC4uLnZhbHVlKSA9PiB0aGlzLnByb3BzLm9uQ2hhbmdlKC4uLnZhbHVlKSwgMjApO1xuICAgIH1cblxuICAgIGNvbXBvbmVudERpZFVwZGF0ZSgpIHtcbiAgICAgIGlmICghdGhpcy5fYW5pbWF0aW9uICYmIHRoaXMuc3RhdGUuaXNBbmltYXRpbmcpIHtcbiAgICAgICAgdGhpcy5fYW5pbWF0aW9uID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuX25leHRGcmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGltZVNlbGVjdG9yID0gcHJvcHMgPT4gcHJvcHMuY3VycmVudFRpbWU7XG4gICAgZm9ybWF0U2VsZWN0b3IgPSBwcm9wcyA9PiBwcm9wcy5mb3JtYXQ7XG4gICAgZGlzcGxheVRpbWVTZWxlY3RvciA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy50aW1lU2VsZWN0b3IsXG4gICAgICB0aGlzLmZvcm1hdFNlbGVjdG9yLFxuICAgICAgKGN1cnJlbnRUaW1lLCBmb3JtYXQpID0+IHtcbiAgICAgICAgY29uc3QgZ3JvdXBUaW1lID0gQXJyYXkuaXNBcnJheShjdXJyZW50VGltZSkgPyBjdXJyZW50VGltZSA6IFtjdXJyZW50VGltZV07XG4gICAgICAgIHJldHVybiBncm91cFRpbWUucmVkdWNlKFxuICAgICAgICAgIChhY2N1LCBjdXJyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkaXNwbGF5RGF0ZVRpbWUgPSBtb21lbnQudXRjKGN1cnIpLmZvcm1hdChmb3JtYXQpO1xuICAgICAgICAgICAgY29uc3QgW2Rpc3BsYXlEYXRlLCBkaXNwbGF5VGltZV0gPSBkaXNwbGF5RGF0ZVRpbWUuc3BsaXQoJyAnKTtcblxuICAgICAgICAgICAgaWYgKCFhY2N1LmRpc3BsYXlEYXRlLmluY2x1ZGVzKGRpc3BsYXlEYXRlKSkge1xuICAgICAgICAgICAgICBhY2N1LmRpc3BsYXlEYXRlLnB1c2goZGlzcGxheURhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWNjdS5kaXNwbGF5VGltZS5wdXNoKGRpc3BsYXlUaW1lKTtcblxuICAgICAgICAgICAgcmV0dXJuIGFjY3U7XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7ZGlzcGxheURhdGU6IFtdLCBkaXNwbGF5VGltZTogW119XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIF9zbGlkZXJVcGRhdGUgPSBhcmdzID0+IHtcbiAgICAgIHRoaXMuX3NsaWRlclRocm90dGxlLmNhbmNlbCgpO1xuICAgICAgdGhpcy5fc2xpZGVyVGhyb3R0bGUoYXJncyk7XG4gICAgfTtcblxuICAgIF9yZXNldEFuaW1hdGlvbiA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHtkb21haW4sIHZhbHVlfSA9IHRoaXMucHJvcHM7XG4gICAgICBjb25zdCB2YWx1ZTAgPSBkb21haW5bMF07XG4gICAgICBjb25zdCB2YWx1ZTEgPSB2YWx1ZTAgKyB2YWx1ZVsxXSAtIHZhbHVlWzBdO1xuICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZShbdmFsdWUwLCB2YWx1ZTFdKTtcbiAgICB9O1xuXG4gICAgX3N0YXJ0QW5pbWF0aW9uID0gKCkgPT4ge1xuICAgICAgdGhpcy5fcGF1c2VBbmltYXRpb24oKTtcbiAgICAgIHRoaXMucHJvcHMudG9nZ2xlQW5pbWF0aW9uKCk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtpc0FuaW1hdGluZzogdHJ1ZX0pO1xuICAgIH07XG5cbiAgICBfcGF1c2VBbmltYXRpb24gPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fYW5pbWF0aW9uKSB7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuX2FuaW1hdGlvbik7XG4gICAgICAgIHRoaXMucHJvcHMudG9nZ2xlQW5pbWF0aW9uKCk7XG4gICAgICAgIHRoaXMuX2FuaW1hdGlvbiA9IG51bGw7XG4gICAgICB9XG4gICAgICB0aGlzLnNldFN0YXRlKHtpc0FuaW1hdGluZzogZmFsc2V9KTtcbiAgICB9O1xuXG4gICAgX25leHRGcmFtZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2FuaW1hdGlvbiA9IG51bGw7XG5cbiAgICAgIGNvbnN0IHtkb21haW4sIHZhbHVlfSA9IHRoaXMucHJvcHM7XG4gICAgICBjb25zdCBzcGVlZCA9ICgoZG9tYWluWzFdIC0gZG9tYWluWzBdKSAvIEJBU0VfU1BFRUQpICogdGhpcy5wcm9wcy5zcGVlZDtcblxuICAgICAgLy8gbG9vcCB3aGVuIHJlYWNoZXMgdGhlIGVuZFxuICAgICAgY29uc3QgdmFsdWUwID0gdmFsdWVbMV0gKyBzcGVlZCA+IGRvbWFpblsxXSA/IGRvbWFpblswXSA6IHZhbHVlWzBdICsgc3BlZWQ7XG4gICAgICBjb25zdCB2YWx1ZTEgPSB2YWx1ZTAgKyB2YWx1ZVsxXSAtIHZhbHVlWzBdO1xuICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZShbdmFsdWUwLCB2YWx1ZTFdKTtcbiAgICB9O1xuXG4gICAgcmVuZGVyKCkge1xuICAgICAgY29uc3Qge2RvbWFpbiwgdmFsdWUsIGlzRW5sYXJnZWQsIGhpZGVUaW1lVGl0bGV9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHtpc0FuaW1hdGluZ30gPSB0aGlzLnN0YXRlO1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInRpbWUtcmFuZ2Utc2xpZGVyXCI+XG4gICAgICAgICAgeyFoaWRlVGltZVRpdGxlID8gKFxuICAgICAgICAgICAgPFRpbWVUaXRsZSB0aW1lRm9ybWF0PXt0aGlzLnByb3BzLnRpbWVGb3JtYXR9IHZhbHVlPXt2YWx1ZX0gaXNFbmxhcmdlZD17aXNFbmxhcmdlZH0gLz5cbiAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICA8U3R5bGVkU2xpZGVyQ29udGFpbmVyIGNsYXNzTmFtZT1cInRpbWUtcmFuZ2Utc2xpZGVyX19jb250YWluZXJcIiBpc0VubGFyZ2VkPXtpc0VubGFyZ2VkfT5cbiAgICAgICAgICAgIHtpc0VubGFyZ2VkID8gKFxuICAgICAgICAgICAgICA8UGxheWJhY2tDb250cm9sc1xuICAgICAgICAgICAgICAgIGlzQW5pbWF0YWJsZT17dGhpcy5wcm9wcy5pc0FuaW1hdGFibGV9XG4gICAgICAgICAgICAgICAgaXNFbmxhcmdlZD17aXNFbmxhcmdlZH1cbiAgICAgICAgICAgICAgICBpc0FuaW1hdGluZz17aXNBbmltYXRpbmd9XG4gICAgICAgICAgICAgICAgcGF1c2VBbmltYXRpb249e3RoaXMuX3BhdXNlQW5pbWF0aW9ufVxuICAgICAgICAgICAgICAgIHJlc2V0QW5pbWF0aW9uPXt0aGlzLl9yZXNldEFuaW1hdGlvbn1cbiAgICAgICAgICAgICAgICBzdGFydEFuaW1hdGlvbj17dGhpcy5fc3RhcnRBbmltYXRpb259XG4gICAgICAgICAgICAgICAgYnV0dG9uSGVpZ2h0PVwiMTJweFwiXG4gICAgICAgICAgICAgICAgYnV0dG9uU3R5bGU9XCJzZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSA6IG51bGx9XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgICAgd2lkdGg6IGlzRW5sYXJnZWQgPyBgY2FsYygxMDAlIC0gJHthbmltYXRpb25Db250cm9sV2lkdGh9cHgpYCA6ICcxMDAlJ1xuICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8UmFuZ2VTbGlkZXJcbiAgICAgICAgICAgICAgICByYW5nZT17ZG9tYWlufVxuICAgICAgICAgICAgICAgIHZhbHVlMD17dmFsdWVbMF19XG4gICAgICAgICAgICAgICAgdmFsdWUxPXt2YWx1ZVsxXX1cbiAgICAgICAgICAgICAgICBoaXN0b2dyYW09e3RoaXMucHJvcHMuaGlzdG9ncmFtfVxuICAgICAgICAgICAgICAgIGxpbmVDaGFydD17dGhpcy5wcm9wcy5saW5lQ2hhcnR9XG4gICAgICAgICAgICAgICAgcGxvdFR5cGU9e3RoaXMucHJvcHMucGxvdFR5cGV9XG4gICAgICAgICAgICAgICAgaXNFbmxhcmdlZD17aXNFbmxhcmdlZH1cbiAgICAgICAgICAgICAgICBzaG93SW5wdXQ9e2ZhbHNlfVxuICAgICAgICAgICAgICAgIHN0ZXA9e3RoaXMucHJvcHMuc3RlcH1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5fc2xpZGVyVXBkYXRlfVxuICAgICAgICAgICAgICAgIHhBeGlzPXtUaW1lU2xpZGVyTWFya2VyfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9TdHlsZWRTbGlkZXJDb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBUaW1lUmFuZ2VTbGlkZXIuZGVmYXVsdFByb3BzID0ge1xuICAgIHRpbWVGb3JtYXQ6IERFRkFVTFRfVElNRV9GT1JNQVRcbiAgfTtcblxuICByZXR1cm4gVGltZVJhbmdlU2xpZGVyO1xufVxuXG5jb25zdCBUaW1lVmFsdWVXcmFwcGVyID0gc3R5bGVkLmRpdmBcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6ICR7cHJvcHMgPT4gKHByb3BzLmlzRW5sYXJnZWQgPyAnY2VudGVyJyA6ICdzcGFjZS1iZXR3ZWVuJyl9O1xuXG4gIC5ob3Jpem9udGFsLWJhciB7XG4gICAgcGFkZGluZzogMCAxMnB4O1xuICAgIGNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLnRpdGxlVGV4dENvbG9yfTtcbiAgfVxuXG4gIC50aW1lLXZhbHVlIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiAke3Byb3BzID0+IChwcm9wcy5pc0VubGFyZ2VkID8gJ3JvdycgOiAnY29sdW1uJyl9O1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xuXG4gICAgc3BhbiB7XG4gICAgICBjb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS50aXRsZVRleHRDb2xvcn07XG4gICAgfVxuICB9XG5cbiAgLnRpbWUtdmFsdWU6bGFzdC1jaGlsZCB7XG4gICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICB9XG5gO1xuXG5jb25zdCBUaW1lVGl0bGUgPSAoe3ZhbHVlLCBpc0VubGFyZ2VkLCB0aW1lRm9ybWF0ID0gREVGQVVMVF9USU1FX0ZPUk1BVH0pID0+IChcbiAgPFRpbWVWYWx1ZVdyYXBwZXIgaXNFbmxhcmdlZD17aXNFbmxhcmdlZH0gY2xhc3NOYW1lPVwidGltZS1yYW5nZS1zbGlkZXJfX3RpbWUtdGl0bGVcIj5cbiAgICA8VGltZVZhbHVlIGtleT17MH0gdmFsdWU9e21vbWVudC51dGModmFsdWVbMF0pLmZvcm1hdCh0aW1lRm9ybWF0KX0gc3BsaXQ9eyFpc0VubGFyZ2VkfSAvPlxuICAgIHtpc0VubGFyZ2VkID8gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJob3Jpem9udGFsLWJhclwiPlxuICAgICAgICA8TWludXMgaGVpZ2h0PVwiMTJweFwiIC8+XG4gICAgICA8L2Rpdj5cbiAgICApIDogbnVsbH1cbiAgICA8VGltZVZhbHVlIGtleT17MX0gdmFsdWU9e21vbWVudC51dGModmFsdWVbMV0pLmZvcm1hdCh0aW1lRm9ybWF0KX0gc3BsaXQ9eyFpc0VubGFyZ2VkfSAvPlxuICA8L1RpbWVWYWx1ZVdyYXBwZXI+XG4pO1xuXG5jb25zdCBUaW1lVmFsdWUgPSAoe3ZhbHVlLCBzcGxpdH0pID0+IChcbiAgLy8gcmVuZGVyIHR3byBsaW5lcyBpZiBub3QgZW5sYXJnZWRcbiAgPGRpdiBjbGFzc05hbWU9XCJ0aW1lLXZhbHVlXCI+XG4gICAge3NwbGl0ID8gKFxuICAgICAgdmFsdWVcbiAgICAgICAgLnNwbGl0KCcgJylcbiAgICAgICAgLm1hcCgodiwgaSkgPT4gKFxuICAgICAgICAgIDxkaXYga2V5PXtpfT5cbiAgICAgICAgICAgIHtpID09PSAwID8gPFNlbGVjdFRleHQ+e3Z9PC9TZWxlY3RUZXh0PiA6IDxTZWxlY3RUZXh0Qm9sZD57dn08L1NlbGVjdFRleHRCb2xkPn1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKSlcbiAgICApIDogKFxuICAgICAgPFNlbGVjdFRleHRCb2xkPnt2YWx1ZX08L1NlbGVjdFRleHRCb2xkPlxuICAgICl9XG4gIDwvZGl2PlxuKTtcbiJdfQ==