@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
273 lines • 32.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Duration = void 0;
const token_1 = require("./token");
/**
* Represents a length of time.
*
* The amount can be specified either as a literal value (e.g: `10`) which
* cannot be negative, or as an unresolved number token.
*
* When the amount is passed as a token, unit conversion is not possible.
*/
class Duration {
constructor(amount, unit) {
if (!token_1.Token.isUnresolved(amount) && amount < 0) {
throw new Error(`Duration amounts cannot be negative. Received: ${amount}`);
}
this.amount = amount;
this.unit = unit;
}
/**
* Create a Duration representing an amount of milliseconds.
*
* @param amount the amount of Milliseconds the `Duration` will represent.
* @returns a new `Duration` representing `amount` ms.
*/
static millis(amount) {
return new Duration(amount, TimeUnit.Milliseconds);
}
/**
* Create a Duration representing an amount of seconds.
*
* @param amount the amount of Seconds the `Duration` will represent.
* @returns a new `Duration` representing `amount` Seconds.
*/
static seconds(amount) {
return new Duration(amount, TimeUnit.Seconds);
}
/**
* Create a Duration representing an amount of minutes.
*
* @param amount the amount of Minutes the `Duration` will represent.
* @returns a new `Duration` representing `amount` Minutes.
*/
static minutes(amount) {
return new Duration(amount, TimeUnit.Minutes);
}
/**
* Create a Duration representing an amount of hours.
*
* @param amount the amount of Hours the `Duration` will represent.
* @returns a new `Duration` representing `amount` Hours.
*/
static hours(amount) {
return new Duration(amount, TimeUnit.Hours);
}
/**
* Create a Duration representing an amount of days.
*
* @param amount the amount of Days the `Duration` will represent.
* @returns a new `Duration` representing `amount` Days.
*/
static days(amount) {
return new Duration(amount, TimeUnit.Days);
}
/**
* Parse a period formatted according to the ISO 8601 standard.
*
* @param duration an ISO-formtted duration to be parsed.
* @returns the parsed `Duration`.
* @see https://www.iso.org/fr/standard/70907.html
*/
static parse(duration) {
const matches = duration.match(/^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/);
if (!matches) {
throw new Error(`Not a valid ISO duration: ${duration}`);
}
const [, days, hours, minutes, seconds] = matches;
if (!days && !hours && !minutes && !seconds) {
throw new Error(`Not a valid ISO duration: ${duration}`);
}
return Duration.millis(_toInt(seconds) * TimeUnit.Seconds.inMillis
+ (_toInt(minutes) * TimeUnit.Minutes.inMillis)
+ (_toInt(hours) * TimeUnit.Hours.inMillis)
+ (_toInt(days) * TimeUnit.Days.inMillis));
function _toInt(str) {
if (!str) {
return 0;
}
return Number(str);
}
}
/**
* Add two Durations together.
*/
plus(rhs) {
const targetUnit = finestUnit(this.unit, rhs.unit);
const total = convert(this.amount, this.unit, targetUnit, {}) + convert(rhs.amount, rhs.unit, targetUnit, {});
return new Duration(total, targetUnit);
}
/**
* Return the total number of milliseconds in this Duration.
*
* @returns the value of this `Duration` expressed in Milliseconds.
*/
toMilliseconds(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Milliseconds, opts);
}
/**
* Return the total number of seconds in this Duration.
*
* @returns the value of this `Duration` expressed in Seconds.
*/
toSeconds(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Seconds, opts);
}
/**
* Return the total number of minutes in this Duration.
*
* @returns the value of this `Duration` expressed in Minutes.
*/
toMinutes(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Minutes, opts);
}
/**
* Return the total number of hours in this Duration.
*
* @returns the value of this `Duration` expressed in Hours.
*/
toHours(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Hours, opts);
}
/**
* Return the total number of days in this Duration.
*
* @returns the value of this `Duration` expressed in Days.
*/
toDays(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Days, opts);
}
/**
* Return an ISO 8601 representation of this period.
*
* @returns a string starting with 'P' describing the period
* @see https://www.iso.org/fr/standard/70907.html
*/
toIsoString() {
if (this.amount === 0) {
return 'PT0S';
}
const ret = ['P'];
let tee = false;
for (const [amount, unit] of this.components(true)) {
if ([TimeUnit.Seconds, TimeUnit.Minutes, TimeUnit.Hours].includes(unit) && !tee) {
ret.push('T');
tee = true;
}
ret.push(`${amount}${unit.isoLabel}`);
}
return ret.join('');
}
/**
* (deprecated) Return an ISO 8601 representation of this period.
*
* @returns a string starting with 'P' describing the period
* @see https://www.iso.org/fr/standard/70907.html
* @deprecated Use `toIsoString()` instead.
*/
toISOString() {
return this.toIsoString();
}
/**
* Turn this duration into a human-readable string.
*/
toHumanString() {
if (this.amount === 0) {
return fmtUnit(0, this.unit);
}
if (token_1.Token.isUnresolved(this.amount)) {
return `<token> ${this.unit.label}`;
}
return this.components(false)
// 2 significant parts, that's totally enough for humans
.slice(0, 2)
.map(([amount, unit]) => fmtUnit(amount, unit))
.join(' ');
function fmtUnit(amount, unit) {
if (amount === 1) {
// All of the labels end in 's'
return `${amount} ${unit.label.substring(0, unit.label.length - 1)}`;
}
return `${amount} ${unit.label}`;
}
}
/**
* Returns a string representation of this `Duration` that is also a Token that cannot be successfully resolved.
*
* This
* protects users against inadvertently stringifying a `Duration` object, when they should have called one of the
* `to*` methods instead.
*/
toString() {
return token_1.Token.asString(() => {
throw new Error('Duration.toString() was used, but .toSeconds, .toMinutes or .toDays should have been called instead');
}, { displayHint: `${this.amount} ${this.unit.label}` });
}
/**
* Return the duration in a set of whole numbered time components, ordered from largest to smallest
*
* Only components != 0 will be returned.
*
* Can combine millis and seconds together for the benefit of toIsoString,
* makes the logic in there simpler.
*/
components(combineMillisWithSeconds) {
const ret = new Array();
let millis = convert(this.amount, this.unit, TimeUnit.Milliseconds, { integral: false });
for (const unit of [TimeUnit.Days, TimeUnit.Hours, TimeUnit.Minutes, TimeUnit.Seconds]) {
const count = convert(millis, TimeUnit.Milliseconds, unit, { integral: false });
// Round down to a whole number UNLESS we're combining millis and seconds and we got to the seconds
const wholeCount = unit === TimeUnit.Seconds && combineMillisWithSeconds ? count : Math.floor(count);
if (wholeCount > 0) {
ret.push([wholeCount, unit]);
millis -= wholeCount * unit.inMillis;
}
}
// Remainder in millis
if (millis > 0) {
ret.push([millis, TimeUnit.Milliseconds]);
}
return ret;
}
}
exports.Duration = Duration;
class TimeUnit {
constructor(label, isoLabel, inMillis) {
this.label = label;
this.isoLabel = isoLabel;
this.inMillis = inMillis;
// MAX_SAFE_INTEGER is 2^53, so by representing our duration in millis (the lowest
// common unit) the highest duration we can represent is
// 2^53 / 86*10^6 ~= 104 * 10^6 days (about 100 million days).
}
toString() {
return this.label;
}
}
TimeUnit.Milliseconds = new TimeUnit('millis', '', 1);
TimeUnit.Seconds = new TimeUnit('seconds', 'S', 1000);
TimeUnit.Minutes = new TimeUnit('minutes', 'M', 60000);
TimeUnit.Hours = new TimeUnit('hours', 'H', 3600000);
TimeUnit.Days = new TimeUnit('days', 'D', 86400000);
function convert(amount, fromUnit, toUnit, { integral = true }) {
if (fromUnit.inMillis === toUnit.inMillis) {
return amount;
}
const multiplier = fromUnit.inMillis / toUnit.inMillis;
if (token_1.Token.isUnresolved(amount)) {
throw new Error(`Unable to perform time unit conversion on un-resolved token ${amount}.`);
}
const value = amount * multiplier;
if (!Number.isInteger(value) && integral) {
throw new Error(`'${amount} ${fromUnit}' cannot be converted into a whole number of ${toUnit}.`);
}
return value;
}
/**
* Return the time unit with highest granularity
*/
function finestUnit(a, b) {
return a.inMillis < b.inMillis ? a : b;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVyYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkdXJhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBZ0M7Ozs7Ozs7OztBQVVoQyxNQUFhLFFBQVE7SUFtRm5CLFlBQW9CLE1BQWMsRUFBRSxJQUFjO1FBQ2hELElBQUksQ0FBQyxhQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDN0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxrREFBa0QsTUFBTSxFQUFFLENBQUMsQ0FBQztTQUM3RTtRQUVELElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7Ozs7Ozs7SUFuRk0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFjO1FBQ2pDLE9BQU8sSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNyRCxDQUFDOzs7Ozs7O0lBUU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFjO1FBQ2xDLE9BQU8sSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoRCxDQUFDOzs7Ozs7O0lBUU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFjO1FBQ2xDLE9BQU8sSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoRCxDQUFDOzs7Ozs7O0lBUU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFjO1FBQ2hDLE9BQU8sSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxDQUFDOzs7Ozs7O0lBUU0sTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFjO1FBQy9CLE9BQU8sSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDOzs7Ozs7OztJQVNNLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBZ0I7UUFDbEMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1FBQ3hGLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDWixNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixRQUFRLEVBQUUsQ0FBQyxDQUFDO1NBQzFEO1FBQ0QsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsT0FBTyxDQUFDO1FBQ2xELElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsUUFBUSxFQUFFLENBQUMsQ0FBQztTQUMxRDtRQUNELE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FDcEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsUUFBUTtjQUN6QyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztjQUM3QyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztjQUN6QyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUMxQyxDQUFDO1FBRUYsU0FBUyxNQUFNLENBQUMsR0FBVztZQUN6QixJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQUU7WUFDdkIsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckIsQ0FBQztJQUNILENBQUM7Ozs7SUFpQk0sSUFBSSxDQUFDLEdBQWE7UUFDdkIsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25ELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzlHLE9BQU8sSUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7Ozs7OztJQU9NLGNBQWMsQ0FBQyxPQUE4QixFQUFFO1FBQ3BELE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RFLENBQUM7Ozs7OztJQU9NLFNBQVMsQ0FBQyxPQUE4QixFQUFFO1FBQy9DLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Ozs7OztJQU9NLFNBQVMsQ0FBQyxPQUE4QixFQUFFO1FBQy9DLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Ozs7OztJQU9NLE9BQU8sQ0FBQyxPQUE4QixFQUFFO1FBQzdDLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQy9ELENBQUM7Ozs7OztJQU9NLE1BQU0sQ0FBQyxPQUE4QixFQUFFO1FBQzVDLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUks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QUFDSCxTQUFTLFVBQVUsQ0FBQyxDQUFXLEVBQUUsQ0FBVztJQUMxQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRva2VuIH0gZnJvbSAnLi90b2tlbic7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgY2xhc3MgRHVyYXRpb24ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBtaWxsaXMoYW1vdW50OiBudW1iZXIpOiBEdXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBEdXJhdGlvbihhbW91bnQsIFRpbWVVbml0Lk1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgc2Vjb25kcyhhbW91bnQ6IG51bWJlcik6IER1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IER1cmF0aW9uKGFtb3VudCwgVGltZVVuaXQuU2Vjb25kcyk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgbWludXRlcyhhbW91bnQ6IG51bWJlcik6IER1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IER1cmF0aW9uKGFtb3VudCwgVGltZVVuaXQuTWludXRlcyk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgaG91cnMoYW1vdW50OiBudW1iZXIpOiBEdXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBEdXJhdGlvbihhbW91bnQsIFRpbWVVbml0LkhvdXJzKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBkYXlzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5EYXlzKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBwYXJzZShkdXJhdGlvbjogc3RyaW5nKTogRHVyYXRpb24ge1xuICAgIGNvbnN0IG1hdGNoZXMgPSBkdXJhdGlvbi5tYXRjaCgvXlAoPzooXFxkKylEKT8oPzpUKD86KFxcZCspSCk/KD86KFxcZCspTSk/KD86KFxcZCspUyk/KT8kLyk7XG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIHZhbGlkIElTTyBkdXJhdGlvbjogJHtkdXJhdGlvbn1gKTtcbiAgICB9XG4gICAgY29uc3QgWywgZGF5cywgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHNdID0gbWF0Y2hlcztcbiAgICBpZiAoIWRheXMgJiYgIWhvdXJzICYmICFtaW51dGVzICYmICFzZWNvbmRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIHZhbGlkIElTTyBkdXJhdGlvbjogJHtkdXJhdGlvbn1gKTtcbiAgICB9XG4gICAgcmV0dXJuIER1cmF0aW9uLm1pbGxpcyhcbiAgICAgIF90b0ludChzZWNvbmRzKSAqIFRpbWVVbml0LlNlY29uZHMuaW5NaWxsaXNcbiAgICAgICsgKF90b0ludChtaW51dGVzKSAqIFRpbWVVbml0Lk1pbnV0ZXMuaW5NaWxsaXMpXG4gICAgICArIChfdG9JbnQoaG91cnMpICogVGltZVVuaXQuSG91cnMuaW5NaWxsaXMpXG4gICAgICArIChfdG9JbnQoZGF5cykgKiBUaW1lVW5pdC5EYXlzLmluTWlsbGlzKSxcbiAgICApO1xuXG4gICAgZnVuY3Rpb24gX3RvSW50KHN0cjogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgIGlmICghc3RyKSB7IHJldHVybiAwOyB9XG4gICAgICByZXR1cm4gTnVtYmVyKHN0cik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhbW91bnQ6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSB1bml0OiBUaW1lVW5pdDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGFtb3VudDogbnVtYmVyLCB1bml0OiBUaW1lVW5pdCkge1xuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKGFtb3VudCkgJiYgYW1vdW50IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXJhdGlvbiBhbW91bnRzIGNhbm5vdCBiZSBuZWdhdGl2ZS4gUmVjZWl2ZWQ6ICR7YW1vdW50fWApO1xuICAgIH1cblxuICAgIHRoaXMuYW1vdW50ID0gYW1vdW50O1xuICAgIHRoaXMudW5pdCA9IHVuaXQ7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcGx1cyhyaHM6IER1cmF0aW9uKTogRHVyYXRpb24ge1xuICAgIGNvbnN0IHRhcmdldFVuaXQgPSBmaW5lc3RVbml0KHRoaXMudW5pdCwgcmhzLnVuaXQpO1xuICAgIGNvbnN0IHRvdGFsID0gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCB0YXJnZXRVbml0LCB7fSkgKyBjb252ZXJ0KHJocy5hbW91bnQsIHJocy51bml0LCB0YXJnZXRVbml0LCB7fSk7XG4gICAgcmV0dXJuIG5ldyBEdXJhdGlvbih0b3RhbCwgdGFyZ2V0VW5pdCk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgdG9NaWxsaXNlY29uZHMob3B0czogVGltZUNvbnZlcnNpb25PcHRpb25zID0ge30pOiBudW1iZXIge1xuICAgIHJldHVybiBjb252ZXJ0KHRoaXMuYW1vdW50LCB0aGlzLnVuaXQsIFRpbWVVbml0Lk1pbGxpc2Vjb25kcywgb3B0cyk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyB0b1NlY29uZHMob3B0czogVGltZUNvbnZlcnNpb25PcHRpb25zID0ge30pOiBudW1iZXIge1xuICAgIHJldHVybiBjb252ZXJ0KHRoaXMuYW1vdW50LCB0aGlzLnVuaXQsIFRpbWVVbml0LlNlY29uZHMsIG9wdHMpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgdG9NaW51dGVzKG9wdHM6IFRpbWVDb252ZXJzaW9uT3B0aW9ucyA9IHt9KTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCBUaW1lVW5pdC5NaW51dGVzLCBvcHRzKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgdG9Ib3VycyhvcHRzOiBUaW1lQ29udmVyc2lvbk9wdGlvbnMgPSB7fSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGNvbnZlcnQodGhpcy5hbW91bnQsIHRoaXMudW5pdCwgVGltZVVuaXQuSG91cnMsIG9wdHMpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgdG9EYXlzKG9wdHM6IFRpbWVDb252ZXJzaW9uT3B0aW9ucyA9IHt9KTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCBUaW1lVW5pdC5EYXlzLCBvcHRzKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHRvSXNvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuYW1vdW50ID09PSAwKSB7IHJldHVybiAnUFQwUyc7IH1cblxuICAgIGNvbnN0IHJldCA9IFsnUCddO1xuICAgIGxldCB0ZWUgPSBmYWxzZTtcblxuICAgIGZvciAoY29uc3QgW2Ftb3VudCwgdW5pdF0gb2YgdGhpcy5jb21wb25lbnRzKHRydWUpKSB7XG4gICAgICBpZiAoW1RpbWVVbml0LlNlY29uZHMsIFRpbWVVbml0Lk1pbnV0ZXMsIFRpbWVVbml0LkhvdXJzXS5pbmNsdWRlcyh1bml0KSAmJiAhdGVlKSB7XG4gICAgICAgIHJldC5wdXNoKCdUJyk7XG4gICAgICAgIHRlZSA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXQucHVzaChgJHthbW91bnR9JHt1bml0Lmlzb0xhYmVsfWApO1xuICAgIH1cblxuICAgIHJldHVybiByZXQuam9pbignJyk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgdG9JU09TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy50b0lzb1N0cmluZygpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHRvSHVtYW5TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5hbW91bnQgPT09IDApIHsgcmV0dXJuIGZtdFVuaXQoMCwgdGhpcy51bml0KTsgfVxuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQodGhpcy5hbW91bnQpKSB7IHJldHVybiBgPHRva2VuPiAke3RoaXMudW5pdC5sYWJlbH1gOyB9XG5cbiAgICByZXR1cm4gdGhpcy5jb21wb25lbnRzKGZhbHNlKVxuICAgICAgLy8gMiBzaWduaWZpY2FudCBwYXJ0cywgdGhhdCdzIHRvdGFsbHkgZW5vdWdoIGZvciBodW1hbnNcbiAgICAgIC5zbGljZSgwLCAyKVxuICAgICAgLm1hcCgoW2Ftb3VudCwgdW5pdF0pID0+IGZtdFVuaXQoYW1vdW50LCB1bml0KSlcbiAgICAgIC5qb2luKCcgJyk7XG5cbiAgICBmdW5jdGlvbiBmbXRVbml0KGFtb3VudDogbnVtYmVyLCB1bml0OiBUaW1lVW5pdCkge1xuICAgICAgaWYgKGFtb3VudCA9PT0gMSkge1xuICAgICAgICAvLyBBbGwgb2YgdGhlIGxhYmVscyBlbmQgaW4gJ3MnXG4gICAgICAgIHJldHVybiBgJHthbW91bnR9ICR7dW5pdC5sYWJlbC5zdWJzdHJpbmcoMCwgdW5pdC5sYWJlbC5sZW5ndGggLSAxKX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGAke2Ftb3VudH0gJHt1bml0LmxhYmVsfWA7XG4gICAgfVxuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBUb2tlbi5hc1N0cmluZyhcbiAgICAgICgpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEdXJhdGlvbi50b1N0cmluZygpIHdhcyB1c2VkLCBidXQgLnRvU2Vjb25kcywgLnRvTWludXRlcyBvciAudG9EYXlzIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGluc3RlYWQnKTtcbiAgICAgIH0sXG4gICAgICB7IGRpc3BsYXlIaW50OiBgJHt0aGlzLmFtb3VudH0gJHt0aGlzLnVuaXQubGFiZWx9YCB9LFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBkdXJhdGlvbiBpbiBhIHNldCBvZiB3aG9sZSBudW1iZXJlZCB0aW1lIGNvbXBvbmVudHMsIG9yZGVyZWQgZnJvbSBsYXJnZXN0IHRvIHNtYWxsZXN0XG4gICAqXG4gICAqIE9ubHkgY29tcG9uZW50cyAhPSAwIHdpbGwgYmUgcmV0dXJuZWQuXG4gICAqXG4gICAqIENhbiBjb21iaW5lIG1pbGxpcyBhbmQgc2Vjb25kcyB0b2dldGhlciBmb3IgdGhlIGJlbmVmaXQgb2YgdG9Jc29TdHJpbmcsXG4gICAqIG1ha2VzIHRoZSBsb2dpYyBpbiB0aGVyZSBzaW1wbGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBjb21wb25lbnRzKGNvbWJpbmVNaWxsaXNXaXRoU2Vjb25kczogYm9vbGVhbik6IEFycmF5PFtudW1iZXIsIFRpbWVVbml0XT4ge1xuICAgIGNvbnN0IHJldCA9IG5ldyBBcnJheTxbbnVtYmVyLCBUaW1lVW5pdF0+KCk7XG4gICAgbGV0IG1pbGxpcyA9IGNvbnZlcnQodGhpcy5hbW91bnQsIHRoaXMudW5pdCwgVGltZVVuaXQuTWlsbGlzZWNvbmRzLCB7IGludGVncmFsOiBmYWxzZSB9KTtcblxuICAgIGZvciAoY29uc3QgdW5pdCBvZiBbVGltZVVuaXQuRGF5cywgVGltZVVuaXQuSG91cnMsIFRpbWVVbml0Lk1pbnV0ZXMsIFRpbWVVbml0LlNlY29uZHNdKSB7XG4gICAgICBjb25zdCBjb3VudCA9IGNvbnZlcnQobWlsbGlzLCBUaW1lVW5pdC5NaWxsaXNlY29uZHMsIHVuaXQsIHsgaW50ZWdyYWw6IGZhbHNlIH0pO1xuICAgICAgLy8gUm91bmQgZG93biB0byBhIHdob2xlIG51bWJlciBVTkxFU1Mgd2UncmUgY29tYmluaW5nIG1pbGxpcyBhbmQgc2Vjb25kcyBhbmQgd2UgZ290IHRvIHRoZSBzZWNvbmRzXG4gICAgICBjb25zdCB3aG9sZUNvdW50ID0gdW5pdCA9PT0gVGltZVVuaXQuU2Vjb25kcyAmJiBjb21iaW5lTWlsbGlzV2l0aFNlY29uZHMgPyBjb3VudCA6IE1hdGguZmxvb3IoY291bnQpO1xuICAgICAgaWYgKHdob2xlQ291bnQgPiAwKSB7XG4gICAgICAgIHJldC5wdXNoKFt3aG9sZUNvdW50LCB1bml0XSk7XG4gICAgICAgIG1pbGxpcyAtPSB3aG9sZUNvdW50ICogdW5pdC5pbk1pbGxpcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1haW5kZXIgaW4gbWlsbGlzXG4gICAgaWYgKG1pbGxpcyA+IDApIHtcbiAgICAgIHJldC5wdXNoKFttaWxsaXMsIFRpbWVVbml0Lk1pbGxpc2Vjb25kc10pO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBUaW1lQ29udmVyc2lvbk9wdGlvbnMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGludGVncmFsPzogYm9vbGVhbjtcbn1cblxuY2xhc3MgVGltZVVuaXQge1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IE1pbGxpc2Vjb25kcyA9IG5ldyBUaW1lVW5pdCgnbWlsbGlzJywgJycsIDEpO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNlY29uZHMgPSBuZXcgVGltZVVuaXQoJ3NlY29uZHMnLCAnUycsIDFfMDAwKTtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBNaW51dGVzID0gbmV3IFRpbWVVbml0KCdtaW51dGVzJywgJ00nLCA2MF8wMDApO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEhvdXJzID0gbmV3IFRpbWVVbml0KCdob3VycycsICdIJywgM182MDBfMDAwKTtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBEYXlzID0gbmV3IFRpbWVVbml0KCdkYXlzJywgJ0QnLCA4Nl80MDBfMDAwKTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBsYWJlbDogc3RyaW5nLCBwdWJsaWMgcmVhZG9ubHkgaXNvTGFiZWw6IHN0cmluZywgcHVibGljIHJlYWRvbmx5IGluTWlsbGlzOiBudW1iZXIpIHtcbiAgICAvLyBNQVhfU0FGRV9JTlRFR0VSIGlzIDJeNTMsIHNvIGJ5IHJlcHJlc2VudGluZyBvdXIgZHVyYXRpb24gaW4gbWlsbGlzICh0aGUgbG93ZXN0XG4gICAgLy8gY29tbW9uIHVuaXQpIHRoZSBoaWdoZXN0IGR1cmF0aW9uIHdlIGNhbiByZXByZXNlbnQgaXNcbiAgICAvLyAyXjUzIC8gODYqMTBeNiB+PSAxMDQgKiAxMF42IGRheXMgKGFib3V0IDEwMCBtaWxsaW9uIGRheXMpLlxuICB9XG5cbiAgcHVibGljIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmxhYmVsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnQoYW1vdW50OiBudW1iZXIsIGZyb21Vbml0OiBUaW1lVW5pdCwgdG9Vbml0OiBUaW1lVW5pdCwgeyBpbnRlZ3JhbCA9IHRydWUgfTogVGltZUNvbnZlcnNpb25PcHRpb25zKSB7XG4gIGlmIChmcm9tVW5pdC5pbk1pbGxpcyA9PT0gdG9Vbml0LmluTWlsbGlzKSB7IHJldHVybiBhbW91bnQ7IH1cbiAgY29uc3QgbXVsdGlwbGllciA9IGZyb21Vbml0LmluTWlsbGlzIC8gdG9Vbml0LmluTWlsbGlzO1xuXG4gIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoYW1vdW50KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHBlcmZvcm0gdGltZSB1bml0IGNvbnZlcnNpb24gb24gdW4tcmVzb2x2ZWQgdG9rZW4gJHthbW91bnR9LmApO1xuICB9XG4gIGNvbnN0IHZhbHVlID0gYW1vdW50ICogbXVsdGlwbGllcjtcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSAmJiBpbnRlZ3JhbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJyR7YW1vdW50fSAke2Zyb21Vbml0fScgY2Fubm90IGJlIGNvbnZlcnRlZCBpbnRvIGEgd2hvbGUgbnVtYmVyIG9mICR7dG9Vbml0fS5gKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSB0aW1lIHVuaXQgd2l0aCBoaWdoZXN0IGdyYW51bGFyaXR5XG4gKi9cbmZ1bmN0aW9uIGZpbmVzdFVuaXQoYTogVGltZVVuaXQsIGI6IFRpbWVVbml0KSB7XG4gIHJldHVybiBhLmluTWlsbGlzIDwgYi5pbk1pbGxpcyA/IGEgOiBiO1xufVxuIl19