ngx-datetime-range-picker-ng13
Version:
> Ngx Date time range picker with daily, weekly, monthly, quarterly & yearly levels
597 lines • 78.2 kB
JavaScript
import { Injectable } from "@angular/core";
import { DEFAULT_DATE_FORMAT, NgxDatetimeRangePickerConstants as Constants } from "./ngx-datetime-range-picker.constants";
import { getNotAvailableText, cloneDeep, isNil } from "./ngx-datetime-range-picker.utils";
import { CalendarTypes } from "./interfaces";
import * as i0 from "@angular/core";
const moment = require("moment");
const DEFAULT_TIME_FORMAT = Constants.DEFAULT.TIME_FORMAT;
const MONTHS_AVAILABLE = Constants.CONSTANT.MONTHS_AVAILABLE;
const TZ_NAMES = Constants.CONSTANT.TZ_NAMES;
const DEFAULT_RANGES = Constants.DEFAULT.RANGES;
const MOMENT_CONVERSION_MAP = Constants.CONSTANT.MOMENT_CONVERSION_MAP;
export class NgxDatetimeRangePickerService {
getDefaultOptions() {
return cloneDeep(Constants.DEFAULT.OPTIONS);
}
getDefaultSettings() {
return cloneDeep(Constants.DEFAULT.SETTINGS);
}
getDefaultState() {
return cloneDeep(Constants.DEFAULT.STATE);
}
checkSettingsValidity(settings) {
if (settings.type && !CalendarTypes.includes(settings.type)) {
const errMsg = `${settings.type} is an invalid calendar type. It should one of ${[...CalendarTypes]}`;
throw new Error(errMsg);
}
}
formatDateToDefaultFormat(date, format) {
let formattedDate = null;
if (!date) {
return;
}
if (!isNaN(Number(date))) {
formattedDate = moment(date).format(DEFAULT_DATE_FORMAT);
}
else {
formattedDate = moment(date, format).format(DEFAULT_DATE_FORMAT);
}
return formattedDate;
}
formatTimeToDefaultFormat(time) {
let formattedTime = null;
if (!time) {
return;
}
if (time.indexOf(":") > -1) {
if (time.indexOf("AM") > -1 || time.indexOf("PM") > -1) {
formattedTime = moment(time, "h:mm A").format(DEFAULT_TIME_FORMAT);
}
else {
formattedTime = time;
}
}
else {
console.warn(`WARN_NGX_DATETIME_RANGE_PICKER:
The provided time is not in correct format.
Format: HH:mm or hh:mm A
`);
}
return formattedTime;
}
getCalendarRowNumberText(type, number) {
return (() => {
switch (type) {
case "daily":
return `W${number}`;
case "weekly":
return "";
case "monthly":
return `Q${number}`;
case "quarterly":
return `${number}`;
case "yearly":
return "";
}
})();
}
createDefaultRanges(config) {
const ranges = {};
const type = config.type;
const maxDate = cloneDeep(config.maxDate);
DEFAULT_RANGES[type].forEach((rangeInfo) => {
ranges[rangeInfo.label] = {
startDate: moment(maxDate, DEFAULT_DATE_FORMAT)
.subtract(rangeInfo.count, MOMENT_CONVERSION_MAP[type])
.format(DEFAULT_DATE_FORMAT),
endDate: maxDate
};
});
ranges["Custom Range"] = { startDate: null, endDate: null };
return ranges;
}
getSanitizedDateArray(config) {
const sanitizedDateArray = [];
const type = config.type;
const dateArray = config.dateArray;
const inputDateFormat = config.inputDateFormat;
// dateArray can have nulls
dateArray.forEach((date) => {
if (!date) {
return;
}
let format = null;
if (isNaN(Number(date))) {
if (inputDateFormat) {
format = inputDateFormat;
}
else {
format = moment(date)._f; // moment does not support this
}
}
if (inputDateFormat !== moment(date)._f) {
console.warn(`ERR_NGX_DATETIME_RANGE_PICKER:
inputDateFormat !== dateFormat in dateArray.
Converted dates might not be as expected
`);
}
const value = format ? moment(date, format) : moment(date);
if (value) {
const formattedDate = value.endOf(MOMENT_CONVERSION_MAP[type]).format(DEFAULT_DATE_FORMAT);
sanitizedDateArray.push(formattedDate);
}
else {
console.warn(`ERR_NGX_DATETIME_RANGE_PICKER:
dateArray values are in unknown format.
Pass the format or pass the dates in known format
`);
}
});
return [...new Set(sanitizedDateArray)];
}
getNumberOfWeeks(date) {
if (!date) {
return;
}
const monthStart = moment(date, DEFAULT_DATE_FORMAT)
.startOf("month")
.day();
const monthEnd = Number(moment(date, DEFAULT_DATE_FORMAT)
.endOf("month")
.format("D"));
return Math.ceil((monthStart + monthEnd) / 7);
}
getYearlyWeekCount(year) {
if (!year) {
return;
}
const yearStartDate = moment(year, "YYYY")
.startOf("year")
.format(DEFAULT_DATE_FORMAT);
const yearEndDate = moment(year, "YYYY")
.endOf("year")
.format(DEFAULT_DATE_FORMAT);
const yearEndWeekEndDate = moment(yearEndDate, DEFAULT_DATE_FORMAT)
.startOf("week")
.format(DEFAULT_DATE_FORMAT);
const yearStartWeekEndDate = moment(yearStartDate, DEFAULT_DATE_FORMAT)
.endOf("week")
.format(DEFAULT_DATE_FORMAT);
const yearStartWeekNumber = this.getWeekNumber(yearStartWeekEndDate);
const yearEndWeekNumber = this.getWeekNumber(yearEndWeekEndDate);
return yearEndWeekNumber - yearStartWeekNumber + 1;
}
getMonthsAvailable(minDate, maxDate, selectedYear) {
const months = [];
if (!minDate || !maxDate || !selectedYear) {
return;
}
minDate = moment(minDate, DEFAULT_DATE_FORMAT).startOf("month");
maxDate = moment(maxDate, DEFAULT_DATE_FORMAT).startOf("month");
let minDatems = moment(minDate, DEFAULT_DATE_FORMAT).valueOf();
let maxDatems = moment(maxDate, DEFAULT_DATE_FORMAT).valueOf();
const yearStartms = moment()
.year(selectedYear)
.startOf("year")
.valueOf();
const yearEndms = moment()
.year(selectedYear)
.endOf("year")
.valueOf();
if (minDatems < yearStartms) {
minDatems = yearStartms;
}
if (maxDatems > yearEndms) {
maxDatems = yearEndms;
}
let minDateMonthNumber = moment(minDatems).month();
const diff = moment(maxDatems).diff(moment(minDatems), "months");
const maxMonths = diff < MONTHS_AVAILABLE.length ? diff : MONTHS_AVAILABLE.length;
for (let i = 0; i <= maxMonths; i++) {
if (minDateMonthNumber >= MONTHS_AVAILABLE.length) {
months.push(MONTHS_AVAILABLE[minDateMonthNumber - MONTHS_AVAILABLE.length]);
}
else {
months.push(MONTHS_AVAILABLE[minDateMonthNumber]);
}
minDateMonthNumber++;
}
return months;
}
getYearsAvailable(config) {
const minDate = config ? config.minDate : "";
const maxDate = config ? config.maxDate : "";
const years = [];
if (minDate && maxDate) {
const minYear = Number(this.getSelectedYear(minDate));
const maxYear = Number(this.getSelectedYear(maxDate));
const diff = maxYear - minYear;
for (let i = 0; i <= diff; i++) {
years.push(`${minYear + i}`);
}
}
return years.reverse();
}
isDateAvailable(date, minDate, maxDate, startDate, endDate, monthStartDate, monthEndDate, config) {
let available = false;
const type = config.type;
const disableWeekends = config.disableWeekends;
const disableWeekdays = config.disableWeekdays;
if (type === "daily") {
minDate = minDate > monthStartDate ? minDate : monthStartDate;
maxDate = maxDate < monthEndDate ? maxDate : monthEndDate;
}
if (date >= minDate && date <= maxDate) {
available = true;
if (available) {
if (disableWeekends) {
available = !this.isWeekend(date);
}
if (disableWeekdays) {
available = !this.isWeekday(date);
}
if (config.dateArray.length) {
available = this.isInDateArray(date, config.dateArray, DEFAULT_DATE_FORMAT);
}
}
}
return available;
}
isDateInRange(date, minDate, maxDate, startDate, endDate, monthStartDate, monthEndDate, available, config) {
let inRange = false;
const type = config.type;
const singleDatePicker = config.singleDatePicker;
if (!singleDatePicker) {
if (type === "daily") {
minDate = monthStartDate;
maxDate = monthEndDate;
}
if (date >= startDate && date <= endDate && date >= minDate && date <= maxDate) {
if (available) {
inRange = true;
}
}
}
return inRange;
}
isDateActive(date, startDate, endDate, side) {
return (date === startDate && side === "left") || (date === endDate && side === "right");
}
isDateToday(dateMs, config) {
const todayDate = moment().format(DEFAULT_DATE_FORMAT);
const type = config.type;
const { firstDay, lastDay } = this.getFirstLastDay(todayDate, type);
const firstDayMs = moment(firstDay, DEFAULT_DATE_FORMAT).valueOf();
const lastDayMs = moment(lastDay, DEFAULT_DATE_FORMAT).valueOf();
return dateMs >= firstDayMs && dateMs <= lastDayMs;
}
isWeekday(date, format) {
return !this.isWeekend(date, format);
}
isWeekend(date, format) {
if (!format) {
format = null;
}
const day = moment(date, format).day();
return day === 0 || day === 6;
}
isInDateArray(date, dateArray, format) {
if (!format) {
format = null;
}
return dateArray.find((d) => moment(d, format).valueOf() === date) !== undefined;
}
getCalendarRowVariables(options) {
const variables = {
rowNumber: "",
columns: 0
};
const type = options.type;
const monthStartWeekNumber = options.monthStartWeekNumber;
const dateRows = options.dateRows;
const year = `${options.year}`;
if (type === "daily") {
variables.rowNumber = `${monthStartWeekNumber + dateRows}`;
variables.columns = 6;
}
else if (type === "weekly") {
variables.rowNumber = ``;
variables.columns = 6;
}
else if (type === "monthly") {
variables.rowNumber = `${dateRows + 1}`;
variables.columns = 2;
}
else if (type === "quarterly") {
variables.rowNumber = year.charAt(dateRows);
variables.columns = 0;
}
else if (type === "yearly") {
variables.rowNumber = "";
variables.columns = 0;
}
return variables;
}
getCalendarRowItemVariables(options) {
const { type, monthStartWeekNumber, yearStartDate, year, rowItem, dateRows, columns } = options;
const itemCount = rowItem + dateRows * columns + dateRows;
let currentItemDate = "";
let rowItemText = "";
if (type === "daily") {
if (!isNil(monthStartWeekNumber) && !isNil(dateRows) && !isNil(year)) {
const yearStartDateDaily = moment()
.year(year)
.startOf("year")
.format(DEFAULT_DATE_FORMAT);
currentItemDate = moment(yearStartDateDaily, DEFAULT_DATE_FORMAT)
.add(monthStartWeekNumber + dateRows - 1, "week")
.startOf("week")
.add(rowItem, "day")
.format(DEFAULT_DATE_FORMAT);
rowItemText = moment(currentItemDate, DEFAULT_DATE_FORMAT).format("D");
}
}
else if (type === "weekly") {
if (!isNil(yearStartDate) && !isNil(itemCount)) {
currentItemDate = moment(yearStartDate, DEFAULT_DATE_FORMAT)
.add(itemCount, "week")
.endOf("week")
.format(DEFAULT_DATE_FORMAT);
const weekNumber = itemCount + 1;
rowItemText = `W${weekNumber}`;
}
}
else if (type === "monthly") {
if (!isNil(itemCount) && !isNil(year)) {
currentItemDate = moment()
.year(year)
.month(itemCount)
.endOf("month")
.format(DEFAULT_DATE_FORMAT);
rowItemText = moment(currentItemDate, DEFAULT_DATE_FORMAT).format("MMM");
}
}
else if (type === "quarterly") {
if (!isNil(itemCount) && !isNil(year)) {
currentItemDate = moment()
.year(year)
.quarter(itemCount + 1)
.endOf("quarter")
.format(DEFAULT_DATE_FORMAT);
rowItemText = `Quarter ${itemCount + 1}`;
}
}
const { firstDay, lastDay } = this.getFirstLastDay(currentItemDate, type);
return {
itemCount,
currentItemDate,
rowItemText,
firstDay,
lastDay
};
}
isRowIemValid(options) {
let valid = false;
const type = options.type;
const year = options.year;
const itemCount = options.itemCount;
const validWeekCount = this.getYearlyWeekCount(year);
if (type === "daily") {
valid = true;
}
else if (type === "weekly") {
if (itemCount < validWeekCount) {
valid = true;
}
}
else if (type === "monthly") {
valid = true;
}
else if (type === "quarterly") {
valid = true;
}
return valid;
}
formatStartDate(config, returnFormat) {
const startDate = config ? config.startDate : null;
const type = config ? config.type : "";
let formattedStartDate = null;
if (startDate) {
formattedStartDate = moment(startDate, DEFAULT_DATE_FORMAT)
.startOf(MOMENT_CONVERSION_MAP[type])
.format(returnFormat);
}
return formattedStartDate;
}
getSelectedYear(date) {
return moment(date, DEFAULT_DATE_FORMAT).format("YYYY");
}
getFirstLastDay(date, type) {
let firstDay = "";
let lastDay = "";
if (type === "daily") {
firstDay = lastDay = date;
}
else if (type === "weekly") {
firstDay = moment(date, DEFAULT_DATE_FORMAT)
.startOf("week")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment(date, DEFAULT_DATE_FORMAT)
.endOf("week")
.format(DEFAULT_DATE_FORMAT);
}
else if (type === "monthly") {
firstDay = moment(date, DEFAULT_DATE_FORMAT)
.startOf("month")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment(date, DEFAULT_DATE_FORMAT)
.endOf("month")
.format(DEFAULT_DATE_FORMAT);
}
else if (type === "quarterly") {
firstDay = moment(date, DEFAULT_DATE_FORMAT)
.startOf("quarter")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment(date, DEFAULT_DATE_FORMAT)
.endOf("quarter")
.format(DEFAULT_DATE_FORMAT);
}
else if (type === "yearly") {
firstDay = moment(date, DEFAULT_DATE_FORMAT)
.startOf("year")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment(date, DEFAULT_DATE_FORMAT)
.endOf("year")
.format(DEFAULT_DATE_FORMAT);
}
return { firstDay, lastDay };
}
getZoneDate(tz, format, date) {
let _date = moment().valueOf();
if (date) {
_date = moment(date, format)
.startOf("day")
.valueOf();
}
const today = new Date(_date).toLocaleString("en-US", {
timeZone: TZ_NAMES[tz]
});
return moment(today, "MM/DD/YYYY, hh:mm:ss A");
}
getZoneToday(tz, viewDateFormat) {
const today = this.getZoneDate(tz, viewDateFormat);
return moment(today).format(`${viewDateFormat} hh:mm A`);
}
formatToZoneDate(tz, format, date) {
const formattedDate = this.getZoneDate(tz, format, date);
return moment(formattedDate).format(`${format}`);
}
convertToViewTimeItem(item) {
let stringified_item = item + "";
if (stringified_item.length === 1) {
stringified_item = `0${stringified_item}`;
}
return stringified_item;
}
getWeekNumber(date) {
if (date) {
const year = moment(date, "YYYY-MM-DD").year();
const month = moment(date, "YYYY-MM-DD").month();
const day = Number(moment(date, "YYYY-MM-DD").format("D"));
const yearStartms = new Date(year, 0, 1);
const datems = new Date(year, month, day);
return Math.ceil(((datems.getTime() - yearStartms.getTime()) / 86400000 + yearStartms.getDay() + 1) / 7);
}
else {
console.warn(`
WARN_NGX_DATETIME_RANGE_PICKER | getWeekNumber:
Invalid date
`);
return getNotAvailableText();
}
}
iterateOverDateObj(dates, func) {
for (const side in dates) {
if (side) {
const sideDates = dates[side];
sideDates.itemRows.forEach((rows) => {
rows.items.forEach((rowItem) => {
func(rowItem);
});
});
}
}
}
getCalendarColspan(type) {
if (type === "daily") {
return 6;
}
else if (type === "weekly") {
return 8;
}
else if (type === "monthly") {
return 3;
}
else if (type === "quarterly") {
return 1;
}
else if (type === "yearly") {
return 1;
}
}
getCalendarRowItemColspan(type) {
if (type === "monthly") {
return 3;
}
else if (type === "quarterly") {
return 6;
}
else if (type === "yearly") {
return 6;
}
}
getDateCharacteristics(config, state, date, month, side) {
const currentDate = moment(date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
let _date = this.formatDateToDefaultFormat(config.minDate, DEFAULT_DATE_FORMAT);
const minDate = moment(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
_date = this.formatDateToDefaultFormat(config.maxDate, DEFAULT_DATE_FORMAT);
const maxDate = moment(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
_date = this.formatDateToDefaultFormat(config.startDate, DEFAULT_DATE_FORMAT);
const startDate = moment(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
_date = this.formatDateToDefaultFormat(config.endDate, DEFAULT_DATE_FORMAT);
const endDate = moment(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
const currentMonthStartDate = moment(month, "MMM YYYY")
.startOf("month")
.startOf("day")
.valueOf();
const currentMonthEndDate = moment(month, "MMM YYYY")
.endOf("month")
.startOf("day")
.valueOf();
const available = this.isDateAvailable(currentDate, minDate, maxDate, startDate, endDate, currentMonthStartDate, currentMonthEndDate, config);
const inRange = this.isDateInRange(currentDate, minDate, maxDate, startDate, endDate, currentMonthStartDate, currentMonthEndDate, available, config);
const active = this.isDateActive(currentDate, startDate, endDate, side);
const today = this.isDateToday(currentDate, config);
// Active
if (currentDate === startDate && side === "left") {
state.activeStartDate = date;
}
else if (currentDate === endDate && side === "right") {
state.activeEndDate = date;
}
return { available, inRange, active, today };
}
getLabelProps(state, calendarType, side) {
let label, labelFormat, type;
if (calendarType === "daily") {
label = `${state.selectedMonth[side]} ${state.selectedYear[side]}`;
labelFormat = "MMM YYYY";
type = "month";
}
else {
label = `${state.selectedYear[side]}`;
labelFormat = "YYYY";
type = "year";
}
return { label, labelFormat, type };
}
}
NgxDatetimeRangePickerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NgxDatetimeRangePickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
NgxDatetimeRangePickerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NgxDatetimeRangePickerService, providedIn: "root" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NgxDatetimeRangePickerService, decorators: [{
type: Injectable,
args: [{
providedIn: "root"
}]
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWRhdGV0aW1lLXJhbmdlLXBpY2tlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9uZ3gtZGF0ZXRpbWUtcmFuZ2UtcGlja2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLCtCQUErQixJQUFJLFNBQVMsRUFDN0MsTUFBTSx1Q0FBdUMsQ0FBQztBQUMvQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzFGLE9BQU8sRUFVTCxhQUFhLEVBR2QsTUFBTSxjQUFjLENBQUM7O0FBSXRCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVqQyxNQUFNLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO0FBQzFELE1BQU0sZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQztBQUM3RCxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztBQUM3QyxNQUFNLGNBQWMsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUNoRCxNQUFNLHFCQUFxQixHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUM7QUFLdkUsTUFBTSxPQUFPLDZCQUE2QjtJQUN4QyxpQkFBaUI7UUFDZixPQUFPLFNBQVMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBWSxDQUFDO0lBQ3pELENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsT0FBTyxTQUFTLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQWEsQ0FBQztJQUMzRCxDQUFDO0lBRUQsZUFBZTtRQUNiLE9BQU8sU0FBUyxD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LElBQUksQ0FBQztTQUM1QjtRQUVELE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBRUQsYUFBYSxDQUNYLEtBQVksRUFDWixZQUFvQixFQUNwQixJQUFZO1FBRVosSUFBSSxLQUFhLEVBQUUsV0FBbUIsRUFBRSxJQUFZLENBQUM7UUFFckQsSUFBSSxZQUFZLEtBQUssT0FBTyxFQUFFO1lBQzVCLEtBQUssR0FBRyxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ25FLFdBQVcsR0FBRyxVQUFVLENBQUM7WUFDekIsSUFBSSxHQUFHLE9BQU8sQ0FBQztTQUNoQjthQUFNO1lBQ0wsS0FBSyxHQUFHLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3RDLFdBQVcsR0FBRyxNQUFNLENBQUM7WUFDckIsSUFBSSxHQUFHLE1BQU0sQ0FBQztTQUNmO1FBRUQsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDdEMsQ0FBQzs7MEhBOXFCVSw2QkFBNkI7OEhBQTdCLDZCQUE2QixjQUY1QixNQUFNOzJGQUVQLDZCQUE2QjtrQkFIekMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7XG4gIERFRkFVTFRfREFURV9GT1JNQVQsXG4gIE5neERhdGV0aW1lUmFuZ2VQaWNrZXJDb25zdGFudHMgYXMgQ29uc3RhbnRzXG59IGZyb20gXCIuL25neC1kYXRldGltZS1yYW5nZS1waWNrZXIuY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBnZXROb3RBdmFpbGFibGVUZXh0LCBjbG9uZURlZXAsIGlzTmlsIH0gZnJvbSBcIi4vbmd4LWRhdGV0aW1lLXJhbmdlLXBpY2tlci51dGlsc1wiO1xuaW1wb3J0IHtcbiAgT3B0aW9ucyxcbiAgU2V0dGluZ3MsXG4gIENhbGVuZGFyU2lkZXMsXG4gIFN0YXRlLFxuICBSb3dJdGVtVmFyaWFibGVzLFxuICBSb3dJdGVtT3B0aW9ucyxcbiAgRGF0ZUNoYXJhY3RlcmlzdGljcyxcbiAgQ29uZmlnLFxuICBSb3dPcHRpb25zLFxuICBDYWxlbmRhclR5cGVzLFxuICBSb3dWYXJpYWJsZXMsXG4gIENhbGVuZGFyVHlwZVxufSBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBNb21lbnQgfSBmcm9tIFwibW9tZW50XCI7XG5cbmRlY2xhcmUgdmFyIHJlcXVpcmU6IGFueTtcbmNvbnN0IG1vbWVudCA9IHJlcXVpcmUoXCJtb21lbnRcIik7XG5cbmNvbnN0IERFRkFVTFRfVElNRV9GT1JNQVQgPSBDb25zdGFudHMuREVGQVVMVC5USU1FX0ZPUk1BVDtcbmNvbnN0IE1PTlRIU19BVkFJTEFCTEUgPSBDb25zdGFudHMuQ09OU1RBTlQuTU9OVEhTX0FWQUlMQUJMRTtcbmNvbnN0IFRaX05BTUVTID0gQ29uc3RhbnRzLkNPTlNUQU5ULlRaX05BTUVTO1xuY29uc3QgREVGQVVMVF9SQU5HRVMgPSBDb25zdGFudHMuREVGQVVMVC5SQU5HRVM7XG5jb25zdCBNT01FTlRfQ09OVkVSU0lPTl9NQVAgPSBDb25zdGFudHMuQ09OU1RBTlQuTU9NRU5UX0NPTlZFUlNJT05fTUFQO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46IFwicm9vdFwiXG59KVxuZXhwb3J0IGNsYXNzIE5neERhdGV0aW1lUmFuZ2VQaWNrZXJTZXJ2aWNlIHtcbiAgZ2V0RGVm