UNPKG

@future-grid/fgp-graph

Version:

fgp-graph is a chart lib based on Dygraphs

455 lines (385 loc) 59.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Formatters = void 0; var _dygraphs = _interopRequireDefault(require("dygraphs")); var _momentTimezone = _interopRequireDefault(require("moment-timezone")); var _configurations = require("../metadata/configurations"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 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 Formatters = /** *show graph timestamp with this timezone * @type {string} * @memberof Formatters */ /** *Creates an instance of Formatters. * @param {string} timezone show graph timestamp with this timezone * @memberof Formatters */ function Formatters(timezone) { var _this = this; _classCallCheck(this, Formatters); _defineProperty(this, "timezone", void 0); _defineProperty(this, "dateformat", void 0); _defineProperty(this, "TICK_PLACEMENT", void 0); _defineProperty(this, "SHORT_SPACINGS", void 0); _defineProperty(this, "setFormat", function (format) { _this.dateformat = format; }); _defineProperty(this, "numDateTicks", function (start_time, end_time, granularity) { var spacing = _this.TICK_PLACEMENT[granularity].spacing; return Math.round(1.0 * (end_time - start_time) / spacing); }); _defineProperty(this, "pickDateTickGranularity", function (a, b, pixels, opts) { var pixels_per_tick = opts('pixelsPerLabel'); for (var i = 0; i < 21; i++) { var num_ticks = _this.numDateTicks(a, b, i); if (pixels / num_ticks >= pixels_per_tick) { return i; } } return -1; }); _defineProperty(this, "zeropad", function (x) { if (x < 10) return "0" + x;else return "" + x; }); _defineProperty(this, "getDateAxis", function (start, end, granularity, opts, dygraph) { // var formatter = /** @type{AxisLabelFormatter} */ opts("axisLabelFormatter"); var ticks = []; var t; if (granularity < _configurations.GraphConstant.MONTHLY) { // Generate one tick mark for every fixed interval of time. var spacing = _this.SHORT_SPACINGS[granularity]; // Find a time less than start_time which occurs on a "nice" time boundary // for this granularity. var g = spacing / 1000; var d = (0, _momentTimezone["default"])(start).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()); d.millisecond(0); var x; if (g <= 60) { // seconds x = d.second(); d.second(x - x % g); } else { d.second(0); g /= 60; if (g <= 60) { // minutes x = d.minute(); d.minute(x - x % g); } else { d.minute(0); g /= 60; if (g <= 24) { // days x = d.hour(); d.hour(x - x % g); } else { d.hour(0); g /= 24; if (g == 7) { // one week d.startOf('week'); } } } } start = d.valueOf(); var start_offset_min = (0, _momentTimezone["default"])(start).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()).utcOffset(); var check_dst = spacing >= _this.SHORT_SPACINGS[_configurations.GraphConstant.TWO_HOURLY]; for (t = start; t <= end; t += spacing) { var _d = (0, _momentTimezone["default"])(t).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()); // console.info(check_dst , d.utcOffset() , start_offset_min); if (check_dst && _d.utcOffset() != start_offset_min) { var delta_min = -(_d.utcOffset() - start_offset_min); t += delta_min * 60 * 1000; _d = (0, _momentTimezone["default"])(t).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()); start_offset_min = _d.utcOffset(); // Check whether we've backed into the previous timezone again. // This can happen during a "day light" transition. In this case, // it's best to skip this tick altogether (we may be shooting for a // non-existent time like the 2AM that's skipped) and go to the next // one. if ((0, _momentTimezone["default"])(t + spacing).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()).utcOffset() != start_offset_min) { t += spacing; _d = (0, _momentTimezone["default"])(t).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()); start_offset_min = _d.utcOffset(); } } ticks.push({ v: t, label: formatter(_d, granularity, opts, dygraph) }); } } else { // Display a tick mark on the first of a set of months of each year. // Years get a tick mark iff y % year_mod == 0. This is useful for // displaying a tick mark once every 10 years, say, on long time scales. var months = []; var year_mod = 1; // e.g. to only print one point every 10 years. if (granularity == _configurations.GraphConstant.MONTHLY) { months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; } else if (granularity == _configurations.GraphConstant.QUARTERLY) { months = [0, 3, 6, 9]; } else if (granularity == _configurations.GraphConstant.BIANNUAL) { months = [0, 6]; } else if (granularity == _configurations.GraphConstant.ANNUAL) { months = [0]; } else if (granularity == _configurations.GraphConstant.DECADAL) { months = [0]; year_mod = 10; } else if (granularity == _configurations.GraphConstant.CENTENNIAL) { months = [0]; year_mod = 100; } else { console.warn("Span of dates is too long"); } var start_year = (0, _momentTimezone["default"])(start).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()).year(); var end_year = (0, _momentTimezone["default"])(end).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()).year(); for (var i = start_year; i <= end_year; i++) { if (i % year_mod !== 0) continue; for (var j = 0; j < months.length; j++) { var dt = _momentTimezone["default"].tz(new Date(i, months[j], 1), _this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()); dt.year(i); t = dt.valueOf(); if (t < start || t > end) continue; ticks.push({ v: t, label: formatter((0, _momentTimezone["default"])(t).tz(_this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()), granularity, opts, dygraph) }); } } } return ticks; }); _defineProperty(this, "DateTickerTZ", function (a, b, pixels, opts, dygraph, vals) { var granularity = _this.pickDateTickGranularity(a, b, pixels, opts); if (granularity >= 0) { return _this.getDateAxis(a, b, granularity, opts, dygraph); // use own function here } else { // this can happen if self.width_ is zero. return []; } }); _defineProperty(this, "legendForAllSeries", function (data) { var g = data.dygraph; if (g.getOption('showLabelsOnHighlight') !== true) return ''; if (data.x == null) { // This happens when there's no selection and {legend: 'always'} is set. return '<br>' + data.series.map(function (series) { return series.dashHTML + ' ' + series.labelHTML; }).join('<br>'); } var html = _momentTimezone["default"].tz(data.x, _this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()).format(_this.dateformat ? _this.dateformat : 'lll z'); data.series.forEach(function (series) { if (!series.isVisible || series.label.indexOf('_markline') != -1) return; var labeledData = series.labelHTML + ': ' + (series.yHTML ? series.yHTML : ""); if (series.isHighlighted) { labeledData = '<b style="color:' + series.color + ';">' + labeledData + '</b>'; } html += '<br>' + series.dashHTML + ' ' + labeledData; }); return html; }); _defineProperty(this, "legendForSingleSeries", function (data) { var g = data.dygraph; if (g.getOption('showLabelsOnHighlight') !== true) return ''; if (data.x == null) { // This happens when there's no selection and {legend: 'always'} is set. return '<br>' + data.series.map(function (series) { return series.dashHTML + ' ' + series.labelHTML; }).join('<br>'); } var html = _momentTimezone["default"].tz(data.x, _this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()).format(_this.dateformat ? _this.dateformat : 'lll z'); data.series.forEach(function (series) { if (!series.isVisible || series.label.indexOf('_markline') != -1) return; var labeledData = series.labelHTML + ': ' + (series.yHTML ? series.yHTML : ""); if (series.isHighlighted) { labeledData = '<b style="color:' + series.color + ';">' + labeledData + '</b>'; html += '<br>' + series.dashHTML + ' ' + labeledData; } }); return html; }); _defineProperty(this, "axisLabel", function (d, granularity, opts, dygraph) { // don't put it into formatters.ts becault we need to timezone later var momentDatetime; if (d instanceof Date) { momentDatetime = _momentTimezone["default"].tz(d.getTime(), _this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()); } else { momentDatetime = _momentTimezone["default"].tz(d, _this.timezone ? _this.timezone : _momentTimezone["default"].tz.guess()); } var SHORT_MONTH_NAMES = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; var zeropad = function zeropad(x) { if (x < 10) return "0" + x;else return "" + x; }; var hmsString_ = function hmsString_(hh, mm, ss) { var ret = zeropad(hh) + ":" + zeropad(mm); if (ss) { ret += ":" + zeropad(ss); } return ret; }; if (granularity >= _dygraphs["default"].DECADAL) { return '' + momentDatetime.year(); } else if (granularity >= _dygraphs["default"].MONTHLY) { return SHORT_MONTH_NAMES[momentDatetime.month()] + '&#160;' + momentDatetime.year(); } else { var frac = momentDatetime.hours() * 3600 + momentDatetime.minutes() * 60 + momentDatetime.seconds() + 1e-3 * momentDatetime.milliseconds(); if (frac === 0 || granularity >= _dygraphs["default"].DAILY) { // e.g. '21 Jan' (%d%b) return zeropad(momentDatetime.date()) + '&#160;' + SHORT_MONTH_NAMES[momentDatetime.month()]; } else { return hmsString_(momentDatetime.hours(), momentDatetime.minutes(), momentDatetime.seconds()); } } }); this.timezone = timezone; var DATEFIELD_Y = 0; var DATEFIELD_M = 1; var DATEFIELD_D = 2; var DATEFIELD_HH = 3; var DATEFIELD_MM = 4; var DATEFIELD_SS = 5; var DATEFIELD_MS = 6; var NUM_DATEFIELDS = 7; this.TICK_PLACEMENT = []; this.TICK_PLACEMENT[_configurations.GraphConstant.SECONDLY] = { datefield: DATEFIELD_SS, step: 1, spacing: 1000 * 1 }; this.TICK_PLACEMENT[_configurations.GraphConstant.TWO_SECONDLY] = { datefield: DATEFIELD_SS, step: 2, spacing: 1000 * 2 }; this.TICK_PLACEMENT[_configurations.GraphConstant.FIVE_SECONDLY] = { datefield: DATEFIELD_SS, step: 5, spacing: 1000 * 5 }; this.TICK_PLACEMENT[_configurations.GraphConstant.TEN_SECONDLY] = { datefield: DATEFIELD_SS, step: 10, spacing: 1000 * 10 }; this.TICK_PLACEMENT[_configurations.GraphConstant.THIRTY_SECONDLY] = { datefield: DATEFIELD_SS, step: 30, spacing: 1000 * 30 }; this.TICK_PLACEMENT[_configurations.GraphConstant.MINUTELY] = { datefield: DATEFIELD_MM, step: 1, spacing: 1000 * 60 }; this.TICK_PLACEMENT[_configurations.GraphConstant.TWO_MINUTELY] = { datefield: DATEFIELD_MM, step: 2, spacing: 1000 * 60 * 2 }; this.TICK_PLACEMENT[_configurations.GraphConstant.FIVE_MINUTELY] = { datefield: DATEFIELD_MM, step: 5, spacing: 1000 * 60 * 5 }; this.TICK_PLACEMENT[_configurations.GraphConstant.TEN_MINUTELY] = { datefield: DATEFIELD_MM, step: 10, spacing: 1000 * 60 * 10 }; this.TICK_PLACEMENT[_configurations.GraphConstant.THIRTY_MINUTELY] = { datefield: DATEFIELD_MM, step: 30, spacing: 1000 * 60 * 30 }; this.TICK_PLACEMENT[_configurations.GraphConstant.HOURLY] = { datefield: DATEFIELD_HH, step: 1, spacing: 1000 * 3600 }; this.TICK_PLACEMENT[_configurations.GraphConstant.TWO_HOURLY] = { datefield: DATEFIELD_HH, step: 2, spacing: 1000 * 3600 * 2 }; this.TICK_PLACEMENT[_configurations.GraphConstant.SIX_HOURLY] = { datefield: DATEFIELD_HH, step: 6, spacing: 1000 * 3600 * 6 }; this.TICK_PLACEMENT[_configurations.GraphConstant.DAILY] = { datefield: DATEFIELD_D, step: 1, spacing: 1000 * 86400 }; this.TICK_PLACEMENT[_configurations.GraphConstant.TWO_DAILY] = { datefield: DATEFIELD_D, step: 2, spacing: 1000 * 86400 * 2 }; this.TICK_PLACEMENT[_configurations.GraphConstant.WEEKLY] = { datefield: DATEFIELD_D, step: 7, spacing: 1000 * 604800 }; this.TICK_PLACEMENT[_configurations.GraphConstant.MONTHLY] = { datefield: DATEFIELD_M, step: 1, spacing: 1000 * 7200 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 12 this.TICK_PLACEMENT[_configurations.GraphConstant.QUARTERLY] = { datefield: DATEFIELD_M, step: 3, spacing: 1000 * 21600 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 4 this.TICK_PLACEMENT[_configurations.GraphConstant.BIANNUAL] = { datefield: DATEFIELD_M, step: 6, spacing: 1000 * 43200 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 2 this.TICK_PLACEMENT[_configurations.GraphConstant.ANNUAL] = { datefield: DATEFIELD_Y, step: 1, spacing: 1000 * 86400 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 1 this.TICK_PLACEMENT[_configurations.GraphConstant.DECADAL] = { datefield: DATEFIELD_Y, step: 10, spacing: 1000 * 864000 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 10 this.TICK_PLACEMENT[_configurations.GraphConstant.CENTENNIAL] = { datefield: DATEFIELD_Y, step: 100, spacing: 1000 * 8640000 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 100 this.SHORT_SPACINGS = []; this.SHORT_SPACINGS[_configurations.GraphConstant.SECONDLY] = 1000 * 1; this.SHORT_SPACINGS[_configurations.GraphConstant.TWO_SECONDLY] = 1000 * 2; this.SHORT_SPACINGS[_configurations.GraphConstant.FIVE_SECONDLY] = 1000 * 5; this.SHORT_SPACINGS[_configurations.GraphConstant.TEN_SECONDLY] = 1000 * 10; this.SHORT_SPACINGS[_configurations.GraphConstant.THIRTY_SECONDLY] = 1000 * 30; this.SHORT_SPACINGS[_configurations.GraphConstant.MINUTELY] = 1000 * 60; this.SHORT_SPACINGS[_configurations.GraphConstant.TWO_MINUTELY] = 1000 * 60 * 2; this.SHORT_SPACINGS[_configurations.GraphConstant.FIVE_MINUTELY] = 1000 * 60 * 5; this.SHORT_SPACINGS[_configurations.GraphConstant.TEN_MINUTELY] = 1000 * 60 * 10; this.SHORT_SPACINGS[_configurations.GraphConstant.THIRTY_MINUTELY] = 1000 * 60 * 30; this.SHORT_SPACINGS[_configurations.GraphConstant.HOURLY] = 1000 * 3600; this.SHORT_SPACINGS[_configurations.GraphConstant.TWO_HOURLY] = 1000 * 3600 * 2; this.SHORT_SPACINGS[_configurations.GraphConstant.SIX_HOURLY] = 1000 * 3600 * 6; this.SHORT_SPACINGS[_configurations.GraphConstant.DAILY] = 1000 * 86400; this.SHORT_SPACINGS[_configurations.GraphConstant.WEEKLY] = 1000 * 604800; this.SHORT_SPACINGS[_configurations.GraphConstant.TWO_DAILY] = 1000 * 86400 * 2; } /** * update date format for legend and range-bar * @param format */ ; exports.Formatters = Formatters; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHRyYXMvZm9ybWF0dGVycy50cyJdLCJuYW1lcyI6WyJGb3JtYXR0ZXJzIiwidGltZXpvbmUiLCJmb3JtYXQiLCJkYXRlZm9ybWF0Iiwic3RhcnRfdGltZSIsImVuZF90aW1lIiwiZ3JhbnVsYXJpdHkiLCJzcGFjaW5nIiwiVElDS19QTEFDRU1FTlQiLCJNYXRoIiwicm91bmQiLCJhIiwiYiIsInBpeGVscyIsIm9wdHMiLCJwaXhlbHNfcGVyX3RpY2siLCJpIiwibnVtX3RpY2tzIiwibnVtRGF0ZVRpY2tzIiwieCIsInN0YXJ0IiwiZW5kIiwiZHlncmFwaCIsImZvcm1hdHRlciIsInRpY2tzIiwidCIsIkdyYXBoQ29uc3RhbnQiLCJNT05USExZIiwiU0hPUlRfU1BBQ0lOR1MiLCJnIiwiZCIsInR6IiwibW9tZW50IiwiZ3Vlc3MiLCJtaWxsaXNlY29uZCIsInNlY29uZCIsIm1pbnV0ZSIsImhvdXIiLCJzdGFydE9mIiwidmFsdWVPZiIsInN0YXJ0X29mZnNldF9taW4iLCJ1dGNPZmZzZXQiLCJjaGVja19kc3QiLCJUV09fSE9VUkxZIiwiZGVsdGFfbWluIiwicHVzaCIsInYiLCJsYWJlbCIsIm1vbnRocyIsInllYXJfbW9kIiwiUVVBUlRFUkxZIiwiQklBTk5VQUwiLCJBTk5VQUwiLCJERUNBREFMIiwiQ0VOVEVOTklBTCIsImNvbnNvbGUiLCJ3YXJuIiwic3RhcnRfeWVhciIsInllYXIiLCJlbmRfeWVhciIsImoiLCJsZW5ndGgiLCJkdCIsIkRhdGUiLCJ2YWxzIiwicGlja0RhdGVUaWNrR3JhbnVsYXJpdHkiLCJnZXREYXRlQXhpcyIsImRhdGEiLCJnZXRPcHRpb24iLCJzZXJpZXMiLCJtYXAiLCJkYXNoSFRNTCIsImxhYmVsSFRNTCIsImpvaW4iLCJodG1sIiwiZm9yRWFjaCIsImlzVmlzaWJsZSIsImluZGV4T2YiLCJsYWJlbGVkRGF0YSIsInlIVE1MIiwiaXNIaWdobGlnaHRlZCIsImNvbG9yIiwibW9tZW50RGF0ZXRpbWUiLCJnZXRUaW1lIiwiU0hPUlRfTU9OVEhfTkFNRVMiLCJ6ZXJvcGFkIiwiaG1zU3RyaW5nXyIsImhoIiwibW0iLCJzcyIsInJldCIsIkR5Z3JhcGgiLCJtb250aCIsImZyYWMiLCJob3VycyIsIm1pbnV0ZXMiLCJzZWNvbmRzIiwibWlsbGlzZWNvbmRzIiwiREFJTFkiLCJkYXRlIiwiREFURUZJRUxEX1kiLCJEQVRFRklFTERfTSIsIkRBVEVGSUVMRF9EIiwiREFURUZJRUxEX0hIIiwiREFURUZJRUxEX01NIiwiREFURUZJRUxEX1NTIiwiREFURUZJRUxEX01TIiwiTlVNX0RBVEVGSUVMRFMiLCJTRUNPTkRMWSIsImRhdGVmaWVsZCIsInN0ZXAiLCJUV09fU0VDT05ETFkiLCJGSVZFX1NFQ09ORExZIiwiVEVOX1NFQ09ORExZIiwiVEhJUlRZX1NFQ09ORExZIiwiTUlOVVRFTFkiLCJUV09fTUlOVVRFTFkiLCJGSVZFX01JTlVURUxZIiwiVEVOX01JTlVURUxZIiwiVEhJUlRZX01JTlVURUxZIiwiSE9VUkxZIiwiU0lYX0hPVVJMWSIsIlRXT19EQUlMWSIsIldFRUtMWSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztJQUdhQSxVO0FBRVQ7Ozs7OztBQWFBOzs7OztBQUtBLG9CQUFZQyxRQUFaLEVBQThCO0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQUEscUNBOEVYLFVBQUNDLE1BQUQsRUFBb0I7QUFDbkMsSUFBQSxLQUFJLENBQUNDLFVBQUwsR0FBa0JELE1BQWxCO0FBQ0gsR0FoRjZCOztBQUFBLHdDQW1GUCxVQUFDRSxVQUFELEVBQXFCQyxRQUFyQixFQUF1Q0MsV0FBdkMsRUFBK0Q7QUFDbEYsUUFBTUMsT0FBTyxHQUFHLEtBQUksQ0FBQ0MsY0FBTCxDQUFvQkYsV0FBcEIsRUFBaUNDLE9BQWpEO0FBQ0EsV0FBT0UsSUFBSSxDQUFDQyxLQUFMLENBQVcsT0FBT0wsUUFBUSxHQUFHRCxVQUFsQixJQUFnQ0csT0FBM0MsQ0FBUDtBQUNILEdBdEY2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dUYsWUFBbEMsSUFBa0QsT0FBTyxFQUF6RDtBQUNBLE9BQUtyRixjQUFMLENBQW9CRiw4QkFBY3dGLGVBQWxDLElBQXFELE9BQU8sRUFBNUQ7QUFDQSxPQUFLdEYsY0FBTCxDQUFvQkYsOEJBQWN5RixRQUFsQyxJQUE4QyxPQUFPLEVBQXJEO0FBQ0EsT0FBS3ZGLGNBQUwsQ0FBb0JGLDhCQUFjMEYsWUFBbEMsSUFBa0QsT0FBTyxFQUFQLEdBQVksQ0FBOUQ7QUFDQSxPQUFLeEYsY0FBTCxDQUFvQkYsOEJBQWMyRixhQUFsQyxJQUFtRCxPQUFPLEVBQVAsR0FBWSxDQUEvRDtBQUNBLE9BQUt6RixjQUFMLENBQW9CRiw4QkFBYzRGLFlBQWxDLElBQWtELE9BQU8sRUFBUCxHQUFZLEVBQTlEO0FBQ0EsT0FBSzFGLGNBQUwsQ0FBb0JGLDhCQUFjNkYsZUFBbEMsSUFBcUQsT0FBTyxFQUFQLEdBQVksRUFBakU7QUFDQSxPQUFLM0YsY0FBTCxDQUFvQkYsOEJBQWM4RixNQUFsQyxJQUE0QyxPQUFPLElBQW5EO0FBQ0EsT0FBSzVGLGNBQUwsQ0FBb0JGLDhCQUFjaUIsVUFBbEMsSUFBZ0QsT0FBTyxJQUFQLEdBQWMsQ0FBOUQ7QUFDQSxPQUFLZixjQUFMLENBQW9CRiw4QkFBYytGLFVBQWxDLElBQWdELE9BQU8sSUFBUCxHQUFjLENBQTlEO0FBQ0EsT0FBSzdGLGNBQUwsQ0FBb0JGLDhCQUFjd0UsS0FBbEMsSUFBMkMsT0FBTyxLQUFsRDtBQUNBLE9BQUt0RSxjQUFMLENBQW9CRiw4QkFBY2lHLE1BQWxDLElBQTRDLE9BQU8sTUFBbkQ7QUFDQSxPQUFLL0YsY0FBTCxDQUFvQkYsOEJBQWNnRyxTQUFsQyxJQUErQyxPQUFPLEtBQVAsR0FBZSxDQUE5RDtBQUNIO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRHlncmFwaCBmcm9tICdkeWdyYXBocyc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudC10aW1lem9uZSc7XG5pbXBvcnQge0dyYXBoQ29uc3RhbnR9IGZyb20gJy4uL21ldGFkYXRhL2NvbmZpZ3VyYXRpb25zJztcblxuXG5leHBvcnQgY2xhc3MgRm9ybWF0dGVycyB7XG5cbiAgICAvKipcbiAgICAgKnNob3cgZ3JhcGggdGltZXN0YW1wIHdpdGggdGhpcyB0aW1lem9uZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mIEZvcm1hdHRlcnNcbiAgICAgKi9cbiAgICBwdWJsaWMgdGltZXpvbmU6IHN0cmluZztcblxuICAgIHB1YmxpYyBkYXRlZm9ybWF0Pzogc3RyaW5nO1xuXG4gICAgcHJpdmF0ZSBUSUNLX1BMQUNFTUVOVDogYW55W107XG5cbiAgICBwcml2YXRlIFNIT1JUX1NQQUNJTkdTOiBhbnlbXTtcblxuICAgIC8qKlxuICAgICAqQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBGb3JtYXR0ZXJzLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aW1lem9uZSAgc2hvdyBncmFwaCB0aW1lc3RhbXAgd2l0aCB0aGlzIHRpbWV6b25lXG4gICAgICogQG1lbWJlcm9mIEZvcm1hdHRlcnNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0aW1lem9uZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMudGltZXpvbmUgPSB0aW1lem9uZTtcbiAgICAgICAgY29uc3QgREFURUZJRUxEX1kgPSAwO1xuICAgICAgICBjb25zdCBEQVRFRklFTERfTSA9IDE7XG4gICAgICAgIGNvbnN0IERBVEVGSUVMRF9EID0gMjtcbiAgICAgICAgY29uc3QgREFURUZJRUxEX0hIID0gMztcbiAgICAgICAgY29uc3QgREFURUZJRUxEX01NID0gNDtcbiAgICAgICAgY29uc3QgREFURUZJRUxEX1NTID0gNTtcbiAgICAgICAgY29uc3QgREFURUZJRUxEX01TID0gNjtcbiAgICAgICAgY29uc3QgTlVNX0RBVEVGSUVMRFMgPSA3O1xuXG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlQgPSBbXTtcbiAgICAgICAgdGhpcy5USUNLX1BMQUNFTUVOVFtHcmFwaENvbnN0YW50LlNFQ09ORExZXSA9IHtkYXRlZmllbGQ6IERBVEVGSUVMRF9TUywgc3RlcDogMSwgc3BhY2luZzogMTAwMCAqIDF9O1xuICAgICAgICB0aGlzLlRJQ0tfUExBQ0VNRU5UW0dyYXBoQ29uc3RhbnQuVFdPX1NFQ09ORExZXSA9IHtkYXRlZmllbGQ6IERBVEVGSUVMRF9TUywgc3RlcDogMiwgc3BhY2luZzogMTAwMCAqIDJ9O1xuICAgICAgICB0aGlzLlRJQ0tfUExBQ0VNRU5UW0dyYXBoQ29uc3RhbnQuRklWRV9TRUNPTkRMWV0gPSB7ZGF0ZWZpZWxkOiBEQVRFRklFTERfU1MsIHN0ZXA6IDUsIHNwYWNpbmc6IDEwMDAgKiA1fTtcbiAgICAgICAgdGhpcy5USUNLX1BMQUNFTUVOVFtHcmFwaENvbnN0YW50LlRFTl9TRUNPTkRMWV0gPSB7ZGF0ZWZpZWxkOiBEQVRFRklFTERfU1MsIHN0ZXA6IDEwLCBzcGFjaW5nOiAxMDAwICogMTB9O1xuICAgICAgICB0aGlzLlRJQ0tfUExBQ0VNRU5UW0dyYXBoQ29uc3RhbnQuVEhJUlRZX1NFQ09ORExZXSA9IHtkYXRlZmllbGQ6IERBVEVGSUVMRF9TUywgc3RlcDogMzAsIHNwYWNpbmc6IDEwMDAgKiAzMH07XG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5NSU5VVEVMWV0gPSB7ZGF0ZWZpZWxkOiBEQVRFRklFTERfTU0sIHN0ZXA6IDEsIHNwYWNpbmc6IDEwMDAgKiA2MH07XG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5UV09fTUlOVVRFTFldID0ge2RhdGVmaWVsZDogREFURUZJRUxEX01NLCBzdGVwOiAyLCBzcGFjaW5nOiAxMDAwICogNjAgKiAyfTtcbiAgICAgICAgdGhpcy5USUNLX1BMQUNFTUVOVFtHcmFwaENvbnN0YW50LkZJVkVfTUlOVVRFTFldID0ge2RhdGVmaWVsZDogREFURUZJRUxEX01NLCBzdGVwOiA1LCBzcGFjaW5nOiAxMDAwICogNjAgKiA1fTtcbiAgICAgICAgdGhpcy5USUNLX1BMQUNFTUVOVFtHcmFwaENvbnN0YW50LlRFTl9NSU5VVEVMWV0gPSB7ZGF0ZWZpZWxkOiBEQVRFRklFTERfTU0sIHN0ZXA6IDEwLCBzcGFjaW5nOiAxMDAwICogNjAgKiAxMH07XG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5USElSVFlfTUlOVVRFTFldID0ge1xuICAgICAgICAgICAgZGF0ZWZpZWxkOiBEQVRFRklFTERfTU0sXG4gICAgICAgICAgICBzdGVwOiAzMCxcbiAgICAgICAgICAgIHNwYWNpbmc6IDEwMDAgKiA2MCAqIDMwXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5IT1VSTFldID0ge2RhdGVmaWVsZDogREFURUZJRUxEX0hILCBzdGVwOiAxLCBzcGFjaW5nOiAxMDAwICogMzYwMH07XG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5UV09fSE9VUkxZXSA9IHtkYXRlZmllbGQ6IERBVEVGSUVMRF9ISCwgc3RlcDogMiwgc3BhY2luZzogMTAwMCAqIDM2MDAgKiAyfTtcbiAgICAgICAgdGhpcy5USUNLX1BMQUNFTUVOVFtHcmFwaENvbnN0YW50LlNJWF9IT1VSTFldID0ge2RhdGVmaWVsZDogREFURUZJRUxEX0hILCBzdGVwOiA2LCBzcGFjaW5nOiAxMDAwICogMzYwMCAqIDZ9O1xuICAgICAgICB0aGlzLlRJQ0tfUExBQ0VNRU5UW0dyYXBoQ29uc3RhbnQuREFJTFldID0ge2RhdGVmaWVsZDogREFURUZJRUxEX0QsIHN0ZXA6IDEsIHNwYWNpbmc6IDEwMDAgKiA4NjQwMH07XG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5UV09fREFJTFldID0ge2RhdGVmaWVsZDogREFURUZJRUxEX0QsIHN0ZXA6IDIsIHNwYWNpbmc6IDEwMDAgKiA4NjQwMCAqIDJ9O1xuICAgICAgICB0aGlzLlRJQ0tfUExBQ0VNRU5UW0dyYXBoQ29uc3RhbnQuV0VFS0xZXSA9IHtkYXRlZmllbGQ6IERBVEVGSUVMRF9ELCBzdGVwOiA3LCBzcGFjaW5nOiAxMDAwICogNjA0ODAwfTtcbiAgICAgICAgdGhpcy5USUNLX1BMQUNFTUVOVFtHcmFwaENvbnN0YW50Lk1PTlRITFldID0ge2RhdGVmaWVsZDogREFURUZJRUxEX00sIHN0ZXA6IDEsIHNwYWNpbmc6IDEwMDAgKiA3MjAwICogMzY1LjI1MjR9OyAvLyAxZTMgKiA2MCAqIDYwICogMjQgKiAzNjUuMjUyNCAvIDEyXG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5RVUFSVEVSTFldID0ge1xuICAgICAgICAgICAgZGF0ZWZpZWxkOiBEQVRFRklFTERfTSxcbiAgICAgICAgICAgIHN0ZXA6IDMsXG4gICAgICAgICAgICBzcGFjaW5nOiAxMDAwICogMjE2MDAgKiAzNjUuMjUyNFxuICAgICAgICB9OyAvLyAxZTMgKiA2MCAqIDYwICogMjQgKiAzNjUuMjUyNCAvIDRcbiAgICAgICAgdGhpcy5USUNLX1BMQUNFTUVOVFtHcmFwaENvbnN0YW50LkJJQU5OVUFMXSA9IHtcbiAgICAgICAgICAgIGRhdGVmaWVsZDogREFURUZJRUxEX00sXG4gICAgICAgICAgICBzdGVwOiA2LFxuICAgICAgICAgICAgc3BhY2luZzogMTAwMCAqIDQzMjAwICogMzY1LjI1MjRcbiAgICAgICAgfTsgLy8gMWUzICogNjAgKiA2MCAqIDI0ICogMzY1LjI1MjQgLyAyXG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5BTk5VQUxdID0ge2RhdGVmaWVsZDogREFURUZJRUxEX1ksIHN0ZXA6IDEsIHNwYWNpbmc6IDEwMDAgKiA4NjQwMCAqIDM2NS4yNTI0fTsgLy8gMWUzICogNjAgKiA2MCAqIDI0ICogMzY1LjI1MjQgKiAxXG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5ERUNBREFMXSA9IHtcbiAgICAgICAgICAgIGRhdGVmaWVsZDogREFURUZJRUxEX1ksXG4gICAgICAgICAgICBzdGVwOiAxMCxcbiAgICAgICAgICAgIHNwYWNpbmc6IDEwMDAgKiA4NjQwMDAgKiAzNjUuMjUyNFxuICAgICAgICB9OyAvLyAxZTMgKiA2MCAqIDYwICogMjQgKiAzNjUuMjUyNCAqIDEwXG4gICAgICAgIHRoaXMuVElDS19QTEFDRU1FTlRbR3JhcGhDb25zdGFudC5DRU5URU5OSUFMXSA9IHtcbiAgICAgICAgICAgIGRhdGVmaWVsZDogREFURUZJRUxEX1ksXG4gICAgICAgICAgICBzdGVwOiAxMDAsXG4gICAgICAgICAgICBzcGFjaW5nOiAxMDAwICogODY0MDAwMCAqIDM2NS4yNTI0XG4gICAgICAgIH07IC8vIDFlMyAqIDYwICogNjAgKiAyNCAqIDM2NS4yNTI0ICogMTAwXG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1MgPSBbXTtcbiAgICAgICAgdGhpcy5TSE9SVF9TUEFDSU5HU1tHcmFwaENvbnN0YW50LlNFQ09ORExZXSA9IDEwMDAgKiAxO1xuICAgICAgICB0aGlzLlNIT1JUX1NQQUNJTkdTW0dyYXBoQ29uc3RhbnQuVFdPX1NFQ09ORExZXSA9IDEwMDAgKiAyO1xuICAgICAgICB0aGlzLlNIT1JUX1NQQUNJTkdTW0dyYXBoQ29uc3RhbnQuRklWRV9TRUNPTkRMWV0gPSAxMDAwICogNTtcbiAgICAgICAgdGhpcy5TSE9SVF9TUEFDSU5HU1tHcmFwaENvbnN0YW50LlRFTl9TRUNPTkRMWV0gPSAxMDAwICogMTA7XG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5USElSVFlfU0VDT05ETFldID0gMTAwMCAqIDMwO1xuICAgICAgICB0aGlzLlNIT1JUX1NQQUNJTkdTW0dyYXBoQ29uc3RhbnQuTUlOVVRFTFldID0gMTAwMCAqIDYwO1xuICAgICAgICB0aGlzLlNIT1JUX1NQQUNJTkdTW0dyYXBoQ29uc3RhbnQuVFdPX01JTlVURUxZXSA9IDEwMDAgKiA2MCAqIDI7XG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5GSVZFX01JTlVURUxZXSA9IDEwMDAgKiA2MCAqIDU7XG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5URU5fTUlOVVRFTFldID0gMTAwMCAqIDYwICogMTA7XG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5USElSVFlfTUlOVVRFTFldID0gMTAwMCAqIDYwICogMzA7XG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5IT1VSTFldID0gMTAwMCAqIDM2MDA7XG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5UV09fSE9VUkxZXSA9IDEwMDAgKiAzNjAwICogMjtcbiAgICAgICAgdGhpcy5TSE9SVF9TUEFDSU5HU1tHcmFwaENvbnN0YW50LlNJWF9IT1VSTFldID0gMTAwMCAqIDM2MDAgKiA2O1xuICAgICAgICB0aGlzLlNIT1JUX1NQQUNJTkdTW0dyYXBoQ29uc3RhbnQuREFJTFldID0gMTAwMCAqIDg2NDAwO1xuICAgICAgICB0aGlzLlNIT1JUX1NQQUNJTkdTW0dyYXBoQ29uc3RhbnQuV0VFS0xZXSA9IDEwMDAgKiA2MDQ4MDA7XG4gICAgICAgIHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5UV09fREFJTFldID0gMTAwMCAqIDg2NDAwICogMjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIHVwZGF0ZSBkYXRlIGZvcm1hdCBmb3IgbGVnZW5kIGFuZCByYW5nZS1iYXJcbiAgICAgKiBAcGFyYW0gZm9ybWF0XG4gICAgICovXG4gICAgcHVibGljIHNldEZvcm1hdCA9IChmb3JtYXQ6IHN0cmluZykgPT4ge1xuICAgICAgICB0aGlzLmRhdGVmb3JtYXQgPSBmb3JtYXQ7XG4gICAgfTtcblxuXG4gICAgcHJpdmF0ZSBudW1EYXRlVGlja3MgPSAoc3RhcnRfdGltZTogbnVtYmVyLCBlbmRfdGltZTogbnVtYmVyLCBncmFudWxhcml0eTogbnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwYWNpbmcgPSB0aGlzLlRJQ0tfUExBQ0VNRU5UW2dyYW51bGFyaXR5XS5zcGFjaW5nO1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgxLjAgKiAoZW5kX3RpbWUgLSBzdGFydF90aW1lKSAvIHNwYWNpbmcpO1xuICAgIH07XG5cblxuICAgIHByaXZhdGUgcGlja0RhdGVUaWNrR3JhbnVsYXJpdHkgPSAoYTogYW55LCBiOiBhbnksIHBpeGVsczogYW55LCBvcHRzOiBhbnkpID0+IHtcbiAgICAgICAgbGV0IHBpeGVsc19wZXJfdGljayA9IG9wdHMoJ3BpeGVsc1BlckxhYmVsJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMjE7IGkrKykge1xuICAgICAgICAgICAgbGV0IG51bV90aWNrcyA9IHRoaXMubnVtRGF0ZVRpY2tzKGEsIGIsIGkpO1xuICAgICAgICAgICAgaWYgKHBpeGVscyAvIG51bV90aWNrcyA+PSBwaXhlbHNfcGVyX3RpY2spIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfTtcblxuICAgIHByaXZhdGUgemVyb3BhZCA9ICh4OiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKHggPCAxMCkgcmV0dXJuIFwiMFwiICsgeDsgZWxzZSByZXR1cm4gXCJcIiArIHg7XG4gICAgfTtcblxuXG4gICAgcHJpdmF0ZSBnZXREYXRlQXhpcyA9IChzdGFydDogYW55LCBlbmQ6IGFueSwgZ3JhbnVsYXJpdHk6IGFueSwgb3B0czogYW55LCBkeWdyYXBoOiBEeWdyYXBoKSA9PiB7XG4gICAgICAgIC8vXG4gICAgICAgIGxldCBmb3JtYXR0ZXIgPSAvKiogQHR5cGV7QXhpc0xhYmVsRm9ybWF0dGVyfSAqLyhcbiAgICAgICAgICAgIG9wdHMoXCJheGlzTGFiZWxGb3JtYXR0ZXJcIikpO1xuICAgICAgICBsZXQgdGlja3MgPSBbXTtcbiAgICAgICAgbGV0IHQ7XG5cbiAgICAgICAgaWYgKGdyYW51bGFyaXR5IDwgR3JhcGhDb25zdGFudC5NT05USExZKSB7XG4gICAgICAgICAgICAvLyBHZW5lcmF0ZSBvbmUgdGljayBtYXJrIGZvciBldmVyeSBmaXhlZCBpbnRlcnZhbCBvZiB0aW1lLlxuICAgICAgICAgICAgbGV0IHNwYWNpbmcgPSB0aGlzLlNIT1JUX1NQQUNJTkdTW2dyYW51bGFyaXR5XTtcbiAgICAgICAgICAgIC8vIEZpbmQgYSB0aW1lIGxlc3MgdGhhbiBzdGFydF90aW1lIHdoaWNoIG9jY3VycyBvbiBhIFwibmljZVwiIHRpbWUgYm91bmRhcnlcbiAgICAgICAgICAgIC8vIGZvciB0aGlzIGdyYW51bGFyaXR5LlxuICAgICAgICAgICAgbGV0IGcgPSBzcGFjaW5nIC8gMTAwMDtcbiAgICAgICAgICAgIGxldCBkID0gbW9tZW50KHN0YXJ0KS50eih0aGlzLnRpbWV6b25lID8gdGhpcy50aW1lem9uZSA6IG1vbWVudC50ei5ndWVzcygpKTtcbiAgICAgICAgICAgIGQubWlsbGlzZWNvbmQoMCk7XG4gICAgICAgICAgICBsZXQgeDtcbiAgICAgICAgICAgIGlmIChnIDw9IDYwKSB7ICAvLyBzZWNvbmRzXG4gICAgICAgICAgICAgICAgeCA9IGQuc2Vjb25kKCk7XG4gICAgICAgICAgICAgICAgZC5zZWNvbmQoeCAtIHggJSBnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZC5zZWNvbmQoMCk7XG4gICAgICAgICAgICAgICAgZyAvPSA2MDtcbiAgICAgICAgICAgICAgICBpZiAoZyA8PSA2MCkgeyAgLy8gbWludXRlc1xuICAgICAgICAgICAgICAgICAgICB4ID0gZC5taW51dGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZC5taW51dGUoeCAtIHggJSBnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkLm1pbnV0ZSgwKTtcbiAgICAgICAgICAgICAgICAgICAgZyAvPSA2MDtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZyA8PSAyNCkgeyAgLy8gZGF5c1xuICAgICAgICAgICAgICAgICAgICAgICAgeCA9IGQuaG91cigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZC5ob3VyKHggLSB4ICUgZyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkLmhvdXIoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBnIC89IDI0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZyA9PSA3KSB7ICAvLyBvbmUgd2Vla1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuc3RhcnRPZignd2VlaycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RhcnQgPSBkLnZhbHVlT2YoKTtcblxuICAgICAgICAgICAgbGV0IHN0YXJ0X29mZnNldF9taW4gPSBtb21lbnQoc3RhcnQpLnR6KHRoaXMudGltZXpvbmUgPyB0aGlzLnRpbWV6b25lIDogbW9tZW50LnR6Lmd1ZXNzKCkpLnV0Y09mZnNldCgpO1xuICAgICAgICAgICAgbGV0IGNoZWNrX2RzdCA9IChzcGFjaW5nID49IHRoaXMuU0hPUlRfU1BBQ0lOR1NbR3JhcGhDb25zdGFudC5UV09fSE9VUkxZXSk7XG4gICAgICAgICAgICBmb3IgKHQgPSBzdGFydDsgdCA8PSBlbmQ7IHQgKz0gc3BhY2luZykge1xuICAgICAgICAgICAgICAgIGxldCBkID0gbW9tZW50KHQpLnR6KHRoaXMudGltZXpvbmUgPyB0aGlzLnRpbWV6b25lIDogbW9tZW50LnR6Lmd1ZXNzKCkpO1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUuaW5mbyhjaGVja19kc3QgLCBkLnV0Y09mZnNldCgpICwgc3RhcnRfb2Zmc2V0X21pbik7XG4gICAgICAgICAgICAgICAgaWYgKGNoZWNrX2RzdCAmJiBkLnV0Y09mZnNldCgpICE9IHN0YXJ0X29mZnNldF9taW4pIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGRlbHRhX21pbiA9IC0oZC51dGNPZmZzZXQoKSAtIHN0YXJ0X29mZnNldF9taW4pO1xuICAgICAgICAgICAgICAgICAgICB0ICs9IGRlbHRhX21pbiAqIDYwICogMTAwMDtcbiAgICAgICAgICAgICAgICAgICAgZCA9IG1vbWVudCh0KS50eih0aGlzLnRpbWV6b25lID8gdGhpcy50aW1lem9uZSA6IG1vbWVudC50ei5ndWVzcygpKTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRfb2Zmc2V0X21pbiA9IGQudXRjT2Zmc2V0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB3ZSd2ZSBiYWNrZWQgaW50byB0aGUgcHJldmlvdXMgdGltZXpvbmUgYWdhaW4uXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgY2FuIGhhcHBlbiBkdXJpbmcgYSBcImRheSBsaWdodFwiIHRyYW5zaXRpb24uIEluIHRoaXMgY2FzZSxcbiAgICAgICAgICAgICAgICAgICAgLy8gaXQncyBiZXN0IHRvIHNraXAgdGhpcyB0aWNrIGFsdG9nZXRoZXIgKHdlIG1heSBiZSBzaG9vdGluZyBmb3IgYVxuICAgICAgICAgICAgICAgICAgICAvLyBub24tZXhpc3RlbnQgdGltZSBsaWtlIHRoZSAyQU0gdGhhdCdzIHNraXBwZWQpIGFuZCBnbyB0byB0aGUgbmV4dFxuICAgICAgICAgICAgICAgICAgICAvLyBvbmUuXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG1vbWVudCh0ICsgc3BhY2luZykudHoodGhpcy50aW1lem9uZSA/IHRoaXMudGltZXpvbmUgOiBtb21lbnQudHouZ3Vlc3MoKSkudXRjT2Zmc2V0KCkgIT0gc3RhcnRfb2Zmc2V0X21pbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdCArPSBzcGFjaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgZCA9IG1vbWVudCh0KS50eih0aGlzLnRpbWV6b25lID8gdGhpcy50aW1lem9uZSA6IG1vbWVudC50ei5ndWVzcygpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0X29mZ