UNPKG

ngx-mat-datefns-date-adapter

Version:

[![NPM](https://img.shields.io/npm/l/ngx-mat-datefns-date-adapter)](https://github.com/sapozhnikovay/ngx-mat-datefns-date-adapter/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/ngx-mat-datefns-date-adapter)](https://www.npmjs.com/package/ngx-ma

226 lines 27.6 kB
import { Inject, Injectable, InjectionToken, Optional } from '@angular/core'; import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core'; import { addDays, addMonths, addYears, format, getDate, getDay, getDaysInMonth, getMonth, getYear, parse, parseISO, setDay, setMonth, toDate, parseJSON, } from 'date-fns'; import { zonedTimeToUtc } from 'date-fns-tz'; import { enUS } from 'date-fns/locale'; import { NGX_MAT_DATEFNS_LOCALES } from './ngx-mat-datefns-locales'; export const NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS = new InjectionToken('NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS', { providedIn: 'root', factory: NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS_FACTORY, }); export function NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS_FACTORY() { return { useUtc: false, }; } function range(start, end) { const arr = []; for (let i = start; i <= end; i++) { arr.push(i); } return arr; } const UTC_TIMEZONE = 'UTC'; export class NgxDateFnsDateAdapter extends DateAdapter { constructor(dateLocale, locales, options) { super(); this.locales = locales; this.options = options; this.getLocale = (localeCodeOrLocale) => { if (localeCodeOrLocale && localeCodeOrLocale.code) { return localeCodeOrLocale; } if (!this.locales || !this.locales.length) { throw new Error('locales array does not provided or is empty. Provide it via the NGX_MAT_DATEFNS_LOCALES token.'); } const locale = this.locales.find((item) => item.code === localeCodeOrLocale); if (!locale) { throw new Error(`locale '${localeCodeOrLocale}' does not exist in locales array. Add it to the NGX_MAT_DATEFNS_LOCALES token.`); } return locale; }; if (!this.locales || this.locales.length === 0) { this.locales = [enUS]; } try { this.setLocale(dateLocale || enUS); } catch (err) { this.setLocale(enUS); } } setLocale(locale) { if (!locale) { throw new Error('setLocale should be called with the string locale code or date-fns Locale object'); } this._dateFnsLocale = this.getLocale(locale); super.setLocale(locale); } addCalendarDays(date, days) { return addDays(date, days); } addCalendarMonths(date, months) { return addMonths(date, months); } addCalendarYears(date, years) { return addYears(date, years); } clone(date) { return toDate(date); } createDate(year, month, date) { // Check for invalid month and date (except upper bound on date which we have to check after // creating the Date). 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.`); } const result = this._createDateWithOverflow(year, month, date); // Check that the date wasn't above the upper bound for the month, causing the month to overflow if (result.getMonth() !== month) { throw Error(`Invalid date "${date}" for month with index "${month}".`); } return result; } deserialize(value) { var _a; if (value) { if (typeof value === 'string') { if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.useUtc) { return parseJSON(value); } return parseISO(value); } if (typeof value === 'number') { return toDate(value); } if (value instanceof Date) { return this.clone(value); } return null; } return null; } format(date, displayFormat) { return format(date, displayFormat, { locale: this._dateFnsLocale }); } getDate(date) { return getDate(date); } getDateNames() { return range(1, 31).map((day) => String(day)); } getDayOfWeek(date) { return getDay(date); } getDayOfWeekNames(style) { const map = { long: 'EEEE', short: 'EEE', narrow: 'EEEEE', }; const formatStr = map[style]; const date = new Date(); return range(0, 6).map((day) => format(setDay(date, day), formatStr, { locale: this._dateFnsLocale, })); } getFirstDayOfWeek() { var _a, _b; return (_b = (_a = this._dateFnsLocale.options) === null || _a === void 0 ? void 0 : _a.weekStartsOn) !== null && _b !== void 0 ? _b : 0; } getMonth(date) { return getMonth(date); } getMonthNames(style) { const map = { long: 'LLLL', short: 'LLL', narrow: 'LLLLL', }; const formatStr = map[style]; const date = new Date(); return range(0, 11).map((month) => format(setMonth(date, month), formatStr, { locale: this._dateFnsLocale, })); } getNumDaysInMonth(date) { return getDaysInMonth(date); } getYear(date) { return getYear(date); } getYearName(date) { return format(date, 'yyyy', { locale: this._dateFnsLocale, }); } invalid() { return new Date(NaN); } isDateInstance(obj) { return obj instanceof Date; } isValid(date) { return date instanceof Date && !isNaN(date.getTime()); } parse(value, parseFormat) { var _a; if (value) { if (typeof value === 'string') { if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.useUtc) { const d = parse(value.trim(), parseFormat, new Date(), { locale: this._dateFnsLocale, }); return zonedTimeToUtc(d, UTC_TIMEZONE); } return parse(value.trim(), parseFormat, new Date(), { locale: this._dateFnsLocale, }); } if (typeof value === 'number') { return toDate(value); } if (value instanceof Date) { return this.clone(value); } return null; } return null; } toIso8601(date) { return date.toISOString(); } today() { const d = new Date(); return this._createDateWithOverflow(d.getFullYear(), d.getMonth(), d.getDate()); } /** Creates a date but allows the month and date to overflow. */ _createDateWithOverflow(year, month, date) { const result = this._createDateInternal(year, month, date); // We need to correct for the fact that JS native Date treats years in range [0, 99] as // abbreviations for 19xx. if (year >= 0 && year < 100) { result.setFullYear(this.getYear(result) - 1900); } return result; } _createDateInternal(year, month, date) { var _a; if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.useUtc) { return zonedTimeToUtc(new Date(year, month, date), UTC_TIMEZONE); } return new Date(year, month, date); } } NgxDateFnsDateAdapter.decorators = [ { type: Injectable } ]; NgxDateFnsDateAdapter.ctorParameters = () => [ { type: String, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DATE_LOCALE,] }] }, { type: Array, decorators: [{ type: Optional }, { type: Inject, args: [NGX_MAT_DATEFNS_LOCALES,] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS,] }] } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW1hdC1kYXRlZm5zLWRhdGUtYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1tYXQtZGF0ZWZucy1kYXRlLWFkYXB0ZXIvc3JjL2xpYi9uZ3gtbWF0LWRhdGVmbnMtZGF0ZS1hZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RSxPQUFPLEVBQ0wsT0FBTyxFQUNQLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLE9BQU8sRUFDUCxNQUFNLEVBQ04sY0FBYyxFQUNkLFFBQVEsRUFDUixPQUFPLEVBRVAsS0FBSyxFQUNMLFFBQVEsRUFDUixNQUFNLEVBQ04sUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEdBQ1YsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3QyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFNcEUsTUFBTSxDQUFDLE1BQU0sb0NBQW9DLEdBQy9DLElBQUksY0FBYyxDQUNoQixzQ0FBc0MsRUFDdEM7SUFDRSxVQUFVLEVBQUUsTUFBTTtJQUNsQixPQUFPLEVBQUUsNENBQTRDO0NBQ3RELENBQ0YsQ0FBQztBQUVKLE1BQU0sVUFBVSw0Q0FBNEM7SUFDMUQsT0FBTztRQUNMLE1BQU0sRUFBRSxLQUFLO0tBQ2QsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLEtBQUssQ0FBQyxLQUFhLEVBQUUsR0FBVztJQUN2QyxNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7SUFDekIsS0FB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M0QsdUZBQXVGO1FBQ3ZGLDBCQUEwQjtRQUMxQixJQUFJLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxHQUFHLEdBQUcsRUFBRTtZQUMzQixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7U0FDakQ7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sbUJBQW1CLENBQUMsSUFBWSxFQUFFLEtBQWEsRUFBRSxJQUFZOztRQUNuRSxJQUFJLE1BQUEsSUFBSSxDQUFDLE9BQU8sMENBQUUsTUFBTSxFQUFFO1lBQ3hCLE9BQU8sY0FBYyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7U0FDbEU7UUFDRCxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDckMsQ0FBQzs7O1lBcFBGLFVBQVU7Ozt5Q0FvQk4sUUFBUSxZQUFJLE1BQU0sU0FBQyxlQUFlO3dDQUNsQyxRQUFRLFlBQUksTUFBTSxTQUFDLHVCQUF1Qjs0Q0FDMUMsUUFBUSxZQUNSLE1BQU0sU0FBQyxvQ0FBb0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIEluamVjdGlvblRva2VuLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGF0ZUFkYXB0ZXIsIE1BVF9EQVRFX0xPQ0FMRSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xuaW1wb3J0IHtcbiAgYWRkRGF5cyxcbiAgYWRkTW9udGhzLFxuICBhZGRZZWFycyxcbiAgZm9ybWF0LFxuICBnZXREYXRlLFxuICBnZXREYXksXG4gIGdldERheXNJbk1vbnRoLFxuICBnZXRNb250aCxcbiAgZ2V0WWVhcixcbiAgTG9jYWxlLFxuICBwYXJzZSxcbiAgcGFyc2VJU08sXG4gIHNldERheSxcbiAgc2V0TW9udGgsXG4gIHRvRGF0ZSxcbiAgcGFyc2VKU09OLFxufSBmcm9tICdkYXRlLWZucyc7XG5pbXBvcnQgeyB6b25lZFRpbWVUb1V0YyB9IGZyb20gJ2RhdGUtZm5zLXR6JztcbmltcG9ydCB7IGVuVVMgfSBmcm9tICdkYXRlLWZucy9sb2NhbGUnO1xuaW1wb3J0IHsgTkdYX01BVF9EQVRFRk5TX0xPQ0FMRVMgfSBmcm9tICcuL25neC1tYXQtZGF0ZWZucy1sb2NhbGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBOZ3hEYXRlRm5zRGF0ZUFkYXB0ZXJPcHRpb25zIHtcbiAgdXNlVXRjPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IE5HWF9NQVRfREFURUZOU19EQVRFX0FEQVBURVJfT1BUSU9OUyA9XG4gIG5ldyBJbmplY3Rpb25Ub2tlbjxOZ3hEYXRlRm5zRGF0ZUFkYXB0ZXJPcHRpb25zPihcbiAgICAnTkdYX01BVF9EQVRFRk5TX0RBVEVfQURBUFRFUl9PUFRJT05TJyxcbiAgICB7XG4gICAgICBwcm92aWRlZEluOiAncm9vdCcsXG4gICAgICBmYWN0b3J5OiBOR1hfTUFUX0RBVEVGTlNfREFURV9BREFQVEVSX09QVElPTlNfRkFDVE9SWSxcbiAgICB9XG4gICk7XG5cbmV4cG9ydCBmdW5jdGlvbiBOR1hfTUFUX0RBVEVGTlNfREFURV9BREFQVEVSX09QVElPTlNfRkFDVE9SWSgpOiBOZ3hEYXRlRm5zRGF0ZUFkYXB0ZXJPcHRpb25zIHtcbiAgcmV0dXJuIHtcbiAgICB1c2VVdGM6IGZhbHNlLFxuICB9O1xufVxuXG5mdW5jdGlvbiByYW5nZShzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IG51bWJlcltdIHtcbiAgY29uc3QgYXJyOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPD0gZW5kOyBpKyspIHtcbiAgICBhcnIucHVzaChpKTtcbiAgfVxuXG4gIHJldHVybiBhcnI7XG59XG5cbmNvbnN0IFVUQ19USU1FWk9ORSA9ICdVVEMnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmd4RGF0ZUZuc0RhdGVBZGFwdGVyIGV4dGVuZHMgRGF0ZUFkYXB0ZXI8RGF0ZT4ge1xuICBwcml2YXRlIF9kYXRlRm5zTG9jYWxlITogTG9jYWxlO1xuICBwcml2YXRlIGdldExvY2FsZSA9IChsb2NhbGVDb2RlT3JMb2NhbGU6IHN0cmluZyB8IExvY2FsZSk6IExvY2FsZSA9PiB7XG4gICAgaWYgKGxvY2FsZUNvZGVPckxvY2FsZSAmJiAobG9jYWxlQ29kZU9yTG9jYWxlIGFzIExvY2FsZSkuY29kZSkge1xuICAgICAgcmV0dXJuIGxvY2FsZUNvZGVPckxvY2FsZSBhcyBMb2NhbGU7XG4gICAgfVxuICAgIGlmICghdGhpcy5sb2NhbGVzIHx8ICF0aGlzLmxvY2FsZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xvY2FsZXMgYXJyYXkgZG9lcyBub3QgcHJvdmlkZWQgb3IgaXMgZW1wdHkuIFByb3ZpZGUgaXQgdmlhIHRoZSBOR1hfTUFUX0RBVEVGTlNfTE9DQUxFUyB0b2tlbi4nKTtcbiAgICB9XG4gICAgY29uc3QgbG9jYWxlID0gdGhpcy5sb2NhbGVzLmZpbmQoXG4gICAgICAoaXRlbSkgPT4gaXRlbS5jb2RlID09PSBsb2NhbGVDb2RlT3JMb2NhbGVcbiAgICApO1xuICAgIGlmICghbG9jYWxlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvY2FsZSAnJHtsb2NhbGVDb2RlT3JMb2NhbGV9JyBkb2VzIG5vdCBleGlzdCBpbiBsb2NhbGVzIGFycmF5LiBBZGQgaXQgdG8gdGhlIE5HWF9NQVRfREFURUZOU19MT0NBTEVTIHRva2VuLmApO1xuICAgIH1cbiAgICByZXR1cm4gbG9jYWxlO1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTUFUX0RBVEVfTE9DQUxFKSBkYXRlTG9jYWxlOiBzdHJpbmcgfCBudWxsLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTkdYX01BVF9EQVRFRk5TX0xPQ0FMRVMpIHByaXZhdGUgbG9jYWxlczogTG9jYWxlW10gfCBudWxsLFxuICAgIEBPcHRpb25hbCgpXG4gICAgQEluamVjdChOR1hfTUFUX0RBVEVGTlNfREFURV9BREFQVEVSX09QVElPTlMpXG4gICAgcHJpdmF0ZSBvcHRpb25zPzogTmd4RGF0ZUZuc0RhdGVBZGFwdGVyT3B0aW9uc1xuICApIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKCF0aGlzLmxvY2FsZXMgfHwgdGhpcy5sb2NhbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5sb2NhbGVzID0gW2VuVVNdO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB0aGlzLnNldExvY2FsZShkYXRlTG9jYWxlIHx8IGVuVVMpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5zZXRMb2NhbGUoZW5VUyk7XG4gICAgfVxuICB9XG5cbiAgc2V0TG9jYWxlKGxvY2FsZTogc3RyaW5nIHwgTG9jYWxlKSB7XG4gICAgaWYgKCFsb2NhbGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ3NldExvY2FsZSBzaG91bGQgYmUgY2FsbGVkIHdpdGggdGhlIHN0cmluZyBsb2NhbGUgY29kZSBvciBkYXRlLWZucyBMb2NhbGUgb2JqZWN0J1xuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5fZGF0ZUZuc0xvY2FsZSA9IHRoaXMuZ2V0TG9jYWxlKGxvY2FsZSk7XG4gICAgc3VwZXIuc2V0TG9jYWxlKGxvY2FsZSk7XG4gIH1cblxuICBhZGRDYWxlbmRhckRheXMoZGF0ZTogRGF0ZSwgZGF5czogbnVtYmVyKTogRGF0ZSB7XG4gICAgcmV0dXJuIGFkZERheXMoZGF0ZSwgZGF5cyk7XG4gIH1cblxuICBhZGRDYWxlbmRhck1vbnRocyhkYXRlOiBEYXRlLCBtb250aHM6IG51bWJlcik6IERhdGUge1xuICAgIHJldHVybiBhZGRNb250aHMoZGF0ZSwgbW9udGhzKTtcbiAgfVxuXG4gIGFkZENhbGVuZGFyWWVhcnMoZGF0ZTogRGF0ZSwgeWVhcnM6IG51bWJlcik6IERhdGUge1xuICAgIHJldHVybiBhZGRZZWFycyhkYXRlLCB5ZWFycyk7XG4gIH1cblxuICBjbG9uZShkYXRlOiBEYXRlKTogRGF0ZSB7XG4gICAgcmV0dXJuIHRvRGF0ZShkYXRlKTtcbiAgfVxuXG4gIGNyZWF0ZURhdGUoeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyLCBkYXRlOiBudW1iZXIpOiBEYXRlIHtcbiAgICAvLyBDaGVjayBmb3IgaW52YWxpZCBtb250aCBhbmQgZGF0ZSAoZXhjZXB0IHVwcGVyIGJvdW5kIG9uIGRhdGUgd2hpY2ggd2UgaGF2ZSB0byBjaGVjayBhZnRlclxuICAgIC8vIGNyZWF0aW5nIHRoZSBEYXRlKS5cbiAgICBpZiAobW9udGggPCAwIHx8IG1vbnRoID4gMTEpIHtcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgSW52YWxpZCBtb250aCBpbmRleCBcIiR7bW9udGh9XCIuIE1vbnRoIGluZGV4IGhhcyB0byBiZSBiZXR3ZWVuIDAgYW5kIDExLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGRhdGUgPCAxKSB7XG4gICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBkYXRlIFwiJHtkYXRlfVwiLiBEYXRlIGhhcyB0byBiZSBncmVhdGVyIHRoYW4gMC5gKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9jcmVhdGVEYXRlV2l0aE92ZXJmbG93KHllYXIsIG1vbnRoLCBkYXRlKTtcbiAgICAvLyBDaGVjayB0aGF0IHRoZSBkYXRlIHdhc24ndCBhYm92ZSB0aGUgdXBwZXIgYm91bmQgZm9yIHRoZSBtb250aCwgY2F1c2luZyB0aGUgbW9udGggdG8gb3ZlcmZsb3dcbiAgICBpZiAocmVzdWx0LmdldE1vbnRoKCkgIT09IG1vbnRoKSB7XG4gICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBkYXRlIFwiJHtkYXRlfVwiIGZvciBtb250aCB3aXRoIGluZGV4IFwiJHttb250aH1cIi5gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZGVzZXJpYWxpemUodmFsdWU6IGFueSk6IERhdGUgfCBudWxsIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnM/LnVzZVV0Yykge1xuICAgICAgICAgIHJldHVybiBwYXJzZUpTT04odmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJzZUlTTyh2YWx1ZSk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdG9EYXRlKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUodmFsdWUgYXMgRGF0ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmb3JtYXQoZGF0ZTogRGF0ZSwgZGlzcGxheUZvcm1hdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZm9ybWF0KGRhdGUsIGRpc3BsYXlGb3JtYXQsIHsgbG9jYWxlOiB0aGlzLl9kYXRlRm5zTG9jYWxlIH0pO1xuICB9XG5cbiAgZ2V0RGF0ZShkYXRlOiBEYXRlKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZ2V0RGF0ZShkYXRlKTtcbiAgfVxuXG4gIGdldERhdGVOYW1lcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHJhbmdlKDEsIDMxKS5tYXAoKGRheSkgPT4gU3RyaW5nKGRheSkpO1xuICB9XG5cbiAgZ2V0RGF5T2ZXZWVrKGRhdGU6IERhdGUpOiBudW1iZXIge1xuICAgIHJldHVybiBnZXREYXkoZGF0ZSk7XG4gIH1cblxuICBnZXREYXlPZldlZWtOYW1lcyhzdHlsZTogJ2xvbmcnIHwgJ3Nob3J0JyB8ICduYXJyb3cnKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IG1hcCA9IHtcbiAgICAgIGxvbmc6ICdFRUVFJyxcbiAgICAgIHNob3J0OiAnRUVFJyxcbiAgICAgIG5hcnJvdzogJ0VFRUVFJyxcbiAgICB9O1xuXG4gICAgY29uc3QgZm9ybWF0U3RyID0gbWFwW3N0eWxlXTtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcblxuICAgIHJldHVybiByYW5nZSgwLCA2KS5tYXAoKGRheSkgPT5cbiAgICAgIGZvcm1hdChzZXREYXkoZGF0ZSwgZGF5KSwgZm9ybWF0U3RyLCB7XG4gICAgICAgIGxvY2FsZTogdGhpcy5fZGF0ZUZuc0xvY2FsZSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGdldEZpcnN0RGF5T2ZXZWVrKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGVGbnNMb2NhbGUub3B0aW9ucz8ud2Vla1N0YXJ0c09uID8/IDA7XG4gIH1cblxuICBnZXRNb250aChkYXRlOiBEYXRlKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZ2V0TW9udGgoZGF0ZSk7XG4gIH1cblxuICBnZXRNb250aE5hbWVzKHN0eWxlOiAnbG9uZycgfCAnc2hvcnQnIHwgJ25hcnJvdycpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgbWFwID0ge1xuICAgICAgbG9uZzogJ0xMTEwnLFxuICAgICAgc2hvcnQ6ICdMTEwnLFxuICAgICAgbmFycm93OiAnTExMTEwnLFxuICAgIH07XG5cbiAgICBjb25zdCBmb3JtYXRTdHIgPSBtYXBbc3R5bGVdO1xuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgcmV0dXJuIHJhbmdlKDAsIDExKS5tYXAoKG1vbnRoKSA9PlxuICAgICAgZm9ybWF0KHNldE1vbnRoKGRhdGUsIG1vbnRoKSwgZm9ybWF0U3RyLCB7XG4gICAgICAgIGxvY2FsZTogdGhpcy5fZGF0ZUZuc0xvY2FsZSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGdldE51bURheXNJbk1vbnRoKGRhdGU6IERhdGUpOiBudW1iZXIge1xuICAgIHJldHVybiBnZXREYXlzSW5Nb250aChkYXRlKTtcbiAgfVxuXG4gIGdldFllYXIoZGF0ZTogRGF0ZSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGdldFllYXIoZGF0ZSk7XG4gIH1cblxuICBnZXRZZWFyTmFtZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZm9ybWF0KGRhdGUsICd5eXl5Jywge1xuICAgICAgbG9jYWxlOiB0aGlzLl9kYXRlRm5zTG9jYWxlLFxuICAgIH0pO1xuICB9XG5cbiAgaW52YWxpZCgpOiBEYXRlIHtcbiAgICByZXR1cm4gbmV3IERhdGUoTmFOKTtcbiAgfVxuXG4gIGlzRGF0ZUluc3RhbmNlKG9iajogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIERhdGU7XG4gIH1cblxuICBpc1ZhbGlkKGRhdGU6IERhdGUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZGF0ZSBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKGRhdGUuZ2V0VGltZSgpKTtcbiAgfVxuXG4gIHBhcnNlKHZhbHVlOiBhbnksIHBhcnNlRm9ybWF0OiBhbnkpOiBEYXRlIHwgbnVsbCB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zPy51c2VVdGMpIHtcbiAgICAgICAgICBjb25zdCBkID0gcGFyc2UodmFsdWUudHJpbSgpLCBwYXJzZUZvcm1hdCwgbmV3IERhdGUoKSwge1xuICAgICAgICAgICAgbG9jYWxlOiB0aGlzLl9kYXRlRm5zTG9jYWxlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiB6b25lZFRpbWVUb1V0YyhkLCBVVENfVElNRVpPTkUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJzZSh2YWx1ZS50cmltKCksIHBhcnNlRm9ybWF0LCBuZXcgRGF0ZSgpLCB7XG4gICAgICAgICAgbG9jYWxlOiB0aGlzLl9kYXRlRm5zTG9jYWxlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiB0b0RhdGUodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSh2YWx1ZSBhcyBEYXRlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRvSXNvODYwMShkYXRlOiBEYXRlKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGF0ZS50b0lTT1N0cmluZygpO1xuICB9XG5cbiAgdG9kYXkoKTogRGF0ZSB7XG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZURhdGVXaXRoT3ZlcmZsb3coXG4gICAgICBkLmdldEZ1bGxZZWFyKCksXG4gICAgICBkLmdldE1vbnRoKCksXG4gICAgICBkLmdldERhdGUoKVxuICAgICk7XG4gIH1cblxuICAvKiogQ3JlYXRlcyBhIGRhdGUgYnV0IGFsbG93cyB0aGUgbW9udGggYW5kIGRhdGUgdG8gb3ZlcmZsb3cuICovXG4gIHByaXZhdGUgX2NyZWF0ZURhdGVXaXRoT3ZlcmZsb3coeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyLCBkYXRlOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9jcmVhdGVEYXRlSW50ZXJuYWwoeWVhciwgbW9udGgsIGRhdGUpO1xuXG4gICAgLy8gV2UgbmVlZCB0byBjb3JyZWN0IGZvciB0aGUgZmFjdCB0aGF0IEpTIG5hdGl2ZSBEYXRlIHRyZWF0cyB5ZWFycyBpbiByYW5nZSBbMCwgOTldIGFzXG4gICAgLy8gYWJicmV2aWF0aW9ucyBmb3IgMTl4eC5cbiAgICBpZiAoeWVhciA+PSAwICYmIHllYXIgPCAxMDApIHtcbiAgICAgIHJlc3VsdC5zZXRGdWxsWWVhcih0aGlzLmdldFllYXIocmVzdWx0KSAtIDE5MDApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBfY3JlYXRlRGF0ZUludGVybmFsKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlciwgZGF0ZTogbnVtYmVyKTogRGF0ZSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucz8udXNlVXRjKSB7XG4gICAgICByZXR1cm4gem9uZWRUaW1lVG9VdGMobmV3IERhdGUoeWVhciwgbW9udGgsIGRhdGUpLCBVVENfVElNRVpPTkUpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGgsIGRhdGUpO1xuICB9XG59XG4iXX0=