UNPKG

@matheo/datepicker

Version:

Angular material date+time picker

259 lines 33.3 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { Inject, Injectable, Optional, InjectionToken } from '@angular/core'; import { MAT_DATE_LOCALE } from '@angular/material/core'; import { DateAdapter } from '@matheo/datepicker/core'; import { DateTime as LuxonDateTime, Info as LuxonInfo, } from 'luxon'; import * as i0 from "@angular/core"; /** InjectionToken for LuxonDateAdapter to configure options. */ export const MAT_LUXON_DATE_ADAPTER_OPTIONS = new InjectionToken('MAT_LUXON_DATE_ADAPTER_OPTIONS', { providedIn: 'root', factory: MAT_LUXON_DATE_ADAPTER_OPTIONS_FACTORY, }); /** @docs-private */ export function MAT_LUXON_DATE_ADAPTER_OPTIONS_FACTORY() { return { useUtc: false, }; } /** The default hour names to use if Intl API is not available. */ const DEFAULT_HOUR_NAMES = range(24, (i) => (i === 0 ? '00' : String(i))); /** The default minute names to use if Intl API is not available. */ const DEFAULT_MINUTE_NAMES = range(60, String); /** Creates an array and fills it with values. */ function range(length, valueFunction) { const valuesArray = Array(length); for (let i = 0; i < length; i++) { valuesArray[i] = valueFunction(i); } return valuesArray; } /** Adapts Luxon Dates for use with Angular Material. */ export class LuxonDateAdapter extends DateAdapter { constructor(dateLocale, options) { super(); this._useUTC = options ? !!options.useUtc : false; this._getFirstDayOfWeek = options?.firstDayOfWeek; this.setLocale(dateLocale || LuxonDateTime.local().locale); } setLocale(locale) { super.setLocale(locale); } getYear(date) { return date.year; } getMonth(date) { // Luxon works with 1-indexed months whereas our code expects 0-indexed. return date.month - 1; } getDate(date) { return date.day; } getHours(date) { return date.hour; } setHours(date, hour) { return date.set({ hour }); } getMinutes(date) { return date.minute; } setMinutes(date, minute) { return date.set({ minute }); } getSeconds(date) { return date.second; } setSeconds(date, second, ms) { return date.set({ second, millisecond: ms }); } getMilliseconds(date) { return date.millisecond; } getDayOfWeek(date) { return date.weekday === 7 ? 0 : date.weekday; } getMonthNames(style) { return LuxonInfo.months(style, { locale: this.locale }); } getDateNames() { // At the time of writing, Luxon doesn't offer similar // functionality so we have to fall back to the Intl API. const dtf = new Intl.DateTimeFormat(this.locale, { day: 'numeric', timeZone: 'utc', }); // Format a UTC date in order to avoid DST issues. return range(31, (i) => { return dtf.format(LuxonDateTime.utc(2017, 1, i + 1).toJSDate()); }); } getHourNames() { return DEFAULT_HOUR_NAMES; } getMinuteNames() { return DEFAULT_MINUTE_NAMES; } getDayOfWeekNames(style) { // Note that we shift the array once, because Luxon returns Monday as the // first day of the week, whereas our logic assumes that it's Sunday. See: // https://moment.github.io/luxon/api-docs/index.html#infoweekdays const days = LuxonInfo.weekdays(style, { locale: this.locale }); days.unshift(days.pop()); return days; } getYearName(date) { return date.toFormat('yyyy'); } getFirstDayOfWeek() { // Luxon doesn't have support for getting the first day of the week. if (this._getFirstDayOfWeek) { return this._getFirstDayOfWeek(this.locale); } return 0; } getNumDaysInMonth(date) { return date.daysInMonth; } clone(date) { return LuxonDateTime.fromObject(date.toObject({ includeConfig: true })); } createDate(year, month, date, hours = 0, minutes = 0, seconds = 0, ms = 0) { if (month < 0 || month > 11) { throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`); } if (date < 1) { throw Error(`Invalid date "${date}". Date has to be greater than 0.`); } // Luxon uses 1-indexed months so we need to add one to the month. const result = this._useUTC ? LuxonDateTime.utc(year, month + 1, date, hours, minutes, seconds, ms) : LuxonDateTime.local(year, month + 1, date, hours, minutes, seconds, ms); if (!this.isValid(result)) { throw Error(`Invalid date "${date}". Reason: "${result.invalidReason}".`); } return result.setLocale(this.locale); } today() { return (this._useUTC ? LuxonDateTime.utc() : LuxonDateTime.local()).setLocale(this.locale); } parse(value, parseFormat) { const options = this._getOptions(); if (typeof value == 'string' && value.length > 0) { const iso8601Date = LuxonDateTime.fromISO(value, options); if (this.isValid(iso8601Date)) { return iso8601Date; } const parseFormats = Array.isArray(parseFormat) ? parseFormat : [parseFormat]; for (const format of parseFormats) { const fromFormat = LuxonDateTime.fromFormat(value, format, options); if (this.isValid(fromFormat)) { return fromFormat; } } return this.invalid(); } else if (typeof value === 'number') { return LuxonDateTime.fromMillis(value, options); } else if (value instanceof Date) { return LuxonDateTime.fromJSDate(value, options); } else if (value instanceof LuxonDateTime) { return LuxonDateTime.fromMillis(value.toMillis(), options); } return null; } format(date, displayFormat) { if (!this.isValid(date)) { throw Error('LuxonDateAdapter: Cannot format invalid date.'); } let result = date.setLocale(this.locale); if (this._useUTC) { result = result.toUTC(); } return result.toFormat(displayFormat); } addCalendarYears(date, years) { return date.plus({ years }).setLocale(this.locale); } addCalendarMonths(date, months) { return date.plus({ months }).setLocale(this.locale); } addCalendarDays(date, days) { return date.plus({ days }).setLocale(this.locale); } addCalendarHours(date, hours) { return date.plus({ hours }); } addCalendarMinutes(date, minutes) { return date.plus({ minutes }); } addCalendarSeconds(date, seconds, ms) { return date.plus({ seconds, milliseconds: ms }); } toIso8601(date) { return date.toISO(); } /** * Returns the given value if given a valid Luxon or null. Deserializes valid ISO 8601 strings * (https://www.ietf.org/rfc/rfc3339.txt) and valid Date objects into valid DateTime and empty * string into null. Returns an invalid date for all other values. */ deserialize(value) { const options = this._getOptions(); let date; if (value instanceof Date) { date = LuxonDateTime.fromJSDate(value, options); } if (typeof value === 'string') { if (!value) { return null; } date = LuxonDateTime.fromISO(value, options); } if (date && this.isValid(date)) { return date; } return super.deserialize(value); } isDateInstance(obj) { return obj instanceof LuxonDateTime; } isValid(date) { return date.isValid; } invalid() { return LuxonDateTime.invalid('Invalid Luxon DateTime object.'); } /** Gets the options that should be used when constructing a new `DateTime` object. */ _getOptions() { return { zone: this._useUTC ? 'utc' : undefined, locale: this.locale, }; } } /** @nocollapse */ /** @nocollapse */ LuxonDateAdapter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: LuxonDateAdapter, deps: [{ token: MAT_DATE_LOCALE, optional: true }, { token: MAT_LUXON_DATE_ADAPTER_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ /** @nocollapse */ LuxonDateAdapter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: LuxonDateAdapter }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: LuxonDateAdapter, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DATE_LOCALE] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_LUXON_DATE_ADAPTER_OPTIONS] }] }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibHV4b24tZGF0ZS1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRlcGlja2VyL2x1eG9uL2x1eG9uLWRhdGUtYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdEQsT0FBTyxFQUNMLFFBQVEsSUFBSSxhQUFhLEVBQ3pCLElBQUksSUFBSSxTQUFTLEdBRWxCLE1BQU0sT0FBTyxDQUFDOztBQW1CZixnRUFBZ0U7QUFDaEUsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUcsSUFBSSxjQUFjLENBQzlELGdDQUFnQyxFQUNoQztJQUNFLFVBQVUsRUFBRSxNQUFNO0lBQ2xCLE9BQU8sRUFBRSxzQ0FBc0M7Q0FDaEQsQ0FDRixDQUFDO0FBRUYsb0JBQW9CO0FBQ3BCLE1BQU0sVUFBVSxzQ0FBc0M7SUFDcEQsT0FBTztRQUNMLE1BQU0sRUFBRSxLQUFLO0tBQ2QsQ0FBQztBQUNKLENBQUM7QUFFRCxrRUFBa0U7QUFDbEUsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUUxRSxvRUFBb0U7QUFDcEUsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBRS9DLGlEQUFpRDtBQUNqRCxTQUFTLEtBQUssQ0FBSSxNQUFj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QU8sR0FBRyxZQUFZLGFBQWEsQ0FBQztJQUN0QyxDQUFDO0lBRUQsT0FBTyxDQUFDLElBQW1CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRUQsT0FBTztRQUNMLE9BQU8sYUFBYSxDQUFDLE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxzRkFBc0Y7SUFDOUUsV0FBVztRQUNqQixPQUFPO1lBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUztZQUN0QyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07U0FDcEIsQ0FBQztJQUNKLENBQUM7O21KQS9RVSxnQkFBZ0Isa0JBS0wsZUFBZSw2QkFFM0IsOEJBQThCO3VKQVA3QixnQkFBZ0I7MkZBQWhCLGdCQUFnQjtrQkFENUIsVUFBVTs7MEJBTU4sUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxlQUFlOzswQkFDbEMsUUFBUTs7MEJBQ1IsTUFBTTsyQkFBQyw4QkFBOEIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBPcHRpb25hbCwgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1BVF9EQVRFX0xPQ0FMRSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xuaW1wb3J0IHsgRGF0ZUFkYXB0ZXIgfSBmcm9tICdAbWF0aGVvL2RhdGVwaWNrZXIvY29yZSc7XG5pbXBvcnQge1xuICBEYXRlVGltZSBhcyBMdXhvbkRhdGVUaW1lLFxuICBJbmZvIGFzIEx1eG9uSW5mbyxcbiAgRGF0ZVRpbWVPcHRpb25zIGFzIEx1eG9uRGF0ZVRpbWVPcHRpb25zLFxufSBmcm9tICdsdXhvbic7XG5cbi8qKiBDb25maWd1cmFibGUgb3B0aW9ucyBmb3Ige0BzZWUgTHV4b25EYXRlQWRhcHRlcn0uICovXG5leHBvcnQgaW50ZXJmYWNlIE1hdEx1eG9uRGF0ZUFkYXB0ZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIFR1cm5zIHRoZSB1c2Ugb2YgdXRjIGRhdGVzIG9uIG9yIG9mZi5cbiAgICogQ2hhbmdpbmcgdGhpcyB3aWxsIGNoYW5nZSBob3cgQW5ndWxhciBNYXRlcmlhbCBjb21wb25lbnRzIGxpa2UgRGF0ZVBpY2tlciBvdXRwdXQgZGF0ZXMuXG4gICAqIHtAZGVmYXVsdCBmYWxzZX1cbiAgICovXG4gIHVzZVV0YzogYm9vbGVhbjtcblxuICAvKipcbiAgICogTHV4b24gZG9lcyBub3QgaGF2ZSBzdXBwb3J0IGZvciByZXRyaWV2aW5nIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsuXG4gICAqIFRoaXMgYWxsb3dzIHN1cHBseWluZyBhIGN1c3RvbSBmdW5jdGlvbiB0byBvdmVycmlkZSBpdC5cbiAgICogUmVtZW1iZXIgdGhhdCB5b3UgbmVlZCB0byByZXR1cm4gMCA9IFN1bmRheSwgMSA9IE1vbmRheVxuICAgKi9cbiAgZmlyc3REYXlPZldlZWs/OiAobG9jYWxlOiBzdHJpbmcpID0+IG51bWJlcjtcbn1cblxuLyoqIEluamVjdGlvblRva2VuIGZvciBMdXhvbkRhdGVBZGFwdGVyIHRvIGNvbmZpZ3VyZSBvcHRpb25zLiAqL1xuZXhwb3J0IGNvbnN0IE1BVF9MVVhPTl9EQVRFX0FEQVBURVJfT1BUSU9OUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxNYXRMdXhvbkRhdGVBZGFwdGVyT3B0aW9ucz4oXG4gICdNQVRfTFVYT05fREFURV9BREFQVEVSX09QVElPTlMnLFxuICB7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICAgIGZhY3Rvcnk6IE1BVF9MVVhPTl9EQVRFX0FEQVBURVJfT1BUSU9OU19GQUNUT1JZLFxuICB9XG4pO1xuXG4vKiogQGRvY3MtcHJpdmF0ZSAqL1xuZXhwb3J0IGZ1bmN0aW9uIE1BVF9MVVhPTl9EQVRFX0FEQVBURVJfT1BUSU9OU19GQUNUT1JZKCk6IE1hdEx1eG9uRGF0ZUFkYXB0ZXJPcHRpb25zIHtcbiAgcmV0dXJuIHtcbiAgICB1c2VVdGM6IGZhbHNlLFxuICB9O1xufVxuXG4vKiogVGhlIGRlZmF1bHQgaG91ciBuYW1lcyB0byB1c2UgaWYgSW50bCBBUEkgaXMgbm90IGF2YWlsYWJsZS4gKi9cbmNvbnN0IERFRkFVTFRfSE9VUl9OQU1FUyA9IHJhbmdlKDI0LCAoaSkgPT4gKGkgPT09IDAgPyAnMDAnIDogU3RyaW5nKGkpKSk7XG5cbi8qKiBUaGUgZGVmYXVsdCBtaW51dGUgbmFtZXMgdG8gdXNlIGlmIEludGwgQVBJIGlzIG5vdCBhdmFpbGFibGUuICovXG5jb25zdCBERUZBVUxUX01JTlVURV9OQU1FUyA9IHJhbmdlKDYwLCBTdHJpbmcpO1xuXG4vKiogQ3JlYXRlcyBhbiBhcnJheSBhbmQgZmlsbHMgaXQgd2l0aCB2YWx1ZXMuICovXG5mdW5jdGlvbiByYW5nZTxUPihsZW5ndGg6IG51bWJlciwgdmFsdWVGdW5jdGlvbjogKGluZGV4OiBudW1iZXIpID0+IFQpOiBUW10ge1xuICBjb25zdCB2YWx1ZXNBcnJheSA9IEFycmF5KGxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YWx1ZXNBcnJheVtpXSA9IHZhbHVlRnVuY3Rpb24oaSk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlc0FycmF5O1xufVxuXG4vKiogQWRhcHRzIEx1eG9uIERhdGVzIGZvciB1c2Ugd2l0aCBBbmd1bGFyIE1hdGVyaWFsLiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEx1eG9uRGF0ZUFkYXB0ZXIgZXh0ZW5kcyBEYXRlQWRhcHRlcjxMdXhvbkRhdGVUaW1lPiB7XG4gIHByaXZhdGUgX3VzZVVUQzogYm9vbGVhbjtcbiAgcHJpdmF0ZSBfZ2V0Rmlyc3REYXlPZldlZWs/OiBNYXRMdXhvbkRhdGVBZGFwdGVyT3B0aW9uc1snZmlyc3REYXlPZldlZWsnXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KE1BVF9EQVRFX0xPQ0FMRSkgZGF0ZUxvY2FsZTogc3RyaW5nLFxuICAgIEBPcHRpb25hbCgpXG4gICAgQEluamVjdChNQVRfTFVYT05fREFURV9BREFQVEVSX09QVElPTlMpXG4gICAgb3B0aW9ucz86IE1hdEx1eG9uRGF0ZUFkYXB0ZXJPcHRpb25zLFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX3VzZVVUQyA9IG9wdGlvbnMgPyAhIW9wdGlvbnMudXNlVXRjIDogZmFsc2U7XG4gICAgdGhpcy5fZ2V0Rmlyc3REYXlPZldlZWsgPSBvcHRpb25zPy5maXJzdERheU9mV2VlaztcbiAgICB0aGlzLnNldExvY2FsZShkYXRlTG9jYWxlIHx8IEx1eG9uRGF0ZVRpbWUubG9jYWwoKS5sb2NhbGUpO1xuICB9XG5cbiAgc2V0TG9jYWxlKGxvY2FsZTogc3RyaW5nKSB7XG4gICAgc3VwZXIuc2V0TG9jYWxlKGxvY2FsZSk7XG4gIH1cblxuICBnZXRZZWFyKGRhdGU6IEx1eG9uRGF0ZVRpbWUpOiBudW1iZXIge1xuICAgIHJldHVybiBkYXRlLnllYXI7XG4gIH1cblxuICBnZXRNb250aChkYXRlOiBMdXhvbkRhdGVUaW1lKTogbnVtYmVyIHtcbiAgICAvLyBMdXhvbiB3b3JrcyB3aXRoIDEtaW5kZXhlZCBtb250aHMgd2hlcmVhcyBvdXIgY29kZSBleHBlY3RzIDAtaW5kZXhlZC5cbiAgICByZXR1cm4gZGF0ZS5tb250aCAtIDE7XG4gIH1cblxuICBnZXREYXRlKGRhdGU6IEx1eG9uRGF0ZVRpbWUpOiBudW1iZXIge1xuICAgIHJldHVybiBkYXRlLmRheTtcbiAgfVxuXG4gIGdldEhvdXJzKGRhdGU6IEx1eG9uRGF0ZVRpbWUpOiBudW1iZXIge1xuICAgIHJldHVybiBkYXRlLmhvdXI7XG4gIH1cblxuICBzZXRIb3VycyhkYXRlOiBMdXhvbkRhdGVUaW1lLCBob3VyOiBudW1iZXIpOiBMdXhvbkRhdGVUaW1lIHtcbiAgICByZXR1cm4gZGF0ZS5zZXQoeyBob3VyIH0pO1xuICB9XG5cbiAgZ2V0TWludXRlcyhkYXRlOiBMdXhvbkRhdGVUaW1lKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZGF0ZS5taW51dGU7XG4gIH1cblxuICBzZXRNaW51dGVzKGRhdGU6IEx1eG9uRGF0ZVRpbWUsIG1pbnV0ZTogbnVtYmVyKTogTHV4b25EYXRlVGltZSB7XG4gICAgcmV0dXJuIGRhdGUuc2V0KHsgbWludXRlIH0pO1xuICB9XG5cbiAgZ2V0U2Vjb25kcyhkYXRlOiBMdXhvbkRhdGVUaW1lKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZGF0ZS5zZWNvbmQ7XG4gIH1cblxuICBzZXRTZWNvbmRzKGRhdGU6IEx1eG9uRGF0ZVRpbWUsIHNlY29uZDogbnVtYmVyLCBtcz86IG51bWJlcik6IEx1eG9uRGF0ZVRpbWUge1xuICAgIHJldHVybiBkYXRlLnNldCh7IHNlY29uZCwgbWlsbGlzZWNvbmQ6IG1zIH0pO1xuICB9XG5cbiAgZ2V0TWlsbGlzZWNvbmRzKGRhdGU6IEx1eG9uRGF0ZVRpbWUpOiBudW1iZXIge1xuICAgIHJldHVybiBkYXRlLm1pbGxpc2Vjb25kO1xuICB9XG5cbiAgZ2V0RGF5T2ZXZWVrKGRhdGU6IEx1eG9uRGF0ZVRpbWUpOiBudW1iZXIge1xuICAgIHJldHVybiBkYXRlLndlZWtkYXkgPT09IDcgPyAwIDogZGF0ZS53ZWVrZGF5O1xuICB9XG5cbiAgZ2V0TW9udGhOYW1lcyhzdHlsZTogJ2xvbmcnIHwgJ3Nob3J0JyB8ICduYXJyb3cnKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBMdXhvbkluZm8ubW9udGhzKHN0eWxlLCB7IGxvY2FsZTogdGhpcy5sb2NhbGUgfSk7XG4gIH1cblxuICBnZXREYXRlTmFtZXMoKTogc3RyaW5nW10ge1xuICAgIC8vIEF0IHRoZSB0aW1lIG9mIHdyaXRpbmcsIEx1eG9uIGRvZXNuJ3Qgb2ZmZXIgc2ltaWxhclxuICAgIC8vIGZ1bmN0aW9uYWxpdHkgc28gd2UgaGF2ZSB0byBmYWxsIGJhY2sgdG8gdGhlIEludGwgQVBJLlxuICAgIGNvbnN0IGR0ZiA9IG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KHRoaXMubG9jYWxlLCB7XG4gICAgICBkYXk6ICdudW1lcmljJyxcbiAgICAgIHRpbWVab25lOiAndXRjJyxcbiAgICB9KTtcblxuICAgIC8vIEZvcm1hdCBhIFVUQyBkYXRlIGluIG9yZGVyIHRvIGF2b2lkIERTVCBpc3N1ZXMuXG4gICAgcmV0dXJuIHJhbmdlKDMxLCAoaSkgPT4ge1xuICAgICAgcmV0dXJuIGR0Zi5mb3JtYXQoTHV4b25EYXRlVGltZS51dGMoMjAxNywgMSwgaSArIDEpLnRvSlNEYXRlKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0SG91ck5hbWVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gREVGQVVMVF9IT1VSX05BTUVTO1xuICB9XG5cbiAgZ2V0TWludXRlTmFtZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBERUZBVUxUX01JTlVURV9OQU1FUztcbiAgfVxuXG4gIGdldERheU9mV2Vla05hbWVzKHN0eWxlOiAnbG9uZycgfCAnc2hvcnQnIHwgJ25hcnJvdycpOiBzdHJpbmdbXSB7XG4gICAgLy8gTm90ZSB0aGF0IHdlIHNoaWZ0IHRoZSBhcnJheSBvbmNlLCBiZWNhdXNlIEx1eG9uIHJldHVybnMgTW9uZGF5IGFzIHRoZVxuICAgIC8vIGZpcnN0IGRheSBvZiB0aGUgd2Vlaywgd2hlcmVhcyBvdXIgbG9naWMgYXNzdW1lcyB0aGF0IGl0J3MgU3VuZGF5LiBTZWU6XG4gICAgLy8gaHR0cHM6Ly9tb21lbnQuZ2l0aHViLmlvL2x1eG9uL2FwaS1kb2NzL2luZGV4Lmh0bWwjaW5mb3dlZWtkYXlzXG4gICAgY29uc3QgZGF5cyA9IEx1eG9uSW5mby53ZWVrZGF5cyhzdHlsZSwgeyBsb2NhbGU6IHRoaXMubG9jYWxlIH0pO1xuICAgIGRheXMudW5zaGlmdChkYXlzLnBvcCgpISk7XG4gICAgcmV0dXJuIGRheXM7XG4gIH1cblxuICBnZXRZZWFyTmFtZShkYXRlOiBMdXhvbkRhdGVUaW1lKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGF0ZS50b0Zvcm1hdCgneXl5eScpO1xuICB9XG5cbiAgZ2V0Rmlyc3REYXlPZldlZWsoKTogbnVtYmVyIHtcbiAgICAvLyBMdXhvbiBkb2Vzbid0IGhhdmUgc3VwcG9ydCBmb3IgZ2V0dGluZyB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrLlxuICAgIGlmICh0aGlzLl9nZXRGaXJzdERheU9mV2Vlaykge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldEZpcnN0RGF5T2ZXZWVrKHRoaXMubG9jYWxlKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBnZXROdW1EYXlzSW5Nb250aChkYXRlOiBMdXhvbkRhdGVUaW1lKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZGF0ZS5kYXlzSW5Nb250aDtcbiAgfVxuXG4gIGNsb25lKGRhdGU6IEx1eG9uRGF0ZVRpbWUpOiBMdXhvbkRhdGVUaW1lIHtcbiAgICByZXR1cm4gTHV4b25EYXRlVGltZS5mcm9tT2JqZWN0KGRhdGUudG9PYmplY3QoeyBpbmNsdWRlQ29uZmlnOiB0cnVlIH0pKTtcbiAgfVxuXG4gIGNyZWF0ZURhdGUoXG4gICAgeWVhcjogbnVtYmVyLFxuICAgIG1vbnRoOiBudW1iZXIsXG4gICAgZGF0ZTogbnVtYmVyLFxuICAgIGhvdXJzOiBudW1iZXIgPSAwLFxuICAgIG1pbnV0ZXM6IG51bWJlciA9IDAsXG4gICAgc2Vjb25kczogbnVtYmVyID0gMCxcbiAgICBtczogbnVtYmVyID0gMFxuICApOiBMdXhvbkRhdGVUaW1lIHtcbiAgICBpZiAobW9udGggPCAwIHx8IG1vbnRoID4gMTEpIHtcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgSW52YWxpZCBtb250aCBpbmRleCBcIiR7bW9udGh9XCIuIE1vbnRoIGluZGV4IGhhcyB0byBiZSBiZXR3ZWVuIDAgYW5kIDExLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGRhdGUgPCAxKSB7XG4gICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBkYXRlIFwiJHtkYXRlfVwiLiBEYXRlIGhhcyB0byBiZSBncmVhdGVyIHRoYW4gMC5gKTtcbiAgICB9XG5cbiAgICAvLyBMdXhvbiB1c2VzIDEtaW5kZXhlZCBtb250aHMgc28gd2UgbmVlZCB0byBhZGQgb25lIHRvIHRoZSBtb250aC5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl91c2VVVENcbiAgICAgID8gTHV4b25EYXRlVGltZS51dGMoeWVhciwgbW9udGggKyAxLCBkYXRlLCBob3VycywgbWludXRlcywgc2Vjb25kcywgbXMpXG4gICAgICA6IEx1eG9uRGF0ZVRpbWUubG9jYWwoeWVhciwgbW9udGggKyAxLCBkYXRlLCBob3VycywgbWludXRlcywgc2Vjb25kcywgbXMpO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWQocmVzdWx0KSkge1xuICAgICAgdGhyb3cgRXJyb3IoYEludmFsaWQgZGF0ZSBcIiR7ZGF0ZX1cIi4gUmVhc29uOiBcIiR7cmVzdWx0LmludmFsaWRSZWFzb259XCIuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdC5zZXRMb2NhbGUodGhpcy5sb2NhbGUpO1xuICB9XG5cbiAgdG9kYXkoKTogTHV4b25EYXRlVGltZSB7XG4gICAgcmV0dXJuICh0aGlzLl91c2VVVEMgPyBMdXhvbkRhdGVUaW1lLnV0YygpIDogTHV4b25EYXRlVGltZS5sb2NhbCgpKS5zZXRMb2NhbGUoXG4gICAgICB0aGlzLmxvY2FsZVxuICAgICk7XG4gIH1cblxuICBwYXJzZSh2YWx1ZTogYW55LCBwYXJzZUZvcm1hdDogc3RyaW5nIHwgc3RyaW5nW10pOiBMdXhvbkRhdGVUaW1lIHwgbnVsbCB7XG4gICAgY29uc3Qgb3B0aW9uczogTHV4b25EYXRlVGltZU9wdGlvbnMgPSB0aGlzLl9nZXRPcHRpb25zKCk7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnICYmIHZhbHVlLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGlzbzg2MDFEYXRlID0gTHV4b25EYXRlVGltZS5mcm9tSVNPKHZhbHVlLCBvcHRpb25zKTtcblxuICAgICAgaWYgKHRoaXMuaXNWYWxpZChpc284NjAxRGF0ZSkpIHtcbiAgICAgICAgcmV0dXJuIGlzbzg2MDFEYXRlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXJzZUZvcm1hdHMgPSBBcnJheS5pc0FycmF5KHBhcnNlRm9ybWF0KVxuICAgICAgICA/IHBhcnNlRm9ybWF0XG4gICAgICAgIDogW3BhcnNlRm9ybWF0XTtcbiAgICAgIGZvciAoY29uc3QgZm9ybWF0IG9mIHBhcnNlRm9ybWF0cykge1xuICAgICAgICBjb25zdCBmcm9tRm9ybWF0ID0gTHV4b25EYXRlVGltZS5mcm9tRm9ybWF0KHZhbHVlLCBmb3JtYXQsIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmICh0aGlzLmlzVmFsaWQoZnJvbUZvcm1hdCkpIHtcbiAgICAgICAgICByZXR1cm4gZnJvbUZvcm1hdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gTHV4b25EYXRlVGltZS5mcm9tTWlsbGlzKHZhbHVlLCBvcHRpb25zKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgcmV0dXJuIEx1eG9uRGF0ZVRpbWUuZnJvbUpTRGF0ZSh2YWx1ZSwgb3B0aW9ucyk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEx1eG9uRGF0ZVRpbWUpIHtcbiAgICAgIHJldHVybiBMdXhvbkRhdGVUaW1lLmZyb21NaWxsaXModmFsdWUudG9NaWxsaXMoKSwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmb3JtYXQoZGF0ZTogTHV4b25EYXRlVGltZSwgZGlzcGxheUZvcm1hdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZChkYXRlKSkge1xuICAgICAgdGhyb3cgRXJyb3IoJ0x1eG9uRGF0ZUFkYXB0ZXI6IENhbm5vdCBmb3JtYXQgaW52YWxpZCBkYXRlLicpO1xuICAgIH1cblxuICAgIGxldCByZXN1bHQgPSBkYXRlLnNldExvY2FsZSh0aGlzLmxvY2FsZSk7XG4gICAgaWYgKHRoaXMuX3VzZVVUQykge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0LnRvVVRDKCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQudG9Gb3JtYXQoZGlzcGxheUZvcm1hdCk7XG4gIH1cblxuICBhZGRDYWxlbmRhclllYXJzKGRhdGU6IEx1eG9uRGF0ZVRpbWUsIHllYXJzOiBudW1iZXIpOiBMdXhvbkRhdGVUaW1lIHtcbiAgICByZXR1cm4gZGF0ZS5wbHVzKHsgeWVhcnMgfSkuc2V0TG9jYWxlKHRoaXMubG9jYWxlKTtcbiAgfVxuXG4gIGFkZENhbGVuZGFyTW9udGhzKGRhdGU6IEx1eG9uRGF0ZVRpbWUsIG1vbnRoczogbnVtYmVyKTogTHV4b25EYXRlVGltZSB7XG4gICAgcmV0dXJuIGRhdGUucGx1cyh7IG1vbnRocyB9KS5zZXRMb2NhbGUodGhpcy5sb2NhbGUpO1xuICB9XG5cbiAgYWRkQ2FsZW5kYXJEYXlzKGRhdGU6IEx1eG9uRGF0ZVRpbWUsIGRheXM6IG51bWJlcik6IEx1eG9uRGF0ZVRpbWUge1xuICAgIHJldHVybiBkYXRlLnBsdXMoeyBkYXlzIH0pLnNldExvY2FsZSh0aGlzLmxvY2FsZSk7XG4gIH1cblxuICBhZGRDYWxlbmRhckhvdXJzKGRhdGU6IEx1eG9uRGF0ZVRpbWUsIGhvdXJzOiBudW1iZXIpOiBMdXhvbkRhdGVUaW1lIHtcbiAgICByZXR1cm4gZGF0ZS5wbHVzKHsgaG91cnMgfSk7XG4gIH1cblxuICBhZGRDYWxlbmRhck1pbnV0ZXMoZGF0ZTogTHV4b25EYXRlVGltZSwgbWludXRlczogbnVtYmVyKTogTHV4b25EYXRlVGltZSB7XG4gICAgcmV0dXJuIGRhdGUucGx1cyh7IG1pbnV0ZXMgfSk7XG4gIH1cblxuICBhZGRDYWxlbmRhclNlY29uZHMoZGF0ZTogTHV4b25EYXRlVGltZSwgc2Vjb25kczogbnVtYmVyLCBtcz86IG51bWJlcik6IEx1eG9uRGF0ZVRpbWUge1xuICAgIHJldHVybiBkYXRlLnBsdXMoeyBzZWNvbmRzLCBtaWxsaXNlY29uZHM6IG1zIH0pO1xuICB9XG5cbiAgdG9Jc284NjAxKGRhdGU6IEx1eG9uRGF0ZVRpbWUpOiBzdHJpbmcge1xuICAgIHJldHVybiBkYXRlLnRvSVNPKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZ2l2ZW4gdmFsdWUgaWYgZ2l2ZW4gYSB2YWxpZCBMdXhvbiBvciBudWxsLiBEZXNlcmlhbGl6ZXMgdmFsaWQgSVNPIDg2MDEgc3RyaW5nc1xuICAgKiAoaHR0cHM6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMzMzkudHh0KSBhbmQgdmFsaWQgRGF0ZSBvYmplY3RzIGludG8gdmFsaWQgRGF0ZVRpbWUgYW5kIGVtcHR5XG4gICAqIHN0cmluZyBpbnRvIG51bGwuIFJldHVybnMgYW4gaW52YWxpZCBkYXRlIGZvciBhbGwgb3RoZXIgdmFsdWVzLlxuICAgKi9cbiAgZGVzZXJpYWxpemUodmFsdWU6IGFueSk6IEx1eG9uRGF0ZVRpbWUgfCBudWxsIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fZ2V0T3B0aW9ucygpO1xuICAgIGxldCBkYXRlO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIGRhdGUgPSBMdXhvbkRhdGVUaW1lLmZyb21KU0RhdGUodmFsdWUsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGRhdGUgPSBMdXhvbkRhdGVUaW1lLmZyb21JU08odmFsdWUsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBpZiAoZGF0ZSAmJiB0aGlzLmlzVmFsaWQoZGF0ZSkpIHtcbiAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuZGVzZXJpYWxpemUodmFsdWUpO1xuICB9XG5cbiAgaXNEYXRlSW5zdGFuY2Uob2JqOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTHV4b25EYXRlVGltZTtcbiAgfVxuXG4gIGlzVmFsaWQoZGF0ZTogTHV4b25EYXRlVGltZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBkYXRlLmlzVmFsaWQ7XG4gIH1cblxuICBpbnZhbGlkKCk6IEx1eG9uRGF0ZVRpbWUge1xuICAgIHJldHVybiBMdXhvbkRhdGVUaW1lLmludmFsaWQoJ0ludmFsaWQgTHV4b24gRGF0ZVRpbWUgb2JqZWN0LicpO1xuICB9XG5cbiAgLyoqIEdldHMgdGhlIG9wdGlvbnMgdGhhdCBzaG91bGQgYmUgdXNlZCB3aGVuIGNvbnN0cnVjdGluZyBhIG5ldyBgRGF0ZVRpbWVgIG9iamVjdC4gKi9cbiAgcHJpdmF0ZSBfZ2V0T3B0aW9ucygpOiBMdXhvbkRhdGVUaW1lT3B0aW9ucyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHpvbmU6IHRoaXMuX3VzZVVUQyA/ICd1dGMnIDogdW5kZWZpbmVkLFxuICAgICAgbG9jYWxlOiB0aGlzLmxvY2FsZSxcbiAgICB9O1xuICB9XG59XG4iXX0=