UNPKG

kepler.gl

Version:

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

269 lines (263 loc) 35.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _react = require("react"); var _d3Array = require("d3-array"); var _window = require("global/window"); var _console = _interopRequireDefault(require("global/console")); var _constants = require("@kepler.gl/constants"); function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project var AnimationControllerType = /*#__PURE__*/function (_Component) { function AnimationControllerType() { (0, _classCallCheck2["default"])(this, AnimationControllerType); return _callSuper(this, AnimationControllerType, arguments); } (0, _inherits2["default"])(AnimationControllerType, _Component); return (0, _createClass2["default"])(AnimationControllerType); }(_react.Component); function AnimationControllerFactory() { /** * 4 Animation Window Types * 1. free * |-> |-> * Current time is a fixed range, animate a moving window that calls next animation frames continuously * The increment id based on domain / BASE_SPEED * SPEED * * 2. incremental * | |-> * Same as free, current time is a growing range, only the max value of range increment during animation. * The increment is also based on domain / BASE_SPEED * SPEED * * 3. point * o -> o * Current time is a point, animate a moving point calls next animation frame continuously * The increment is based on domain / BASE_SPEED * SPEED * * 4. interval * o ~> o * Current time is a point. An array of sorted time steps are provided, * animate a moving point jumps to the next step */ var AnimationController = /*#__PURE__*/function (_Component2) { function AnimationController() { var _this; (0, _classCallCheck2["default"])(this, AnimationController); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, AnimationController, [].concat(args)); (0, _defineProperty2["default"])(_this, "state", { isAnimating: false }); (0, _defineProperty2["default"])(_this, "_timer", null); (0, _defineProperty2["default"])(_this, "_startTime", 0); (0, _defineProperty2["default"])(_this, "_animate", function (delay) { _this._startTime = new Date().getTime(); var _loop = function loop() { var current = new Date().getTime(); var delta = current - _this._startTime; if (delta >= delay) { _this._nextFrame(); _this._startTime = new Date().getTime(); } else { _this._timer = (0, _window.requestAnimationFrame)(_loop); } }; _this._timer = (0, _window.requestAnimationFrame)(_loop); }); (0, _defineProperty2["default"])(_this, "_resetAnimationByDomain", function () { var _this$props = _this.props, domain = _this$props.domain, value = _this$props.value, animationWindow = _this$props.animationWindow, updateAnimation = _this$props.updateAnimation; if (!domain) { return; } // interim solution while we fully migrate filter and layer controllers var setTimelineValue = updateAnimation || _this.props.setTimelineValue; if (Array.isArray(value)) { if (animationWindow === _constants.ANIMATION_WINDOW.incremental) { setTimelineValue([value[0], value[0] + 1]); } else { setTimelineValue([domain[0], domain[0] + value[1] - value[0]]); } } else { setTimelineValue(domain[0]); } }); (0, _defineProperty2["default"])(_this, "_resetAnimationByTimeStep", function () { var _this$props2 = _this.props, _this$props2$steps = _this$props2.steps, steps = _this$props2$steps === void 0 ? null : _this$props2$steps, updateAnimation = _this$props2.updateAnimation; if (!steps) return; // interim solution while we fully migrate filter and layer controllers var setTimelineValue = updateAnimation || _this.props.setTimelineValue; // go to the first steps setTimelineValue([steps[0], 0]); }); (0, _defineProperty2["default"])(_this, "_resetAnimation", function () { if (_this.props.animationWindow === _constants.ANIMATION_WINDOW.interval) { _this._resetAnimationByTimeStep(); } else { _this._resetAnimationByDomain(); } }); (0, _defineProperty2["default"])(_this, "_startAnimation", function () { var _this$props$speed = _this.props.speed, speed = _this$props$speed === void 0 ? 1 : _this$props$speed; _this._clearTimer(); if (speed > 0) { if (_this.props.animationWindow === _constants.ANIMATION_WINDOW.interval) { // animate by interval // 30*600 var steps = _this.props.steps; if (!Array.isArray(steps) || !steps.length) { _console["default"].warn('animation steps should be an array'); return; } // when speed = 1, animation should loop through 600 frames at 60 FPS // calculate delay based on # steps var delay = _constants.BASE_SPEED * (1000 / _constants.FPS) / steps.length / (speed || 1); _this._animate(delay); } else { _this._timer = (0, _window.requestAnimationFrame)(_this._nextFrame); } } _this.setState({ isAnimating: true }); }); (0, _defineProperty2["default"])(_this, "_clearTimer", function () { if (_this._timer) { (0, _window.cancelAnimationFrame)(_this._timer); _this._timer = null; } }); (0, _defineProperty2["default"])(_this, "_pauseAnimation", function () { _this._clearTimer(); _this.setState({ isAnimating: false }); }); (0, _defineProperty2["default"])(_this, "_nextFrame", function () { _this._timer = null; var nextValue = _this.props.animationWindow === _constants.ANIMATION_WINDOW.interval ? _this._nextFrameByTimeStep() : _this._nextFrameByDomain(); // interim solution while we fully migrate filter and layer controllers var setTimelineValue = _this.props.updateAnimation || _this.props.setTimelineValue; setTimelineValue(nextValue); }); return _this; } (0, _inherits2["default"])(AnimationController, _Component2); return (0, _createClass2["default"])(AnimationController, [{ key: "componentDidMount", value: function componentDidMount() { this._startOrPauseAnimation(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this._startOrPauseAnimation(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._timer) { (0, _window.cancelAnimationFrame)(this._timer); } } }, { key: "_startOrPauseAnimation", value: function _startOrPauseAnimation() { var _this$props3 = this.props, isAnimating = _this$props3.isAnimating, _this$props3$speed = _this$props3.speed, speed = _this$props3$speed === void 0 ? 1 : _this$props3$speed; if (!this._timer && isAnimating && speed > 0) { this._startAnimation(); } else if (this._timer && !isAnimating) { this._pauseAnimation(); } } }, { key: "_nextFrameByDomain", value: function _nextFrameByDomain() { var _this$props4 = this.props, domain = _this$props4.domain, value = _this$props4.value, _this$props4$speed = _this$props4.speed, speed = _this$props4$speed === void 0 ? 1 : _this$props4$speed, _this$props4$baseSpee = _this$props4.baseSpeed, baseSpeed = _this$props4$baseSpee === void 0 ? 600 : _this$props4$baseSpee, animationWindow = _this$props4.animationWindow; if (!domain) { return; } var delta = (domain[1] - domain[0]) / baseSpeed * speed; // loop when reaches the end // current time is a range if (Array.isArray(value)) { var value0; var value1; if (animationWindow === _constants.ANIMATION_WINDOW.incremental) { var lastFrame = value[1] + delta > domain[1]; value0 = value[0]; value1 = lastFrame ? value[0] + 1 : value[1] + delta; } else { // use value[0] to display the last item duration as the first item var _lastFrame = value[0] + delta > domain[1]; value0 = _lastFrame ? domain[0] : value[0] + delta; value1 = value0 + value[1] - value[0]; } return [value0, value1]; } // current time is a point return Number(value) + delta > domain[1] ? domain[0] : Number(value) + delta; } }, { key: "_nextFrameByTimeStep", value: function _nextFrameByTimeStep() { var _this$props5 = this.props, _this$props5$steps = _this$props5.steps, steps = _this$props5$steps === void 0 ? null : _this$props5$steps, value = _this$props5.value; if (!steps) return; var val = Array.isArray(value) ? value[0] : Number(value); var index = (0, _d3Array.bisectLeft)(steps, val); var nextIdx = index >= steps.length - 1 ? 0 : index + 1; // why do we need to pass an array of two objects? are we reading nextIdx at some point? // _nextFrameByDomain only returns one value return [steps[nextIdx], nextIdx]; } }, { key: "render", value: function render() { var isAnimating = this.state.isAnimating; var children = this.props.children; return typeof children === 'function' ? children(isAnimating, this._startAnimation, this._pauseAnimation, this._resetAnimation, this.props.timeline, this.props.setTimelineValue) : null; } }]); }(_react.Component); (0, _defineProperty2["default"])(AnimationController, "defaultProps", { baseSpeed: _constants.BASE_SPEED, speed: 1, steps: null, animationWindow: _constants.ANIMATION_WINDOW.free }); return AnimationController; } var _default = exports["default"] = AnimationControllerFactory; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJyZXF1aXJlIiwiX2QzQXJyYXkiLCJfd2luZG93IiwiX2NvbnNvbGUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2NvbnN0YW50cyIsIl9jYWxsU3VwZXIiLCJ0IiwibyIsImUiLCJfZ2V0UHJvdG90eXBlT2YyIiwiX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yIiwiX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCIsIlJlZmxlY3QiLCJjb25zdHJ1Y3QiLCJjb25zdHJ1Y3RvciIsImFwcGx5IiwiQm9vbGVhbiIsInByb3RvdHlwZSIsInZhbHVlT2YiLCJjYWxsIiwiQW5pbWF0aW9uQ29udHJvbGxlclR5cGUiLCJfQ29tcG9uZW50IiwiX2NsYXNzQ2FsbENoZWNrMiIsImFyZ3VtZW50cyIsIl9pbmhlcml0czIiLCJfY3JlYXRlQ2xhc3MyIiwiQ29tcG9uZW50IiwiQW5pbWF0aW9uQ29udHJvbGxlckZhY3RvcnkiLCJBbmltYXRpb25Db250cm9sbGVyIiwiX0NvbXBvbmVudDIiLCJfdGhpcyIsIl9sZW4iLCJsZW5ndGgiLCJhcmdzIiwiQXJyYXkiLCJfa2V5IiwiY29uY2F0IiwiX2RlZmluZVByb3BlcnR5MiIsImlzQW5pbWF0aW5nIiwiZGVsYXkiLCJfc3RhcnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJsb29wIiwiY3VycmVudCIsImRlbHRhIiwiX25leHRGcmFtZSIsIl90aW1lciIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsIl90aGlzJHByb3BzIiwicHJvcHMiLCJkb21haW4iLCJ2YWx1ZSIsImFuaW1hdGlvbldpbmRvdyIsInVwZGF0ZUFuaW1hdGlvbiIsInNldFRpbWVsaW5lVmFsdWUiLCJpc0FycmF5IiwiQU5JTUFUSU9OX1dJTkRPVyIsImluY3JlbWVudGFsIiwiX3RoaXMkcHJvcHMyIiwiX3RoaXMkcHJvcHMyJHN0ZXBzIiwic3RlcHMiLCJpbnRlcnZhbCIsIl9yZXNldEFuaW1hdGlvbkJ5VGltZVN0ZXAiLCJfcmVzZXRBbmltYXRpb25CeURvbWFpbiIsIl90aGlzJHByb3BzJHNwZWVkIiwic3BlZWQiLCJfY2xlYXJUaW1lciIsIkNvbnNvbGUiLCJ3YXJuIiwiQkFTRV9TUEVFRCIsIkZQUyIsIl9hbmltYXRlIiwic2V0U3RhdGUiLCJjYW5jZWxBbmltYXRpb25GcmFtZSIsIm5leHRWYWx1ZSIsIl9uZXh0RnJhbWVCeVRpbWVTdGVwIiwiX25leHRGcmFtZUJ5RG9tYWluIiwia2V5IiwiY29tcG9uZW50RGlkTW91bnQiLCJfc3RhcnRPclBhdXNlQW5pbWF0aW9uIiwiY29tcG9uZW50RGlkVXBkYXRlIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJfdGhpcyRwcm9wczMiLCJfdGhpcyRwcm9wczMkc3BlZWQiLCJfc3RhcnRBbmltYXRpb24iLCJfcGF1c2VBbmltYXRpb24iLCJfdGhpcyRwcm9wczQiLCJfdGhpcyRwcm9wczQkc3BlZWQiLCJfdGhpcyRwcm9wczQkYmFzZVNwZWUiLCJiYXNlU3BlZWQiLCJ2YWx1ZTAiLCJ2YWx1ZTEiLCJsYXN0RnJhbWUiLCJOdW1iZXIiLCJfdGhpcyRwcm9wczUiLCJfdGhpcyRwcm9wczUkc3RlcHMiLCJ2YWwiLCJpbmRleCIsImJpc2VjdExlZnQiLCJuZXh0SWR4IiwicmVuZGVyIiwic3RhdGUiLCJjaGlsZHJlbiIsIl9yZXNldEFuaW1hdGlvbiIsInRpbWVsaW5lIiwiZnJlZSIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tb24vYW5pbWF0aW9uLWNvbnRyb2wvYW5pbWF0aW9uLWNvbnRyb2xsZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IFJlYWN0LCB7Q29tcG9uZW50fSBmcm9tICdyZWFjdCc7XG5pbXBvcnQge2Jpc2VjdExlZnR9IGZyb20gJ2QzLWFycmF5JztcbmltcG9ydCB7cmVxdWVzdEFuaW1hdGlvbkZyYW1lLCBjYW5jZWxBbmltYXRpb25GcmFtZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQgQ29uc29sZSBmcm9tICdnbG9iYWwvY29uc29sZSc7XG5pbXBvcnQge0JBU0VfU1BFRUQsIEZQUywgQU5JTUFUSU9OX1dJTkRPV30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtUaW1lbGluZX0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5cbmludGVyZmFjZSBBbmltYXRpb25Db250cm9sbGVyUHJvcHM8VCBleHRlbmRzIG51bWJlciB8IG51bWJlcltdPiB7XG4gIGlzQW5pbWF0aW5nPzogYm9vbGVhbjtcbiAgc3BlZWQ/OiBudW1iZXI7XG4gIHVwZGF0ZUFuaW1hdGlvbj86ICh4OiBUKSA9PiB2b2lkO1xuICBzZXRUaW1lbGluZVZhbHVlOiAoeDogVCkgPT4gdm9pZDtcbiAgdGltZWxpbmU/OiBUaW1lbGluZTtcbiAgYW5pbWF0aW9uV2luZG93Pzogc3RyaW5nO1xuICBzdGVwcz86IG51bWJlcltdIHwgbnVsbDtcbiAgZG9tYWluOiBudW1iZXJbXSB8IG51bGw7XG4gIHZhbHVlOiBUO1xuICBiYXNlU3BlZWQ/OiBudW1iZXI7XG4gIGNoaWxkcmVuPzogKFxuICAgIGlzQW5pbWF0aW5nOiBib29sZWFuIHwgdW5kZWZpbmVkLFxuICAgIHN0YXJ0QW5pbWF0aW9uOiAoKSA9PiB2b2lkLFxuICAgIHBhdXNlQW5pbWF0aW9uOiAoKSA9PiB2b2lkLFxuICAgIHJlc2V0QW5pbWF0aW9uOiAoKSA9PiB2b2lkLFxuICAgIHRpbWVsaW5lOiBUaW1lbGluZSB8IHVuZGVmaW5lZCxcbiAgICBzZXRUaW1lbGluZVZhbHVlOiAoeDogVCkgPT4gdm9pZFxuICApID0+IFJlYWN0LlJlYWN0RWxlbWVudCB8IG51bGw7XG59XG5cbmNsYXNzIEFuaW1hdGlvbkNvbnRyb2xsZXJUeXBlPFQgZXh0ZW5kcyBudW1iZXIgfCBudW1iZXJbXT4gZXh0ZW5kcyBDb21wb25lbnQ8XG4gIEFuaW1hdGlvbkNvbnRyb2xsZXJQcm9wczxUPlxuPiB7fVxuXG5mdW5jdGlvbiBBbmltYXRpb25Db250cm9sbGVyRmFjdG9yeSgpOiB0eXBlb2YgQW5pbWF0aW9uQ29udHJvbGxlclR5cGUge1xuICAvKipcbiAgICogNCBBbmltYXRpb24gV2luZG93IFR5cGVzXG4gICAqIDEuIGZyZWVcbiAgICogIHwtPiAgfC0+XG4gICAqIEN1cnJlbnQgdGltZSBpcyBhIGZpeGVkIHJhbmdlLCBhbmltYXRlIGEgbW92aW5nIHdpbmRvdyB0aGF0IGNhbGxzIG5leHQgYW5pbWF0aW9uIGZyYW1lcyBjb250aW51b3VzbHlcbiAgICogVGhlIGluY3JlbWVudCBpZCBiYXNlZCBvbiBkb21haW4gLyBCQVNFX1NQRUVEICogU1BFRURcbiAgICpcbiAgICogMi4gaW5jcmVtZW50YWxcbiAgICogfCAgICB8LT5cbiAgICogU2FtZSBhcyBmcmVlLCBjdXJyZW50IHRpbWUgaXMgYSBncm93aW5nIHJhbmdlLCBvbmx5IHRoZSBtYXggdmFsdWUgb2YgcmFuZ2UgaW5jcmVtZW50IGR1cmluZyBhbmltYXRpb24uXG4gICAqIFRoZSBpbmNyZW1lbnQgaXMgYWxzbyBiYXNlZCBvbiBkb21haW4gLyBCQVNFX1NQRUVEICogU1BFRURcbiAgICpcbiAgICogMy4gcG9pbnRcbiAgICogbyAtPiBvXG4gICAqIEN1cnJlbnQgdGltZSBpcyBhIHBvaW50LCBhbmltYXRlIGEgbW92aW5nIHBvaW50IGNhbGxzIG5leHQgYW5pbWF0aW9uIGZyYW1lIGNvbnRpbnVvdXNseVxuICAgKiBUaGUgaW5jcmVtZW50IGlzIGJhc2VkIG9uIGRvbWFpbiAvIEJBU0VfU1BFRUQgKiBTUEVFRFxuICAgKlxuICAgKiA0LiBpbnRlcnZhbFxuICAgKiBvIH4+IG9cbiAgICogQ3VycmVudCB0aW1lIGlzIGEgcG9pbnQuIEFuIGFycmF5IG9mIHNvcnRlZCB0aW1lIHN0ZXBzIGFyZSBwcm92aWRlZCxcbiAgICogYW5pbWF0ZSBhIG1vdmluZyBwb2ludCBqdW1wcyB0byB0aGUgbmV4dCBzdGVwXG4gICAqL1xuICBjbGFzcyBBbmltYXRpb25Db250cm9sbGVyPFQgZXh0ZW5kcyBudW1iZXIgfCBudW1iZXJbXT4gZXh0ZW5kcyBDb21wb25lbnQ8XG4gICAgQW5pbWF0aW9uQ29udHJvbGxlclByb3BzPFQ+XG4gID4ge1xuICAgIHN0YXRpYyBkZWZhdWx0UHJvcHMgPSB7XG4gICAgICBiYXNlU3BlZWQ6IEJBU0VfU1BFRUQsXG4gICAgICBzcGVlZDogMSxcbiAgICAgIHN0ZXBzOiBudWxsLFxuICAgICAgYW5pbWF0aW9uV2luZG93OiBBTklNQVRJT05fV0lORE9XLmZyZWVcbiAgICB9O1xuXG4gICAgc3RhdGUgPSB7XG4gICAgICBpc0FuaW1hdGluZzogZmFsc2VcbiAgICB9O1xuXG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICB0aGlzLl9zdGFydE9yUGF1c2VBbmltYXRpb24oKTtcbiAgICB9XG5cbiAgICBjb21wb25lbnREaWRVcGRhdGUoKSB7XG4gICAgICB0aGlzLl9zdGFydE9yUGF1c2VBbmltYXRpb24oKTtcbiAgICB9XG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgIGlmICh0aGlzLl90aW1lcikge1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLl90aW1lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX3RpbWVyID0gbnVsbDtcbiAgICBfc3RhcnRUaW1lID0gMDtcblxuICAgIF9zdGFydE9yUGF1c2VBbmltYXRpb24oKSB7XG4gICAgICBjb25zdCB7aXNBbmltYXRpbmcsIHNwZWVkID0gMX0gPSB0aGlzLnByb3BzO1xuICAgICAgaWYgKCF0aGlzLl90aW1lciAmJiBpc0FuaW1hdGluZyAmJiBzcGVlZCA+IDApIHtcbiAgICAgICAgdGhpcy5fc3RhcnRBbmltYXRpb24oKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fdGltZXIgJiYgIWlzQW5pbWF0aW5nKSB7XG4gICAgICAgIHRoaXMuX3BhdXNlQW5pbWF0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2FuaW1hdGUgPSBkZWxheSA9PiB7XG4gICAgICB0aGlzLl9zdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgY29uc3QgbG9vcCA9ICgpID0+IHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBkZWx0YSA9IGN1cnJlbnQgLSB0aGlzLl9zdGFydFRpbWU7XG5cbiAgICAgICAgaWYgKGRlbHRhID49IGRlbGF5KSB7XG4gICAgICAgICAgdGhpcy5fbmV4dEZyYW1lKCk7XG4gICAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fdGltZXIgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobG9vcCk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX3RpbWVyID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGxvb3ApO1xuICAgIH07XG5cbiAgICBfcmVzZXRBbmltYXRpb25CeURvbWFpbiA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHtkb21haW4sIHZhbHVlLCBhbmltYXRpb25XaW5kb3csIHVwZGF0ZUFuaW1hdGlvbn0gPSB0aGlzLnByb3BzO1xuICAgICAgaWYgKCFkb21haW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gaW50ZXJpbSBzb2x1dGlvbiB3aGlsZSB3ZSBmdWxseSBtaWdyYXRlIGZpbHRlciBhbmQgbGF5ZXIgY29udHJvbGxlcnNcbiAgICAgIGNvbnN0IHNldFRpbWVsaW5lVmFsdWUgPSB1cGRhdGVBbmltYXRpb24gfHwgdGhpcy5wcm9wcy5zZXRUaW1lbGluZVZhbHVlO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgaWYgKGFuaW1hdGlvbldpbmRvdyA9PT0gQU5JTUFUSU9OX1dJTkRPVy5pbmNyZW1lbnRhbCkge1xuICAgICAgICAgIHNldFRpbWVsaW5lVmFsdWUoW3ZhbHVlWzBdLCB2YWx1ZVswXSArIDFdIGFzIFQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldFRpbWVsaW5lVmFsdWUoW2RvbWFpblswXSwgZG9tYWluWzBdICsgdmFsdWVbMV0gLSB2YWx1ZVswXV0gYXMgVCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVsaW5lVmFsdWUoZG9tYWluWzBdIGFzIFQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBfcmVzZXRBbmltYXRpb25CeVRpbWVTdGVwID0gKCkgPT4ge1xuICAgICAgY29uc3Qge3N0ZXBzID0gbnVsbCwgdXBkYXRlQW5pbWF0aW9ufSA9IHRoaXMucHJvcHM7XG4gICAgICBpZiAoIXN0ZXBzKSByZXR1cm47XG4gICAgICAvLyBpbnRlcmltIHNvbHV0aW9uIHdoaWxlIHdlIGZ1bGx5IG1pZ3JhdGUgZmlsdGVyIGFuZCBsYXllciBjb250cm9sbGVyc1xuICAgICAgY29uc3Qgc2V0VGltZWxpbmVWYWx1ZSA9IHVwZGF0ZUFuaW1hdGlvbiB8fCB0aGlzLnByb3BzLnNldFRpbWVsaW5lVmFsdWU7XG5cbiAgICAgIC8vIGdvIHRvIHRoZSBmaXJzdCBzdGVwc1xuICAgICAgc2V0VGltZWxpbmVWYWx1ZShbc3RlcHNbMF0sIDBdIGFzIFQpO1xuICAgIH07XG5cbiAgICBfcmVzZXRBbmltYXRpb24gPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wcm9wcy5hbmltYXRpb25XaW5kb3cgPT09IEFOSU1BVElPTl9XSU5ET1cuaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fcmVzZXRBbmltYXRpb25CeVRpbWVTdGVwKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9yZXNldEFuaW1hdGlvbkJ5RG9tYWluKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIF9zdGFydEFuaW1hdGlvbiA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHtzcGVlZCA9IDF9ID0gdGhpcy5wcm9wcztcbiAgICAgIHRoaXMuX2NsZWFyVGltZXIoKTtcbiAgICAgIGlmIChzcGVlZCA+IDApIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuYW5pbWF0aW9uV2luZG93ID09PSBBTklNQVRJT05fV0lORE9XLmludGVydmFsKSB7XG4gICAgICAgICAgLy8gYW5pbWF0ZSBieSBpbnRlcnZhbFxuICAgICAgICAgIC8vIDMwKjYwMFxuICAgICAgICAgIGNvbnN0IHtzdGVwc30gPSB0aGlzLnByb3BzO1xuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzdGVwcykgfHwgIXN0ZXBzLmxlbmd0aCkge1xuICAgICAgICAgICAgQ29uc29sZS53YXJuKCdhbmltYXRpb24gc3RlcHMgc2hvdWxkIGJlIGFuIGFycmF5Jyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdoZW4gc3BlZWQgPSAxLCBhbmltYXRpb24gc2hvdWxkIGxvb3AgdGhyb3VnaCA2MDAgZnJhbWVzIGF0IDYwIEZQU1xuICAgICAgICAgIC8vIGNhbGN1bGF0ZSBkZWxheSBiYXNlZCBvbiAjIHN0ZXBzXG4gICAgICAgICAgY29uc3QgZGVsYXkgPSAoQkFTRV9TUEVFRCAqICgxMDAwIC8gRlBTKSkgLyBzdGVwcy5sZW5ndGggLyAoc3BlZWQgfHwgMSk7XG4gICAgICAgICAgdGhpcy5fYW5pbWF0ZShkZWxheSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fdGltZXIgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fbmV4dEZyYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5zZXRTdGF0ZSh7aXNBbmltYXRpbmc6IHRydWV9KTtcbiAgICB9O1xuXG4gICAgX2NsZWFyVGltZXIgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fdGltZXIpIHtcbiAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5fdGltZXIpO1xuICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XG4gICAgICB9XG4gICAgfTtcblxuICAgIF9wYXVzZUFuaW1hdGlvbiA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2NsZWFyVGltZXIoKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe2lzQW5pbWF0aW5nOiBmYWxzZX0pO1xuICAgIH07XG5cbiAgICBfbmV4dEZyYW1lID0gKCkgPT4ge1xuICAgICAgdGhpcy5fdGltZXIgPSBudWxsO1xuICAgICAgY29uc3QgbmV4dFZhbHVlID1cbiAgICAgICAgdGhpcy5wcm9wcy5hbmltYXRpb25XaW5kb3cgPT09IEFOSU1BVElPTl9XSU5ET1cuaW50ZXJ2YWxcbiAgICAgICAgICA/IHRoaXMuX25leHRGcmFtZUJ5VGltZVN0ZXAoKVxuICAgICAgICAgIDogdGhpcy5fbmV4dEZyYW1lQnlEb21haW4oKTtcblxuICAgICAgLy8gaW50ZXJpbSBzb2x1dGlvbiB3aGlsZSB3ZSBmdWxseSBtaWdyYXRlIGZpbHRlciBhbmQgbGF5ZXIgY29udHJvbGxlcnNcbiAgICAgIGNvbnN0IHNldFRpbWVsaW5lVmFsdWUgPSB0aGlzLnByb3BzLnVwZGF0ZUFuaW1hdGlvbiB8fCB0aGlzLnByb3BzLnNldFRpbWVsaW5lVmFsdWU7XG4gICAgICBzZXRUaW1lbGluZVZhbHVlKG5leHRWYWx1ZSBhcyBUKTtcbiAgICB9O1xuXG4gICAgX25leHRGcmFtZUJ5RG9tYWluKCkge1xuICAgICAgY29uc3Qge2RvbWFpbiwgdmFsdWUsIHNwZWVkID0gMSwgYmFzZVNwZWVkID0gNjAwLCBhbmltYXRpb25XaW5kb3d9ID0gdGhpcy5wcm9wcztcbiAgICAgIGlmICghZG9tYWluKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlbHRhID0gKChkb21haW5bMV0gLSBkb21haW5bMF0pIC8gYmFzZVNwZWVkKSAqIHNwZWVkO1xuXG4gICAgICAvLyBsb29wIHdoZW4gcmVhY2hlcyB0aGUgZW5kXG4gICAgICAvLyBjdXJyZW50IHRpbWUgaXMgYSByYW5nZVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGxldCB2YWx1ZTA6IG51bWJlcjtcbiAgICAgICAgbGV0IHZhbHVlMTogbnVtYmVyO1xuICAgICAgICBpZiAoYW5pbWF0aW9uV2luZG93ID09PSBBTklNQVRJT05fV0lORE9XLmluY3JlbWVudGFsKSB7XG4gICAgICAgICAgY29uc3QgbGFzdEZyYW1lID0gdmFsdWVbMV0gKyBkZWx0YSA+IGRvbWFpblsxXTtcbiAgICAgICAgICB2YWx1ZTAgPSB2YWx1ZVswXTtcbiAgICAgICAgICB2YWx1ZTEgPSBsYXN0RnJhbWUgPyB2YWx1ZVswXSArIDEgOiB2YWx1ZVsxXSArIGRlbHRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHVzZSB2YWx1ZVswXSB0byBkaXNwbGF5IHRoZSBsYXN0IGl0ZW0gIGR1cmF0aW9uIGFzIHRoZSBmaXJzdCBpdGVtXG4gICAgICAgICAgY29uc3QgbGFzdEZyYW1lID0gdmFsdWVbMF0gKyBkZWx0YSA+IGRvbWFpblsxXTtcbiAgICAgICAgICB2YWx1ZTAgPSBsYXN0RnJhbWUgPyBkb21haW5bMF0gOiB2YWx1ZVswXSArIGRlbHRhO1xuICAgICAgICAgIHZhbHVlMSA9IHZhbHVlMCArIHZhbHVlWzFdIC0gdmFsdWVbMF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFt2YWx1ZTAsIHZhbHVlMV07XG4gICAgICB9XG5cbiAgICAgIC8vIGN1cnJlbnQgdGltZSBpcyBhIHBvaW50XG4gICAgICByZXR1cm4gTnVtYmVyKHZhbHVlKSArIGRlbHRhID4gZG9tYWluWzFdID8gZG9tYWluWzBdIDogTnVtYmVyKHZhbHVlKSArIGRlbHRhO1xuICAgIH1cblxuICAgIF9uZXh0RnJhbWVCeVRpbWVTdGVwKCkge1xuICAgICAgY29uc3Qge3N0ZXBzID0gbnVsbCwgdmFsdWV9ID0gdGhpcy5wcm9wcztcbiAgICAgIGlmICghc3RlcHMpIHJldHVybjtcbiAgICAgIGNvbnN0IHZhbCA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWVbMF0gOiBOdW1iZXIodmFsdWUpO1xuICAgICAgY29uc3QgaW5kZXggPSBiaXNlY3RMZWZ0KHN0ZXBzLCB2YWwpO1xuICAgICAgY29uc3QgbmV4dElkeCA9IGluZGV4ID49IHN0ZXBzLmxlbmd0aCAtIDEgPyAwIDogaW5kZXggKyAxO1xuXG4gICAgICAvLyB3aHkgZG8gd2UgbmVlZCB0byBwYXNzIGFuIGFycmF5IG9mIHR3byBvYmplY3RzPyBhcmUgd2UgcmVhZGluZyBuZXh0SWR4IGF0IHNvbWUgcG9pbnQ/XG4gICAgICAvLyBfbmV4dEZyYW1lQnlEb21haW4gb25seSByZXR1cm5zIG9uZSB2YWx1ZVxuICAgICAgcmV0dXJuIFtzdGVwc1tuZXh0SWR4XSwgbmV4dElkeF07XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgY29uc3Qge2lzQW5pbWF0aW5nfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCB7Y2hpbGRyZW59ID0gdGhpcy5wcm9wcztcblxuICAgICAgcmV0dXJuIHR5cGVvZiBjaGlsZHJlbiA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IGNoaWxkcmVuKFxuICAgICAgICAgICAgaXNBbmltYXRpbmcsXG4gICAgICAgICAgICB0aGlzLl9zdGFydEFuaW1hdGlvbixcbiAgICAgICAgICAgIHRoaXMuX3BhdXNlQW5pbWF0aW9uLFxuICAgICAgICAgICAgdGhpcy5fcmVzZXRBbmltYXRpb24sXG4gICAgICAgICAgICB0aGlzLnByb3BzLnRpbWVsaW5lLFxuICAgICAgICAgICAgdGhpcy5wcm9wcy5zZXRUaW1lbGluZVZhbHVlXG4gICAgICAgICAgKVxuICAgICAgICA6IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEFuaW1hdGlvbkNvbnRyb2xsZXI7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuaW1hdGlvbkNvbnRyb2xsZXJGYWN0b3J5O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBR0EsSUFBQUEsTUFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsUUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsT0FBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsUUFBQSxHQUFBQyxzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQUssVUFBQSxHQUFBTCxPQUFBO0FBQXVFLFNBQUFNLFdBQUFDLENBQUEsRUFBQUMsQ0FBQSxFQUFBQyxDQUFBLFdBQUFELENBQUEsT0FBQUUsZ0JBQUEsYUFBQUYsQ0FBQSxPQUFBRywyQkFBQSxhQUFBSixDQUFBLEVBQUFLLHlCQUFBLEtBQUFDLE9BQUEsQ0FBQUMsU0FBQSxDQUFBTixDQUFBLEVBQUFDLENBQUEsWUFBQUMsZ0JBQUEsYUFBQUgsQ0FBQSxFQUFBUSxXQUFBLElBQUFQLENBQUEsQ0FBQVEsS0FBQSxDQUFBVCxDQUFBLEVBQUFFLENBQUE7QUFBQSxTQUFBRywwQkFBQSxjQUFBTCxDQUFBLElBQUFVLE9BQUEsQ0FBQUMsU0FBQSxDQUFBQyxPQUFBLENBQUFDLElBQUEsQ0FBQVAsT0FBQSxDQUFBQyxTQUFBLENBQUFHLE9BQUEsaUNBQUFWLENBQUEsYUFBQUsseUJBQUEsWUFBQUEsMEJBQUEsYUFBQUwsQ0FBQSxVQVB2RTtBQUNBO0FBQUEsSUE4Qk1jLHVCQUF1QiwwQkFBQUMsVUFBQTtFQUFBLFNBQUFELHdCQUFBO0lBQUEsSUFBQUUsZ0JBQUEsbUJBQUFGLHVCQUFBO0lBQUEsT0FBQWYsVUFBQSxPQUFBZSx1QkFBQSxFQUFBRyxTQUFBO0VBQUE7RUFBQSxJQUFBQyxVQUFBLGFBQUFKLHVCQUFBLEVBQUFDLFVBQUE7RUFBQSxXQUFBSSxhQUFBLGFBQUFMLHVCQUFBO0FBQUEsRUFBc0NNLGdCQUFTO0FBSTVFLFNBQVNDLDBCQUEwQkEsQ0FBQSxFQUFtQztFQUNwRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQXJCRSxJQXNCTUMsbUJBQW1CLDBCQUFBQyxXQUFBO0lBQUEsU0FBQUQsb0JBQUE7TUFBQSxJQUFBRSxLQUFBO01BQUEsSUFBQVIsZ0JBQUEsbUJBQUFNLG1CQUFBO01BQUEsU0FBQUcsSUFBQSxHQUFBUixTQUFBLENBQUFTLE1BQUEsRUFBQUMsSUFBQSxPQUFBQyxLQUFBLENBQUFILElBQUEsR0FBQUksSUFBQSxNQUFBQSxJQUFBLEdBQUFKLElBQUEsRUFBQUksSUFBQTtRQUFBRixJQUFBLENBQUFFLElBQUEsSUFBQVosU0FBQSxDQUFBWSxJQUFBO01BQUE7TUFBQUwsS0FBQSxHQUFBekIsVUFBQSxPQUFBdUIsbUJBQUEsS0FBQVEsTUFBQSxDQUFBSCxJQUFBO01BQUEsSUFBQUksZ0JBQUEsYUFBQVAsS0FBQSxXQVVmO1FBQ05RLFdBQVcsRUFBRTtNQUNmLENBQUM7TUFBQSxJQUFBRCxnQkFBQSxhQUFBUCxLQUFBLFlBZ0JRLElBQUk7TUFBQSxJQUFBTyxnQkFBQSxhQUFBUCxLQUFBLGdCQUNBLENBQUM7TUFBQSxJQUFBTyxnQkFBQSxhQUFBUCxLQUFBLGNBV0gsVUFBQVMsS0FBSyxFQUFJO1FBQ2xCVCxLQUFBLENBQUtVLFVBQVUsR0FBRyxJQUFJQyxJQUFJLENBQUMsQ0FBQyxDQUFDQyxPQUFPLENBQUMsQ0FBQztRQUV0QyxJQUFNQyxLQUFJLEdBQUcsU0FBUEEsSUFBSUEsQ0FBQSxFQUFTO1VBQ2pCLElBQU1DLE9BQU8sR0FBRyxJQUFJSCxJQUFJLENBQUMsQ0FBQyxDQUFDQyxPQUFPLENBQUMsQ0FBQztVQUNwQyxJQUFNRyxLQUFLLEdBQUdELE9BQU8sR0FBR2QsS0FBQSxDQUFLVSxVQUFVO1VBRXZDLElBQUlLLEtBQUssSUFBSU4sS0FBSyxFQUFFO1lBQ2xCVCxLQUFBLENBQUtnQixVQUFVLENBQUMsQ0FBQztZQUNqQmhCLEtBQUEsQ0FBS1UsVUFBVSxHQUFHLElBQUlDLElBQUksQ0FBQyxDQUFDLENBQUNDLE9BQU8sQ0FBQyxDQUFDO1VBQ3hDLENBQUMsTUFBTTtZQUNMWixLQUFBLENBQUtpQixNQUFNLEdBQUcsSUFBQUMsNkJBQXFCLEVBQUNMLEtBQUksQ0FBQztVQUMzQztRQUNGLENBQUM7UUFFRGIsS0FBQSxDQUFLaUIsTUFBTSxHQUFHLElBQUFDLDZCQUFxQixFQUFDTCxLQUFJLENBQUM7TUFDM0MsQ0FBQztNQUFBLElBQUFOLGdCQUFBLGFBQUFQLEtBQUEsNkJBRXlCLFlBQU07UUFDOUIsSUFBQW1CLFdBQUEsR0FBMERuQixLQUFBLENBQUtvQixLQUFLO1VBQTdEQyxNQUFNLEdBQUFGLFdBQUEsQ0FBTkUsTUFBTTtVQUFFQyxLQUFLLEdBQUFILFdBQUEsQ0FBTEcsS0FBSztVQUFFQyxlQUFlLEdBQUFKLFdBQUEsQ0FBZkksZUFBZTtVQUFFQyxlQUFlLEdBQUFMLFdBQUEsQ0FBZkssZUFBZTtRQUN0RCxJQUFJLENBQUNILE1BQU0sRUFBRTtVQUNYO1FBQ0Y7UUFDQTtRQUNBLElBQU1JLGdCQUFnQixHQUFHRCxlQUFlLElBQUl4QixLQUFBLENBQUtvQixLQUFLLENBQUNLLGdCQUFnQjtRQUV2RSxJQUFJckIsS0FBSyxDQUFDc0IsT0FBTyxDQUFDSixLQUFLLENBQUMsRUFBRTtVQUN4QixJQUFJQyxlQUFlLEtBQUtJLDJCQUFnQixDQUFDQyxXQUFXLEVBQUU7WUFDcERILGdCQUFnQixDQUFDLENBQUNILEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRUEsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBTSxDQUFDO1VBQ2pELENBQUMsTUFBTTtZQUNMRyxnQkFBZ0IsQ0FBQyxDQUFDSixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUVBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBR0MsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHQSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQU0sQ0FBQztVQUNyRTtRQUNGLENBQUMsTUFBTTtVQUNMRyxnQkFBZ0IsQ0FBQ0osTUFBTSxDQUFDLENBQUMsQ0FBTSxDQUFDO1FBQ2xDO01BQ0YsQ0FBQztNQUFBLElBQUFkLGdCQUFBLGFBQUFQLEtBQUEsK0JBRTJCLFlBQU07UUFDaEMsSUFBQTZCLFlBQUEsR0FBd0M3QixLQUFBLENBQUtvQixLQUFLO1VBQUFVLGtCQUFBLEdBQUFELFlBQUEsQ0FBM0NFLEtBQUs7VUFBTEEsS0FBSyxHQUFBRCxrQkFBQSxjQUFHLElBQUksR0FBQUEsa0JBQUE7VUFBRU4sZUFBZSxHQUFBSyxZQUFBLENBQWZMLGVBQWU7UUFDcEMsSUFBSSxDQUFDTyxLQUFLLEVBQUU7UUFDWjtRQUNBLElBQU1OLGdCQUFnQixHQUFHRCxlQUFlLElBQUl4QixLQUFBLENBQUtvQixLQUFLLENBQUNLLGdCQUFnQjs7UUFFdkU7UUFDQUEsZ0JBQWdCLENBQUMsQ0FBQ00sS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBTSxDQUFDO01BQ3RDLENBQUM7TUFBQSxJQUFBeEIsZ0JBQUEsYUFBQVAsS0FBQSxxQkFFaUIsWUFBTTtRQUN0QixJQUFJQSxLQUFBLENBQUtvQixLQUFLLENBQUNHLGVBQWUsS0FBS0ksMkJBQWdCLENBQUNLLFFBQVEsRUFBRTtVQUM1RGhDLEtBQUEsQ0FBS2lDLHlCQUF5QixDQUFDLENBQUM7UUFDbEMsQ0FBQyxNQUFNO1VBQ0xqQyxLQUFBLENBQUtrQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ2hDO01BQ0YsQ0FBQztNQUFBLElBQUEzQixnQkFBQSxhQUFBUCxLQUFBLHFCQUVpQixZQUFNO1FBQ3RCLElBQUFtQyxpQkFBQSxHQUFvQm5DLEtBQUEsQ0FBS29CLEtBQUssQ0FBdkJnQixLQUFLO1VBQUxBLEtBQUssR0FBQUQsaUJBQUEsY0FBRyxDQUFDLEdBQUFBLGlCQUFBO1FBQ2hCbkMsS0FBQSxDQUFLcUMsV0FBVyxDQUFDLENBQUM7UUFDbEIsSUFBSUQsS0FBSyxHQUFHLENBQUMsRUFBRTtVQUNiLElBQUlwQyxLQUFBLENBQUtvQixLQUFLLENBQUNHLGVBQWUsS0FBS0ksMkJBQWdCLENBQUNLLFFBQVEsRUFBRTtZQUM1RDtZQUNBO1lBQ0EsSUFBT0QsS0FBSyxHQUFJL0IsS0FBQSxDQUFLb0IsS0FBSyxDQUFuQlcsS0FBSztZQUNaLElBQUksQ0FBQzNCLEtBQUssQ0FBQ3NCLE9BQU8sQ0FBQ0ssS0FBSyxDQUFDLElBQUksQ0FBQ0EsS0FBSyxDQUFDN0IsTUFBTSxFQUFFO2NBQzFDb0MsbUJBQU8sQ0FBQ0MsSUFBSSxDQUFDLG9DQUFvQyxDQUFDO2NBQ2xEO1lBQ0Y7WUFDQTtZQUNBO1lBQ0EsSUFBTTlCLEtBQUssR0FBSStCLHFCQUFVLElBQUksSUFBSSxHQUFHQyxjQUFHLENBQUMsR0FBSVYsS0FBSyxDQUFDN0IsTUFBTSxJQUFJa0MsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUN2RXBDLEtBQUEsQ0FBSzBDLFFBQVEsQ0FBQ2pDLEtBQUssQ0FBQztVQUN0QixDQUFDLE1BQU07WUFDTFQsS0FBQSxDQUFLaUIsTUFBTSxHQUFHLElBQUFDLDZCQUFxQixFQUFDbEIsS0FBQSxDQUFLZ0IsVUFBVSxDQUFDO1VBQ3REO1FBQ0Y7UUFDQWhCLEtBQUEsQ0FBSzJDLFFBQVEsQ0FBQztVQUFDbkMsV0FBVyxFQUFFO1FBQUksQ0FBQyxDQUFDO01BQ3BDLENBQUM7TUFBQSxJQUFBRCxnQkFBQSxhQUFBUCxLQUFBLGlCQUVhLFlBQU07UUFDbEIsSUFBSUEsS0FBQSxDQUFLaUIsTUFBTSxFQUFFO1VBQ2YsSUFBQTJCLDRCQUFvQixFQUFDNUMsS0FBQSxDQUFLaUIsTUFBTSxDQUFDO1VBQ2pDakIsS0FBQSxDQUFLaUIsTUFBTSxHQUFHLElBQUk7UUFDcEI7TUFDRixDQUFDO01BQUEsSUFBQVYsZ0JBQUEsYUFBQVAsS0FBQSxxQkFFaUIsWUFBTTtRQUN0QkEsS0FBQSxDQUFLcUMsV0FBVyxDQUFDLENBQUM7UUFDbEJyQyxLQUFBLENBQUsyQyxRQUFRLENBQUM7VUFBQ25DLFdBQVcsRUFBRTtRQUFLLENBQUMsQ0FBQztNQUNyQyxDQUFDO01BQUEsSUFBQUQsZ0JBQUEsYUFBQVAsS0FBQSxnQkFFWSxZQUFNO1FBQ2pCQSxLQUFBLENBQUtpQixNQUFNLEdBQUcsSUFBSTtRQUNsQixJQUFNNEIsU0FBUyxHQUNiN0MsS0FBQSxDQUFLb0IsS0FBSyxDQUFDRyxlQUFlLEtBQUtJLDJCQUFnQixDQUFDSyxRQUFRLEdBQ3BEaEMsS0FBQSxDQUFLOEMsb0JBQW9CLENBQUMsQ0FBQyxHQUMzQjlDLEtBQUEsQ0FBSytDLGtCQUFrQixDQUFDLENBQUM7O1FBRS9CO1FBQ0EsSUFBTXRCLGdCQUFnQixHQUFHekIsS0FBQSxDQUFLb0IsS0FBSyxDQUFDSSxlQUFlLElBQUl4QixLQUFBLENBQUtvQixLQUFLLENBQUNLLGdCQUFnQjtRQUNsRkEsZ0JBQWdCLENBQUNvQixTQUFjLENBQUM7TUFDbEMsQ0FBQztNQUFBLE9BQUE3QyxLQUFBO0lBQUE7SUFBQSxJQUFBTixVQUFBLGFBQUFJLG1CQUFBLEVBQUFDLFdBQUE7SUFBQSxXQUFBSixhQUFBLGFBQUFHLG1CQUFBO01BQUFrRCxHQUFBO01BQUExQixLQUFBLEVBOUhELFNBQUEyQixpQkFBaUJBLENBQUEsRUFBRztRQUNsQixJQUFJLENBQUNDLHNCQUFzQixDQUFDLENBQUM7TUFDL0I7SUFBQztNQUFBRixHQUFBO01BQUExQixLQUFBLEVBRUQsU0FBQTZCLGtCQUFrQkEsQ0FBQSxFQUFHO1FBQ25CLElBQUksQ0FBQ0Qsc0JBQXNCLENBQUMsQ0FBQztNQUMvQjtJQUFDO01BQUFGLEdBQUE7TUFBQTFCLEtBQUEsRUFFRCxTQUFBOEIsb0JBQW9CQSxDQUFBLEVBQUc7UUFDckIsSUFBSSxJQUFJLENBQUNuQyxNQUFNLEVBQUU7VUFDZixJQUFBMkIsNEJBQW9CLEVBQUMsSUFBSSxDQUFDM0IsTUFBTSxDQUFDO1FBQ25DO01BQ0Y7SUFBQztNQUFBK0IsR0FBQTtNQUFBMUIsS0FBQSxFQUtELFNBQUE0QixzQkFBc0JBLENBQUEsRUFBRztRQUN2QixJQUFBRyxZQUFBLEdBQWlDLElBQUksQ0FBQ2pDLEtBQUs7VUFBcENaLFdBQVcsR0FBQTZDLFlBQUEsQ0FBWDdDLFdBQVc7VUFBQThDLGtCQUFBLEdBQUFELFlBQUEsQ0FBRWpCLEtBQUs7VUFBTEEsS0FBSyxHQUFBa0Isa0JBQUEsY0FBRyxDQUFDLEdBQUFBLGtCQUFBO1FBQzdCLElBQUksQ0FBQyxJQUFJLENBQUNyQyxNQUFNLElBQUlULFdBQVcsSUFBSTRCLEtBQUssR0FBRyxDQUFDLEVBQUU7VUFDNUMsSUFBSSxDQUFDbUIsZUFBZSxDQUFDLENBQUM7UUFDeEIsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDdEMsTUFBTSxJQUFJLENBQUNULFdBQVcsRUFBRTtVQUN0QyxJQUFJLENBQUNnRCxlQUFlLENBQUMsQ0FBQztRQUN4QjtNQUNGO0lBQUM7TUFBQVIsR0FBQTtNQUFBMUIsS0FBQSxFQXdHRCxTQUFBeUIsa0JBQWtCQSxDQUFBLEVBQUc7UUFDbkIsSUFBQVUsWUFBQSxHQUFxRSxJQUFJLENBQUNyQyxLQUFLO1VBQXhFQyxNQUFNLEdBQUFvQyxZQUFBLENBQU5wQyxNQUFNO1VBQUVDLEtBQUssR0FBQW1DLFlBQUEsQ0FBTG5DLEtBQUs7VUFBQW9DLGtCQUFBLEdBQUFELFlBQUEsQ0FBRXJCLEtBQUs7VUFBTEEsS0FBSyxHQUFBc0Isa0JBQUEsY0FBRyxDQUFDLEdBQUFBLGtCQUFBO1VBQUFDLHFCQUFBLEdBQUFGLFlBQUEsQ0FBRUcsU0FBUztVQUFUQSxTQUFTLEdBQUFELHFCQUFBLGNBQUcsR0FBRyxHQUFBQSxxQkFBQTtVQUFFcEMsZUFBZSxHQUFBa0MsWUFBQSxDQUFmbEMsZUFBZTtRQUNqRSxJQUFJLENBQUNGLE1BQU0sRUFBRTtVQUNYO1FBQ0Y7UUFDQSxJQUFNTixLQUFLLEdBQUksQ0FBQ00sTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHQSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUl1QyxTQUFTLEdBQUl4QixLQUFLOztRQUUzRDtRQUNBO1FBQ0EsSUFBSWhDLEtBQUssQ0FBQ3NCLE9BQU8sQ0FBQ0osS0FBSyxDQUFDLEVBQUU7VUFDeEIsSUFBSXVDLE1BQWM7VUFDbEIsSUFBSUMsTUFBYztVQUNsQixJQUFJdkMsZUFBZSxLQUFLSSwyQkFBZ0IsQ0FBQ0MsV0FBVyxFQUFFO1lBQ3BELElBQU1tQyxTQUFTLEdBQUd6QyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUdQLEtBQUssR0FBR00sTUFBTSxDQUFDLENBQUMsQ0FBQztZQUM5Q3dDLE1BQU0sR0FBR3ZDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDakJ3QyxNQUFNLEdBQUdDLFNBQVMsR0FBR3pDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUdBLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBR1AsS0FBSztVQUN0RCxDQUFDLE1BQU07WUFDTDtZQUNBLElBQU1nRCxVQUFTLEdBQUd6QyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUdQLEtBQUssR0FBR00sTUFBTSxDQUFDLENBQUMsQ0FBQztZQUM5Q3dDLE1BQU0sR0FBR0UsVUFBUyxHQUFHMUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUdQLEtBQUs7WUFDakQrQyxNQUFNLEdBQUdELE1BQU0sR0FBR3ZDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBR0EsS0FBSyxDQUFDLENBQUMsQ0FBQztVQUN2QztVQUNBLE9BQU8sQ0FBQ3VDLE1BQU0sRUFBRUMsTUFBTSxDQUFDO1FBQ3pCOztRQUVBO1FBQ0EsT0FBT0UsTUFBTSxDQUFDMUMsS0FBSyxDQUFDLEdBQUdQLEtBQUssR0FBR00sTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcyQyxNQUFNLENBQUMxQyxLQUFLLENBQUMsR0FBR1AsS0FBSztNQUM5RTtJQUFDO01BQUFpQyxHQUFBO01BQUExQixLQUFBLEVBRUQsU0FBQXdCLG9CQUFvQkEsQ0FBQSxFQUFHO1FBQ3JCLElBQUFtQixZQUFBLEdBQThCLElBQUksQ0FBQzdDLEtBQUs7VUFBQThDLGtCQUFBLEdBQUFELFlBQUEsQ0FBakNsQyxLQUFLO1VBQUxBLEtBQUssR0FBQW1DLGtCQUFBLGNBQUcsSUFBSSxHQUFBQSxrQkFBQTtVQUFFNUMsS0FBSyxHQUFBMkMsWUFBQSxDQUFMM0MsS0FBSztRQUMxQixJQUFJLENBQUNTLEtBQUssRUFBRTtRQUNaLElBQU1vQyxHQUFHLEdBQUcvRCxLQUFLLENBQUNzQixPQUFPLENBQUNKLEtBQUssQ0FBQyxHQUFHQSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcwQyxNQUFNLENBQUMxQyxLQUFLLENBQUM7UUFDM0QsSUFBTThDLEtBQUssR0FBRyxJQUFBQyxtQkFBVSxFQUFDdEMsS0FBSyxFQUFFb0MsR0FBRyxDQUFDO1FBQ3BDLElBQU1HLE9BQU8sR0FBR0YsS0FBSyxJQUFJckMsS0FBSyxDQUFDN0IsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUdrRSxLQUFLLEdBQUcsQ0FBQzs7UUFFekQ7UUFDQTtRQUNBLE9BQU8sQ0FBQ3JDLEtBQUssQ0FBQ3VDLE9BQU8sQ0FBQyxFQUFFQSxPQUFPLENBQUM7TUFDbEM7SUFBQztNQUFBdEIsR0FBQTtNQUFBMUIsS0FBQSxFQUVELFNBQUFpRCxNQUFNQSxDQUFBLEVBQUc7UUFDUCxJQUFPL0QsV0FBVyxHQUFJLElBQUksQ0FBQ2dFLEtBQUssQ0FBekJoRSxXQUFXO1FBQ2xCLElBQU9pRSxRQUFRLEdBQUksSUFBSSxDQUFDckQsS0FBSyxDQUF0QnFELFFBQVE7UUFFZixPQUFPLE9BQU9BLFFBQVEsS0FBSyxVQUFVLEdBQ2pDQSxRQUFRLENBQ05qRSxXQUFXLEVBQ1gsSUFBSSxDQUFDK0MsZUFBZSxFQUNwQixJQUFJLENBQUNDLGVBQWUsRUFDcEIsSUFBSSxDQUFDa0IsZUFBZSxFQUNwQixJQUFJLENBQUN0RCxLQUFLLENBQUN1RCxRQUFRLEVBQ25CLElBQUksQ0FBQ3ZELEtBQUssQ0FBQ0ssZ0JBQ2IsQ0FBQyxHQUNELElBQUk7TUFDVjtJQUFDO0VBQUEsRUFyTTREN0IsZ0JBQVM7RUFBQSxJQUFBVyxnQkFBQSxhQUFsRVQsbUJBQW1CLGtCQUdEO0lBQ3BCOEQsU0FBUyxFQUFFcEIscUJBQVU7SUFDckJKLEtBQUssRUFBRSxDQUFDO0lBQ1JMLEtBQUssRUFBRSxJQUFJO0lBQ1hSLGVBQWUsRUFBRUksMkJBQWdCLENBQUNpRDtFQUNwQyxDQUFDO0VBZ01ILE9BQU85RSxtQkFBbUI7QUFDNUI7QUFBQyxJQUFBK0UsUUFBQSxHQUFBQyxPQUFBLGNBRWNqRiwwQkFBMEIiLCJpZ25vcmVMaXN0IjpbXX0=