@nova-ui/bits
Version:
SolarWinds Nova Framework
226 lines (224 loc) • 28.2 kB
JavaScript
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import { Injectable } from "@angular/core";
import extend from "lodash/extend";
import isUndefined from "lodash/isUndefined";
import moment from "moment/moment";
import * as i0 from "@angular/core";
/**
* __Name : __
* Timeframe service
*
* __Usage :__
* Used to get time frames via time patterns or presets
*/
/**
* @ignore
*/
export class TimeframeService {
static cloneTimeFrame(timeFrame) {
return {
...timeFrame,
startDatetime: timeFrame.startDatetime.clone(),
endDatetime: timeFrame.endDatetime.clone(),
};
}
constructor() {
this.defaultPresets = {
lastHour: {
name: $localize `Last hour`,
startDatetimePattern: { hours: -1 },
endDatetimePattern: {},
},
last12Hours: {
name: $localize `Last 12 hours`,
startDatetimePattern: { hours: -12 },
endDatetimePattern: {},
},
last24Hours: {
name: $localize `Last 24 hours`,
startDatetimePattern: { hours: -24 },
endDatetimePattern: {},
},
last5Days: {
name: $localize `Last 5 days`,
startDatetimePattern: { days: -5 },
endDatetimePattern: {},
},
last7Days: {
name: $localize `Last 7 days`,
startDatetimePattern: { days: -7 },
endDatetimePattern: {},
},
last30Days: {
name: $localize `Last 30 days`,
startDatetimePattern: { days: -30 },
endDatetimePattern: {},
},
};
this.currentPresets = extend({}, this.defaultPresets);
/**
* __Description:__ Updates start and end time of timeframe according to preset if selected
*
* @param timeFrame timeframe to be updated
* @param presets presets to look at. Defaults to service's currentPresets
* @param baseDatetime date that should be used for relative time calculations. Defaults to now.
* @returns updated clone of timeframe with startDatetime and endDatetime reconciled with selectedPresetId
*/
this.reconcileTimeframe = (timeFrame, presets, baseDatetime) => {
if (!presets) {
presets = this.currentPresets;
}
if (!baseDatetime) {
baseDatetime = moment();
}
const preset = timeFrame.selectedPresetId && presets[timeFrame.selectedPresetId];
return preset
? {
...timeFrame,
startDatetime: baseDatetime
.clone()
.add(preset.startDatetimePattern),
endDatetime: baseDatetime
.clone()
.add(preset.endDatetimePattern),
}
: TimeframeService.cloneTimeFrame(timeFrame);
};
}
/**
*
* __Description:__ Get timeframe from patterns of start and end points in time
* @param startDatetimePattern
* @param endDatetimePattern
* @param baseDatetime
*/
getTimeframe(startDatetimePattern, endDatetimePattern, baseDatetime) {
// check input parameters
if (isUndefined(startDatetimePattern)) {
throw new Error("Parameter 'startDatetimePattern' is undefined");
}
if (isUndefined(endDatetimePattern)) {
throw new Error("Parameter 'endDateTimePattern' is undefined");
}
const startDatetime = moment(baseDatetime).add(startDatetimePattern);
const endDatetime = moment(baseDatetime).add(endDatetimePattern);
return {
startDatetime: startDatetime,
endDatetime: endDatetime,
// @ts-ignore: preventing breaking default flow;
selectedPresetId: null,
};
}
/**
* __Description:__ Get timeframe by preset id, using the list of pre-defined presets
*/
getTimeframeByPresetId(id, baseDatetime) {
// check input parameters
if (isUndefined(id)) {
throw new Error("Parameter 'id' is undefined");
}
const startDatetime = moment(baseDatetime).add(this.currentPresets[id].startDatetimePattern);
const endDatetime = moment(baseDatetime).add(this.currentPresets[id].endDatetimePattern);
return {
startDatetime: startDatetime,
endDatetime: endDatetime,
selectedPresetId: id,
title: this.currentPresets[id].name,
};
}
/**
* __Description:__ Get the list of all default presets
*/
getDefaultPresets() {
return this.defaultPresets;
}
/**
* __Description:__ Add custom presets to existing list of default presets
* @param presets
*/
extendCurrentPresets(presets) {
extend(this.currentPresets, presets);
}
/**
* __Description:__ Compare two timeframes, return false if they are not equal
*/
isEqual(firstTimeFrame, secondTimeFrame, units = "minutes") {
return (firstTimeFrame &&
secondTimeFrame &&
firstTimeFrame.endDatetime.isSame(secondTimeFrame.endDatetime, units) &&
firstTimeFrame.startDatetime.isSame(secondTimeFrame.startDatetime, units));
}
/**
* __Description:__ Compare two timeframe durations, return false if they are not equal
*/
isEqualDuration(firstTimeFrame, secondTimeFrame, units = "minutes") {
return (firstTimeFrame &&
secondTimeFrame &&
firstTimeFrame.startDatetime.diff(firstTimeFrame.endDatetime, units) ===
secondTimeFrame.startDatetime.diff(secondTimeFrame.endDatetime, units));
}
/**
* __Description:__
* Adds the specified duration to startDatetime and endDatetime and returns a new timeframe.
* Note: Input timeframe is not mutated.
*
* @param {ITimeframe} timeFrame The timeframe to shift
* @param {Duration} duration The duration of the timeframe shift
* @returns {ITimeframe} The shifted timeframe
*/
shiftTimeFrame(timeFrame, duration) {
return {
startDatetime: timeFrame.startDatetime.clone().add(duration),
endDatetime: timeFrame.endDatetime.clone().add(duration),
// @ts-ignore: preventing breaking default flow;
selectedPresetId: null,
};
}
/**
* __Description:__
* Returns the difference between timeFrame's startDatetime and endDatetime as moment.Duration
*
* @param {ITimeframe} timeFrame
* @returns {Duration}
*/
getDuration(timeFrame) {
return moment.duration(timeFrame.endDatetime.diff(timeFrame.startDatetime));
}
/**
* __Description:__
* Checks timeFrame "startDatetime" and "endDatetime" attributes for moment validity
*
* @param {ITimeframe} tf
* @returns {Boolean}
*/
areTimeFrameDatesValid(tf) {
const { startDatetime, endDatetime } = tf;
const startValid = startDatetime && startDatetime.isValid();
const endValid = endDatetime && endDatetime.isValid();
return startValid && endValid;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeframeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeframeService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeframeService, decorators: [{
type: Injectable
}], ctorParameters: () => [] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWZyYW1lLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RpbWUtZnJhbWUtcGlja2VyL3NlcnZpY2VzL3RpbWVmcmFtZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sTUFBTSxNQUFNLGVBQWUsQ0FBQztBQUNuQyxPQUFPLFdBQVcsTUFBTSxvQkFBb0IsQ0FBQztBQUM3QyxPQUFPLE1BQTRCLE1BQU0sZUFBZSxDQUFDOztBQUl6RDs7Ozs7O0dBTUc7QUFDSDs7R0FFRztBQUVILE1BQU0sT0FBTyxnQkFBZ0I7SUFDbEIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxTQUFxQjtRQUM5QyxPQUFPO1lBQ0gsR0FBRyxTQUFTO1lBQ1osYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFO1lBQzlDLFdBQVcsRUFBRSxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRTtTQUM3QyxDQUFDO0lBQ04sQ0FBQztJQXdDRDtRQXRDTyxtQkFBYyxHQUErQjtZQUNoRCxRQUFRLEVBQUU7Z0JBQ04sSUFBSSxFQUFFLFNBQVMsQ0FBQSxXQUFXO2dCQUMxQixvQkFBb0IsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRTtnQkFDbkMsa0JBQWtCLEVBQUUs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QUM7K0dBM1BRLGdCQUFnQjttSEFBaEIsZ0JBQWdCOzs0RkFBaEIsZ0JBQWdCO2tCQUQ1QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IGV4dGVuZCBmcm9tIFwibG9kYXNoL2V4dGVuZFwiO1xuaW1wb3J0IGlzVW5kZWZpbmVkIGZyb20gXCJsb2Rhc2gvaXNVbmRlZmluZWRcIjtcbmltcG9ydCBtb21lbnQsIHsgRHVyYXRpb24sIE1vbWVudCB9IGZyb20gXCJtb21lbnQvbW9tZW50XCI7XG5cbmltcG9ydCB7IElUaW1lZnJhbWUsIElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5IH0gZnJvbSBcIi4uL3B1YmxpYy1hcGlcIjtcblxuLyoqXG4gKiBfX05hbWUgOiBfX1xuICogVGltZWZyYW1lIHNlcnZpY2VcbiAqXG4gKiBfX1VzYWdlIDpfX1xuICogVXNlZCB0byBnZXQgdGltZSBmcmFtZXMgdmlhIHRpbWUgcGF0dGVybnMgb3IgcHJlc2V0c1xuICovXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFRpbWVmcmFtZVNlcnZpY2Uge1xuICAgIHB1YmxpYyBzdGF0aWMgY2xvbmVUaW1lRnJhbWUodGltZUZyYW1lOiBJVGltZWZyYW1lKTogSVRpbWVmcmFtZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi50aW1lRnJhbWUsXG4gICAgICAgICAgICBzdGFydERhdGV0aW1lOiB0aW1lRnJhbWUuc3RhcnREYXRldGltZS5jbG9uZSgpLFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWU6IHRpbWVGcmFtZS5lbmREYXRldGltZS5jbG9uZSgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWZhdWx0UHJlc2V0czogSVRpbWVGcmFtZVByZXNldERpY3Rpb25hcnkgPSB7XG4gICAgICAgIGxhc3RIb3VyOiB7XG4gICAgICAgICAgICBuYW1lOiAkbG9jYWxpemVgTGFzdCBob3VyYCxcbiAgICAgICAgICAgIHN0YXJ0RGF0ZXRpbWVQYXR0ZXJuOiB7IGhvdXJzOiAtMSB9LFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWVQYXR0ZXJuOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgbGFzdDEySG91cnM6IHtcbiAgICAgICAgICAgIG5hbWU6ICRsb2NhbGl6ZWBMYXN0IDEyIGhvdXJzYCxcbiAgICAgICAgICAgIHN0YXJ0RGF0ZXRpbWVQYXR0ZXJuOiB7IGhvdXJzOiAtMTIgfSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lUGF0dGVybjoge30sXG4gICAgICAgIH0sXG4gICAgICAgIGxhc3QyNEhvdXJzOiB7XG4gICAgICAgICAgICBuYW1lOiAkbG9jYWxpemVgTGFzdCAyNCBob3Vyc2AsXG4gICAgICAgICAgICBzdGFydERhdGV0aW1lUGF0dGVybjogeyBob3VyczogLTI0IH0sXG4gICAgICAgICAgICBlbmREYXRldGltZVBhdHRlcm46IHt9LFxuICAgICAgICB9LFxuICAgICAgICBsYXN0NURheXM6IHtcbiAgICAgICAgICAgIG5hbWU6ICRsb2NhbGl6ZWBMYXN0IDUgZGF5c2AsXG4gICAgICAgICAgICBzdGFydERhdGV0aW1lUGF0dGVybjogeyBkYXlzOiAtNSB9LFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWVQYXR0ZXJuOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgbGFzdDdEYXlzOiB7XG4gICAgICAgICAgICBuYW1lOiAkbG9jYWxpemVgTGFzdCA3IGRheXNgLFxuICAgICAgICAgICAgc3RhcnREYXRldGltZVBhdHRlcm46IHsgZGF5czogLTcgfSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lUGF0dGVybjoge30sXG4gICAgICAgIH0sXG4gICAgICAgIGxhc3QzMERheXM6IHtcbiAgICAgICAgICAgIG5hbWU6ICRsb2NhbGl6ZWBMYXN0IDMwIGRheXNgLFxuICAgICAgICAgICAgc3RhcnREYXRldGltZVBhdHRlcm46IHsgZGF5czogLTMwIH0sXG4gICAgICAgICAgICBlbmREYXRldGltZVBhdHRlcm46IHt9LFxuICAgICAgICB9LFxuICAgIH07XG5cbiAgICBwdWJsaWMgY3VycmVudFByZXNldHM6IElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5ID0gZXh0ZW5kKFxuICAgICAgICB7fSxcbiAgICAgICAgdGhpcy5kZWZhdWx0UHJlc2V0c1xuICAgICk7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIF9fRGVzY3JpcHRpb246X18gR2V0IHRpbWVmcmFtZSBmcm9tIHBhdHRlcm5zIG9mIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGluIHRpbWVcbiAgICAgKiBAcGFyYW0gc3RhcnREYXRldGltZVBhdHRlcm5cbiAgICAgKiBAcGFyYW0gZW5kRGF0ZXRpbWVQYXR0ZXJuXG4gICAgICogQHBhcmFtIGJhc2VEYXRldGltZVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRUaW1lZnJhbWUoXG4gICAgICAgIHN0YXJ0RGF0ZXRpbWVQYXR0ZXJuOiBhbnksXG4gICAgICAgIGVuZERhdGV0aW1lUGF0dGVybjogYW55LFxuICAgICAgICBiYXNlRGF0ZXRpbWU/OiBzdHJpbmdcbiAgICApOiBJVGltZWZyYW1lIHtcbiAgICAgICAgLy8gY2hlY2sgaW5wdXQgcGFyYW1ldGVyc1xuICAgICAgICBpZiAoaXNVbmRlZmluZWQoc3RhcnREYXRldGltZVBhdHRlcm4pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXJhbWV0ZXIgJ3N0YXJ0RGF0ZXRpbWVQYXR0ZXJuJyBpcyB1bmRlZmluZWRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNVbmRlZmluZWQoZW5kRGF0ZXRpbWVQYXR0ZXJuKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFyYW1ldGVyICdlbmREYXRlVGltZVBhdHRlcm4nIGlzIHVuZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZXRpbWUgPSBtb21lbnQoYmFzZURhdGV0aW1lKS5hZGQoc3RhcnREYXRldGltZVBhdHRlcm4pO1xuICAgICAgICBjb25zdCBlbmREYXRldGltZSA9IG1vbWVudChiYXNlRGF0ZXRpbWUpLmFkZChlbmREYXRldGltZVBhdHRlcm4pO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGFydERhdGV0aW1lOiBzdGFydERhdGV0aW1lLFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWU6IGVuZERhdGV0aW1lLFxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogcHJldmVudGluZyBicmVha2luZyBkZWZhdWx0IGZsb3c7XG4gICAgICAgICAgICBzZWxlY3RlZFByZXNldElkOiBudWxsLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIF9fRGVzY3JpcHRpb246X18gR2V0IHRpbWVmcmFtZSBieSBwcmVzZXQgaWQsIHVzaW5nIHRoZSBsaXN0IG9mIHByZS1kZWZpbmVkIHByZXNldHNcblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRUaW1lZnJhbWVCeVByZXNldElkKFxuICAgICAgICBpZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgICAgICBiYXNlRGF0ZXRpbWU/OiBzdHJpbmdcbiAgICApOiBJVGltZWZyYW1lIHtcbiAgICAgICAgLy8gY2hlY2sgaW5wdXQgcGFyYW1ldGVyc1xuICAgICAgICBpZiAoaXNVbmRlZmluZWQoaWQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXJhbWV0ZXIgJ2lkJyBpcyB1bmRlZmluZWRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdGFydERhdGV0aW1lID0gbW9tZW50KGJhc2VEYXRldGltZSkuYWRkKFxuICAgICAgICAgICAgdGhpcy5jdXJyZW50UHJlc2V0c1tpZF0uc3RhcnREYXRldGltZVBhdHRlcm5cbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZW5kRGF0ZXRpbWUgPSBtb21lbnQoYmFzZURhdGV0aW1lKS5hZGQoXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRQcmVzZXRzW2lkXS5lbmREYXRldGltZVBhdHRlcm5cbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhcnREYXRldGltZTogc3RhcnREYXRldGltZSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lOiBlbmREYXRldGltZSxcbiAgICAgICAgICAgIHNlbGVjdGVkUHJlc2V0SWQ6IGlkLFxuICAgICAgICAgICAgdGl0bGU6IHRoaXMuY3VycmVudFByZXNldHNbaWRdLm5hbWUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBVcGRhdGVzIHN0YXJ0IGFuZCBlbmQgdGltZSBvZiB0aW1lZnJhbWUgYWNjb3JkaW5nIHRvIHByZXNldCBpZiBzZWxlY3RlZFxuICAgICAqXG4gICAgICogQHBhcmFtIHRpbWVGcmFtZSB0aW1lZnJhbWUgdG8gYmUgdXBkYXRlZFxuICAgICAqIEBwYXJhbSBwcmVzZXRzIHByZXNldHMgdG8gbG9vayBhdC4gRGVmYXVsdHMgdG8gc2VydmljZSdzIGN1cnJlbnRQcmVzZXRzXG4gICAgICogQHBhcmFtIGJhc2VEYXRldGltZSBkYXRlIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHJlbGF0aXZlIHRpbWUgY2FsY3VsYXRpb25zLiBEZWZhdWx0cyB0byBub3cuXG4gICAgICogQHJldHVybnMgdXBkYXRlZCBjbG9uZSBvZiB0aW1lZnJhbWUgd2l0aCBzdGFydERhdGV0aW1lIGFuZCBlbmREYXRldGltZSByZWNvbmNpbGVkIHdpdGggc2VsZWN0ZWRQcmVzZXRJZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWNvbmNpbGVUaW1lZnJhbWUgPSAoXG4gICAgICAgIHRpbWVGcmFtZTogSVRpbWVmcmFtZSxcbiAgICAgICAgcHJlc2V0cz86IElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5LFxuICAgICAgICBiYXNlRGF0ZXRpbWU/OiBNb21lbnRcbiAgICApOiBJVGltZWZyYW1lID0+IHtcbiAgICAgICAgaWYgKCFwcmVzZXRzKSB7XG4gICAgICAgICAgICBwcmVzZXRzID0gdGhpcy5jdXJyZW50UHJlc2V0cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWJhc2VEYXRldGltZSkge1xuICAgICAgICAgICAgYmFzZURhdGV0aW1lID0gbW9tZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVzZXQgPVxuICAgICAgICAgICAgdGltZUZyYW1lLnNlbGVjdGVkUHJlc2V0SWQgJiYgcHJlc2V0c1t0aW1lRnJhbWUuc2VsZWN0ZWRQcmVzZXRJZF07XG4gICAgICAgIHJldHVybiBwcmVzZXRcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgLi4udGltZUZyYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhcnREYXRldGltZTogYmFzZURhdGV0aW1lXG4gICAgICAgICAgICAgICAgICAgICAgLmNsb25lKClcbiAgICAgICAgICAgICAgICAgICAgICAuYWRkKHByZXNldC5zdGFydERhdGV0aW1lUGF0dGVybiksXG4gICAgICAgICAgICAgICAgICBlbmREYXRldGltZTogYmFzZURhdGV0aW1lXG4gICAgICAgICAgICAgICAgICAgICAgLmNsb25lKClcbiAgICAgICAgICAgICAgICAgICAgICAuYWRkKHByZXNldC5lbmREYXRldGltZVBhdHRlcm4pLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IFRpbWVmcmFtZVNlcnZpY2UuY2xvbmVUaW1lRnJhbWUodGltZUZyYW1lKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBHZXQgdGhlIGxpc3Qgb2YgYWxsIGRlZmF1bHQgcHJlc2V0c1xuXG4gICAgICovXG4gICAgcHVibGljIGdldERlZmF1bHRQcmVzZXRzKCk6IElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVmYXVsdFByZXNldHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBBZGQgY3VzdG9tIHByZXNldHMgdG8gZXhpc3RpbmcgbGlzdCBvZiBkZWZhdWx0IHByZXNldHNcbiAgICAgKiBAcGFyYW0gcHJlc2V0c1xuICAgICAqL1xuICAgIHB1YmxpYyBleHRlbmRDdXJyZW50UHJlc2V0cyhwcmVzZXRzOiBJVGltZUZyYW1lUHJlc2V0RGljdGlvbmFyeSk6IHZvaWQge1xuICAgICAgICBleHRlbmQodGhpcy5jdXJyZW50UHJlc2V0cywgcHJlc2V0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBDb21wYXJlIHR3byB0aW1lZnJhbWVzLCByZXR1cm4gZmFsc2UgaWYgdGhleSBhcmUgbm90IGVxdWFsXG4gICAgICovXG4gICAgcHVibGljIGlzRXF1YWwoXG4gICAgICAgIGZpcnN0VGltZUZyYW1lOiBJVGltZWZyYW1lLFxuICAgICAgICBzZWNvbmRUaW1lRnJhbWU6IElUaW1lZnJhbWUsXG4gICAgICAgIHVuaXRzOiBtb21lbnQudW5pdE9mVGltZS5CYXNlID0gXCJtaW51dGVzXCJcbiAgICApOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lICYmXG4gICAgICAgICAgICBzZWNvbmRUaW1lRnJhbWUgJiZcbiAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lLmVuZERhdGV0aW1lLmlzU2FtZShcbiAgICAgICAgICAgICAgICBzZWNvbmRUaW1lRnJhbWUuZW5kRGF0ZXRpbWUsXG4gICAgICAgICAgICAgICAgdW5pdHNcbiAgICAgICAgICAgICkgJiZcbiAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lLnN0YXJ0RGF0ZXRpbWUuaXNTYW1lKFxuICAgICAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZS5zdGFydERhdGV0aW1lLFxuICAgICAgICAgICAgICAgIHVuaXRzXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBDb21wYXJlIHR3byB0aW1lZnJhbWUgZHVyYXRpb25zLCByZXR1cm4gZmFsc2UgaWYgdGhleSBhcmUgbm90IGVxdWFsXG4gICAgICovXG4gICAgcHVibGljIGlzRXF1YWxEdXJhdGlvbihcbiAgICAgICAgZmlyc3RUaW1lRnJhbWU6IElUaW1lZnJhbWUsXG4gICAgICAgIHNlY29uZFRpbWVGcmFtZTogSVRpbWVmcmFtZSxcbiAgICAgICAgdW5pdHM6IG1vbWVudC51bml0T2ZUaW1lLkJhc2UgPSBcIm1pbnV0ZXNcIlxuICAgICk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgZmlyc3RUaW1lRnJhbWUgJiZcbiAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZSAmJlxuICAgICAgICAgICAgZmlyc3RUaW1lRnJhbWUuc3RhcnREYXRldGltZS5kaWZmKFxuICAgICAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lLmVuZERhdGV0aW1lLFxuICAgICAgICAgICAgICAgIHVuaXRzXG4gICAgICAgICAgICApID09PVxuICAgICAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZS5zdGFydERhdGV0aW1lLmRpZmYoXG4gICAgICAgICAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZS5lbmREYXRldGltZSxcbiAgICAgICAgICAgICAgICAgICAgdW5pdHNcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfX1xuICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBkdXJhdGlvbiB0byBzdGFydERhdGV0aW1lIGFuZCBlbmREYXRldGltZSBhbmQgcmV0dXJucyBhIG5ldyB0aW1lZnJhbWUuXG4gICAgICogTm90ZTogSW5wdXQgdGltZWZyYW1lIGlzIG5vdCBtdXRhdGVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtJVGltZWZyYW1lfSB0aW1lRnJhbWUgVGhlIHRpbWVmcmFtZSB0byBzaGlmdFxuICAgICAqIEBwYXJhbSB7RHVyYXRpb259IGR1cmF0aW9uIFRoZSBkdXJhdGlvbiBvZiB0aGUgdGltZWZyYW1lIHNoaWZ0XG4gICAgICogQHJldHVybnMge0lUaW1lZnJhbWV9IFRoZSBzaGlmdGVkIHRpbWVmcmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBzaGlmdFRpbWVGcmFtZShcbiAgICAgICAgdGltZUZyYW1lOiBJVGltZWZyYW1lLFxuICAgICAgICBkdXJhdGlvbjogRHVyYXRpb25cbiAgICApOiBJVGltZWZyYW1lIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0RGF0ZXRpbWU6IHRpbWVGcmFtZS5zdGFydERhdGV0aW1lLmNsb25lKCkuYWRkKGR1cmF0aW9uKSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lOiB0aW1lRnJhbWUuZW5kRGF0ZXRpbWUuY2xvbmUoKS5hZGQoZHVyYXRpb24pLFxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogcHJldmVudGluZyBicmVha2luZyBkZWZhdWx0IGZsb3c7XG4gICAgICAgICAgICBzZWxlY3RlZFByZXNldElkOiBudWxsLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIF9fRGVzY3JpcHRpb246X19cbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGltZUZyYW1lJ3Mgc3RhcnREYXRldGltZSBhbmQgZW5kRGF0ZXRpbWUgYXMgbW9tZW50LkR1cmF0aW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0lUaW1lZnJhbWV9IHRpbWVGcmFtZVxuICAgICAqIEByZXR1cm5zIHtEdXJhdGlvbn1cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0RHVyYXRpb24odGltZUZyYW1lOiBJVGltZWZyYW1lKTogRHVyYXRpb24ge1xuICAgICAgICByZXR1cm4gbW9tZW50LmR1cmF0aW9uKFxuICAgICAgICAgICAgdGltZUZyYW1lLmVuZERhdGV0aW1lLmRpZmYodGltZUZyYW1lLnN0YXJ0RGF0ZXRpbWUpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfX1xuICAgICAqIENoZWNrcyB0aW1lRnJhbWUgXCJzdGFydERhdGV0aW1lXCIgYW5kIFwiZW5kRGF0ZXRpbWVcIiBhdHRyaWJ1dGVzIGZvciBtb21lbnQgdmFsaWRpdHlcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SVRpbWVmcmFtZX0gdGZcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBwdWJsaWMgYXJlVGltZUZyYW1lRGF0ZXNWYWxpZCh0ZjogSVRpbWVmcmFtZSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB7IHN0YXJ0RGF0ZXRpbWUsIGVuZERhdGV0aW1lIH0gPSB0ZjtcbiAgICAgICAgY29uc3Qgc3RhcnRWYWxpZCA9IHN0YXJ0RGF0ZXRpbWUgJiYgc3RhcnREYXRldGltZS5pc1ZhbGlkKCk7XG4gICAgICAgIGNvbnN0IGVuZFZhbGlkID0gZW5kRGF0ZXRpbWUgJiYgZW5kRGF0ZXRpbWUuaXNWYWxpZCgpO1xuXG4gICAgICAgIHJldHVybiBzdGFydFZhbGlkICYmIGVuZFZhbGlkO1xuICAgIH1cbn1cbiJdfQ==