UNPKG

@taiga-ui/cdk

Version:

Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance

161 lines • 26.1 kB
/// <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)); ngDevMode && console.assert(tuiInRange(milliseconds, 0, MILLISECONDS_IN_DAY), `Milliseconds must be below ${MILLISECONDS_IN_DAY} (milliseconds in a day).`); 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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dHNjb25maWcvbmctZGV2LW1vZGVcIiAvPlxuXG5pbXBvcnQge0NIQVJfTk9fQlJFQUtfU1BBQ0V9IGZyb20gJ0B0YWlnYS11aS9jZGsvY29uc3RhbnRzJztcbmltcG9ydCB7dHVpSW5SYW5nZX0gZnJvbSAnQHRhaWdhLXVpL2Nkay91dGlscy9tYXRoJztcblxuaW1wb3J0IHtcbiAgICBIT1VSU19JTl9EQVksXG4gICAgTUlMTElTRUNPTkRTX0lOX0RBWSxcbiAgICBNSUxMSVNFQ09ORFNfSU5fSE9VUixcbiAgICBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFLFxuICAgIE1JTExJU0VDT05EU19JTl9TRUNPTkQsXG4gICAgTUlOVVRFU19JTl9IT1VSLFxuICAgIFNFQ09ORFNfSU5fTUlOVVRFLFxufSBmcm9tICcuL2RhdGUtdGltZSc7XG5pbXBvcnQgdHlwZSB7VHVpVGltZUxpa2UsIFR1aVRpbWVNb2RlfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBJbW11dGFibGUgdGltZSBvYmplY3Qgd2l0aCBob3VycywgbWludXRlcywgc2Vjb25kcyBhbmQgbXNcbiAqL1xuZXhwb3J0IGNsYXNzIFR1aVRpbWUgaW1wbGVtZW50cyBUdWlUaW1lTGlrZSB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyByZWFkb25seSBob3VyczogbnVtYmVyLFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgbWludXRlczogbnVtYmVyLFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgc2Vjb25kcyA9IDAsXG4gICAgICAgIHB1YmxpYyByZWFkb25seSBtcyA9IDAsXG4gICAgKSB7XG4gICAgICAgIG5nRGV2TW9kZSAmJlxuICAgICAgICAgICAgY29uc29sZS5hc3NlcnQoXG4gICAgICAgICAgICAgICAgLy8gQ3VycmVudGx5IGBUdWlUaW1lYCBjb3VsZCBoYXZlIGhvdXJzIG1vcmUgdGhhbiAyM1xuICAgICAgICAgICAgICAgIC8vIGluIG9yZGVyIHRvIG5vdCBicmVhayBjdXJyZW50IGJlaGF2aW91ciBvZiBgaXNWYWxpZFRpbWVgIHRoZSBsb2dpYyBpcyBkdXBsaWNhdGVkXG4gICAgICAgICAgICAgICAgTnVtYmVyLmlzSW50ZWdlcihob3VycykgJiZcbiAgICAgICAgICAgICAgICAgICAgdHVpSW5SYW5nZShob3VycywgMCwgSW5maW5pdHkpICYmXG4gICAgICAgICAgICAgICAgICAgIE51bWJlci5pc0ludGVnZXIobWludXRlcykgJiZcbiAgICAgICAgICAgICAgICAgICAgdHVpSW5SYW5nZShtaW51dGVzLCAwLCBNSU5VVEVTX0lOX0hPVVIpICYmXG4gICAgICAgICAgICAgICAgICAgIE51bWJlci5pc0ludGVnZXIoc2Vjb25kcykgJiZcbiAgICAgICAgICAgICAgICAgICAgdHVpSW5SYW5nZShzZWNvbmRzLCAwLCBTRUNPTkRTX0lOX01JTlVURSkgJiZcbiAgICAgICAgICAgICAgICAgICAgTnVtYmVyLmlzSW50ZWdlcihtcykgJiZcbiAgICAgICAgICAgICAgICAgICAgdHVpSW5SYW5nZShtcywgMCwgMTAwMCksXG4gICAgICAgICAgICAgICAgJ1RpbWUgbXVzdCBiZSByZWFsLCBidXQgZ290OicsXG4gICAgICAgICAgICAgICAgaG91cnMsXG4gICAgICAgICAgICAgICAgbWludXRlcyxcbiAgICAgICAgICAgICAgICBzZWNvbmRzLFxuICAgICAgICAgICAgICAgIG1zLFxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGltZSBpcyB2YWxpZFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgaXNWYWxpZFRpbWUoXG4gICAgICAgIGhvdXJzOiBudW1iZXIsXG4gICAgICAgIG1pbnV0ZXM6IG51bWJlcixcbiAgICAgICAgc2Vjb25kcyA9IDAsXG4gICAgICAgIG1zID0gMCxcbiAgICApOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIE51bWJlci5pc0ludGVnZXIoaG91cnMpICYmXG4gICAgICAgICAgICB0dWlJblJhbmdlKGhvdXJzLCAwLCBIT1VSU19JTl9EQVkpICYmXG4gICAgICAgICAgICBOdW1iZXIuaXNJbnRlZ2VyKG1pbnV0ZXMpICYmXG4gICAgICAgICAgICB0dWlJblJhbmdlKG1pbnV0ZXMsIDAsIE1JTlVURVNfSU5fSE9VUikgJiZcbiAgICAgICAgICAgIE51bWJlci5pc0ludGVnZXIoc2Vjb25kcykgJiZcbiAgICAgICAgICAgIHR1aUluUmFuZ2Uoc2Vjb25kcywgMCwgU0VDT05EU19JTl9NSU5VVEUpICYmXG4gICAgICAgICAgICBOdW1iZXIuaXNJbnRlZ2VyKG1zKSAmJlxuICAgICAgICAgICAgdHVpSW5SYW5nZShtcywgMCwgMTAwMClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IFVUQyB0aW1lLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3VycmVudCgpOiBUdWlUaW1lIHtcbiAgICAgICAgcmV0dXJuIFR1aVRpbWUuZnJvbUFic29sdXRlTWlsbGlzZWNvbmRzKERhdGUubm93KCkgJSBNSUxMSVNFQ09ORFNfSU5fREFZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IHRpbWUgaW4gbG9jYWwgdGltZXpvbmVcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGN1cnJlbnRMb2NhbCgpOiBUdWlUaW1lIHtcbiAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XG5cbiAgICAgICAgcmV0dXJuIFR1aVRpbWUuZnJvbUFic29sdXRlTWlsbGlzZWNvbmRzKFxuICAgICAgICAgICAgKERhdGUubm93KCkgLSBkYXRlLmdldFRpbWV6b25lT2Zmc2V0KCkgKiBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFKSAlXG4gICAgICAgICAgICAgICAgTUlMTElTRUNPTkRTX0lOX0RBWSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIFR1aVRpbWUgZnJvbSBtaWxsaXNlY29uZHNcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGZyb21BYnNvbHV0ZU1pbGxpc2Vjb25kcyhtaWxsaXNlY29uZHM6IG51bWJlcik6IFR1aVRpbWUge1xuICAgICAgICBuZ0Rldk1vZGUgJiYgY29uc29sZS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihtaWxsaXNlY29uZHMpKTtcbiAgICAgICAgbmdEZXZNb2RlICYmXG4gICAgICAgICAgICBjb25zb2xlLmFzc2VydChcbiAgICAgICAgICAgICAgICB0dWlJblJhbmdlKG1pbGxpc2Vjb25kcywgMCwgTUlMTElTRUNPTkRTX0lOX0RBWSksXG4gICAgICAgICAgICAgICAgYE1pbGxpc2Vjb25kcyBtdXN0IGJlIGJlbG93ICR7TUlMTElTRUNPTkRTX0lOX0RBWX0gKG1pbGxpc2Vjb25kcyBpbiBhIGRheSkuYCxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKG1pbGxpc2Vjb25kcyAvIE1JTExJU0VDT05EU19JTl9IT1VSKTtcbiAgICAgICAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IoXG4gICAgICAgICAgICAobWlsbGlzZWNvbmRzICUgTUlMTElTRUNPTkRTX0lOX0hPVVIpIC8gTUlMTElTRUNPTkRTX0lOX01JTlVURSxcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9XG4gICAgICAgICAgICBNYXRoLmZsb29yKFxuICAgICAgICAgICAgICAgICgobWlsbGlzZWNvbmRzICUgTUlMTElTRUNPTkRTX0lOX0hPVVIpICUgTUlMTElTRUNPTkRTX0lOX01JTlVURSkgLyAxMDAwLFxuICAgICAgICAgICAgKSB8fCAwO1xuICAgICAgICBjb25zdCBtcyA9XG4gICAgICAgICAgICBNYXRoLmZsb29yKFxuICAgICAgICAgICAgICAgICgobWlsbGlzZWNvbmRzICUgTUlMTElTRUNPTkRTX0lOX0hPVVIpICUgTUlMTElTRUNPTkRTX0lOX01JTlVURSkgJSAxMDAwLFxuICAgICAgICAgICAgKSB8fCAwO1xuXG4gICAgICAgIHJldHVybiBuZXcgVHVpVGltZShob3VycywgbWludXRlcywgc2Vjb25kcywgbXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyBzdHJpbmcgaW50byBUdWlUaW1lIG9iamVjdFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgZnJvbVN0cmluZyh0aW1lOiBzdHJpbmcpOiBUdWlUaW1lIHtcbiAgICAgICAgY29uc3QgaG91cnMgPSB0aGlzLnBhcnNlSG91cnModGltZSk7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSBOdW1iZXIodGltZS5zbGljZSgzLCA1KSkgfHwgMDtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IE51bWJlcih0aW1lLnNsaWNlKDYsIDgpKSB8fCAwO1xuICAgICAgICBjb25zdCBtcyA9IE51bWJlcih0aW1lLnNsaWNlKDksIDEyKSkgfHwgMDtcblxuICAgICAgICByZXR1cm4gbmV3IFR1aVRpbWUoaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIG1zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBEYXRlIG9iamVjdCBpbnRvIFR1aVRpbWVcbiAgICAgKiBAcGFyYW0gZGF0ZVxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgZnJvbUxvY2FsTmF0aXZlRGF0ZShkYXRlOiBEYXRlKTogVHVpVGltZSB7XG4gICAgICAgIHJldHVybiBuZXcgVHVpVGltZShcbiAgICAgICAgICAgIGRhdGUuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0TWludXRlcygpLFxuICAgICAgICAgICAgZGF0ZS5nZXRTZWNvbmRzKCksXG4gICAgICAgICAgICBkYXRlLmdldE1pbGxpc2Vjb25kcygpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIHBhcnNlTWVyaWRpZW1QZXJpb2QodGltZTogc3RyaW5nKTogJ0FNJyB8ICdQTScgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICgvW0FQXU0vLmV4ZWModGltZS50b1VwcGVyQ2FzZSgpLnJlcGxhY2VBbGwoL1xcVy9nLCAnJykpPy5bMF0gYXNcbiAgICAgICAgICAgICAgICB8ICdBTSdcbiAgICAgICAgICAgICAgICB8ICdQTScpIHx8IG51bGxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBwYXJzZUhvdXJzKHRpbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGhvdXJzID0gTnVtYmVyKHRpbWUuc2xpY2UoMCwgMikpO1xuICAgICAgICBjb25zdCBtZXJpZGllbSA9IHRoaXMucGFyc2VNZXJpZGllbVBlcmlvZCh0aW1lKTtcblxuICAgICAgICBpZiAoIW1lcmlkaWVtKSB7XG4gICAgICAgICAgICByZXR1cm4gaG91cnM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaG91cnMgPT09IDEyKSB7XG4gICAgICAgICAgICByZXR1cm4gbWVyaWRpZW0gPT09ICdBTScgPyAwIDogMTI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWVyaWRpZW0gPT09ICdQTScgPyBob3VycyArIDEyIDogaG91cnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hpZnRzIHRpbWUgYnkgaG91cnMgYW5kIG1pbnV0ZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgc2hpZnQoe2hvdXJzID0gMCwgbWludXRlcyA9IDAsIHNlY29uZHMgPSAwLCBtcyA9IDB9OiBUdWlUaW1lTGlrZSk6IFR1aVRpbWUge1xuICAgICAgICBjb25zdCB0b3RhbE1zID1cbiAgICAgICAgICAgIHRoaXMudG9BYnNvbHV0ZU1pbGxpc2Vjb25kcygpICtcbiAgICAgICAgICAgIGhvdXJzICogTUlMTElTRUNPTkRTX0lOX0hPVVIgK1xuICAgICAgICAgICAgbWludXRlcyAqIE1JTExJU0VDT05EU19JTl9NSU5VVEUgK1xuICAgICAgICAgICAgc2Vjb25kcyAqIE1JTExJU0VDT05EU19JTl9TRUNPTkQgK1xuICAgICAgICAgICAgbXM7XG4gICAgICAgIGNvbnN0IHRvdGFsU2Vjb25kcyA9IE1hdGguZmxvb3IodG90YWxNcyAvIE1JTExJU0VDT05EU19JTl9TRUNPTkQpO1xuICAgICAgICBjb25zdCB0b3RhbE1pbnV0ZXMgPSBNYXRoLmZsb29yKHRvdGFsU2Vjb25kcyAvIFNFQ09ORFNfSU5fTUlOVVRFKTtcbiAgICAgICAgY29uc3QgdG90YWxIb3VycyA9IE1hdGguZmxvb3IodG90YWxNaW51dGVzIC8gTUlOVVRFU19JTl9IT1VSKTtcblxuICAgICAgICByZXR1cm4gbmV3IFR1aVRpbWUoXG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZVRvUmFuZ2UodG90YWxIb3VycywgSE9VUlNfSU5fREFZKSxcbiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplVG9SYW5nZSh0b3RhbE1pbnV0ZXMsIE1JTlVURVNfSU5fSE9VUiksXG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZVRvUmFuZ2UodG90YWxTZWNvbmRzLCBTRUNPTkRTX0lOX01JTlVURSksXG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZVRvUmFuZ2UodG90YWxNcywgTUlMTElTRUNPTkRTX0lOX1NFQ09ORCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgVHVpVGltZSB0byBzdHJpbmdcbiAgICAgKi9cbiAgICBwdWJsaWMgdG9TdHJpbmcoXG4gICAgICAgIG1vZGU/OiBUdWlUaW1lTW9kZSwgLy8gVE9ETyh2NSk6IHJlbW92ZSB1c2FnZSBvZiBgVHVpVGltZU1vZGVgIGFuZCBpbmxpbmUgYWxsIG1vZGVzIGFzIGh1Z2UgdW5pb24gdHlwZVxuICAgICk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IG5lZWRBZGRNcyA9IG1vZGU/LnN0YXJ0c1dpdGgoJ0hIOk1NOlNTLk1TUycpIHx8ICghbW9kZSAmJiB0aGlzLm1zID4gMCk7XG4gICAgICAgIGNvbnN0IG5lZWRBZGRTZWNvbmRzID1cbiAgICAgICAgICAgIG5lZWRBZGRNcyB8fCBtb2RlPy5zdGFydHNXaXRoKCdISDpNTTpTUycpIHx8ICghbW9kZSAmJiB0aGlzLnNlY29uZHMgPiAwKTtcbiAgICAgICAgY29uc3Qge2hvdXJzID0gdGhpcy5ob3VycywgbWVyaWRpZW0gPSAnJ30gPSBtb2RlPy5pbmNsdWRlcygnQUEnKVxuICAgICAgICAgICAgPyB0aGlzLnRvVHdlbHZlSG91cih0aGlzLmhvdXJzKVxuICAgICAgICAgICAgOiB7fTtcbiAgICAgICAgY29uc3QgaGhNbSA9IGAke3RoaXMuZm9ybWF0VGltZShob3Vycyl9OiR7dGhpcy5mb3JtYXRUaW1lKHRoaXMubWludXRlcyl9YDtcbiAgICAgICAgY29uc3Qgc3MgPSBuZWVkQWRkU2Vjb25kcyA/IGA6JHt0aGlzLmZvcm1hdFRpbWUodGhpcy5zZWNvbmRzKX1gIDogJyc7XG4gICAgICAgIGNvbnN0IG1zcyA9IG5lZWRBZGRNcyA/IGAuJHt0aGlzLmZvcm1hdFRpbWUodGhpcy5tcywgMyl9YCA6ICcnO1xuICAgICAgICBjb25zdCBhYSA9IG1lcmlkaWVtICYmIGAke0NIQVJfTk9fQlJFQUtfU1BBQ0V9JHttZXJpZGllbX1gO1xuXG4gICAgICAgIHJldHVybiBgJHtoaE1tfSR7c3N9JHttc3N9JHthYX1gO1xuICAgIH1cblxuICAgIHB1YmxpYyB2YWx1ZU9mKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvQWJzb2x1dGVNaWxsaXNlY29uZHMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwcmltaXRpdmUgdmFsdWUgb2YgdGhlIGdpdmVuIERhdGUgb2JqZWN0LlxuICAgICAqIERlcGVuZGluZyBvbiB0aGUgYXJndW1lbnQsIHRoZSBtZXRob2QgY2FuIHJldHVybiBlaXRoZXIgYSBzdHJpbmcgb3IgYSBudW1iZXIuXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9EYXRlL0BAdG9QcmltaXRpdmVcbiAgICAgKi9cbiAgICBwdWJsaWMgW1N5bWJvbC50b1ByaW1pdGl2ZV0oaGludDogc3RyaW5nKTogbnVtYmVyIHwgc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIERhdGUucHJvdG90eXBlW1N5bWJvbC50b1ByaW1pdGl2ZV0uY2FsbCh0aGlzLCBoaW50KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBUdWlUaW1lIHRvIG1pbGxpc2Vjb25kc1xuICAgICAqL1xuICAgIHB1YmxpYyB0b0Fic29sdXRlTWlsbGlzZWNvbmRzKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLmhvdXJzICogTUlMTElTRUNPTkRTX0lOX0hPVVIgK1xuICAgICAgICAgICAgdGhpcy5taW51dGVzICogTUlMTElTRUNPTkRTX0lOX01JTlVURSArXG4gICAgICAgICAgICB0aGlzLnNlY29uZHMgKiAxMDAwICtcbiAgICAgICAgICAgIHRoaXMubXNcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZvcm1hdFRpbWUodGltZTogbnVtYmVyLCBkaWdpdHMgPSAyKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZyh0aW1lKS5wYWRTdGFydChkaWdpdHMsICcwJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB0b1R3ZWx2ZUhvdXIoaG91cnM6IG51bWJlcik6IHtob3VyczogbnVtYmVyOyBtZXJpZGllbTogc3RyaW5nfSB7XG4gICAgICAgIGNvbnN0IG1lcmlkaWVtID0gaG91cnMgPj0gMTIgPyAnUE0nIDogJ0FNJztcblxuICAgICAgICBpZiAoaG91cnMgPT09IDAgfHwgaG91cnMgPT09IDEyKSB7XG4gICAgICAgICAgICByZXR1cm4ge21lcmlkaWVtLCBob3VyczogMTJ9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHttZXJpZGllbSwgaG91cnM6IGhvdXJzICUgMTJ9O1xuICAgIH1cblxuICAgIHByaXZhdGUgbm9ybWFsaXplVG9SYW5nZSh2YWx1ZTogbnVtYmVyLCBtb2R1bHVzOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gKCh2YWx1ZSAlIG1vZHVsdXMpICsgbW9kdWx1cykgJSBtb2R1bHVzO1xuICAgIH1cbn1cbiJdfQ==