@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
376 lines • 40.5 kB
JavaScript
import { __values } from "tslib";
import { DateRangeType } from '../core/dates';
var MDAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var FEBRUARY = 1;
export function range(start, stop, step) {
if (start === void 0) { start = 0; }
if (step === void 0) { step = 1; }
var res = [];
var cur = (stop === undefined) ? 0 : start;
var max = (stop === undefined) ? start : stop;
for (var 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');
}
var day = weekDay(year, month, 1);
var nDays = MDAYS[month];
if ((month === FEBRUARY) && (isLeap(year))) {
nDays++;
}
return [day, nDays];
}
export function isDateInRanges(date, ranges) {
var e_1, _a, e_2, _b;
date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
var dateInMs = date.getTime();
if (!ranges) {
return false;
}
try {
for (var ranges_1 = __values(ranges), ranges_1_1 = ranges_1.next(); !ranges_1_1.done; ranges_1_1 = ranges_1.next()) {
var descriptor = ranges_1_1.value;
var dRanges = descriptor.dateRange ? descriptor.dateRange.map(function (r) { return 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):
var dRange = dRanges.map(function (d) { return d.getTime(); });
var min = Math.min(dRange[0], dRange[1]);
var max = Math.max(dRange[0], dRange[1]);
if (dateInMs >= min && dateInMs <= max) {
return true;
}
break;
case (DateRangeType.Specific):
var datesInMs = dRanges.map(function (d) { return d.getTime(); });
try {
for (var datesInMs_1 = (e_2 = void 0, __values(datesInMs)), datesInMs_1_1 = datesInMs_1.next(); !datesInMs_1_1.done; datesInMs_1_1 = datesInMs_1.next()) {
var specificDateInMs = datesInMs_1_1.value;
if (dateInMs === specificDateInMs) {
return true;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (datesInMs_1_1 && !datesInMs_1_1.done && (_b = datesInMs_1.return)) _b.call(datesInMs_1);
}
finally { if (e_2) throw e_2.error; }
}
break;
case (DateRangeType.Weekdays):
var day = date.getDay();
if (day % 6 !== 0) {
return true;
}
break;
case (DateRangeType.Weekends):
var weekday = date.getDay();
if (weekday % 6 === 0) {
return true;
}
break;
default:
return false;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (ranges_1_1 && !ranges_1_1.done && (_a = ranges_1.return)) _a.call(ranges_1);
}
finally { if (e_1) throw e_1.error; }
}
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 = {}));
var Calendar = /** @class */ (function () {
function Calendar(firstWeekDay) {
if (firstWeekDay === void 0) { firstWeekDay = WEEKDAYS.SUNDAY; }
this._firstWeekDay = firstWeekDay;
}
Object.defineProperty(Calendar.prototype, "firstWeekDay", {
get: function () {
return this._firstWeekDay % 7;
},
set: function (value) {
this._firstWeekDay = value;
},
enumerable: true,
configurable: true
});
/**
* 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
*/
Calendar.prototype.weekdays = function () {
var e_3, _a;
var res = [];
try {
for (var _b = __values(range(this.firstWeekDay, this.firstWeekDay + 7)), _c = _b.next(); !_c.done; _c = _b.next()) {
var i = _c.value;
res.push(i % 7);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_3) throw e_3.error; }
}
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
*/
Calendar.prototype.monthdates = function (year, month, extraWeek) {
var e_4, _a;
if (extraWeek === void 0) { extraWeek = false; }
var date = new Date(year, month, 1);
var days = (date.getDay() - this.firstWeekDay) % 7;
if (days < 0) {
days = 7 - Math.abs(days);
}
date = this.timedelta(date, 'day', -days);
var res = [];
var 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) {
try {
for (var _b = (e_4 = void 0, __values(range(0, 7))), _c = _b.next(); !_c.done; _c = _b.next()) {
var _ = _c.value;
value = this.generateICalendarDate(date, year, month);
res.push(value);
date = this.timedelta(date, 'day', 1);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_4) throw e_4.error; }
}
}
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
*/
Calendar.prototype.monthdatescalendar = function (year, month, extraWeek) {
var e_5, _a;
if (extraWeek === void 0) { extraWeek = false; }
var dates = this.monthdates(year, month, extraWeek);
var res = [];
try {
for (var _b = __values(range(0, dates.length, 7)), _c = _b.next(); !_c.done; _c = _b.next()) {
var i = _c.value;
res.push(dates.slice(i, i + 7));
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_5) throw e_5.error; }
}
return res;
};
Calendar.prototype.timedelta = function (date, interval, units) {
var ret = new Date(date);
var checkRollover = function () {
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;
};
Calendar.prototype.formatToParts = function (date, locale, options, parts) {
var e_6, _a, e_7, _b;
var formatter = new Intl.DateTimeFormat(locale, options);
var result = {
date: date,
full: formatter.format(date)
};
if (formatter.formatToParts) {
var formattedParts_1 = formatter.formatToParts(date);
var toType = function (partType) {
var index = formattedParts_1.findIndex(function (_a) {
var type = _a.type;
return type === partType;
});
var o = { value: '', literal: '', combined: '' };
if (partType === 'era' && index > -1) {
o.value = formattedParts_1[index].value;
return o;
}
else if (partType === 'era' && index === -1) {
return o;
}
o.value = formattedParts_1[index].value;
o.literal = formattedParts_1[index + 1] ? formattedParts_1[index + 1].value : '';
o.combined = [o.value, o.literal].join('');
return o;
};
try {
for (var parts_1 = __values(parts), parts_1_1 = parts_1.next(); !parts_1_1.done; parts_1_1 = parts_1.next()) {
var each = parts_1_1.value;
result[each] = toType(each);
}
}
catch (e_6_1) { e_6 = { error: e_6_1 }; }
finally {
try {
if (parts_1_1 && !parts_1_1.done && (_a = parts_1.return)) _a.call(parts_1);
}
finally { if (e_6) throw e_6.error; }
}
}
else {
try {
for (var parts_2 = __values(parts), parts_2_1 = parts_2.next(); !parts_2_1.done; parts_2_1 = parts_2.next()) {
var each = parts_2_1.value;
result[each] = { value: '', literal: '', combined: '' };
}
}
catch (e_7_1) { e_7 = { error: e_7_1 }; }
finally {
try {
if (parts_2_1 && !parts_2_1.done && (_b = parts_2.return)) _b.call(parts_2);
}
finally { if (e_7) throw e_7.error; }
}
}
return result;
};
Calendar.prototype.generateICalendarDate = function (date, year, month) {
return {
date: date,
isCurrentMonth: date.getFullYear() === year && date.getMonth() === month,
isNextMonth: this.isNextMonth(date, year, month),
isPrevMonth: this.isPreviousMonth(date, year, month)
};
};
Calendar.prototype.isPreviousMonth = function (date, year, month) {
if (date.getFullYear() === year) {
return date.getMonth() < month;
}
return date.getFullYear() < year;
};
Calendar.prototype.isNextMonth = function (date, year, month) {
if (date.getFullYear() === year) {
return date.getMonth() > month;
}
return date.getFullYear() > year;
};
return Calendar;
}());
export { Calendar };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2NhbGVuZGFyL2NhbGVuZGFyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQXVCLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRSxJQUFNLEtBQUssR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDL0QsSUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBRW5CLE1BQU0sVUFBVSxLQUFLLENBQUMsS0FBUyxFQUFFLElBQUksRUFBRSxJQUFRO0lBQXpCLHNCQUFBLEVBQUEsU0FBUztJQUFRLHFCQUFBLEVBQUEsUUFBUTtJQUMzQyxJQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDZixJQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDN0MsSUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2hELEtBQUssSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLElBQUksRUFBRTtRQUN2RCxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ2Y7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFN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QWUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQztTQUN2RCxDQUFDO0lBQ04sQ0FBQztJQUVPLGtDQUFlLEdBQXZCLFVBQXdCLElBQVUsRUFBRSxJQUFZLEVBQUUsS0FBYTtRQUMzRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDN0IsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsS0FBSyxDQUFDO1NBQ2xDO1FBQ0QsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ3JDLENBQUM7SUFFTyw4QkFBVyxHQUFuQixVQUFvQixJQUFVLEVBQUUsSUFBWSxFQUFFLEtBQWE7UUFDdkQsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzdCLE9BQU8sSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLEtBQUssQ0FBQztTQUNsQztRQUVELE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQztJQUNyQyxDQUFDO0lBQ0wsZUFBQztBQUFELENBQUMsQUF4TUQsSUF3TUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlUmFuZ2VEZXNjcmlwdG9yLCBEYXRlUmFuZ2VUeXBlIH0gZnJvbSAnLi4vY29yZS9kYXRlcyc7XG5cbmNvbnN0IE1EQVlTID0gWzMxLCAyOCwgMzEsIDMwLCAzMSwgMzAsIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzFdO1xuY29uc3QgRkVCUlVBUlkgPSAxO1xuXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2Uoc3RhcnQgPSAwLCBzdG9wLCBzdGVwID0gMSkge1xuICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgIGNvbnN0IGN1ciA9IChzdG9wID09PSB1bmRlZmluZWQpID8gMCA6IHN0YXJ0O1xuICAgIGNvbnN0IG1heCA9IChzdG9wID09PSB1bmRlZmluZWQpID8gc3RhcnQgOiBzdG9wO1xuICAgIGZvciAobGV0IGkgPSBjdXI7IHN0ZXAgPCAwID8gaSA+IG1heCA6IGkgPCBtYXg7IGkgKz0gc3RlcCkge1xuICAgICAgICByZXMucHVzaChpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgZm9yIGxlYXAgeWVhcnMsIGZhbHNlIGZvciBub24tbGVhcCB5ZWFycy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0geWVhclxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTGVhcCh5ZWFyOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHllYXIgJSA0ID09PSAwKSAmJiAoKHllYXIgJSAxMDAgIT09IDApIHx8ICh5ZWFyICUgNDAwID09PSAwKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3ZWVrRGF5KHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlciwgZGF5OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KS5nZXREYXkoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2Vla2RheSBhbmQgbnVtYmVyIG9mIGRheXMgZm9yIHllYXIsIG1vbnRoLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB5ZWFyXG4gKiBAcGFyYW0gbW9udGhcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb250aFJhbmdlKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IG51bWJlcltdIHtcbiAgICBpZiAoKG1vbnRoIDwgMCkgfHwgKG1vbnRoID4gMTEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBtb250aCBzcGVjaWZpZWQnKTtcbiAgICB9XG4gICAgY29uc3QgZGF5ID0gd2Vla0RheSh5ZWFyLCBtb250aCwgMSk7XG4gICAgbGV0IG5EYXlzID0gTURBWVNbbW9udGhdO1xuICAgIGlmICgobW9udGggPT09IEZFQlJVQVJZKSAmJiAoaXNMZWFwKHllYXIpKSkge1xuICAgICAgICBuRGF5cysrO1xuICAgIH1cbiAgICByZXR1cm4gW2RheSwgbkRheXNdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRlSW5SYW5nZXMoZGF0ZTogRGF0ZSwgcmFuZ2VzOiBEYXRlUmFuZ2VEZXNjcmlwdG9yW10pOiBib29sZWFuIHtcbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksIGRhdGUuZ2V0RGF0ZSgpKTtcbiAgICBjb25zdCBkYXRlSW5NcyA9IGRhdGUuZ2V0VGltZSgpO1xuXG4gICAgaWYgKCFyYW5nZXMpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGVzY3JpcHRvciBvZiByYW5nZXMpIHtcbiAgICAgICAgY29uc3QgZFJhbmdlcyA9IGRlc2NyaXB0b3IuZGF0ZVJhbmdlID8gZGVzY3JpcHRvci5kYXRlUmFuZ2UubWFwKFxuICAgICAgICAgICAgciA9PiBuZXcgRGF0ZShyLmdldEZ1bGxZZWFyKCksIHIuZ2V0TW9udGgoKSwgci5nZXREYXRlKCkpKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgc3dpdGNoIChkZXNjcmlwdG9yLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgKERhdGVSYW5nZVR5cGUuQWZ0ZXIpOlxuICAgICAgICAgICAgICAgIGlmIChkYXRlSW5NcyA+IGRSYW5nZXNbMF0uZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5CZWZvcmUpOlxuICAgICAgICAgICAgICAgIGlmIChkYXRlSW5NcyA8IGRSYW5nZXNbMF0uZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5CZXR3ZWVuKTpcbiAgICAgICAgICAgICAgICBjb25zdCBkUmFuZ2UgPSBkUmFuZ2VzLm1hcChkID0+IGQuZ2V0VGltZSgpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBtaW4gPSBNYXRoLm1pbihkUmFuZ2VbMF0sIGRSYW5nZVsxXSk7XG4gICAgICAgICAgICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoZFJhbmdlWzBdLCBkUmFuZ2VbMV0pO1xuICAgICAgICAgICAgICAgIGlmIChkYXRlSW5NcyA+PSBtaW4gJiYgZGF0ZUluTXMgPD0gbWF4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5TcGVjaWZpYyk6XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZXNJbk1zID0gZFJhbmdlcy5tYXAoZCA9PiBkLmdldFRpbWUoKSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzcGVjaWZpY0RhdGVJbk1zIG9mIGRhdGVzSW5Ncykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0ZUluTXMgPT09IHNwZWNpZmljRGF0ZUluTXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIChEYXRlUmFuZ2VUeXBlLldlZWtkYXlzKTpcbiAgICAgICAgICAgICAgICBjb25zdCBkYXkgPSBkYXRlLmdldERheSgpO1xuICAgICAgICAgICAgICAgIGlmIChkYXkgJSA2ICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5XZWVrZW5kcyk6XG4gICAgICAgICAgICAgICAgY29uc3Qgd2Vla2RheSA9IGRhdGUuZ2V0RGF5KCk7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgJSA2ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUNhbGVuZGFyRGF0ZSB7XG4gICAgZGF0ZTogRGF0ZTtcbiAgICBpc0N1cnJlbnRNb250aDogYm9vbGVhbjtcbiAgICBpc1ByZXZNb250aDogYm9vbGVhbjtcbiAgICBpc05leHRNb250aDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRm9ybWF0dGVkUGFydHMge1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gICAgbGl0ZXJhbD86IHN0cmluZztcbiAgICBjb21iaW5lZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElGb3JtYXR0aW5nT3B0aW9ucyB7XG4gICAgZGF5Pzogc3RyaW5nO1xuICAgIG1vbnRoPzogc3RyaW5nO1xuICAgIHdlZWtkYXk/OiBzdHJpbmc7XG4gICAgeWVhcj86IHN0cmluZztcbn1cblxuXG5leHBvcnQgaW50ZXJmYWNlIElGb3JtYXR0aW5nVmlld3Mge1xuICAgIGRheT86IGJvb2xlYW47XG4gICAgbW9udGg/OiBib29sZWFuO1xuICAgIHllYXI/OiBib29sZWFuO1xufVxuXG5leHBvcnQgZW51bSBXRUVLREFZUyB7XG4gICAgU1VOREFZID0gMCxcbiAgICBNT05EQVkgPSAxLFxuICAgIFRVRVNEQVkgPSAyLFxuICAgIFdFRE5FU0RBWSA9IDMsXG4gICAgVEhVUlNEQVkgPSA0LFxuICAgIEZSSURBWSA9IDUsXG4gICAgU0FUVVJEQVkgPSA2XG59XG5cbmV4cG9ydCBjbGFzcyBDYWxlbmRhciB7XG5cbiAgICBwcml2YXRlIF9maXJzdFdlZWtEYXk6IG51bWJlciB8IFdFRUtEQVlTO1xuXG4gICAgY29uc3RydWN0b3IoZmlyc3RXZWVrRGF5OiBudW1iZXIgfCBXRUVLREFZUyA9IFdFRUtEQVlTLlNVTkRBWSkge1xuICAgICAgICB0aGlzLl9maXJzdFdlZWtEYXkgPSBmaXJzdFdlZWtEYXk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBmaXJzdFdlZWtEYXkoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpcnN0V2Vla0RheSAlIDc7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBmaXJzdFdlZWtEYXkodmFsdWU6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9maXJzdFdlZWtEYXkgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHdlZWtkYXlzIGZvciBvbmUgd2VlayBzdGFydGluZ1xuICAgICAqIHdpdGggdGhlIGN1cnJlbnRseSBzZXQgYGZpcnN0V2Vla0RheWBcbiAgICAgKlxuICAgICAqIHRoaXMuZmlyc3RXZWVrRGF5ID0gMCAoU3VuZGF5KSAtLT4gWzAsIDEsIDIsIDMsIDQsIDUsIDZdXG4gICAgICogdGhpcy5maXJzdFdlZWtEYXkgPSAxIChNb25kYXkpIC0tPiBbMSwgMiwgMywgNCwgNSwgNiwgMF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgQ2FsZW5kYXJcbiAgICAgKi9cbiAgICBwdWJsaWMgd2Vla2RheXMoKTogbnVtYmVyW10ge1xuICAgICAgICBjb25zdCByZXMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpIG9mIHJhbmdlKHRoaXMuZmlyc3RXZWVrRGF5LCB0aGlzLmZpcnN0V2Vla0RheSArIDcpKSB7XG4gICAgICAgICAgICByZXMucHVzaChpICUgNyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkYXRlIHZhbHVlcyBmb3Igb25lIG1vbnRoLiBJdCB3aWxsIGFsd2F5cyBpdGVyYXRlIHRocm91Z2h0XG4gICAgICogY29tcGxldGUgd2Vla3MsIHNvIGl0IHdpbGwgY29udGFpbiBkYXRlcyBvdXRzaWRlIHRoZSBzcGVjaWZpZWQgbW9udGguXG4gICAgICpcbiAgICAgKiBAcGFyYW0geWVhclxuICAgICAqIEBwYXJhbSBtb250aFxuICAgICAqIEBwYXJhbSBib29sZWFuXG4gICAgICogQHJldHVybnNcbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBDYWxlbmRhclxuICAgICAqL1xuICAgIHB1YmxpYyBtb250aGRhdGVzKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlciwgZXh0cmFXZWVrOiBib29sZWFuID0gZmFsc2UpOiBJQ2FsZW5kYXJEYXRlW10ge1xuICAgICAgICBsZXQgZGF0ZSA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAxKTtcbiAgICAgICAgbGV0IGRheXMgPSAoZGF0ZS5nZXREYXkoKSAtIHRoaXMuZmlyc3RXZWVrRGF5KSAlIDc7XG4gICAgICAgIGlmIChkYXlzIDwgMCkge1xuICAgICAgICAgICAgZGF5cyA9IDcgLSBNYXRoLmFicyhkYXlzKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRlID0gdGhpcy50aW1lZGVsdGEoZGF0ZSwgJ2RheScsIC1kYXlzKTtcbiAgICAgICAgY29uc3QgcmVzID0gW107XG4gICAgICAgIGxldCB2YWx1ZTogSUNhbGVuZGFyRGF0ZTtcblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuXG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuZ2VuZXJhdGVJQ2FsZW5kYXJEYXRlKGRhdGUsIHllYXIsIG1vbnRoKTtcbiAgICAgICAgICAgIHJlcy5wdXNoKHZhbHVlKTtcblxuICAgICAgICAgICAgZGF0ZSA9IHRoaXMudGltZWRlbHRhKGRhdGUsICdkYXknLCAxKTtcblxuICAgICAgICAgICAgaWYgKChkYXRlLmdldE1vbnRoKCkgIT09IG1vbnRoKSAmJiAoZGF0ZS5nZXREYXkoKSA9PT0gdGhpcy5maXJzdFdlZWtEYXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4dHJhV2VlayAmJiByZXMubGVuZ3RoIDw9IDM1KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgXyBvZiByYW5nZSgwLCA3KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmdlbmVyYXRlSUNhbGVuZGFyRGF0ZShkYXRlLCB5ZWFyLCBtb250aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRlID0gdGhpcy50aW1lZGVsdGEoZGF0ZSwgJ2RheScsIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIG1hdHJpeCAoYXJyYXkgb2YgYXJyYXlzKSByZXByZXNlbnRpbmcgYSBtb250aCdzIGNhbGVuZGFyLlxuICAgICAqIEVhY2ggcm93IHJlcHJlc2VudHMgYSBmdWxsIHdlZWs7IHdlZWsgZW50cmllcyBhcmUgSUNhbGVuZGFyRGF0ZSBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHllYXJcbiAgICAgKiBAcGFyYW0gbW9udGhcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mIENhbGVuZGFyXG4gICAgICovXG4gICAgcHVibGljIG1vbnRoZGF0ZXNjYWxlbmRhcih5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIsIGV4dHJhV2VlazogYm9vbGVhbiA9IGZhbHNlKTogSUNhbGVuZGFyRGF0ZVtdW10ge1xuICAgICAgICBjb25zdCBkYXRlcyA9IHRoaXMubW9udGhkYXRlcyh5ZWFyLCBtb250aCwgZXh0cmFXZWVrKTtcbiAgICAgICAgY29uc3QgcmVzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgaSBvZiByYW5nZSgwLCBkYXRlcy5sZW5ndGgsIDcpKSB7XG4gICAgICAgICAgICByZXMucHVzaChkYXRlcy5zbGljZShpLCBpICsgNykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgcHVibGljIHRpbWVkZWx0YShkYXRlOiBEYXRlLCBpbnRlcnZhbDogc3RyaW5nLCB1bml0czogbnVtYmVyKTogRGF0ZSB7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBEYXRlKGRhdGUpO1xuXG4gICAgICAgIGNvbnN0IGNoZWNrUm9sbG92ZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAocmV0LmdldERhdGUoKSAhPT0gZGF0ZS5nZXREYXRlKCkpIHtcbiAgICAgICAgICAgICAgICByZXQuc2V0RGF0ZSgwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBzd2l0Y2ggKGludGVydmFsLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgJ3llYXInOlxuICAgICAgICAgICAgICAgIHJldC5zZXRGdWxsWWVhcihyZXQuZ2V0RnVsbFllYXIoKSArIHVuaXRzKTtcbiAgICAgICAgICAgICAgICBjaGVja1JvbGxvdmVyKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdxdWFydGVyJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0TW9udGgocmV0LmdldE1vbnRoKCkgKyAzICogdW5pdHMpO1xuICAgICAgICAgICAgICAgIGNoZWNrUm9sbG92ZXIoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0TW9udGgocmV0LmdldE1vbnRoKCkgKyB1bml0cyk7XG4gICAgICAgICAgICAgICAgY2hlY2tSb2xsb3ZlcigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICAgICAgcmV0LnNldERhdGUocmV0LmdldERhdGUoKSArIDcgKiB1bml0cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgICAgIHJldC5zZXREYXRlKHJldC5nZXREYXRlKCkgKyB1bml0cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0VGltZShyZXQuZ2V0VGltZSgpICsgdW5pdHMgKiAzNjAwMDAwKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgICAgICAgICAgICAgcmV0LnNldFRpbWUocmV0LmdldFRpbWUoKSArIHVuaXRzICogNjAwMDApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0VGltZShyZXQuZ2V0VGltZSgpICsgdW5pdHMgKiAxMDAwKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGludGVydmFsIHNwZWNpZmllcicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgcHVibGljIGZvcm1hdFRvUGFydHMoZGF0ZTogRGF0ZSwgbG9jYWxlOiBzdHJpbmcsIG9wdGlvbnM6IGFueSwgcGFydHM6IHN0cmluZ1tdKSB7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KGxvY2FsZSwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgICAgICAgIGRhdGUsXG4gICAgICAgICAgICBmdWxsOiBmb3JtYXR0ZXIuZm9ybWF0KGRhdGUpXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKChmb3JtYXR0ZXIgYXMgYW55KS5mb3JtYXRUb1BhcnRzKSB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRQYXJ0cyA9IChmb3JtYXR0ZXIgYXMgYW55KS5mb3JtYXRUb1BhcnRzKGRhdGUpO1xuXG4gICAgICAgICAgICBjb25zdCB0b1R5cGUgPSAocGFydFR5cGU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZm9ybWF0dGVkUGFydHMuZmluZEluZGV4KCh7IHR5cGUgfSkgPT4gdHlwZSA9PT0gcGFydFR5cGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG86IElGb3JtYXR0ZWRQYXJ0cyA9IHsgdmFsdWU6ICcnLCBsaXRlcmFsOiAnJywgY29tYmluZWQ6ICcnIH07XG5cbiAgICAgICAgICAgICAgICBpZiAocGFydFR5cGUgPT09ICdlcmEnICYmIGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgby52YWx1ZSA9IGZvcm1hdHRlZFBhcnRzW2luZGV4XS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0VHlwZSA9PT0gJ2VyYScgJiYgaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG8udmFsdWUgPSBmb3JtYXR0ZWRQYXJ0c1tpbmRleF0udmFsdWU7XG4gICAgICAgICAgICAgICAgby5saXRlcmFsID0gZm9ybWF0dGVkUGFydHNbaW5kZXggKyAxXSA/IGZvcm1hdHRlZFBhcnRzW2luZGV4ICsgMV0udmFsdWUgOiAnJztcbiAgICAgICAgICAgICAgICBvLmNvbWJpbmVkID0gW28udmFsdWUsIG8ubGl0ZXJhbF0uam9pbignJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVhY2ggb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRbZWFjaF0gPSB0b1R5cGUoZWFjaCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVhY2ggb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRbZWFjaF0gPSB7IHZhbHVlOiAnJywgbGl0ZXJhbDogJycsIGNvbWJpbmVkOiAnJyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZW5lcmF0ZUlDYWxlbmRhckRhdGUoZGF0ZTogRGF0ZSwgeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyKTogSUNhbGVuZGFyRGF0ZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRlLFxuICAgICAgICAgICAgaXNDdXJyZW50TW9udGg6IGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0geWVhciAmJiBkYXRlLmdldE1vbnRoKCkgPT09IG1vbnRoLFxuICAgICAgICAgICAgaXNOZXh0TW9udGg6IHRoaXMuaXNOZXh0TW9udGgoZGF0ZSwgeWVhciwgbW9udGgpLFxuICAgICAgICAgICAgaXNQcmV2TW9udGg6IHRoaXMuaXNQcmV2aW91c01vbnRoKGRhdGUsIHllYXIsIG1vbnRoKVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNQcmV2aW91c01vbnRoKGRhdGU6IERhdGUsIHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoZGF0ZS5nZXRGdWxsWWVhcigpID09PSB5ZWFyKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpIDwgbW9udGg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKSA8IHllYXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc05leHRNb250aChkYXRlOiBEYXRlLCB5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0geWVhcikge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0TW9udGgoKSA+IG1vbnRoO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKSA+IHllYXI7XG4gICAgfVxufVxuIl19