ngx-daterange
Version:
Date-Range Selector for Angular
151 lines • 30.9 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import * as momentNs from 'moment';
const moment = momentNs;
import { extendMoment } from 'moment-range';
const { range } = extendMoment(moment);
export class CalendarComponent {
constructor() {
this.singleCalendar = false;
this.dateChanged = new EventEmitter();
this.monthChanged = new EventEmitter();
this.yearChanged = new EventEmitter();
}
get monthText() {
return moment.monthsShort()[this.month];
}
ngOnChanges(changes) {
var _a;
// Set the right calendar month and year equal to the left calendar
// if the left calendar's date if after the right
if (!this.isLeft) {
let currentValue = (_a = changes === null || changes === void 0 ? void 0 : changes.selectedFromDate) === null || _a === void 0 ? void 0 : _a.currentValue;
if (currentValue) {
if (!moment.isMoment(currentValue)) {
currentValue = moment(currentValue);
}
const month = currentValue.month();
const year = currentValue.year();
if (year > this.year || (year === this.year && month > this.month)) {
this.month = month;
this.year = year;
}
}
}
this.createCalendarGridData();
}
getWeekNumbers(monthRange) {
const weekNumbers = [];
const weeks = Array.from(monthRange.by('weeks'));
for (let i = 0; i < weeks.length; i++) {
const week = weeks[i];
if (i < 6) {
weekNumbers.push(week.week());
}
else {
break;
}
}
return weekNumbers;
}
getWeeksRange(weeks) {
const weeksRange = [];
for (let i = 0; i < weeks.length; i++) {
const weekNumber = weeks[i];
let firstWeekDay = moment([this.year, this.month]).week(weekNumber).day(0);
let lastWeekDay = moment([this.year, this.month]).week(weekNumber).day(6);
// Set year to the next year if the week number is lower than the starting week
// this indicates that the week is in January of the next year
if (weekNumber < weeks[0]) {
firstWeekDay = moment([this.year + 1, 0]).week(weekNumber).day(0);
lastWeekDay = moment([this.year + 1, 0]).week(weekNumber).day(6);
}
weeksRange.push(range(firstWeekDay, lastWeekDay));
}
return weeksRange;
}
createCalendarGridData() {
const firstDay = moment([this.year, this.month]).startOf('month');
const endDay = moment([this.year, this.month]).endOf('month').add(1, 'week');
const monthRange = range(firstDay, endDay);
const weeksRange = this.getWeeksRange(this.getWeekNumbers(monthRange));
const weekList = [];
weeksRange === null || weeksRange === void 0 ? void 0 : weeksRange.map(week => {
const daysList = [];
Array.from(week.by('days')).forEach((day) => {
if (day.isSame(this.minDate, 'date')) {
day = this.minDate;
}
else if (day.isSame(this.maxDate, 'date')) {
day = this.maxDate;
}
;
daysList.push(day);
});
weekList.push(daysList);
});
this.weekList = weekList;
}
isDisabled(day) {
return (day.isBefore(this.minDate) || day.isAfter(this.maxDate)) || (day.isBefore(this.selectedFromDate) && !this.isLeft);
}
isDateAvailable(day) {
if (this.isLeft) {
return day.isSameOrBefore(this.selectedToDate, 'date') && !day.isSameOrBefore(this.minDate, 'date');
}
return day.isSameOrAfter(this.selectedFromDate, 'date') && !day.isSameOrAfter(this.maxDate, 'date');
}
isSelectedDate(day) {
const date = this.isLeft ? this.selectedFromDate : this.selectedToDate;
return date && day.isSame(date, 'date');
}
isDateInRange(day) {
if (this.selectedFromDate && this.selectedToDate) {
const selectedRange = range(this.selectedFromDate, this.selectedToDate);
return selectedRange.contains(day);
}
return false;
}
isDifferentMonth(day) {
return day.get('month') !== this.month;
}
dateSelected(event, data) {
const target = event.target;
if (!target.classList.contains('disabled')) {
this.dateChanged.emit({ day: data.day, isLeft: this.isLeft });
}
event.stopPropagation();
}
monthSelected(event, data) {
this.monthChanged.emit({ value: data.value, isLeft: this.isLeft });
event.stopPropagation();
}
yearSelected(event, data) {
this.yearChanged.emit({ value: data.value, isLeft: this.isLeft });
event.stopPropagation();
}
}
CalendarComponent.decorators = [
{ type: Component, args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'calendar',
template: "<div class=\"row\">\n <div class=\"col text-center\">\n <div class=\"d-flex align-items-center calendar-pagination {{ icons === 'material' ? 'material' : '' }}\">\n <div>\n <button type=\"button\" class=\"btn btn-link btn-previous-year\" (click)=\"yearSelected($event, { value: -1 })\">\n <i *ngIf=\"icons === 'material'\" class=\"material-icons\">first_page</i>\n <i *ngIf=\"icons === 'font-awesome'\" class=\"fas fa-angle-double-left\"></i>\n <img *ngIf=\"icons === 'default'\" src=\"data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCA0MDcuNDM2IDQwNy40MzYiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDQwNy40MzYgNDA3LjQzNjsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxNnB4IiBoZWlnaHQ9IjE2cHgiPgo8Zz4KCTxwb2x5Z29uIHBvaW50cz0iMjY2LjQ1MiwyMS4xNzggMjQ1LjIwNCwwIDQyLjE0OSwyMDMuNzE4IDI0NS4yMDQsNDA3LjQzNiAyNjYuNDUyLDM4Ni4yNTggODQuNTA3LDIwMy43MTggICIgZmlsbD0iIzAwMDAwMCIvPgoJPHBvbHlnb24gcG9pbnRzPSIzNjUuMjg2LDIxLjE3OCAzNDQuMDM4LDAgMTQwLjk4MywyMDMuNzE4IDM0NC4wMzgsNDA3LjQzNiAzNjUuMjg2LDM4Ni4yNTggMTgzLjM0MSwyMDMuNzE4ICAiIGZpbGw9IiMwMDAwMDAiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K\" />\n </button>\n </div>\n <div>\n <button type=\"button\" class=\"btn btn-link btn-previous-month\" (click)=\"monthSelected($event, { value: -1 })\">\n <i *ngIf=\"icons === 'material'\" class=\"material-icons\">chevron_left</i>\n <i *ngIf=\"icons === 'font-awesome'\" class=\"fas fa-angle-left\"></i>\n <img *ngIf=\"icons === 'default'\" src=\"data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDQ0NC41MzEgNDQ0LjUzMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDQ0LjUzMSA0NDQuNTMxOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTIxMy4xMywyMjIuNDA5TDM1MS44OCw4My42NTNjNy4wNS03LjA0MywxMC41NjctMTUuNjU3LDEwLjU2Ny0yNS44NDFjMC0xMC4xODMtMy41MTgtMTguNzkzLTEwLjU2Ny0yNS44MzUgICBsLTIxLjQwOS0yMS40MTZDMzIzLjQzMiwzLjUyMSwzMTQuODE3LDAsMzA0LjYzNywwcy0xOC43OTEsMy41MjEtMjUuODQxLDEwLjU2MUw5Mi42NDksMTk2LjQyNSAgIGMtNy4wNDQsNy4wNDMtMTAuNTY2LDE1LjY1Ni0xMC41NjYsMjUuODQxczMuNTIxLDE4Ljc5MSwxMC41NjYsMjUuODM3bDE4Ni4xNDYsMTg1Ljg2NGM3LjA1LDcuMDQzLDE1LjY2LDEwLjU2NCwyNS44NDEsMTAuNTY0ICAgczE4Ljc5NS0zLjUyMSwyNS44MzQtMTAuNTY0bDIxLjQwOS0yMS40MTJjNy4wNS03LjAzOSwxMC41NjctMTUuNjA0LDEwLjU2Ny0yNS42OTdjMC0xMC4wODUtMy41MTgtMTguNzQ2LTEwLjU2Ny0yNS45NzggICBMMjEzLjEzLDIyMi40MDl6IiBmaWxsPSIjMDAwMDAwIi8+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==\" />\n </button>\n </div>\n <div class=\"flex-grow-1 month-year\">\n {{ monthText }} {{ year }}\n </div>\n <div>\n <button type=\"button\" class=\"btn btn-link btn-next-month\" (click)=\"monthSelected($event, { value: 1 })\">\n <i *ngIf=\"icons === 'material'\" class=\"material-icons\">chevron_right</i>\n <i *ngIf=\"icons === 'font-awesome'\" class=\"fas fa-angle-right\"></i>\n <img *ngIf=\"icons === 'default'\" src=\"data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDQ0NC44MTkgNDQ0LjgxOSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDQ0LjgxOSA0NDQuODE5OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTM1Mi4wMjUsMTk2LjcxMkwxNjUuODg0LDEwLjg0OEMxNTkuMDI5LDMuNjE1LDE1MC40NjksMCwxNDAuMTg3LDBjLTEwLjI4MiwwLTE4Ljg0MiwzLjYxOS0yNS42OTcsMTAuODQ4TDkyLjc5MiwzMi4yNjQgICBjLTcuMDQ0LDcuMDQzLTEwLjU2NiwxNS42MDQtMTAuNTY2LDI1LjY5MmMwLDkuODk3LDMuNTIxLDE4LjU2LDEwLjU2NiwyNS45ODFsMTM4Ljc1MywxMzguNDczTDkyLjc4NiwzNjEuMTY4ICAgYy03LjA0Miw3LjA0My0xMC41NjQsMTUuNjA0LTEwLjU2NCwyNS42OTNjMCw5Ljg5NiwzLjUyMSwxOC41NjIsMTAuNTY0LDI1Ljk4bDIxLjcsMjEuNDEzICAgYzcuMDQzLDcuMDQzLDE1LjYxMiwxMC41NjQsMjUuNjk3LDEwLjU2NGMxMC4wODksMCwxOC42NTYtMy41MjEsMjUuNjk3LTEwLjU2NGwxODYuMTQ1LTE4NS44NjQgICBjNy4wNDYtNy40MjMsMTAuNTcxLTE2LjA4NCwxMC41NzEtMjUuOTgxQzM2Mi41OTcsMjEyLjMyMSwzNTkuMDcxLDIwMy43NTUsMzUyLjAyNSwxOTYuNzEyeiIgZmlsbD0iIzAwMDAwMCIvPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+Cjwvc3ZnPgo=\" />\n </button>\n </div>\n <div>\n <button type=\"button\" class=\"btn btn-link btn-next-year\" (click)=\"yearSelected($event, { value: 1 })\">\n <i *ngIf=\"icons === 'material'\" class=\"material-icons\">last_page</i>\n <i *ngIf=\"icons === 'font-awesome'\" class=\"fas fa-angle-double-right\"></i>\n <img *ngIf=\"icons === 'default'\" src=\"data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCA0MDcuNDM2IDQwNy40MzYiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDQwNy40MzYgNDA3LjQzNjsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxNnB4IiBoZWlnaHQ9IjE2cHgiPgo8Zz4KCTxwb2x5Z29uIHBvaW50cz0iMTYyLjIzMSwwIDE0MC45ODMsMjEuMTc4IDMyMi45MjksMjAzLjcxOCAxNDAuOTgzLDM4Ni4yNTggMTYyLjIzMSw0MDcuNDM2IDM2NS4yODYsMjAzLjcxOCAgIiBmaWxsPSIjMDAwMDAwIi8+Cgk8cG9seWdvbiBwb2ludHM9IjYzLjM5NywwIDQyLjE0OSwyMS4xNzggMjI0LjA5NSwyMDMuNzE4IDQyLjE0OSwzODYuMjU4IDYzLjM5Nyw0MDcuNDM2IDI2Ni40NTIsMjAzLjcxOCAgIiBmaWxsPSIjMDAwMDAwIi8+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==\" />\n </button>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"row\">\n <div class=\"col\">\n <table class=\"table table-borderless mb-0 w-100\">\n <thead>\n <tr class=\"week-days\">\n <th>Sun</th>\n <th>Mon</th>\n <th>Tue</th>\n <th>Wed</th>\n <th>Thu</th>\n <th>Fri</th>\n <th>Sat</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let week of weekList; let i = index\">\n <td *ngFor=\"let day of weekList[i]\" (click)=\"dateSelected($event, { day: day })\" [attr.data-day]=\"day | date:'MM-dd-yyyy'\" [ngClass]=\"{ 'selected': isSelectedDate(day), 'in-selected-range': isDateInRange(day), 'disabled': isDisabled(day), 'different-month': isDifferentMonth(day) }\">\n {{ day.format('D') }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n</div>\n",
styles: [".calendar.calendar-single .table td.in-selected-range{background-color:transparent}.calendar .calendar-pagination{font-size:16px;margin:.5rem -15px 0}.calendar .calendar-pagination .btn,.calendar .calendar-pagination .btn-link{background-color:transparent;min-width:auto;width:auto}.calendar .calendar-pagination.material .btn.btn-previous-year{padding-right:3px}.calendar .calendar-pagination.material .btn.btn-previous-month{padding-left:0}.calendar .calendar-pagination.material .btn.btn-next-month{padding-right:0}.calendar .calendar-pagination.material .btn.btn-next-year{padding-left:3px}.calendar .calendar-pagination .month-year{font-weight:600}.calendar .week-days{text-transform:uppercase}.calendar .table td,.calendar .table th{border-radius:0;color:#333;font-size:12px;height:36px;line-height:1;padding:0;text-align:center;vertical-align:middle}.calendar .table th{font-weight:400}.calendar .table td{border-radius:5px;cursor:pointer;font-weight:900;max-width:32px;width:32px}.calendar .table td:not(.disabled):not(.selected):hover{background-color:#eee;color:#333}.calendar .table td.selected{color:#fff;font-size:12px}.calendar .table td.selected,.calendar .table td.selected.in-selected-range{background-color:#003d79;border-radius:5px}.calendar .table td.selected.different-month{color:#fff}.calendar .table td.selected:hover{background-color:#003d79}.calendar .table td.in-selected-range{background-color:#dfefff;border-radius:0;font-size:12px}.calendar .table td.disabled{background-color:transparent;color:#666;cursor:not-allowed;font-weight:400}.calendar .table td.different-month{color:#888;font-weight:500}.calendar .table td.different-month.disabled{color:#ccc}"]
},] }
];
CalendarComponent.propDecorators = {
month: [{ type: Input }],
year: [{ type: Input }],
selectedFromDate: [{ type: Input }],
selectedToDate: [{ type: Input }],
isLeft: [{ type: Input }],
format: [{ type: Input }],
minDate: [{ type: Input }],
maxDate: [{ type: Input }],
singleCalendar: [{ type: Input }],
icons: [{ type: Input }],
dateChanged: [{ type: Output }],
monthChanged: [{ type: Output }],
yearChanged: [{ type: Output }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uL3NyYy9tb2R1bGVzL25neC1kYXRlcmFuZ2Uvc3JjLyIsInNvdXJjZXMiOlsiY29tcG9uZW50cy9jYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBaUIsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0ksT0FBTyxLQUFLLFFBQVEsTUFBTSxRQUFRLENBQUM7QUFBQyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUM7QUFFNUQsT0FBTyxFQUFFLFlBQVksRUFBYSxNQUFNLGNBQWMsQ0FBQztBQUd2RCxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBV3ZDLE1BQU0sT0FBTyxpQkFBaUI7SUFUOUI7UUFvQ0UsbUJBQWMsR0FBRyxLQUFLLENBQUM7UUFNdkIsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBZ0IsQ0FBQztRQUcvQyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFnQixDQUFDO1FBR2hELGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7SUF3SmpELENBQUM7SUFwSkMsSUFBSSxTQUFTO1FBQ1gsT0FBTyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7O1FBQ2hDLG1FQUFtRTtRQUNuRSxpREFBaUQ7UUFDakQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsSUFBSSxZQUFZLEdBQUcsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsZ0JBQWdCLDBDQUFFLFlBQTBDLENBQUM7WUFFekYsSUFBSSxZQUFZLEVBQUU7Z0JBQ2hCLElB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Qzs7O1lBdk1GLFNBQVMsU0FBQztnQkFDVCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtnQkFDL0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7Z0JBQ3JDLFFBQVEsRUFBRSxVQUFVO2dCQUlwQiw2NFBBQXdDOzthQUN6Qzs7O29CQUdFLEtBQUs7bUJBR0wsS0FBSzsrQkFHTCxLQUFLOzZCQUdMLEtBQUs7cUJBR0wsS0FBSztxQkFHTCxLQUFLO3NCQUdMLEtBQUs7c0JBR0wsS0FBSzs2QkFHTCxLQUFLO29CQUdMLEtBQUs7MEJBR0wsTUFBTTsyQkFHTixNQUFNOzBCQUdOLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIG1vbWVudE5zIGZyb20gJ21vbWVudCc7IGNvbnN0IG1vbWVudCA9IG1vbWVudE5zO1xuXG5pbXBvcnQgeyBleHRlbmRNb21lbnQsIERhdGVSYW5nZSB9IGZyb20gJ21vbWVudC1yYW5nZSc7XG5pbXBvcnQgeyBJQ2hhbmdlZERhdGEsIElEYXRlUmFuZ2UgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcblxuY29uc3QgeyByYW5nZSB9ID0gZXh0ZW5kTW9tZW50KG1vbWVudCk7XG5cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc2VsZWN0b3I6ICdjYWxlbmRhcicsXG4gIHN0eWxlVXJsczogW1xuICAgICcuL2NhbGVuZGFyLmNvbXBvbmVudC5zY3NzJyxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG5cbiAgQElucHV0KClcbiAgbW9udGg6IG51bWJlcjtcblxuICBASW5wdXQoKVxuICB5ZWFyOiBudW1iZXI7XG5cbiAgQElucHV0KClcbiAgc2VsZWN0ZWRGcm9tRGF0ZTogbW9tZW50TnMuTW9tZW50O1xuXG4gIEBJbnB1dCgpXG4gIHNlbGVjdGVkVG9EYXRlOiBtb21lbnROcy5Nb21lbnQ7XG5cbiAgQElucHV0KClcbiAgaXNMZWZ0OiBib29sZWFuO1xuXG4gIEBJbnB1dCgpXG4gIGZvcm1hdDogc3RyaW5nO1xuXG4gIEBJbnB1dCgpXG4gIG1pbkRhdGU6IG1vbWVudE5zLk1vbWVudDtcblxuICBASW5wdXQoKVxuICBtYXhEYXRlOiBtb21lbnROcy5Nb21lbnQ7XG5cbiAgQElucHV0KClcbiAgc2luZ2xlQ2FsZW5kYXIgPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBpY29uczogc3RyaW5nO1xuXG4gIEBPdXRwdXQoKVxuICBkYXRlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8SUNoYW5nZWREYXRhPigpO1xuXG4gIEBPdXRwdXQoKVxuICBtb250aENoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPElDaGFuZ2VkRGF0YT4oKTtcblxuICBAT3V0cHV0KClcbiAgeWVhckNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPElDaGFuZ2VkRGF0YT4oKTtcblxuICB3ZWVrTGlzdDogSURhdGVSYW5nZVtdO1xuXG4gIGdldCBtb250aFRleHQoKSB7XG4gICAgcmV0dXJuIG1vbWVudC5tb250aHNTaG9ydCgpW3RoaXMubW9udGhdO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vIFNldCB0aGUgcmlnaHQgY2FsZW5kYXIgbW9udGggYW5kIHllYXIgZXF1YWwgdG8gdGhlIGxlZnQgY2FsZW5kYXJcbiAgICAvLyBpZiB0aGUgbGVmdCBjYWxlbmRhcidzIGRhdGUgaWYgYWZ0ZXIgdGhlIHJpZ2h0XG4gICAgaWYgKCF0aGlzLmlzTGVmdCkge1xuICAgICAgbGV0IGN1cnJlbnRWYWx1ZSA9IGNoYW5nZXM/LnNlbGVjdGVkRnJvbURhdGU/LmN1cnJlbnRWYWx1ZSBhcyB1bmtub3duIGFzIG1vbWVudE5zLk1vbWVudDtcblxuICAgICAgaWYgKGN1cnJlbnRWYWx1ZSkge1xuICAgICAgICBpZiAoIW1vbWVudC5pc01vbWVudChjdXJyZW50VmFsdWUpKSB7XG4gICAgICAgICAgY3VycmVudFZhbHVlID0gbW9tZW50KGN1cnJlbnRWYWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtb250aDogbnVtYmVyID0gY3VycmVudFZhbHVlLm1vbnRoKCk7XG4gICAgICAgIGNvbnN0IHllYXI6IG51bWJlciA9IGN1cnJlbnRWYWx1ZS55ZWFyKCk7XG5cbiAgICAgICAgaWYgKHllYXIgPiB0aGlzLnllYXIgfHwgKHllYXIgPT09IHRoaXMueWVhciAmJiBtb250aCA+IHRoaXMubW9udGgpKSB7XG4gICAgICAgICAgdGhpcy5tb250aCA9IG1vbnRoO1xuICAgICAgICAgIHRoaXMueWVhciA9IHllYXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNyZWF0ZUNhbGVuZGFyR3JpZERhdGEoKTtcbiAgfVxuXG4gIGdldFdlZWtOdW1iZXJzKG1vbnRoUmFuZ2U6IERhdGVSYW5nZSk6IG51bWJlcltdIHtcbiAgICBjb25zdCB3ZWVrTnVtYmVycyA9IFtdO1xuICAgIGNvbnN0IHdlZWtzID0gQXJyYXkuZnJvbShtb250aFJhbmdlLmJ5KCd3ZWVrcycpKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd2Vla3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHdlZWsgPSB3ZWVrc1tpXTtcblxuICAgICAgaWYgKGkgPCA2KSB7XG4gICAgICAgIHdlZWtOdW1iZXJzLnB1c2god2Vlay53ZWVrKCkpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB3ZWVrTnVtYmVycztcbiAgfVxuXG4gIGdldFdlZWtzUmFuZ2Uod2Vla3M6IG51bWJlcltdKTogRGF0ZVJhbmdlW10ge1xuICAgIGNvbnN0IHdlZWtzUmFuZ2UgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd2Vla3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHdlZWtOdW1iZXIgPSB3ZWVrc1tpXTtcblxuICAgICAgbGV0IGZpcnN0V2Vla0RheTogbW9tZW50TnMuTW9tZW50ID0gbW9tZW50KFt0aGlzLnllYXIsIHRoaXMubW9udGhdKS53ZWVrKHdlZWtOdW1iZXIpLmRheSgwKTtcbiAgICAgIGxldCBsYXN0V2Vla0RheTogbW9tZW50TnMuTW9tZW50ID0gbW9tZW50KFt0aGlzLnllYXIsIHRoaXMubW9udGhdKS53ZWVrKHdlZWtOdW1iZXIpLmRheSg2KTtcblxuICAgICAgLy8gU2V0IHllYXIgdG8gdGhlIG5leHQgeWVhciBpZiB0aGUgd2VlayBudW1iZXIgaXMgbG93ZXIgdGhhbiB0aGUgc3RhcnRpbmcgd2Vla1xuICAgICAgLy8gdGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgd2VlayBpcyBpbiBKYW51YXJ5IG9mIHRoZSBuZXh0IHllYXJcbiAgICAgIGlmICh3ZWVrTnVtYmVyIDwgd2Vla3NbMF0pIHtcbiAgICAgICAgZmlyc3RXZWVrRGF5ID0gbW9tZW50KFt0aGlzLnllYXIgKyAxLCAwXSkud2Vlayh3ZWVrTnVtYmVyKS5kYXkoMCk7XG4gICAgICAgIGxhc3RXZWVrRGF5ID0gbW9tZW50KFt0aGlzLnllYXIgKyAxLCAwXSkud2Vlayh3ZWVrTnVtYmVyKS5kYXkoNik7XG4gICAgICB9XG5cbiAgICAgIHdlZWtzUmFuZ2UucHVzaChyYW5nZShmaXJzdFdlZWtEYXksIGxhc3RXZWVrRGF5KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHdlZWtzUmFuZ2U7XG4gIH1cblxuICBjcmVhdGVDYWxlbmRhckdyaWREYXRhKCk6IHZvaWQge1xuICAgIGNvbnN0IGZpcnN0RGF5ID0gbW9tZW50KFt0aGlzLnllYXIsIHRoaXMubW9udGhdKS5zdGFydE9mKCdtb250aCcpO1xuICAgIGNvbnN0IGVuZERheSA9IG1vbWVudChbdGhpcy55ZWFyLCB0aGlzLm1vbnRoXSkuZW5kT2YoJ21vbnRoJykuYWRkKDEsICd3ZWVrJyk7XG4gICAgY29uc3QgbW9udGhSYW5nZSA9IHJhbmdlKGZpcnN0RGF5LCBlbmREYXkpO1xuICAgIGNvbnN0IHdlZWtzUmFuZ2UgPSB0aGlzLmdldFdlZWtzUmFuZ2UodGhpcy5nZXRXZWVrTnVtYmVycyhtb250aFJhbmdlKSk7XG4gICAgY29uc3Qgd2Vla0xpc3QgPSBbXTtcblxuICAgIHdlZWtzUmFuZ2U/Lm1hcCh3ZWVrID0+IHtcbiAgICAgIGNvbnN0IGRheXNMaXN0ID0gW107XG5cbiAgICAgIEFycmF5LmZyb20od2Vlay5ieSgnZGF5cycpKS5mb3JFYWNoKChkYXk6IG1vbWVudE5zLk1vbWVudCkgPT4ge1xuICAgICAgICBpZiAoZGF5LmlzU2FtZSh0aGlzLm1pbkRhdGUsICdkYXRlJykpIHtcbiAgICAgICAgICBkYXkgPSB0aGlzLm1pbkRhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGF5LmlzU2FtZSh0aGlzLm1heERhdGUsICdkYXRlJykpIHtcbiAgICAgICAgICBkYXkgPSB0aGlzLm1heERhdGU7XG4gICAgICAgIH07XG5cbiAgICAgICAgZGF5c0xpc3QucHVzaChkYXkpO1xuICAgICAgfSk7XG5cbiAgICAgIHdlZWtMaXN0LnB1c2goZGF5c0xpc3QpO1xuICAgIH0pO1xuXG4gICAgdGhpcy53ZWVrTGlzdCA9IHdlZWtMaXN0O1xuICB9XG5cbiAgaXNEaXNhYmxlZChkYXk6IG1vbWVudE5zLk1vbWVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoZGF5LmlzQmVmb3JlKHRoaXMubWluRGF0ZSkgfHwgZGF5LmlzQWZ0ZXIodGhpcy5tYXhEYXRlKSkgfHwgKGRheS5pc0JlZm9yZSh0aGlzLnNlbGVjdGVkRnJvbURhdGUpICYmICF0aGlzLmlzTGVmdCk7XG4gIH1cblxuICBpc0RhdGVBdmFpbGFibGUoZGF5OiBtb21lbnROcy5Nb21lbnQpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5pc0xlZnQpIHtcbiAgICAgIHJldHVybiBkYXkuaXNTYW1lT3JCZWZvcmUodGhpcy5zZWxlY3RlZFRvRGF0ZSwgJ2RhdGUnKSAmJiAhZGF5LmlzU2FtZU9yQmVmb3JlKHRoaXMubWluRGF0ZSwgJ2RhdGUnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF5LmlzU2FtZU9yQWZ0ZXIodGhpcy5zZWxlY3RlZEZyb21EYXRlLCAnZGF0ZScpICYmICFkYXkuaXNTYW1lT3JBZnRlcih0aGlzLm1heERhdGUsICdkYXRlJyk7XG4gIH1cblxuICBpc1NlbGVjdGVkRGF0ZShkYXk6IG1vbWVudE5zLk1vbWVudCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRhdGUgPSB0aGlzLmlzTGVmdCA/IHRoaXMuc2VsZWN0ZWRGcm9tRGF0ZSA6IHRoaXMuc2VsZWN0ZWRUb0RhdGU7XG5cbiAgICByZXR1cm4gZGF0ZSAmJiBkYXkuaXNTYW1lKGRhdGUsICdkYXRlJyk7XG4gIH1cblxuICBpc0RhdGVJblJhbmdlKGRheTogbW9tZW50TnMuTW9tZW50KTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRGcm9tRGF0ZSAmJiB0aGlzLnNlbGVjdGVkVG9EYXRlKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZFJhbmdlID0gcmFuZ2UodGhpcy5zZWxlY3RlZEZyb21EYXRlLCB0aGlzLnNlbGVjdGVkVG9EYXRlKTtcblxuICAgICAgcmV0dXJuIHNlbGVjdGVkUmFuZ2UuY29udGFpbnMoZGF5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpc0RpZmZlcmVudE1vbnRoKGRheTogbW9tZW50TnMuTW9tZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGRheS5nZXQoJ21vbnRoJykgIT09IHRoaXMubW9udGg7XG4gIH1cblxuICBkYXRlU2VsZWN0ZWQoZXZlbnQ6IEV2ZW50LCBkYXRhOiBJQ2hhbmdlZERhdGEpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTFRhYmxlQ2VsbEVsZW1lbnQ7XG5cbiAgICBpZiAoIXRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoJ2Rpc2FibGVkJykpIHtcbiAgICAgIHRoaXMuZGF0ZUNoYW5nZWQuZW1pdCh7IGRheTogZGF0YS5kYXksIGlzTGVmdDogdGhpcy5pc0xlZnQgfSk7XG4gICAgfVxuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBtb250aFNlbGVjdGVkKGV2ZW50OiBFdmVudCwgZGF0YTogSUNoYW5nZWREYXRhKTogdm9pZCB7XG4gICAgdGhpcy5tb250aENoYW5nZWQuZW1pdCh7IHZhbHVlOiBkYXRhLnZhbHVlLCBpc0xlZnQ6IHRoaXMuaXNMZWZ0IH0pO1xuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICB5ZWFyU2VsZWN0ZWQoZXZlbnQ6IEV2ZW50LCBkYXRhOiBJQ2hhbmdlZERhdGEpOiB2b2lkIHtcbiAgICB0aGlzLnllYXJDaGFuZ2VkLmVtaXQoeyB2YWx1ZTogZGF0YS52YWx1ZSwgaXNMZWZ0OiB0aGlzLmlzTGVmdCB9KTtcblxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG59XG4iXX0=