@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
286 lines • 35.6 kB
JavaScript
import { DateRangeType } from '../core/dates';
const MDAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const FEBRUARY = 1;
export function range(start = 0, stop, step = 1) {
const res = [];
const cur = (stop === undefined) ? 0 : start;
const max = (stop === undefined) ? start : stop;
for (let i = cur; step < 0 ? i > max : i < max; i += step) {
res.push(i);
}
return res;
}
/**
* Returns true for leap years, false for non-leap years.
*
* @export
* @param year
* @returns
*/
export function isLeap(year) {
return (year % 4 === 0) && ((year % 100 !== 0) || (year % 400 === 0));
}
export function weekDay(year, month, day) {
return new Date(year, month, day).getDay();
}
/**
* Return weekday and number of days for year, month.
*
* @export
* @param year
* @param month
* @returns
*/
export function monthRange(year, month) {
if ((month < 0) || (month > 11)) {
throw new Error('Invalid month specified');
}
const day = weekDay(year, month, 1);
let nDays = MDAYS[month];
if ((month === FEBRUARY) && (isLeap(year))) {
nDays++;
}
return [day, nDays];
}
export function isDateInRanges(date, ranges) {
date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
const dateInMs = date.getTime();
if (!ranges) {
return false;
}
for (const descriptor of ranges) {
const dRanges = descriptor.dateRange ? descriptor.dateRange.map(r => new Date(r.getFullYear(), r.getMonth(), r.getDate())) : undefined;
switch (descriptor.type) {
case (DateRangeType.After):
if (dateInMs > dRanges[0].getTime()) {
return true;
}
break;
case (DateRangeType.Before):
if (dateInMs < dRanges[0].getTime()) {
return true;
}
break;
case (DateRangeType.Between):
const dRange = dRanges.map(d => d.getTime());
const min = Math.min(dRange[0], dRange[1]);
const max = Math.max(dRange[0], dRange[1]);
if (dateInMs >= min && dateInMs <= max) {
return true;
}
break;
case (DateRangeType.Specific):
const datesInMs = dRanges.map(d => d.getTime());
for (const specificDateInMs of datesInMs) {
if (dateInMs === specificDateInMs) {
return true;
}
}
break;
case (DateRangeType.Weekdays):
const day = date.getDay();
if (day % 6 !== 0) {
return true;
}
break;
case (DateRangeType.Weekends):
const weekday = date.getDay();
if (weekday % 6 === 0) {
return true;
}
break;
default:
return false;
}
}
return false;
}
export var WEEKDAYS;
(function (WEEKDAYS) {
WEEKDAYS[WEEKDAYS["SUNDAY"] = 0] = "SUNDAY";
WEEKDAYS[WEEKDAYS["MONDAY"] = 1] = "MONDAY";
WEEKDAYS[WEEKDAYS["TUESDAY"] = 2] = "TUESDAY";
WEEKDAYS[WEEKDAYS["WEDNESDAY"] = 3] = "WEDNESDAY";
WEEKDAYS[WEEKDAYS["THURSDAY"] = 4] = "THURSDAY";
WEEKDAYS[WEEKDAYS["FRIDAY"] = 5] = "FRIDAY";
WEEKDAYS[WEEKDAYS["SATURDAY"] = 6] = "SATURDAY";
})(WEEKDAYS || (WEEKDAYS = {}));
export class Calendar {
constructor(firstWeekDay = WEEKDAYS.SUNDAY) {
this._firstWeekDay = firstWeekDay;
}
get firstWeekDay() {
return this._firstWeekDay % 7;
}
set firstWeekDay(value) {
this._firstWeekDay = value;
}
/**
* Returns an array of weekdays for one week starting
* with the currently set `firstWeekDay`
*
* this.firstWeekDay = 0 (Sunday) --> [0, 1, 2, 3, 4, 5, 6]
* this.firstWeekDay = 1 (Monday) --> [1, 2, 3, 4, 5, 6, 0]
*
* @returns
*
* @memberof Calendar
*/
weekdays() {
const res = [];
for (const i of range(this.firstWeekDay, this.firstWeekDay + 7)) {
res.push(i % 7);
}
return res;
}
/**
* Returns the date values for one month. It will always iterate throught
* complete weeks, so it will contain dates outside the specified month.
*
* @param year
* @param month
* @param boolean
* @returns
*
* @memberof Calendar
*/
monthdates(year, month, extraWeek = false) {
let date = new Date(year, month, 1);
let days = (date.getDay() - this.firstWeekDay) % 7;
if (days < 0) {
days = 7 - Math.abs(days);
}
date = this.timedelta(date, 'day', -days);
const res = [];
let value;
while (true) {
value = this.generateICalendarDate(date, year, month);
res.push(value);
date = this.timedelta(date, 'day', 1);
if ((date.getMonth() !== month) && (date.getDay() === this.firstWeekDay)) {
if (extraWeek && res.length <= 35) {
for (const _ of range(0, 7)) {
value = this.generateICalendarDate(date, year, month);
res.push(value);
date = this.timedelta(date, 'day', 1);
}
}
break;
}
}
return res;
}
/**
* Returns a matrix (array of arrays) representing a month's calendar.
* Each row represents a full week; week entries are ICalendarDate objects.
*
* @param year
* @param month
* @returns
*
* @memberof Calendar
*/
monthdatescalendar(year, month, extraWeek = false) {
const dates = this.monthdates(year, month, extraWeek);
const res = [];
for (const i of range(0, dates.length, 7)) {
res.push(dates.slice(i, i + 7));
}
return res;
}
timedelta(date, interval, units) {
const ret = new Date(date);
const checkRollover = () => {
if (ret.getDate() !== date.getDate()) {
ret.setDate(0);
}
};
switch (interval.toLowerCase()) {
case 'year':
ret.setFullYear(ret.getFullYear() + units);
checkRollover();
break;
case 'quarter':
ret.setMonth(ret.getMonth() + 3 * units);
checkRollover();
break;
case 'month':
ret.setMonth(ret.getMonth() + units);
checkRollover();
break;
case 'week':
ret.setDate(ret.getDate() + 7 * units);
break;
case 'day':
ret.setDate(ret.getDate() + units);
break;
case 'hour':
ret.setTime(ret.getTime() + units * 3600000);
break;
case 'minute':
ret.setTime(ret.getTime() + units * 60000);
break;
case 'second':
ret.setTime(ret.getTime() + units * 1000);
break;
default:
throw new Error('Invalid interval specifier');
}
return ret;
}
formatToParts(date, locale, options, parts) {
const formatter = new Intl.DateTimeFormat(locale, options);
const result = {
date,
full: formatter.format(date)
};
if (formatter.formatToParts) {
const formattedParts = formatter.formatToParts(date);
const toType = (partType) => {
const index = formattedParts.findIndex(({ type }) => type === partType);
const o = { value: '', literal: '', combined: '' };
if (partType === 'era' && index > -1) {
o.value = formattedParts[index].value;
return o;
}
else if (partType === 'era' && index === -1) {
return o;
}
o.value = formattedParts[index].value;
o.literal = formattedParts[index + 1] ? formattedParts[index + 1].value : '';
o.combined = [o.value, o.literal].join('');
return o;
};
for (const each of parts) {
result[each] = toType(each);
}
}
else {
for (const each of parts) {
result[each] = { value: '', literal: '', combined: '' };
}
}
return result;
}
generateICalendarDate(date, year, month) {
return {
date,
isCurrentMonth: date.getFullYear() === year && date.getMonth() === month,
isNextMonth: this.isNextMonth(date, year, month),
isPrevMonth: this.isPreviousMonth(date, year, month)
};
}
isPreviousMonth(date, year, month) {
if (date.getFullYear() === year) {
return date.getMonth() < month;
}
return date.getFullYear() < year;
}
isNextMonth(date, year, month) {
if (date.getFullYear() === year) {
return date.getMonth() > month;
}
return date.getFullYear() > year;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2NhbGVuZGFyL2NhbGVuZGFyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBdUIsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5FLE1BQU0sS0FBSyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvRCxNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFFbkIsTUFBTSxVQUFVLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQztJQUMzQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDZixNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDN0MsTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2hELEtBQUssSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLElBQUksRUFBRTtRQUN2RCxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ2Y7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLElBQVk7SUFD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Y3JpcHRvciwgRGF0ZVJhbmdlVHlwZSB9IGZyb20gJy4uL2NvcmUvZGF0ZXMnO1xuXG5jb25zdCBNREFZUyA9IFszMSwgMjgsIDMxLCAzMCwgMzEsIDMwLCAzMSwgMzEsIDMwLCAzMSwgMzAsIDMxXTtcbmNvbnN0IEZFQlJVQVJZID0gMTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlKHN0YXJ0ID0gMCwgc3RvcCwgc3RlcCA9IDEpIHtcbiAgICBjb25zdCByZXMgPSBbXTtcbiAgICBjb25zdCBjdXIgPSAoc3RvcCA9PT0gdW5kZWZpbmVkKSA/IDAgOiBzdGFydDtcbiAgICBjb25zdCBtYXggPSAoc3RvcCA9PT0gdW5kZWZpbmVkKSA/IHN0YXJ0IDogc3RvcDtcbiAgICBmb3IgKGxldCBpID0gY3VyOyBzdGVwIDwgMCA/IGkgPiBtYXggOiBpIDwgbWF4OyBpICs9IHN0ZXApIHtcbiAgICAgICAgcmVzLnB1c2goaSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGZvciBsZWFwIHllYXJzLCBmYWxzZSBmb3Igbm9uLWxlYXAgeWVhcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHllYXJcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0xlYXAoeWVhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh5ZWFyICUgNCA9PT0gMCkgJiYgKCh5ZWFyICUgMTAwICE9PSAwKSB8fCAoeWVhciAlIDQwMCA9PT0gMCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2Vla0RheSh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIsIGRheTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGgsIGRheSkuZ2V0RGF5KCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHdlZWtkYXkgYW5kIG51bWJlciBvZiBkYXlzIGZvciB5ZWFyLCBtb250aC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0geWVhclxuICogQHBhcmFtIG1vbnRoXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbW9udGhSYW5nZSh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gICAgaWYgKChtb250aCA8IDApIHx8IChtb250aCA+IDExKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbW9udGggc3BlY2lmaWVkJyk7XG4gICAgfVxuICAgIGNvbnN0IGRheSA9IHdlZWtEYXkoeWVhciwgbW9udGgsIDEpO1xuICAgIGxldCBuRGF5cyA9IE1EQVlTW21vbnRoXTtcbiAgICBpZiAoKG1vbnRoID09PSBGRUJSVUFSWSkgJiYgKGlzTGVhcCh5ZWFyKSkpIHtcbiAgICAgICAgbkRheXMrKztcbiAgICB9XG4gICAgcmV0dXJuIFtkYXksIG5EYXlzXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0ZUluUmFuZ2VzKGRhdGU6IERhdGUsIHJhbmdlczogRGF0ZVJhbmdlRGVzY3JpcHRvcltdKTogYm9vbGVhbiB7XG4gICAgZGF0ZSA9IG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpLCBkYXRlLmdldERhdGUoKSk7XG4gICAgY29uc3QgZGF0ZUluTXMgPSBkYXRlLmdldFRpbWUoKTtcblxuICAgIGlmICghcmFuZ2VzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRlc2NyaXB0b3Igb2YgcmFuZ2VzKSB7XG4gICAgICAgIGNvbnN0IGRSYW5nZXMgPSBkZXNjcmlwdG9yLmRhdGVSYW5nZSA/IGRlc2NyaXB0b3IuZGF0ZVJhbmdlLm1hcChcbiAgICAgICAgICAgIHIgPT4gbmV3IERhdGUoci5nZXRGdWxsWWVhcigpLCByLmdldE1vbnRoKCksIHIuZ2V0RGF0ZSgpKSkgOiB1bmRlZmluZWQ7XG4gICAgICAgIHN3aXRjaCAoZGVzY3JpcHRvci50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIChEYXRlUmFuZ2VUeXBlLkFmdGVyKTpcbiAgICAgICAgICAgICAgICBpZiAoZGF0ZUluTXMgPiBkUmFuZ2VzWzBdLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgKERhdGVSYW5nZVR5cGUuQmVmb3JlKTpcbiAgICAgICAgICAgICAgICBpZiAoZGF0ZUluTXMgPCBkUmFuZ2VzWzBdLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgKERhdGVSYW5nZVR5cGUuQmV0d2Vlbik6XG4gICAgICAgICAgICAgICAgY29uc3QgZFJhbmdlID0gZFJhbmdlcy5tYXAoZCA9PiBkLmdldFRpbWUoKSk7XG4gICAgICAgICAgICAgICAgY29uc3QgbWluID0gTWF0aC5taW4oZFJhbmdlWzBdLCBkUmFuZ2VbMV0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KGRSYW5nZVswXSwgZFJhbmdlWzFdKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0ZUluTXMgPj0gbWluICYmIGRhdGVJbk1zIDw9IG1heCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgKERhdGVSYW5nZVR5cGUuU3BlY2lmaWMpOlxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGVzSW5NcyA9IGRSYW5nZXMubWFwKGQgPT4gZC5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc3BlY2lmaWNEYXRlSW5NcyBvZiBkYXRlc0luTXMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGVJbk1zID09PSBzcGVjaWZpY0RhdGVJbk1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5XZWVrZGF5cyk6XG4gICAgICAgICAgICAgICAgY29uc3QgZGF5ID0gZGF0ZS5nZXREYXkoKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF5ICUgNiAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgKERhdGVSYW5nZVR5cGUuV2Vla2VuZHMpOlxuICAgICAgICAgICAgICAgIGNvbnN0IHdlZWtkYXkgPSBkYXRlLmdldERheSgpO1xuICAgICAgICAgICAgICAgIGlmICh3ZWVrZGF5ICUgNiA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElDYWxlbmRhckRhdGUge1xuICAgIGRhdGU6IERhdGU7XG4gICAgaXNDdXJyZW50TW9udGg6IGJvb2xlYW47XG4gICAgaXNQcmV2TW9udGg6IGJvb2xlYW47XG4gICAgaXNOZXh0TW9udGg6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUZvcm1hdHRlZFBhcnRzIHtcbiAgICB2YWx1ZTogc3RyaW5nO1xuICAgIGxpdGVyYWw/OiBzdHJpbmc7XG4gICAgY29tYmluZWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRm9ybWF0dGluZ09wdGlvbnMge1xuICAgIGRheT86IHN0cmluZztcbiAgICBtb250aD86IHN0cmluZztcbiAgICB3ZWVrZGF5Pzogc3RyaW5nO1xuICAgIHllYXI/OiBzdHJpbmc7XG59XG5cblxuZXhwb3J0IGludGVyZmFjZSBJRm9ybWF0dGluZ1ZpZXdzIHtcbiAgICBkYXk/OiBib29sZWFuO1xuICAgIG1vbnRoPzogYm9vbGVhbjtcbiAgICB5ZWFyPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGVudW0gV0VFS0RBWVMge1xuICAgIFNVTkRBWSA9IDAsXG4gICAgTU9OREFZID0gMSxcbiAgICBUVUVTREFZID0gMixcbiAgICBXRURORVNEQVkgPSAzLFxuICAgIFRIVVJTREFZID0gNCxcbiAgICBGUklEQVkgPSA1LFxuICAgIFNBVFVSREFZID0gNlxufVxuXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXIge1xuXG4gICAgcHJpdmF0ZSBfZmlyc3RXZWVrRGF5OiBudW1iZXIgfCBXRUVLREFZUztcblxuICAgIGNvbnN0cnVjdG9yKGZpcnN0V2Vla0RheTogbnVtYmVyIHwgV0VFS0RBWVMgPSBXRUVLREFZUy5TVU5EQVkpIHtcbiAgICAgICAgdGhpcy5fZmlyc3RXZWVrRGF5ID0gZmlyc3RXZWVrRGF5O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgZmlyc3RXZWVrRGF5KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maXJzdFdlZWtEYXkgJSA3O1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgZmlyc3RXZWVrRGF5KHZhbHVlOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5fZmlyc3RXZWVrRGF5ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBhcnJheSBvZiB3ZWVrZGF5cyBmb3Igb25lIHdlZWsgc3RhcnRpbmdcbiAgICAgKiB3aXRoIHRoZSBjdXJyZW50bHkgc2V0IGBmaXJzdFdlZWtEYXlgXG4gICAgICpcbiAgICAgKiB0aGlzLmZpcnN0V2Vla0RheSA9IDAgKFN1bmRheSkgLS0+IFswLCAxLCAyLCAzLCA0LCA1LCA2XVxuICAgICAqIHRoaXMuZmlyc3RXZWVrRGF5ID0gMSAoTW9uZGF5KSAtLT4gWzEsIDIsIDMsIDQsIDUsIDYsIDBdXG4gICAgICpcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mIENhbGVuZGFyXG4gICAgICovXG4gICAgcHVibGljIHdlZWtkYXlzKCk6IG51bWJlcltdIHtcbiAgICAgICAgY29uc3QgcmVzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgaSBvZiByYW5nZSh0aGlzLmZpcnN0V2Vla0RheSwgdGhpcy5maXJzdFdlZWtEYXkgKyA3KSkge1xuICAgICAgICAgICAgcmVzLnB1c2goaSAlIDcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGF0ZSB2YWx1ZXMgZm9yIG9uZSBtb250aC4gSXQgd2lsbCBhbHdheXMgaXRlcmF0ZSB0aHJvdWdodFxuICAgICAqIGNvbXBsZXRlIHdlZWtzLCBzbyBpdCB3aWxsIGNvbnRhaW4gZGF0ZXMgb3V0c2lkZSB0aGUgc3BlY2lmaWVkIG1vbnRoLlxuICAgICAqXG4gICAgICogQHBhcmFtIHllYXJcbiAgICAgKiBAcGFyYW0gbW9udGhcbiAgICAgKiBAcGFyYW0gYm9vbGVhblxuICAgICAqIEByZXR1cm5zXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgQ2FsZW5kYXJcbiAgICAgKi9cbiAgICBwdWJsaWMgbW9udGhkYXRlcyh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIsIGV4dHJhV2VlazogYm9vbGVhbiA9IGZhbHNlKTogSUNhbGVuZGFyRGF0ZVtdIHtcbiAgICAgICAgbGV0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSk7XG4gICAgICAgIGxldCBkYXlzID0gKGRhdGUuZ2V0RGF5KCkgLSB0aGlzLmZpcnN0V2Vla0RheSkgJSA3O1xuICAgICAgICBpZiAoZGF5cyA8IDApIHtcbiAgICAgICAgICAgIGRheXMgPSA3IC0gTWF0aC5hYnMoZGF5cyk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0ZSA9IHRoaXMudGltZWRlbHRhKGRhdGUsICdkYXknLCAtZGF5cyk7XG4gICAgICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgICAgICBsZXQgdmFsdWU6IElDYWxlbmRhckRhdGU7XG5cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcblxuICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmdlbmVyYXRlSUNhbGVuZGFyRGF0ZShkYXRlLCB5ZWFyLCBtb250aCk7XG4gICAgICAgICAgICByZXMucHVzaCh2YWx1ZSk7XG5cbiAgICAgICAgICAgIGRhdGUgPSB0aGlzLnRpbWVkZWx0YShkYXRlLCAnZGF5JywgMSk7XG5cbiAgICAgICAgICAgIGlmICgoZGF0ZS5nZXRNb250aCgpICE9PSBtb250aCkgJiYgKGRhdGUuZ2V0RGF5KCkgPT09IHRoaXMuZmlyc3RXZWVrRGF5KSkge1xuICAgICAgICAgICAgICAgIGlmIChleHRyYVdlZWsgJiYgcmVzLmxlbmd0aCA8PSAzNSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IF8gb2YgcmFuZ2UoMCwgNykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5nZW5lcmF0ZUlDYWxlbmRhckRhdGUoZGF0ZSwgeWVhciwgbW9udGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzLnB1c2godmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IHRoaXMudGltZWRlbHRhKGRhdGUsICdkYXknLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBtYXRyaXggKGFycmF5IG9mIGFycmF5cykgcmVwcmVzZW50aW5nIGEgbW9udGgncyBjYWxlbmRhci5cbiAgICAgKiBFYWNoIHJvdyByZXByZXNlbnRzIGEgZnVsbCB3ZWVrOyB3ZWVrIGVudHJpZXMgYXJlIElDYWxlbmRhckRhdGUgb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB5ZWFyXG4gICAgICogQHBhcmFtIG1vbnRoXG4gICAgICogQHJldHVybnNcbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBDYWxlbmRhclxuICAgICAqL1xuICAgIHB1YmxpYyBtb250aGRhdGVzY2FsZW5kYXIoeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyLCBleHRyYVdlZWs6IGJvb2xlYW4gPSBmYWxzZSk6IElDYWxlbmRhckRhdGVbXVtdIHtcbiAgICAgICAgY29uc3QgZGF0ZXMgPSB0aGlzLm1vbnRoZGF0ZXMoeWVhciwgbW9udGgsIGV4dHJhV2Vlayk7XG4gICAgICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGkgb2YgcmFuZ2UoMCwgZGF0ZXMubGVuZ3RoLCA3KSkge1xuICAgICAgICAgICAgcmVzLnB1c2goZGF0ZXMuc2xpY2UoaSwgaSArIDcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIHB1YmxpYyB0aW1lZGVsdGEoZGF0ZTogRGF0ZSwgaW50ZXJ2YWw6IHN0cmluZywgdW5pdHM6IG51bWJlcik6IERhdGUge1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgRGF0ZShkYXRlKTtcblxuICAgICAgICBjb25zdCBjaGVja1JvbGxvdmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHJldC5nZXREYXRlKCkgIT09IGRhdGUuZ2V0RGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgcmV0LnNldERhdGUoMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgc3dpdGNoIChpbnRlcnZhbC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0RnVsbFllYXIocmV0LmdldEZ1bGxZZWFyKCkgKyB1bml0cyk7XG4gICAgICAgICAgICAgICAgY2hlY2tSb2xsb3ZlcigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgcmV0LnNldE1vbnRoKHJldC5nZXRNb250aCgpICsgMyAqIHVuaXRzKTtcbiAgICAgICAgICAgICAgICBjaGVja1JvbGxvdmVyKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtb250aCc6XG4gICAgICAgICAgICAgICAgcmV0LnNldE1vbnRoKHJldC5nZXRNb250aCgpICsgdW5pdHMpO1xuICAgICAgICAgICAgICAgIGNoZWNrUm9sbG92ZXIoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3dlZWsnOlxuICAgICAgICAgICAgICAgIHJldC5zZXREYXRlKHJldC5nZXREYXRlKCkgKyA3ICogdW5pdHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgICAgICByZXQuc2V0RGF0ZShyZXQuZ2V0RGF0ZSgpICsgdW5pdHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnaG91cic6XG4gICAgICAgICAgICAgICAgcmV0LnNldFRpbWUocmV0LmdldFRpbWUoKSArIHVuaXRzICogMzYwMDAwMCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICAgIHJldC5zZXRUaW1lKHJldC5nZXRUaW1lKCkgKyB1bml0cyAqIDYwMDAwKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgICAgICAgICAgICAgcmV0LnNldFRpbWUocmV0LmdldFRpbWUoKSArIHVuaXRzICogMTAwMCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnRlcnZhbCBzcGVjaWZpZXInKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIHB1YmxpYyBmb3JtYXRUb1BhcnRzKGRhdGU6IERhdGUsIGxvY2FsZTogc3RyaW5nLCBvcHRpb25zOiBhbnksIHBhcnRzOiBzdHJpbmdbXSkge1xuICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChsb2NhbGUsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgICAgICBkYXRlLFxuICAgICAgICAgICAgZnVsbDogZm9ybWF0dGVyLmZvcm1hdChkYXRlKVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICgoZm9ybWF0dGVyIGFzIGFueSkuZm9ybWF0VG9QYXJ0cykge1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkUGFydHMgPSAoZm9ybWF0dGVyIGFzIGFueSkuZm9ybWF0VG9QYXJ0cyhkYXRlKTtcblxuICAgICAgICAgICAgY29uc3QgdG9UeXBlID0gKHBhcnRUeXBlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IGZvcm1hdHRlZFBhcnRzLmZpbmRJbmRleCgoeyB0eXBlIH0pID0+IHR5cGUgPT09IHBhcnRUeXBlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvOiBJRm9ybWF0dGVkUGFydHMgPSB7IHZhbHVlOiAnJywgbGl0ZXJhbDogJycsIGNvbWJpbmVkOiAnJyB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHBhcnRUeXBlID09PSAnZXJhJyAmJiBpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIG8udmFsdWUgPSBmb3JtYXR0ZWRQYXJ0c1tpbmRleF0udmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydFR5cGUgPT09ICdlcmEnICYmIGluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBvLnZhbHVlID0gZm9ybWF0dGVkUGFydHNbaW5kZXhdLnZhbHVlO1xuICAgICAgICAgICAgICAgIG8ubGl0ZXJhbCA9IGZvcm1hdHRlZFBhcnRzW2luZGV4ICsgMV0gPyBmb3JtYXR0ZWRQYXJ0c1tpbmRleCArIDFdLnZhbHVlIDogJyc7XG4gICAgICAgICAgICAgICAgby5jb21iaW5lZCA9IFtvLnZhbHVlLCBvLmxpdGVyYWxdLmpvaW4oJycpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBlYWNoIG9mIHBhcnRzKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2VhY2hdID0gdG9UeXBlKGVhY2gpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yIChjb25zdCBlYWNoIG9mIHBhcnRzKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2VhY2hdID0geyB2YWx1ZTogJycsIGxpdGVyYWw6ICcnLCBjb21iaW5lZDogJycgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2VuZXJhdGVJQ2FsZW5kYXJEYXRlKGRhdGU6IERhdGUsIHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IElDYWxlbmRhckRhdGUge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0ZSxcbiAgICAgICAgICAgIGlzQ3VycmVudE1vbnRoOiBkYXRlLmdldEZ1bGxZZWFyKCkgPT09IHllYXIgJiYgZGF0ZS5nZXRNb250aCgpID09PSBtb250aCxcbiAgICAgICAgICAgIGlzTmV4dE1vbnRoOiB0aGlzLmlzTmV4dE1vbnRoKGRhdGUsIHllYXIsIG1vbnRoKSxcbiAgICAgICAgICAgIGlzUHJldk1vbnRoOiB0aGlzLmlzUHJldmlvdXNNb250aChkYXRlLCB5ZWFyLCBtb250aClcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUHJldmlvdXNNb250aChkYXRlOiBEYXRlLCB5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0geWVhcikge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0TW9udGgoKSA8IG1vbnRoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXRlLmdldEZ1bGxZZWFyKCkgPCB5ZWFyO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNOZXh0TW9udGgoZGF0ZTogRGF0ZSwgeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChkYXRlLmdldEZ1bGxZZWFyKCkgPT09IHllYXIpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRlLmdldE1vbnRoKCkgPiBtb250aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRlLmdldEZ1bGxZZWFyKCkgPiB5ZWFyO1xuICAgIH1cbn1cbiJdfQ==