@taiga-ui/cdk
Version:
Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance
160 lines • 25.7 kB
JavaScript
/// <reference types="@taiga-ui/tsconfig/ng-dev-mode" />
import { CHAR_NO_BREAK_SPACE } from '@taiga-ui/cdk/constants';
import { tuiInRange } from '@taiga-ui/cdk/utils/math';
import { HOURS_IN_DAY, MILLISECONDS_IN_DAY, MILLISECONDS_IN_HOUR, MILLISECONDS_IN_MINUTE, MILLISECONDS_IN_SECOND, MINUTES_IN_HOUR, SECONDS_IN_MINUTE, } from './date-time';
/**
* Immutable time object with hours, minutes, seconds and ms
*/
export class TuiTime {
constructor(hours, minutes, seconds = 0, ms = 0) {
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
this.ms = ms;
ngDevMode &&
console.assert(
// Currently `TuiTime` could have hours more than 23
// in order to not break current behaviour of `isValidTime` the logic is duplicated
Number.isInteger(hours) &&
tuiInRange(hours, 0, Infinity) &&
Number.isInteger(minutes) &&
tuiInRange(minutes, 0, MINUTES_IN_HOUR) &&
Number.isInteger(seconds) &&
tuiInRange(seconds, 0, SECONDS_IN_MINUTE) &&
Number.isInteger(ms) &&
tuiInRange(ms, 0, 1000), 'Time must be real, but got:', hours, minutes, seconds, ms);
}
/**
* Checks if time is valid
*/
static isValidTime(hours, minutes, seconds = 0, ms = 0) {
return (Number.isInteger(hours) &&
tuiInRange(hours, 0, HOURS_IN_DAY) &&
Number.isInteger(minutes) &&
tuiInRange(minutes, 0, MINUTES_IN_HOUR) &&
Number.isInteger(seconds) &&
tuiInRange(seconds, 0, SECONDS_IN_MINUTE) &&
Number.isInteger(ms) &&
tuiInRange(ms, 0, 1000));
}
/**
* Current UTC time.
*/
static current() {
return TuiTime.fromAbsoluteMilliseconds(Date.now() % MILLISECONDS_IN_DAY);
}
/**
* Current time in local timezone
*/
static currentLocal() {
const date = new Date();
return TuiTime.fromAbsoluteMilliseconds((Date.now() - date.getTimezoneOffset() * MILLISECONDS_IN_MINUTE) %
MILLISECONDS_IN_DAY);
}
/**
* Calculates TuiTime from milliseconds
*/
static fromAbsoluteMilliseconds(milliseconds) {
ngDevMode &&
console.assert(Number.isInteger(milliseconds) && milliseconds >= 0, 'Milliseconds must be a non-negative integer.');
const hours = Math.floor(milliseconds / MILLISECONDS_IN_HOUR);
const minutes = Math.floor((milliseconds % MILLISECONDS_IN_HOUR) / MILLISECONDS_IN_MINUTE);
const seconds = Math.floor(((milliseconds % MILLISECONDS_IN_HOUR) % MILLISECONDS_IN_MINUTE) / 1000) || 0;
const ms = Math.floor(((milliseconds % MILLISECONDS_IN_HOUR) % MILLISECONDS_IN_MINUTE) % 1000) || 0;
return new TuiTime(hours, minutes, seconds, ms);
}
/**
* Parses string into TuiTime object
*/
static fromString(time) {
const hours = this.parseHours(time);
const minutes = Number(time.slice(3, 5)) || 0;
const seconds = Number(time.slice(6, 8)) || 0;
const ms = Number(time.slice(9, 12)) || 0;
return new TuiTime(hours, minutes, seconds, ms);
}
/**
* Converts Date object into TuiTime
* @param date
*/
static fromLocalNativeDate(date) {
return new TuiTime(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
}
static parseMeridiemPeriod(time) {
return (/[AP]M/.exec(time.toUpperCase().replaceAll(/\W/g, ''))?.[0] || null);
}
static parseHours(time) {
const hours = Number(time.slice(0, 2));
const meridiem = this.parseMeridiemPeriod(time);
if (!meridiem) {
return hours;
}
if (hours === 12) {
return meridiem === 'AM' ? 0 : 12;
}
return meridiem === 'PM' ? hours + 12 : hours;
}
/**
* Shifts time by hours and minutes
*/
shift({ hours = 0, minutes = 0, seconds = 0, ms = 0 }) {
const totalMs = this.toAbsoluteMilliseconds() +
hours * MILLISECONDS_IN_HOUR +
minutes * MILLISECONDS_IN_MINUTE +
seconds * MILLISECONDS_IN_SECOND +
ms;
const totalSeconds = Math.floor(totalMs / MILLISECONDS_IN_SECOND);
const totalMinutes = Math.floor(totalSeconds / SECONDS_IN_MINUTE);
const totalHours = Math.floor(totalMinutes / MINUTES_IN_HOUR);
return new TuiTime(this.normalizeToRange(totalHours, HOURS_IN_DAY), this.normalizeToRange(totalMinutes, MINUTES_IN_HOUR), this.normalizeToRange(totalSeconds, SECONDS_IN_MINUTE), this.normalizeToRange(totalMs, MILLISECONDS_IN_SECOND));
}
/**
* Converts TuiTime to string
*/
toString(mode) {
const needAddMs = mode?.startsWith('HH:MM:SS.MSS') || (!mode && this.ms > 0);
const needAddSeconds = needAddMs || mode?.startsWith('HH:MM:SS') || (!mode && this.seconds > 0);
const { hours = this.hours, meridiem = '' } = mode?.includes('AA')
? this.toTwelveHour(this.hours)
: {};
const hhMm = `${this.formatTime(hours)}:${this.formatTime(this.minutes)}`;
const ss = needAddSeconds ? `:${this.formatTime(this.seconds)}` : '';
const mss = needAddMs ? `.${this.formatTime(this.ms, 3)}` : '';
const aa = meridiem && `${CHAR_NO_BREAK_SPACE}${meridiem}`;
return `${hhMm}${ss}${mss}${aa}`;
}
valueOf() {
return this.toAbsoluteMilliseconds();
}
/**
* Returns the primitive value of the given Date object.
* Depending on the argument, the method can return either a string or a number.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive
*/
[Symbol.toPrimitive](hint) {
return Date.prototype[Symbol.toPrimitive].call(this, hint);
}
/**
* Converts TuiTime to milliseconds
*/
toAbsoluteMilliseconds() {
return (this.hours * MILLISECONDS_IN_HOUR +
this.minutes * MILLISECONDS_IN_MINUTE +
this.seconds * 1000 +
this.ms);
}
formatTime(time, digits = 2) {
return String(time).padStart(digits, '0');
}
toTwelveHour(hours) {
const meridiem = hours >= 12 ? 'PM' : 'AM';
if (hours === 0 || hours === 12) {
return { meridiem, hours: 12 };
}
return { meridiem, hours: hours % 12 };
}
normalizeToRange(value, modulus) {
return ((value % modulus) + modulus) % modulus;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Nkay9kYXRlLXRpbWUvdGltZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3REFBd0Q7QUFFeEQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBRXBELE9BQU8sRUFDSCxZQUFZLEVBQ1osbUJBQW1CLEVBQ25CLG9CQUFvQixFQUNwQixzQkFBc0IsRUFDdEIsc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZixpQkFBaUIsR0FDcEIsTUFBTSxhQUFhLENBQUM7QUFHckI7O0dBRUc7QUFDSCxNQUFNLE9BQU8sT0FBTztJQUNoQixZQUNvQixLQUFhLEVBQ2IsT0FBZSxFQUNmLFVBQVUsQ0FBQyxFQUNYLEtBQUssQ0FBQztRQUhOLFVBQUssR0FBTCxLQUFLLENBQVE7UUFDYixZQUFPLEdBQVAsT0FBTyxDQUFRO1FBQ2YsWUFBTyxHQUFQLE9BQU8sQ0FBSTtRQUNYLE9BQUUsR0FBRixFQUFFLENBQUk7UUFFdEIsU0FBUztZQUNMLE9BQU8sQ0FBQyxNQUFNO1lBQ1Ysb0RBQW9EO1lBQ3BELG1GQUFtRjtZQUNuRixNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztnQkFDbkIsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsUUFBUSxDQUFDO2dCQUM5QixNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztnQkFDekIsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsZUFBZSxDQUFDO2dCQUN2QyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztnQkFDekIsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsaUJBQWlCLENBQUM7Z0JBQ3pDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUNwQixVQUFVLENBQUMsRUFBRSxF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QyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxzQkFBc0I7UUFDekIsT0FBTyxDQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsb0JBQW9CO1lBQ2pDLElBQUksQ0FBQyxPQUFPLEdBQUcsc0JBQXNCO1lBQ3JDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSTtZQUNuQixJQUFJLENBQUMsRUFBRSxDQUNWLENBQUM7SUFDTixDQUFDO0lBRU8sVUFBVSxDQUFDLElBQVksRUFBRSxNQUFNLEdBQUcsQ0FBQztRQUN2QyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFTyxZQUFZLENBQUMsS0FBYTtRQUM5QixNQUFNLFFBQVEsR0FBRyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUUzQyxJQUFJLEtBQUssS0FBSyxDQUFDLElBQUksS0FBSyxLQUFLLEVBQUUsRUFBRTtZQUM3QixPQUFPLEVBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUMsQ0FBQztTQUNoQztRQUVELE9BQU8sRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEtBQUssR0FBRyxFQUFFLEVBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsS0FBYSxFQUFFLE9BQWU7UUFDbkQsT0FBTyxDQUFDLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLE9BQU8sQ0FBQztJQUNuRCxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSB0eXBlcz1cIkB0YWlnYS11aS90c2NvbmZpZy9uZy1kZXYtbW9kZVwiIC8+XG5cbmltcG9ydCB7Q0hBUl9OT19CUkVBS19TUEFDRX0gZnJvbSAnQHRhaWdhLXVpL2Nkay9jb25zdGFudHMnO1xuaW1wb3J0IHt0dWlJblJhbmdlfSBmcm9tICdAdGFpZ2EtdWkvY2RrL3V0aWxzL21hdGgnO1xuXG5pbXBvcnQge1xuICAgIEhPVVJTX0lOX0RBWSxcbiAgICBNSUxMSVNFQ09ORFNfSU5fREFZLFxuICAgIE1JTExJU0VDT05EU19JTl9IT1VSLFxuICAgIE1JTExJU0VDT05EU19JTl9NSU5VVEUsXG4gICAgTUlMTElTRUNPTkRTX0lOX1NFQ09ORCxcbiAgICBNSU5VVEVTX0lOX0hPVVIsXG4gICAgU0VDT05EU19JTl9NSU5VVEUsXG59IGZyb20gJy4vZGF0ZS10aW1lJztcbmltcG9ydCB7dHlwZSBUdWlUaW1lTGlrZSwgdHlwZSBUdWlUaW1lTW9kZX0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogSW1tdXRhYmxlIHRpbWUgb2JqZWN0IHdpdGggaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMgYW5kIG1zXG4gKi9cbmV4cG9ydCBjbGFzcyBUdWlUaW1lIGltcGxlbWVudHMgVHVpVGltZUxpa2Uge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgaG91cnM6IG51bWJlcixcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IG1pbnV0ZXM6IG51bWJlcixcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IHNlY29uZHMgPSAwLFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgbXMgPSAwLFxuICAgICkge1xuICAgICAgICBuZ0Rldk1vZGUgJiZcbiAgICAgICAgICAgIGNvbnNvbGUuYXNzZXJ0KFxuICAgICAgICAgICAgICAgIC8vIEN1cnJlbnRseSBgVHVpVGltZWAgY291bGQgaGF2ZSBob3VycyBtb3JlIHRoYW4gMjNcbiAgICAgICAgICAgICAgICAvLyBpbiBvcmRlciB0byBub3QgYnJlYWsgY3VycmVudCBiZWhhdmlvdXIgb2YgYGlzVmFsaWRUaW1lYCB0aGUgbG9naWMgaXMgZHVwbGljYXRlZFxuICAgICAgICAgICAgICAgIE51bWJlci5pc0ludGVnZXIoaG91cnMpICYmXG4gICAgICAgICAgICAgICAgICAgIHR1aUluUmFuZ2UoaG91cnMsIDAsIEluZmluaXR5KSAmJlxuICAgICAgICAgICAgICAgICAgICBOdW1iZXIuaXNJbnRlZ2VyKG1pbnV0ZXMpICYmXG4gICAgICAgICAgICAgICAgICAgIHR1aUluUmFuZ2UobWludXRlcywgMCwgTUlOVVRFU19JTl9IT1VSKSAmJlxuICAgICAgICAgICAgICAgICAgICBOdW1iZXIuaXNJbnRlZ2VyKHNlY29uZHMpICYmXG4gICAgICAgICAgICAgICAgICAgIHR1aUluUmFuZ2Uoc2Vjb25kcywgMCwgU0VDT05EU19JTl9NSU5VVEUpICYmXG4gICAgICAgICAgICAgICAgICAgIE51bWJlci5pc0ludGVnZXIobXMpICYmXG4gICAgICAgICAgICAgICAgICAgIHR1aUluUmFuZ2UobXMsIDAsIDEwMDApLFxuICAgICAgICAgICAgICAgICdUaW1lIG11c3QgYmUgcmVhbCwgYnV0IGdvdDonLFxuICAgICAgICAgICAgICAgIGhvdXJzLFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMsXG4gICAgICAgICAgICAgICAgc2Vjb25kcyxcbiAgICAgICAgICAgICAgICBtcyxcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRpbWUgaXMgdmFsaWRcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGlzVmFsaWRUaW1lKFxuICAgICAgICBob3VyczogbnVtYmVyLFxuICAgICAgICBtaW51dGVzOiBudW1iZXIsXG4gICAgICAgIHNlY29uZHMgPSAwLFxuICAgICAgICBtcyA9IDAsXG4gICAgKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBOdW1iZXIuaXNJbnRlZ2VyKGhvdXJzKSAmJlxuICAgICAgICAgICAgdHVpSW5SYW5nZShob3VycywgMCwgSE9VUlNfSU5fREFZKSAmJlxuICAgICAgICAgICAgTnVtYmVyLmlzSW50ZWdlcihtaW51dGVzKSAmJlxuICAgICAgICAgICAgdHVpSW5SYW5nZShtaW51dGVzLCAwLCBNSU5VVEVTX0lOX0hPVVIpICYmXG4gICAgICAgICAgICBOdW1iZXIuaXNJbnRlZ2VyKHNlY29uZHMpICYmXG4gICAgICAgICAgICB0dWlJblJhbmdlKHNlY29uZHMsIDAsIFNFQ09ORFNfSU5fTUlOVVRFKSAmJlxuICAgICAgICAgICAgTnVtYmVyLmlzSW50ZWdlcihtcykgJiZcbiAgICAgICAgICAgIHR1aUluUmFuZ2UobXMsIDAsIDEwMDApXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBVVEMgdGltZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGN1cnJlbnQoKTogVHVpVGltZSB7XG4gICAgICAgIHJldHVybiBUdWlUaW1lLmZyb21BYnNvbHV0ZU1pbGxpc2Vjb25kcyhEYXRlLm5vdygpICUgTUlMTElTRUNPTkRTX0lOX0RBWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCB0aW1lIGluIGxvY2FsIHRpbWV6b25lXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjdXJyZW50TG9jYWwoKTogVHVpVGltZSB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgIHJldHVybiBUdWlUaW1lLmZyb21BYnNvbHV0ZU1pbGxpc2Vjb25kcyhcbiAgICAgICAgICAgIChEYXRlLm5vdygpIC0gZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpICogTUlMTElTRUNPTkRTX0lOX01JTlVURSkgJVxuICAgICAgICAgICAgICAgIE1JTExJU0VDT05EU19JTl9EQVksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyBUdWlUaW1lIGZyb20gbWlsbGlzZWNvbmRzXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBmcm9tQWJzb2x1dGVNaWxsaXNlY29uZHMobWlsbGlzZWNvbmRzOiBudW1iZXIpOiBUdWlUaW1lIHtcbiAgICAgICAgbmdEZXZNb2RlICYmXG4gICAgICAgICAgICBjb25zb2xlLmFzc2VydChcbiAgICAgICAgICAgICAgICBOdW1iZXIuaXNJbnRlZ2VyKG1pbGxpc2Vjb25kcykgJiYgbWlsbGlzZWNvbmRzID49IDAsXG4gICAgICAgICAgICAgICAgJ01pbGxpc2Vjb25kcyBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIuJyxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKG1pbGxpc2Vjb25kcyAvIE1JTExJU0VDT05EU19JTl9IT1VSKTtcbiAgICAgICAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IoXG4gICAgICAgICAgICAobWlsbGlzZWNvbmRzICUgTUlMTElTRUNPTkRTX0lOX0hPVVIpIC8gTUlMTElTRUNPTkRTX0lOX01JTlVURSxcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9XG4gICAgICAgICAgICBNYXRoLmZsb29yKFxuICAgICAgICAgICAgICAgICgobWlsbGlzZWNvbmRzICUgTUlMTElTRUNPTkRTX0lOX0hPVVIpICUgTUlMTElTRUNPTkRTX0lOX01JTlVURSkgLyAxMDAwLFxuICAgICAgICAgICAgKSB8fCAwO1xuICAgICAgICBjb25zdCBtcyA9XG4gICAgICAgICAgICBNYXRoLmZsb29yKFxuICAgICAgICAgICAgICAgICgobWlsbGlzZWNvbmRzICUgTUlMTElTRUNPTkRTX0lOX0hPVVIpICUgTUlMTElTRUNPTkRTX0lOX01JTlVURSkgJSAxMDAwLFxuICAgICAgICAgICAgKSB8fCAwO1xuXG4gICAgICAgIHJldHVybiBuZXcgVHVpVGltZShob3VycywgbWludXRlcywgc2Vjb25kcywgbXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyBzdHJpbmcgaW50byBUdWlUaW1lIG9iamVjdFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgZnJvbVN0cmluZyh0aW1lOiBzdHJpbmcpOiBUdWlUaW1lIHtcbiAgICAgICAgY29uc3QgaG91cnMgPSB0aGlzLnBhcnNlSG91cnModGltZSk7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSBOdW1iZXIodGltZS5zbGljZSgzLCA1KSkgfHwgMDtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IE51bWJlcih0aW1lLnNsaWNlKDYsIDgpKSB8fCAwO1xuICAgICAgICBjb25zdCBtcyA9IE51bWJlcih0aW1lLnNsaWNlKDksIDEyKSkgfHwgMDtcblxuICAgICAgICByZXR1cm4gbmV3IFR1aVRpbWUoaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIG1zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBEYXRlIG9iamVjdCBpbnRvIFR1aVRpbWVcbiAgICAgKiBAcGFyYW0gZGF0ZVxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgZnJvbUxvY2FsTmF0aXZlRGF0ZShkYXRlOiBEYXRlKTogVHVpVGltZSB7XG4gICAgICAgIHJldHVybiBuZXcgVHVpVGltZShcbiAgICAgICAgICAgIGRhdGUuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0TWludXRlcygpLFxuICAgICAgICAgICAgZGF0ZS5nZXRTZWNvbmRzKCksXG4gICAgICAgICAgICBkYXRlLmdldE1pbGxpc2Vjb25kcygpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIHBhcnNlTWVyaWRpZW1QZXJpb2QodGltZTogc3RyaW5nKTogJ0FNJyB8ICdQTScgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICgvW0FQXU0vLmV4ZWModGltZS50b1VwcGVyQ2FzZSgpLnJlcGxhY2VBbGwoL1xcVy9nLCAnJykpPy5bMF0gYXNcbiAgICAgICAgICAgICAgICB8ICdBTSdcbiAgICAgICAgICAgICAgICB8ICdQTScpIHx8IG51bGxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBwYXJzZUhvdXJzKHRpbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGhvdXJzID0gTnVtYmVyKHRpbWUuc2xpY2UoMCwgMikpO1xuICAgICAgICBjb25zdCBtZXJpZGllbSA9IHRoaXMucGFyc2VNZXJpZGllbVBlcmlvZCh0aW1lKTtcblxuICAgICAgICBpZiAoIW1lcmlkaWVtKSB7XG4gICAgICAgICAgICByZXR1cm4gaG91cnM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaG91cnMgPT09IDEyKSB7XG4gICAgICAgICAgICByZXR1cm4gbWVyaWRpZW0gPT09ICdBTScgPyAwIDogMTI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWVyaWRpZW0gPT09ICdQTScgPyBob3VycyArIDEyIDogaG91cnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hpZnRzIHRpbWUgYnkgaG91cnMgYW5kIG1pbnV0ZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgc2hpZnQoe2hvdXJzID0gMCwgbWludXRlcyA9IDAsIHNlY29uZHMgPSAwLCBtcyA9IDB9OiBUdWlUaW1lTGlrZSk6IFR1aVRpbWUge1xuICAgICAgICBjb25zdCB0b3RhbE1zID1cbiAgICAgICAgICAgIHRoaXMudG9BYnNvbHV0ZU1pbGxpc2Vjb25kcygpICtcbiAgICAgICAgICAgIGhvdXJzICogTUlMTElTRUNPTkRTX0lOX0hPVVIgK1xuICAgICAgICAgICAgbWludXRlcyAqIE1JTExJU0VDT05EU19JTl9NSU5VVEUgK1xuICAgICAgICAgICAgc2Vjb25kcyAqIE1JTExJU0VDT05EU19JTl9TRUNPTkQgK1xuICAgICAgICAgICAgbXM7XG4gICAgICAgIGNvbnN0IHRvdGFsU2Vjb25kcyA9IE1hdGguZmxvb3IodG90YWxNcyAvIE1JTExJU0VDT05EU19JTl9TRUNPTkQpO1xuICAgICAgICBjb25zdCB0b3RhbE1pbnV0ZXMgPSBNYXRoLmZsb29yKHRvdGFsU2Vjb25kcyAvIFNFQ09ORFNfSU5fTUlOVVRFKTtcbiAgICAgICAgY29uc3QgdG90YWxIb3VycyA9IE1hdGguZmxvb3IodG90YWxNaW51dGVzIC8gTUlOVVRFU19JTl9IT1VSKTtcblxuICAgICAgICByZXR1cm4gbmV3IFR1aVRpbWUoXG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZVRvUmFuZ2UodG90YWxIb3VycywgSE9VUlNfSU5fREFZKSxcbiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplVG9SYW5nZSh0b3RhbE1pbnV0ZXMsIE1JTlVURVNfSU5fSE9VUiksXG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZVRvUmFuZ2UodG90YWxTZWNvbmRzLCBTRUNPTkRTX0lOX01JTlVURSksXG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZVRvUmFuZ2UodG90YWxNcywgTUlMTElTRUNPTkRTX0lOX1NFQ09ORCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgVHVpVGltZSB0byBzdHJpbmdcbiAgICAgKi9cbiAgICBwdWJsaWMgdG9TdHJpbmcoXG4gICAgICAgIG1vZGU/OiBUdWlUaW1lTW9kZSwgLy8gVE9ETyh2NSk6IHJlbW92ZSB1c2FnZSBvZiBgVHVpVGltZU1vZGVgIGFuZCBpbmxpbmUgYWxsIG1vZGVzIGFzIGh1Z2UgdW5pb24gdHlwZVxuICAgICk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IG5lZWRBZGRNcyA9IG1vZGU/LnN0YXJ0c1dpdGgoJ0hIOk1NOlNTLk1TUycpIHx8ICghbW9kZSAmJiB0aGlzLm1zID4gMCk7XG4gICAgICAgIGNvbnN0IG5lZWRBZGRTZWNvbmRzID1cbiAgICAgICAgICAgIG5lZWRBZGRNcyB8fCBtb2RlPy5zdGFydHNXaXRoKCdISDpNTTpTUycpIHx8ICghbW9kZSAmJiB0aGlzLnNlY29uZHMgPiAwKTtcbiAgICAgICAgY29uc3Qge2hvdXJzID0gdGhpcy5ob3VycywgbWVyaWRpZW0gPSAnJ30gPSBtb2RlPy5pbmNsdWRlcygnQUEnKVxuICAgICAgICAgICAgPyB0aGlzLnRvVHdlbHZlSG91cih0aGlzLmhvdXJzKVxuICAgICAgICAgICAgOiB7fTtcbiAgICAgICAgY29uc3QgaGhNbSA9IGAke3RoaXMuZm9ybWF0VGltZShob3Vycyl9OiR7dGhpcy5mb3JtYXRUaW1lKHRoaXMubWludXRlcyl9YDtcbiAgICAgICAgY29uc3Qgc3MgPSBuZWVkQWRkU2Vjb25kcyA/IGA6JHt0aGlzLmZvcm1hdFRpbWUodGhpcy5zZWNvbmRzKX1gIDogJyc7XG4gICAgICAgIGNvbnN0IG1zcyA9IG5lZWRBZGRNcyA/IGAuJHt0aGlzLmZvcm1hdFRpbWUodGhpcy5tcywgMyl9YCA6ICcnO1xuICAgICAgICBjb25zdCBhYSA9IG1lcmlkaWVtICYmIGAke0NIQVJfTk9fQlJFQUtfU1BBQ0V9JHttZXJpZGllbX1gO1xuXG4gICAgICAgIHJldHVybiBgJHtoaE1tfSR7c3N9JHttc3N9JHthYX1gO1xuICAgIH1cblxuICAgIHB1YmxpYyB2YWx1ZU9mKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvQWJzb2x1dGVNaWxsaXNlY29uZHMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwcmltaXRpdmUgdmFsdWUgb2YgdGhlIGdpdmVuIERhdGUgb2JqZWN0LlxuICAgICAqIERlcGVuZGluZyBvbiB0aGUgYXJndW1lbnQsIHRoZSBtZXRob2QgY2FuIHJldHVybiBlaXRoZXIgYSBzdHJpbmcgb3IgYSBudW1iZXIuXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9EYXRlL0BAdG9QcmltaXRpdmVcbiAgICAgKi9cbiAgICBwdWJsaWMgW1N5bWJvbC50b1ByaW1pdGl2ZV0oaGludDogc3RyaW5nKTogbnVtYmVyIHwgc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIERhdGUucHJvdG90eXBlW1N5bWJvbC50b1ByaW1pdGl2ZV0uY2FsbCh0aGlzLCBoaW50KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBUdWlUaW1lIHRvIG1pbGxpc2Vjb25kc1xuICAgICAqL1xuICAgIHB1YmxpYyB0b0Fic29sdXRlTWlsbGlzZWNvbmRzKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLmhvdXJzICogTUlMTElTRUNPTkRTX0lOX0hPVVIgK1xuICAgICAgICAgICAgdGhpcy5taW51dGVzICogTUlMTElTRUNPTkRTX0lOX01JTlVURSArXG4gICAgICAgICAgICB0aGlzLnNlY29uZHMgKiAxMDAwICtcbiAgICAgICAgICAgIHRoaXMubXNcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZvcm1hdFRpbWUodGltZTogbnVtYmVyLCBkaWdpdHMgPSAyKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZyh0aW1lKS5wYWRTdGFydChkaWdpdHMsICcwJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB0b1R3ZWx2ZUhvdXIoaG91cnM6IG51bWJlcik6IHtob3VyczogbnVtYmVyOyBtZXJpZGllbTogc3RyaW5nfSB7XG4gICAgICAgIGNvbnN0IG1lcmlkaWVtID0gaG91cnMgPj0gMTIgPyAnUE0nIDogJ0FNJztcblxuICAgICAgICBpZiAoaG91cnMgPT09IDAgfHwgaG91cnMgPT09IDEyKSB7XG4gICAgICAgICAgICByZXR1cm4ge21lcmlkaWVtLCBob3VyczogMTJ9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHttZXJpZGllbSwgaG91cnM6IGhvdXJzICUgMTJ9O1xuICAgIH1cblxuICAgIHByaXZhdGUgbm9ybWFsaXplVG9SYW5nZSh2YWx1ZTogbnVtYmVyLCBtb2R1bHVzOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gKCh2YWx1ZSAlIG1vZHVsdXMpICsgbW9kdWx1cykgJSBtb2R1bHVzO1xuICAgIH1cbn1cbiJdfQ==