UNPKG

moose-remote-components

Version:

Figuring out how to export components onto npm, to be used in other projects

558 lines (450 loc) 62.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.WeekView = void 0; var _react = _interopRequireWildcard(require("react")); require("./Calendar.css"); var _dateFns = _interopRequireDefault(require("date-fns")); var _utils = _interopRequireDefault(require("../../utils/utils")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var WeekView = /*#__PURE__*/ function (_Component) { _inherits(WeekView, _Component); function WeekView() { var _getPrototypeOf2; var _this; _classCallCheck(this, WeekView); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(WeekView)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "state", { startTime: null, endTime: null, appointments: {}, appointmentBlocks: {}, mouseOverBlock: new Set(), mouseOver: null }); _defineProperty(_assertThisInitialized(_this), "mouseEnter", function (datetime) { _this.updateMouseOver(datetime); _this.updateMouseOverBlock(datetime); }); _defineProperty(_assertThisInitialized(_this), "mouseLeave", function () { _this.clearMouseOver(); _this.clearMouseOverBlock(); }); _defineProperty(_assertThisInitialized(_this), "updateMouseOver", function (datetime) { var date_format = "MM/DD/YYYY H:mm:ss"; var mouseOver = null; if (_this.isBlockAvailable(datetime)) { mouseOver = _dateFns["default"].format(datetime, date_format); } _this.setState({ mouseOver: mouseOver }); }); _defineProperty(_assertThisInitialized(_this), "clearMouseOver", function () { _this.setState({ mouseOver: null }); }); _defineProperty(_assertThisInitialized(_this), "isMouseOver", function (datetime) { var date_format = "MM/DD/YYYY H:mm:ss"; if (_this.state.mouseOver === _dateFns["default"].format(datetime, date_format)) return true; return false; }); _defineProperty(_assertThisInitialized(_this), "updateMouseOverBlock", function (datetime) { var date_format = "MM/DD/YYYY H:mm:ss"; var mouseOverBlock = new Set(); if (_this.isBlockAvailable(datetime)) { var length = _this.props.serviceLength; while (length > 0) { mouseOverBlock.add(_dateFns["default"].format(datetime, date_format)); datetime = _dateFns["default"].addMinutes(datetime, _this.props.interval); length -= _this.props.interval; } } _this.setState({ mouseOverBlock: mouseOverBlock }); }); _defineProperty(_assertThisInitialized(_this), "clearMouseOverBlock", function () { _this.setState({ mouseOverBlock: new Set() }); }); _defineProperty(_assertThisInitialized(_this), "isInMouseOverBlock", function (datetime) { var date_format = "MM/DD/YYYY H:mm:ss"; if (_this.state.mouseOverBlock.has(_dateFns["default"].format(datetime, date_format))) return true; return false; }); _defineProperty(_assertThisInitialized(_this), "setAppointment", function () { if (!_this.isAvailable(new Date(_this.state.mouseOver))) {} else if (_this.props.employee_view) {} else { var dates = []; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = _this.state.mouseOverBlock[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var datetime = _step.value; dates.push(new Date(datetime)); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (dates.length === 0) return; // find earliest date var earliest = dates[0]; dates.forEach(function (date) { if (_dateFns["default"].isBefore(date, earliest)) earliest = date; }); _this.props.setAppointment(earliest); } }); return _this; } _createClass(WeekView, [{ key: "componentDidUpdate", value: function componentDidUpdate(oldProps) { var _this2 = this; if (this.props.availability && oldProps.availability !== this.props.availability) { var startHour = 25; var endHour = -1; _utils["default"].weekdays.forEach(function (day) { startHour = Math.min(startHour, _utils["default"].minutes_to_time(_this2.props.availability[day][0].start).hours); endHour = Math.max(endHour, _utils["default"].minutes_to_time(_this2.props.availability[day][_this2.props.availability[day].length - 1].end).hours); }); var date = _dateFns["default"].startOfWeek(this.props.currentMonth); date = _dateFns["default"].startOfDay(date); this.setState({ startTime: _dateFns["default"].setHours(date, startHour) }); this.setState({ endTime: _dateFns["default"].setHours(date, endHour) }); } if (this.props.appointments && oldProps.appointments !== this.props.appointments) { // format appointments per day var appointments = {}; this.props.appointments.forEach(function (appt) { var date_index = _dateFns["default"].getDayOfYear(appt.datetime); if (appointments[date_index]) appointments[date_index].push(appt);else appointments[date_index] = [appt]; }); this.setState({ appointments: appointments }); // create appointment blocks var appointmentBlocks = this.state.appointmentBlocks; this.props.appointments.forEach(function (appt) { var date_format = "MM/DD/YYYY H:mm:ss"; var length = appt.length; var datetime = appt.datetime; var block_slots = []; while (length > 0) { block_slots.push(_dateFns["default"].format(datetime, date_format)); datetime = _dateFns["default"].addMinutes(datetime, _this2.props.interval); length -= _this2.props.interval; } appointmentBlocks[_dateFns["default"].format(appt.datetime, date_format)] = block_slots; }); this.setState({ appointmentBlocks: appointmentBlocks }); } } }, { key: "getParentDate", value: function getParentDate(datetime) { var date_format = "MM/DD/YYYY H:mm:ss"; var cloneTime = new Date(datetime); var apptBlock = this.state.appointmentBlocks[_dateFns["default"].format(cloneTime, date_format)]; if (apptBlock) { return apptBlock[0]; } while (!this.state.appointmentBlocks[_dateFns["default"].format(cloneTime, date_format)]) { if (_dateFns["default"].isAfter(this.state.startTime, cloneTime)) return null; cloneTime = _dateFns["default"].subMinutes(cloneTime, this.props.interval); } apptBlock = this.state.appointmentBlocks[_dateFns["default"].format(cloneTime, date_format)]; if (apptBlock) return apptBlock[0]; return null; } }, { key: "getAppointment", value: function getAppointment(datetime) { var formattedDate = this.getParentDate(datetime); var date_format = "MM/DD/YYYY H:mm:ss"; for (var i = 0; i < this.props.appointments.length; ++i) { if (_dateFns["default"].format(this.props.appointments[i].datetime, date_format) === formattedDate) { return this.props.appointments[i]; } } // not found } }, { key: "isPast", value: function isPast(datetime) { var now = new Date(); if (datetime - now < 0) return true; if (_dateFns["default"].isPast(datetime)) return true; } }, { key: "isFirstSlotInAppointment", value: function isFirstSlotInAppointment(datetime) { var date_format = "MM/DD/YYYY H:mm:ss"; if (this.state.appointmentBlocks[_dateFns["default"].format(datetime, date_format)]) return true; return false; } }, { key: "isSecondSlotInAppointment", value: function isSecondSlotInAppointment(datetime) { if (this.isFirstSlotInAppointment(datetime)) return false; var cloneTime = _dateFns["default"].subMinutes(datetime, this.props.interval); var date_format = "MM/DD/YYYY H:mm:ss"; var apptBlocks = this.state.appointmentBlocks[_dateFns["default"].format(cloneTime, date_format)]; if (!apptBlocks) return false; if (!(apptBlocks[1] === _dateFns["default"].format(datetime, date_format))) return false; return true; } // MAKE SURE GIVEN DATETIME IS IN AN APPOINTMENT }, { key: "isLastSlotInAppointment", value: function isLastSlotInAppointment(datetime) { var date_format = "MM/DD/YYYY H:mm:ss"; var cloneTime = new Date(datetime); var apptBlock = this.state.appointmentBlocks[_dateFns["default"].format(cloneTime, date_format)]; if (apptBlock) { if (apptBlock.length === 1) return true; return false; } while (!this.state.appointmentBlocks[_dateFns["default"].format(cloneTime, date_format)]) { if (_dateFns["default"].isAfter(this.state.startTime, cloneTime)) break; cloneTime = _dateFns["default"].subMinutes(cloneTime, this.props.interval); } if (_dateFns["default"].isAfter(this.state.startTime, cloneTime)) return false; apptBlock = this.state.appointmentBlocks[_dateFns["default"].format(cloneTime, date_format)]; if (apptBlock && apptBlock[apptBlock.length - 1] === _dateFns["default"].format(datetime, date_format)) return true; return false; } }, { key: "isAvailable", value: function isAvailable(datetime) { var now = new Date(); if (datetime - now < 0) return false; if (_dateFns["default"].isPast(datetime)) return false; var endTime = this.state.endTime; endTime = _dateFns["default"].setDayOfYear(endTime, _dateFns["default"].getDayOfYear(datetime)); if (_dateFns["default"].isEqual(datetime, endTime) || _dateFns["default"].isAfter(datetime, endTime)) return false; var date_index = _dateFns["default"].getDayOfYear(datetime); var appointments = this.state.appointments[date_index]; if (!appointments) return true; for (var i = 0; i < appointments.length; ++i) { var appt = appointments[i]; var appt_end = _dateFns["default"].addMinutes(appt.datetime, appt.length); if (_dateFns["default"].isEqual(appt.datetime, datetime) || _dateFns["default"].isAfter(datetime, appt.datetime) && _dateFns["default"].isBefore(datetime, appt_end)) { return false; } } return true; } }, { key: "isBlockAvailable", value: function isBlockAvailable(datetime) { var length = this.props.serviceLength; while (length > 0) { if (!this.isAvailable(datetime)) return false; datetime = _dateFns["default"].addMinutes(datetime, this.props.interval); length -= this.props.interval; } return true; } }, { key: "renderHeader", value: function renderHeader() { var date_format = "MMMM YYYY"; return _react["default"].createElement("div", { className: "header myrow noselect" }, _react["default"].createElement("div", { className: "mycol mycol-start" }, _react["default"].createElement("div", { className: "icon", onClick: this.props.movePrevWeek }, "chevron_left")), _react["default"].createElement("div", { className: "mycol mycol-center" }, _react["default"].createElement("span", null, " ", _dateFns["default"].format(this.props.currentMonth, date_format), " ")), _react["default"].createElement("div", { className: "mycol mycol-end" }, _react["default"].createElement("div", { className: "icon", onClick: this.props.moveNextWeek }, "chevron_right"))); } }, { key: "renderDays", value: function renderDays() { var date_format = "ddd D"; var days = []; var startDate = _dateFns["default"].startOfWeek(this.props.currentMonth); for (var i = 0; i < 7; ++i) { days.push(_react["default"].createElement("div", { className: "mycol mycol-center", key: i }, _dateFns["default"].format(startDate, date_format))); startDate = _dateFns["default"].addDays(startDate, 1); } return _react["default"].createElement("div", { className: "days myrow noselect" }, days); } }, { key: "renderCells", value: function renderCells() { var _this3 = this; var day_columns = []; // Days of the week for (var day = 0; day < 7; ++day) { var cells = []; var curTime = this.state.startTime; var endTime = this.state.endTime; curTime = _dateFns["default"].setDayOfYear(curTime, _dateFns["default"].getDayOfYear(_dateFns["default"].startOfWeek(this.props.currentMonth))); curTime = _dateFns["default"].setYear(curTime, _dateFns["default"].getYear(_dateFns["default"].startOfWeek(this.props.currentMonth))); endTime = _dateFns["default"].setDayOfYear(endTime, _dateFns["default"].getDayOfYear(_dateFns["default"].startOfWeek(this.props.currentMonth))); endTime = _dateFns["default"].setYear(endTime, _dateFns["default"].getYear(_dateFns["default"].startOfWeek(this.props.currentMonth))); curTime = _dateFns["default"].addDays(curTime, day); endTime = _dateFns["default"].addDays(endTime, day); if (curTime === null || endTime === null) return null; var key = 0; // Hours of the day (cells) while (_dateFns["default"].isAfter(endTime, curTime)) { var slots = []; var slot_count = 60 / this.props.interval; // Slots of the hour (in ~15 minute intervals (this.props.interval minutes)) var _loop = function _loop(i) { var cloneTime = curTime; var isAvailable = _this3.isAvailable(cloneTime); var isPast = _this3.isPast(cloneTime); var mouse_over = isAvailable ? _this3.isMouseOver(cloneTime) : null; var isFirstSlot = null; var isSecondSlot = null; var isLastSlot = null; if (!isAvailable && !isPast) { isFirstSlot = _this3.isFirstSlotInAppointment(cloneTime); isSecondSlot = _this3.isSecondSlotInAppointment(cloneTime); isLastSlot = _this3.isLastSlotInAppointment(cloneTime); } //const isSecondSlot = this.isSecondSlotInAppointment(dateFns.parse(cloneTime)); var appt = null; if (_this3.props.employee_view && !isPast && !isAvailable) { appt = _this3.getAppointment(cloneTime); } // add text ? var text = null; if (day === 0 && i === 0) { text = _react["default"].createElement("span", { className: "mycol mycol-left time noselect" }, _dateFns["default"].format(curTime, "h a")); } if (mouse_over && !_this3.isPast(cloneTime) && isAvailable) { text = _react["default"].createElement("span", { className: "mycol mycol-left time_over noselect" }, _dateFns["default"].format(curTime, "h:mm a")); } if (_this3.props.employee_view && !isAvailable && !isPast && isSecondSlot) { // or appt.customer.firstname if (appt && appt.customer) text = _react["default"].createElement("span", { className: "mycol mycol-left name_over noselect" }, _react["default"].createElement("span", { className: "sm" }, "for"), " ", appt.customer.firstname); } if (_this3.props.employee_view && !isAvailable && !isPast && isFirstSlot) { // or appt.customer.firstname if (appt && appt.customer) text = _react["default"].createElement("span", { className: "mycol mycol-left name_over noselect" }, appt.service.name); } // format styles var classes = "myrow slot "; if (_this3.props.interval === 5) classes += "slot-sm ";else classes += "slot-md "; if (i === slot_count - 1) classes += "border-bot ";else classes += "border-bot-light "; if (isPast) classes += "shaded ";else { if (!isAvailable) { if (_this3.props.employee_view) { classes += "is-appointment "; if (isFirstSlot) classes += "first-slot "; if (isLastSlot) classes += "last-slot "; } else { classes += "shaded "; } } else { classes += "available "; } } if (_this3.isInMouseOverBlock(cloneTime)) classes += "selectable "; // set click function var click = function click() { if (!_this3.props.employee_view) { _this3.setAppointment(); } else { if (!isAvailable && !isPast && _this3.props.showAppointment) { _this3.props.showAppointment(appt); } } }; slots.push(_react["default"].createElement("div", { className: classes, key: i // eslint-disable-next-line , onMouseEnter: function onMouseEnter() { return _this3.mouseEnter(cloneTime); }, onMouseLeave: _this3.mouseLeave, onClick: click }, text)); curTime = _dateFns["default"].addMinutes(curTime, _this3.props.interval); }; for (var i = 0; i < slot_count; ++i) { _loop(i); } cells.push(_react["default"].createElement("div", { className: "cell", key: key }, slots)); key++; } day_columns.push(_react["default"].createElement("div", { className: "cells mycol", key: day }, cells)); } return _react["default"].createElement("div", { className: "myrow viewport" }, day_columns); } }, { key: "render", value: function render() { return _react["default"].createElement("div", { className: "calendar" }, this.renderHeader(), this.renderDays(), this.renderCells()); } }]); return WeekView; }(_react.Component); exports.WeekView = WeekView; var _default = WeekView; exports["default"] = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL0NhbGVuZGFyL1dlZWtWaWV3LmpzIl0sIm5hbWVzIjpbIldlZWtWaWV3Iiwic3RhcnRUaW1lIiwiZW5kVGltZSIsImFwcG9pbnRtZW50cyIsImFwcG9pbnRtZW50QmxvY2tzIiwibW91c2VPdmVyQmxvY2siLCJTZXQiLCJtb3VzZU92ZXIiLCJkYXRldGltZSIsInVwZGF0ZU1vdXNlT3ZlciIsInVwZGF0ZU1vdXNlT3ZlckJsb2NrIiwiY2xlYXJNb3VzZU92ZXIiLCJjbGVhck1vdXNlT3ZlckJsb2NrIiwiZGF0ZV9mb3JtYXQiLCJpc0Jsb2NrQXZhaWxhYmxlIiwiZGF0ZUZucyIsImZvcm1hdCIsInNldFN0YXRlIiwic3RhdGUiLCJsZW5ndGgiLCJwcm9wcyIsInNlcnZpY2VMZW5ndGgiLCJhZGQiLCJhZGRNaW51dGVzIiwiaW50ZXJ2YWwiLCJoYXMiLCJpc0F2YWlsYWJsZSIsIkRhdGUiLCJlbXBsb3llZV92aWV3IiwiZGF0ZXMiLCJwdXNoIiwiZWFybGllc3QiLCJmb3JFYWNoIiwiZGF0ZSIsImlzQmVmb3JlIiwic2V0QXBwb2ludG1lbnQiLCJvbGRQcm9wcyIsImF2YWlsYWJpbGl0eSIsInN0YXJ0SG91ciIsImVuZEhvdXIiLCJ1dGlscyIsIndlZWtkYXlzIiwiZGF5IiwiTWF0aCIsIm1pbiIsIm1pbnV0ZXNfdG9fdGltZSIsInN0YXJ0IiwiaG91cnMiLCJtYXgiLCJlbmQiLCJzdGFydE9mV2VlayIsImN1cnJlbnRNb250aCIsInN0YXJ0T2ZEYXkiLCJzZXRIb3VycyIsImFwcHQiLCJkYXRlX2luZGV4IiwiZ2V0RGF5T2ZZZWFyIiwiYmxvY2tfc2xvdHMiLCJjbG9uZVRpbWUiLCJhcHB0QmxvY2siLCJpc0FmdGVyIiwic3ViTWludXRlcyIsImZvcm1hdHRlZERhdGUiLCJnZXRQYXJlbnREYXRlIiwiaSIsIm5vdyIsImlzUGFzdCIsImlzRmlyc3RTbG90SW5BcHBvaW50bWVudCIsImFwcHRCbG9ja3MiLCJzZXREYXlPZlllYXIiLCJpc0VxdWFsIiwiYXBwdF9lbmQiLCJtb3ZlUHJldldlZWsiLCJtb3ZlTmV4dFdlZWsiLCJkYXlzIiwic3RhcnREYXRlIiwiYWRkRGF5cyIsImRheV9jb2x1bW5zIiwiY2VsbHMiLCJjdXJUaW1lIiwic2V0WWVhciIsImdldFllYXIiLCJrZXkiLCJzbG90cyIsInNsb3RfY291bnQiLCJtb3VzZV9vdmVyIiwiaXNNb3VzZU92ZXIiLCJpc0ZpcnN0U2xvdCIsImlzU2Vjb25kU2xvdCIsImlzTGFzdFNsb3QiLCJpc1NlY29uZFNsb3RJbkFwcG9pbnRtZW50IiwiaXNMYXN0U2xvdEluQXBwb2ludG1lbnQiLCJnZXRBcHBvaW50bWVudCIsInRleHQiLCJjdXN0b21lciIsImZpcnN0bmFtZSIsInNlcnZpY2UiLCJuYW1lIiwiY2xhc3NlcyIsImlzSW5Nb3VzZU92ZXJCbG9jayIsImNsaWNrIiwic2hvd0FwcG9pbnRtZW50IiwibW91c2VFbnRlciIsIm1vdXNlTGVhdmUiLCJyZW5kZXJIZWFkZXIiLCJyZW5kZXJEYXlzIiwicmVuZGVyQ2VsbHMiLCJDb21wb25lbnQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFFYUEsUTs7Ozs7Ozs7Ozs7Ozs7Ozs7OzREQUVKO0FBQ1BDLE1BQUFBLFNBQVMsRUFBRSxJQURKO0FBRVBDLE1BQUFBLE9BQU8sRUFBRSxJQUZGO0FBR1BDLE1BQUFBLFlBQVksRUFBRSxFQUhQO0FBSVBDLE1BQUFBLGlCQUFpQixFQUFFLEVBSlo7QUFLUEMsTUFBQUEsY0FBYyxFQUFFLElBQUlDLEdBQUosRUFMVDtBQU1QQyxNQUFBQSxTQUFTLEVBQUU7QUFOSixLOztpRUErSkssVUFBQ0MsUUFBRCxFQUFjO0FBQzFCLFlBQUtDLGVBQUwsQ0FBcUJELFFBQXJCOztBQUNBLFlBQUtFLG9CQUFMLENBQTBCRixRQUExQjtBQUNBLEs7O2lFQUNZLFlBQU07QUFDbEIsWUFBS0csY0FBTDs7QUFDQSxZQUFL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QXZDLENBQVY7QUEzRnNDOztBQUt2QyxlQUFLLElBQUl3QyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHb0IsVUFBcEIsRUFBZ0MsRUFBRXBCLENBQWxDLEVBQW9DO0FBQUEsa0JBQTNCQSxDQUEyQjtBQXVGbkM7O0FBRURjLFVBQUFBLEtBQUssQ0FBQ2hELElBQU4sQ0FDQztBQUFLLFlBQUEsU0FBUyxFQUFDLE1BQWY7QUFBc0IsWUFBQSxHQUFHLEVBQUVvRDtBQUEzQixhQUNFQyxLQURGLENBREQ7QUFLQUQsVUFBQUEsR0FBRztBQUNIOztBQUdETCxRQUFBQSxXQUFXLENBQUMvQyxJQUFaLENBQ0M7QUFBSyxVQUFBLFNBQVMsRUFBQyxhQUFmO0FBQTZCLFVBQUEsR0FBRyxFQUFFWTtBQUFsQyxXQUNFb0MsS0FERixDQUREO0FBTUE7O0FBRUQsYUFBTztBQUFLLFFBQUEsU0FBUyxFQUFDO0FBQWYsU0FBaUNELFdBQWpDLENBQVA7QUFDQTs7OzZCQUVRO0FBQ1IsYUFDQztBQUFLLFFBQUEsU0FBUyxFQUFDO0FBQWYsU0FDRSxLQUFLMkIsWUFBTCxFQURGLEVBRUUsS0FBS0MsVUFBTCxFQUZGLEVBR0UsS0FBS0MsV0FBTCxFQUhGLENBREQ7QUFPQTs7OztFQWhhNEJDLGdCOzs7ZUFtYWYzRyxRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IENvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCAnLi9DYWxlbmRhci5jc3MnO1xuaW1wb3J0IGRhdGVGbnMgZnJvbSAnZGF0ZS1mbnMnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uL3V0aWxzL3V0aWxzJztcblxuZXhwb3J0IGNsYXNzIFdlZWtWaWV3IGV4dGVuZHMgQ29tcG9uZW50IHtcblxuXHRzdGF0ZSA9IHtcblx0XHRzdGFydFRpbWU6IG51bGwsXG5cdFx0ZW5kVGltZTogbnVsbCxcblx0XHRhcHBvaW50bWVudHM6IHt9LFxuXHRcdGFwcG9pbnRtZW50QmxvY2tzOiB7fSxcblx0XHRtb3VzZU92ZXJCbG9jazogbmV3IFNldCgpLFxuXHRcdG1vdXNlT3ZlcjogbnVsbCxcblx0fVxuXG5cdGNvbXBvbmVudERpZFVwZGF0ZShvbGRQcm9wcykge1xuXG5cdFx0aWYgKHRoaXMucHJvcHMuYXZhaWxhYmlsaXR5ICYmIG9sZFByb3BzLmF2YWlsYWJpbGl0eSAhPT0gdGhpcy5wcm9wcy5hdmFpbGFiaWxpdHkpIHtcblx0XHRcdGxldCBzdGFydEhvdXIgPSAyNTtcblx0XHRcdGxldCBlbmRIb3VyID0gLTE7XG5cdFx0XHR1dGlscy53ZWVrZGF5cy5mb3JFYWNoKGRheSA9PiB7XG5cdFx0XHRcdHN0YXJ0SG91ciA9IE1hdGgubWluKHN0YXJ0SG91ciwgdXRpbHMubWludXRlc190b190aW1lKHRoaXMucHJvcHMuYXZhaWxhYmlsaXR5W2RheV1bMF0uc3RhcnQpLmhvdXJzKTtcblx0XHRcdFx0ZW5kSG91ciA9IE1hdGgubWF4KGVuZEhvdXIsIHV0aWxzLm1pbnV0ZXNfdG9fdGltZSh0aGlzLnByb3BzLmF2YWlsYWJpbGl0eVtkYXldW3RoaXMucHJvcHMuYXZhaWxhYmlsaXR5W2RheV0ubGVuZ3RoIC0gMV0uZW5kKS5ob3Vycyk7XG5cdFx0XHR9KTtcblx0XHRcdGxldCBkYXRlID0gZGF0ZUZucy5zdGFydE9mV2Vlayh0aGlzLnByb3BzLmN1cnJlbnRNb250aCk7XG5cdFx0XHRkYXRlID0gZGF0ZUZucy5zdGFydE9mRGF5KGRhdGUpO1xuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7IHN0YXJ0VGltZTogZGF0ZUZucy5zZXRIb3VycyhkYXRlLCBzdGFydEhvdXIpIH0pXG5cdFx0XHR0aGlzLnNldFN0YXRlKHsgZW5kVGltZTogZGF0ZUZucy5zZXRIb3VycyhkYXRlLCBlbmRIb3VyKSB9KVxuXHRcdH1cblx0XHRcblx0XHRpZiAodGhpcy5wcm9wcy5hcHBvaW50bWVudHMgJiYgb2xkUHJvcHMuYXBwb2ludG1lbnRzICE9PSB0aGlzLnByb3BzLmFwcG9pbnRtZW50cyl7XG5cblx0XHRcdC8vIGZvcm1hdCBhcHBvaW50bWVudHMgcGVyIGRheVxuXHRcdFx0bGV0IGFwcG9pbnRtZW50cyA9IHt9O1xuXHRcdFx0dGhpcy5wcm9wcy5hcHBvaW50bWVudHMuZm9yRWFjaChhcHB0ID0+IHtcblx0XHRcdFx0bGV0IGRhdGVfaW5kZXggPSBkYXRlRm5zLmdldERheU9mWWVhcihhcHB0LmRhdGV0aW1lKTtcblx0XHRcdFx0aWYgKGFwcG9pbnRtZW50c1tkYXRlX2luZGV4XSkgYXBwb2ludG1lbnRzW2RhdGVfaW5kZXhdLnB1c2goYXBwdCk7XG5cdFx0XHRcdGVsc2UgYXBwb2ludG1lbnRzW2RhdGVfaW5kZXhdID0gW2FwcHRdO1xuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLnNldFN0YXRlKHsgYXBwb2ludG1lbnRzIH0pO1xuXG5cdFx0XHQvLyBjcmVhdGUgYXBwb2ludG1lbnQgYmxvY2tzXG5cdFx0XHRsZXQgYXBwb2ludG1lbnRCbG9ja3MgPSB0aGlzLnN0YXRlLmFwcG9pbnRtZW50QmxvY2tzO1xuXHRcdFx0dGhpcy5wcm9wcy5hcHBvaW50bWVudHMuZm9yRWFjaChhcHB0ID0+IHtcblx0XHRcdFx0bGV0IGRhdGVfZm9ybWF0ID0gXCJNTS9ERC9ZWVlZIEg6bW06c3NcIjtcblx0XHRcdFx0bGV0IGxlbmd0aCA9IGFwcHQubGVuZ3RoO1xuXHRcdFx0XHRsZXQgZGF0ZXRpbWUgPSBhcHB0LmRhdGV0aW1lO1xuXHRcdFx0XHRsZXQgYmxvY2tfc2xvdHMgPSBbXTtcblx0XHRcdFx0d2hpbGUobGVuZ3RoID4gMCl7XG5cdFx0XHRcdFx0YmxvY2tfc2xvdHMucHVzaChkYXRlRm5zLmZvcm1hdChkYXRldGltZSwgZGF0ZV9mb3JtYXQpKTtcblx0XHRcdFx0XHRkYXRldGltZSA9IGRhdGVGbnMuYWRkTWludXRlcyhkYXRldGltZSwgdGhpcy5wcm9wcy5pbnRlcnZhbCk7XG5cdFx0XHRcdFx0bGVuZ3RoIC09IHRoaXMucHJvcHMuaW50ZXJ2YWw7XG5cdFx0XHRcdH1cblx0XHRcdFx0YXBwb2ludG1lbnRCbG9ja3NbZGF0ZUZucy5mb3JtYXQoYXBwdC5kYXRldGltZSwgZGF0ZV9mb3JtYXQpXSA9IGJsb2NrX3Nsb3RzO1xuXHRcdFx0fSlcblx0XHRcdHRoaXMuc2V0U3RhdGUoeyBhcHBvaW50bWVudEJsb2NrcyB9KTtcblxuXHRcdH1cblx0fVxuXG5cdGdldFBhcmVudERhdGUoZGF0ZXRpbWUpIHtcblx0XHRsZXQgZGF0ZV9mb3JtYXQgPSBcIk1NL0REL1lZWVkgSDptbTpzc1wiO1xuXHRcdGxldCBjbG9uZVRpbWUgPSBuZXcgRGF0ZShkYXRldGltZSk7XG5cdFx0bGV0IGFwcHRCbG9jayA9IHRoaXMuc3RhdGUuYXBwb2ludG1lbnRCbG9ja3NbZGF0ZUZucy5mb3JtYXQoY2xvbmVUaW1lLCBkYXRlX2Zvcm1hdCldXG5cdFx0aWYgKGFwcHRCbG9jaykge1xuXHRcdFx0cmV0dXJuIGFwcHRCbG9ja1swXVxuXHRcdH0gXG5cdFx0d2hpbGUgKCF0aGlzLnN0YXRlLmFwcG9pbnRtZW50QmxvY2tzW2RhdGVGbnMuZm9ybWF0KGNsb25lVGltZSwgZGF0ZV9mb3JtYXQpXSkge1xuXHRcdFx0aWYgKGRhdGVGbnMuaXNBZnRlcih0aGlzLnN0YXRlLnN0YXJ0VGltZSwgY2xvbmVUaW1lKSkgcmV0dXJuIG51bGw7XG5cdFx0XHRjbG9uZVRpbWUgPSBkYXRlRm5zLnN1Yk1pbnV0ZXMoY2xvbmVUaW1lLCB0aGlzLnByb3BzLmludGVydmFsKTtcblx0XHR9XG5cdFx0YXBwdEJsb2NrID0gdGhpcy5zdGF0ZS5hcHBvaW50bWVudEJsb2Nrc1tkYXRlRm5zLmZvcm1hdChjbG9uZVRpbWUsIGRhdGVfZm9ybWF0KV07XG5cdFx0aWYgKGFwcHRCbG9jaykgcmV0dXJuIGFwcHRCbG9ja1swXTtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdGdldEFwcG9pbnRtZW50KGRhdGV0aW1lKSB7XG5cdFx0bGV0IGZvcm1hdHRlZERhdGUgPSB0aGlzLmdldFBhcmVudERhdGUoZGF0ZXRpbWUpO1xuXHRcdGxldCBkYXRlX2Zvcm1hdCA9IFwiTU0vREQvWVlZWSBIOm1tOnNzXCI7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnByb3BzLmFwcG9pbnRtZW50cy5sZW5ndGg7ICsraSkge1xuXHRcdFx0aWYgKGRhdGVGbnMuZm9ybWF0KHRoaXMucHJvcHMuYXBwb2ludG1lbnRzW2ldLmRhdGV0aW1lLCBkYXRlX2Zvcm1hdCkgPT09IGZvcm1hdHRlZERhdGUpe1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5wcm9wcy5hcHBvaW50bWVudHNbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIG5vdCBmb3VuZFxuXG5cdH1cblxuXHRpc1Bhc3QoZGF0ZXRpbWUpIHtcblx0XHRsZXQgbm93ID0gbmV3IERhdGUoKTtcblx0XHRpZiAoZGF0ZXRpbWUgLSBub3cgPCAwKSByZXR1cm4gdHJ1ZTtcblx0XHRpZiAoZGF0ZUZucy5pc1Bhc3QoZGF0ZXRpbWUpKSByZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdGlzRmlyc3RTbG90SW5BcHBvaW50bWVudChkYXRldGltZSkge1xuXHRcdGxldCBkYXRlX2Zvcm1hdCA9IFwiTU0vREQvWVlZWSBIOm1tOnNzXCI7XG5cdFx0aWYgKHRoaXMuc3RhdGUuYXBwb2ludG1lbnRCbG9ja3NbZGF0ZUZucy5mb3JtYXQoZGF0ZXRpbWUsIGRhdGVfZm9ybWF0KV0pIHJldHVybiB0cnVlO1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRpc1NlY29uZFNsb3RJbkFwcG9pbnRtZW50KGRhdGV0aW1lKSB7XG5cdFx0aWYgKHRoaXMuaXNGaXJzdFNsb3RJbkFwcG9pbnRtZW50KGRhdGV0aW1lKSkgcmV0dXJuIGZhbHNlO1xuXHRcdGxldCBjbG9uZVRpbWUgPSBkYXRlRm5zLnN1Yk1pbnV0ZXMoZGF0ZXRpbWUsIHRoaXMucHJvcHMuaW50ZXJ2YWwpO1xuXHRcdGxldCBkYXRlX2Zvcm1hdCA9IFwiTU0vREQvWVlZWSBIOm1tOnNzXCI7XG5cdFx0bGV0IGFwcHRCbG9ja3MgPSB0aGlzLnN0YXRlLmFwcG9pbnRtZW50QmxvY2tzW2RhdGVGbnMuZm9ybWF0KGNsb25lVGltZSwgZGF0ZV9mb3JtYXQpXTtcblx0XHRpZiAoIWFwcHRCbG9ja3MpIHJldHVybiBmYWxzZTtcblx0XHRpZiAoIShhcHB0QmxvY2tzWzFdID09PSBkYXRlRm5zLmZvcm1hdChkYXRldGltZSwgZGF0ZV9mb3JtYXQpKSkgcmV0dXJuIGZhbHNlO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0Ly8gTUFLRSBTVVJFIEdJVkVOIERBVEVUSU1FIElTIElOIEFOIEFQUE9JTlRNRU5UXG5cdGlzTGFzdFNsb3RJbkFwcG9pbnRtZW50KGRhdGV0aW1lKSB7XG5cdFx0bGV0IGRhdGVfZm9ybWF0ID0gXCJNTS9ERC9ZWVlZIEg6bW06c3NcIjtcblx0XHRsZXQgY2xvbmVUaW1lID0gbmV3IERhdGUoZGF0ZXRpbWUpO1xuXHRcdGxldCBhcHB0QmxvY2sgPSB0aGlzLnN0YXRlLmFwcG9pbnRtZW50QmxvY2tzW2RhdGVGbnMuZm9ybWF0KGNsb25lVGltZSwgZGF0ZV9mb3JtYXQpXVxuXHRcdGlmIChhcHB0QmxvY2spe1xuXHRcdFx0aWYgKGFwcHRCbG9jay5sZW5ndGggPT09IDEpIHJldHVybiB0cnVlO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gXG5cblx0XHR3aGlsZSAoICF0aGlzLnN0YXRlLmFwcG9pbnRtZW50QmxvY2tzW2RhdGVGbnMuZm9ybWF0KGNsb25lVGltZSwgZGF0ZV9mb3JtYXQpXSl7XG5cdFx0XHRpZiAoZGF0ZUZucy5pc0FmdGVyKHRoaXMuc3RhdGUuc3RhcnRUaW1lLCBjbG9uZVRpbWUpKSBicmVhaztcblx0XHRcdGNsb25lVGltZSA9IGRhdGVGbnMuc3ViTWludXRlcyhjbG9uZVRpbWUsIHRoaXMucHJvcHMuaW50ZXJ2YWwpO1xuXHRcdH1cblxuXHRcdGlmIChkYXRlRm5zLmlzQWZ0ZXIodGhpcy5zdGF0ZS5zdGFydFRpbWUsIGNsb25lVGltZSkpIHJldHVybiBmYWxzZTtcblx0XHRcblx0XHRhcHB0QmxvY2sgPSB0aGlzLnN0YXRlLmFwcG9pbnRtZW50QmxvY2tzW2RhdGVGbnMuZm9ybWF0KGNsb25lVGltZSwgZGF0ZV9mb3JtYXQpXTtcblx0XHRpZiAoYXBwdEJsb2NrICYmIGFwcHRCbG9ja1thcHB0QmxvY2subGVuZ3RoLTFdID09PSBkYXRlRm5zLmZvcm1hdChkYXRldGltZSwgZGF0ZV9mb3JtYXQpKSByZXR1cm4gdHJ1ZTtcblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGlzQXZha