UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

4,490 lines 177 kB
Object.defineProperties(exports, {
	__esModule: { value: true },
	[Symbol.toStringTag]: { value: "Module" }
});
require("./kendo.icons.js");
require("./kendo.html.button.js");
require("./kendo.dropdownlist.js");
require("./kendo.multiselect.js");
require("./kendo.editable.js");
require("./kendo.window.js");
require("./kendo.segmentedcontrol.js");
require("./kendo.toolbar.js");
require("./kendo.switch.js");
require("./kendo.pane.js");
require("./kendo.pdf.js");
require("./kendo.dialog.js");
require("./kendo.datetimepicker.js");
require("./kendo.scheduler.view.js");
require("./kendo.scheduler.dayview.js");
require("./kendo.scheduler.agendaview.js");
require("./kendo.scheduler.monthview.js");
require("./kendo.scheduler.yearview.js");
require("./kendo.scheduler.recurrence.js");
require("./kendo.scheduler.timelineview.js");
//#region ../src/kendo.scheduler.js
const __meta__ = {
	id: "scheduler",
	name: "Scheduler",
	category: "web",
	description: "The Scheduler is an event calendar.",
	depends: [
		"dropdownlist",
		"editable",
		"multiselect",
		"window",
		"dialog",
		"datepicker",
		"datetimepicker",
		"toolbar",
		"scheduler.recurrence",
		"scheduler.view",
		"html.button",
		"icons",
		"segmentedcontrol"
	],
	features: [
		{
			id: "scheduler-dayview",
			name: "Scheduler Day View",
			description: "Scheduler Day View",
			depends: ["scheduler.dayview"]
		},
		{
			id: "scheduler-agendaview",
			name: "Scheduler Agenda View",
			description: "Scheduler Agenda View",
			depends: ["scheduler.agendaview"]
		},
		{
			id: "scheduler-monthview",
			name: "Scheduler Month View",
			description: "Scheduler Month View",
			depends: ["scheduler.monthview"]
		},
		{
			id: "scheduler-timelineview",
			name: "Scheduler Timeline View",
			description: "Scheduler Timeline View",
			depends: ["scheduler.timelineview"]
		},
		{
			id: "scheduler-yearview",
			name: "Scheduler Year View",
			description: "Scheduler Year View",
			depends: ["scheduler.yearview"]
		},
		{
			id: "scheduler-mobile",
			name: "Scheduler adaptive rendering",
			description: "Support for adaptive rendering",
			depends: [
				"dialog",
				"pane",
				"switch"
			]
		},
		{
			id: "scheduler-pdf-export",
			name: "PDF export",
			description: "Export the scheduler events as PDF",
			depends: ["pdf", "drawing"]
		},
		{
			id: "scheduler-timezones",
			name: "Timezones",
			description: "Allow selecting timezones different than Etc/UTC",
			depends: ["timezones"]
		}
	]
};
(function($, undefined) {
	var kendo = window.kendo, date = kendo.date, MS_PER_DAY = date.MS_PER_DAY, getDate = date.getDate, getMilliseconds = kendo.date.getMilliseconds, recurrence = kendo.recurrence, encode = kendo.htmlEncode, keys = kendo.keys, ui = kendo.ui, Widget = ui.Widget, DataBoundWidget = ui.DataBoundWidget, STRING = "string", Popup = ui.Popup, Calendar = ui.Calendar, DataSource = kendo.data.DataSource, isPlainObject = $.isPlainObject, extend = $.extend, toString = Object.prototype.toString, isArray = Array.isArray, NS = ".kendoScheduler", CLICK = "click", MOUSEDOWN = "mousedown", TOUCHSTART = kendo.support.pointers ? "pointerdown" : "touchstart", TOUCHMOVE = kendo.support.pointers ? "pointermove" : "touchmove", TOUCHEND = kendo.support.pointers ? "pointerup" : "touchend", MOUSEMOVE = kendo.support.mousemove, CHANGE = "change", PROGRESS = "progress", ERROR = "error", CANCEL = "cancel", REMOVE = "remove", RESET = "resetSeries", SAVE = "save", ADD = "add", EDIT = "edit", DISABLED = "disabled", OPTION = "option", FOCUSEDSTATE = "k-focus", INVERSECOLORCLASS = "k-event-inverse", valueStartEndBoundRegex = /(?:value:start|value:end)(?:,|$)/, MIN_SCREEN = "(min-width: 1024px)", TODAY = getDate(/* @__PURE__ */ new Date()), EXCEPTION_SEPARATOR = ",", OLD_EXCEPTION_SEPARATOR_REGEXP = /\;/g, RECURRENCE_EXCEPTION = "recurrenceException", DELETECONFIRM = "Are you sure you want to delete this event?", DELETERECURRING = "Do you want to delete only this event occurrence or the whole series?", EDITRECURRING = "Do you want to edit only this event occurrence or the whole series?", DELETERECURRINGCONFIRM = "Are you sure you want to delete this event occurrence?", RESETSERIESCONFIRM = "Are you sure you want to reset the whole series?", DELETESERIESCONFIRM = "Are you sure you want to delete the whole series?", RESETTIMEZONECONFIRM = "Are you sure you want to reset the timezone?", TOOLBAR_HYSTERESIS = 20, ONGOING_CLASS = "k-event-ongoing", COMMANDBUTTONTMPL = ({ className, attr, text, icon, fillMode, themeColor }) => kendo.html.renderButton(`<button type="button" class="${className}" ${attr}>${text}</button>`, {
		icon,
		fillMode,
		themeColor
	}), VIEWS_DROPDOWN_TEMPLATE = kendo.template(({ label, views, type }) => `<select aria-label="${label}" class="k-picker k-dropdown-list k-dropdown ${type}">` + Object.keys(views).map((view) => `<option value="${view}">${views[view].title}</option>`).join("") + "</select>"), DEFAULT_TOOLS = {
		pdf: {
			name: "pdf",
			type: "button",
			icon: "file-pdf",
			attributes: { class: "k-pdf" }
		},
		pdfMobile: {
			name: "pdf",
			type: "button",
			icon: "file-pdf",
			showText: "overflow",
			attributes: { class: "k-pdf" }
		},
		today: {
			name: "today",
			type: "button",
			fillMode: "flat",
			attributes: { "ref-nav-today": "" }
		},
		previous: {
			name: "previous",
			type: "button",
			icon: "chevron-left",
			fillMode: "flat",
			showText: "overflow",
			attributes: { "ref-nav-prev": "" },
			groupClass: "k-button-group-flat"
		},
		next: {
			name: "next",
			type: "button",
			icon: "chevron-right",
			fillMode: "flat",
			showText: "overflow",
			attributes: { "ref-nav-next": "" },
			groupClass: "k-button-group-flat"
		},
		current: {
			name: "current",
			type: "button",
			icon: "calendar",
			fillMode: "flat",
			text: "placeholder",
			attributes: {
				"aria-live": "polite",
				class: "k-nav-current"
			}
		},
		search: { template: `<span class="k-scheduler-search k-textbox k-input"><input tabindex="-1" autocomplete="off" class="k-input-inner k-scheduler-search-input k-input-inner" /><span class="k-input-suffix">${kendo.ui.icon("search")}</span></span>` },
		refresh: {
			name: "refresh",
			type: "button",
			icon: "arrow-rotate-cw",
			showText: "overflow",
			attributes: { class: "k-scheduler-refresh" }
		},
		create: {
			name: "create",
			type: "button",
			icon: "plus",
			text: "New Event",
			attributes: {
				class: "k-toolbar-button  k-button k-button-primary",
				"ref-toolbar-create": ""
			}
		},
		createMobile: {
			name: "create",
			type: "button",
			icon: "plus",
			text: "New Event",
			showText: "overflow",
			attributes: {
				class: "k-toolbar-button k-button",
				"ref-toolbar-create": ""
			}
		},
		calendar: {
			name: "calendar",
			type: "button",
			icon: "calendar",
			attributes: { class: "k-nav-calendar" }
		},
		previousMobile: {
			name: "previous",
			type: "button",
			icon: "chevron-left",
			showText: "overflow",
			attributes: { "ref-nav-prev": "" },
			groupClass: "k-scheduler-navigation"
		},
		nextMobile: {
			name: "next",
			type: "button",
			icon: "chevron-right",
			showText: "overflow",
			attributes: { "ref-nav-next": "" },
			groupClass: "k-scheduler-navigation"
		},
		currentMobile: { template: "<span class=\"k-scheduler-navigation\"><span class=\"k-nav-current\"><span class=\"k-m-date-format\"></span><span class=\"k-y-date-format\"></span></span></span>" },
		view: {
			name: "view",
			type: "button",
			togglable: true,
			group: "views"
		}
	}, defaultDesktopTools = [
		"create",
		"today",
		["previous", "next"],
		"current",
		{ type: "spacer" }
	], defaultMobileToolsFirst = [["calendar"], { type: "spacer" }], defaultMobileToolsSecond = [
		"previousMobile",
		{ type: "spacer" },
		"currentMobile",
		{ type: "spacer" },
		"nextMobile"
	], MOBILEDATERANGEEDITOR = function(container, options) {
		var attr = {
			name: options.field,
			title: options.title
		};
		var isAllDay = options.model.isAllDay;
		var dateTimeValidate = kendo.attr("validate") + "='" + !isAllDay + "'";
		var dateValidate = kendo.attr("validate") + "='" + !!isAllDay + "'";
		appendTimezoneAttr(attr, options);
		appendValidDateValidator(attr, options);
		appendDateCompareValidator(attr, options);
		$("<input type=\"datetime-local\" required " + kendo.attr("type") + "=\"datetime-local\" " + kendo.attr("bind") + "=\"value:" + options.field + ", invisible:isAllDay\" " + dateTimeValidate + "/>").attr(attr).appendTo(container);
		$("<input type=\"date\" required " + kendo.attr("type") + "=\"date\" " + kendo.attr("bind") + "=\"value:" + options.field + ",visible:isAllDay\" " + dateValidate + "/>").attr(attr).appendTo(container);
		$("<span " + kendo.attr("for") + "=\"" + options.field + "\" class=\"k-invalid-msg\"/>").hide().appendTo(container);
	}, DATERANGEEDITOR = function(container, options) {
		var attr = {
			name: options.field,
			title: options.title
		}, isStart = options.field === "start", isEnd = options.field === "end";
		appendTimezoneAttr(attr, options);
		appendValidDateValidator(attr, options);
		appendDateCompareValidator(attr, options);
		var row = $("<div class=\"k-scheduler-edit-form-row k-pos-relative\"></div>").appendTo(container);
		$("<input type=\"hidden\" required " + kendo.attr("bind") + "=\"value:" + options.field + "\" " + kendo.attr("validate") + "=\"true\"/>").attr(attr).attr("data-scheduler-date-part", "owner").appendTo(row);
		$("<span " + kendo.attr("for") + "=\"" + options.field + "\" class=\"k-invalid-msg\"/>").hide().appendTo(row);
		$("<input type=\"text\" " + kendo.attr("type") + "=\"date\" " + kendo.attr("role") + "=\"datepicker\" " + kendo.attr("validate") + "=\"false\"/>").attr({
			name: options.field,
			title: options.title
		}).attr(kendo.attr("skip"), "true").attr("data-scheduler-field", options.field).attr("data-scheduler-date-part", "date").appendTo(row);
		$(`<span class="k-scheduler-datetime-separator k-scheduler-datetime-label" 
                    ${isEnd ? "data-bind=\"invisible:isAllDay\"" : ""} 
                    ${isStart ? "data-separator-for='start'" : "data-separator-for='end'"}>
              </span>`).text(isStart ? "from" : "to").appendTo(row);
		$("<input type=\"text\" " + kendo.attr("type") + "=\"time\" " + kendo.attr("role") + "=\"timepicker\" " + kendo.attr("bind") + "=\"invisible:isAllDay\" " + kendo.attr("validate") + "=\"false\"/>").attr({
			name: options.field,
			title: options.title
		}).attr(kendo.attr("skip"), "true").attr("data-scheduler-field", options.field).attr("data-scheduler-date-part", "time").appendTo(row);
		if (isStart && !kendo.timezone.windows_zones) $(`<span class="k-col-span-2" data-bind="invisible:isAllDay"></span>`).appendTo(container);
	}, positionDateRangeValidationMessage = function(message) {
		var callout = message.find(".k-callout");
		var field = message.attr(kendo.attr("for"));
		var datePicker = message.parent().find("[data-scheduler-field='" + field + "'][data-scheduler-date-part=date]").data("kendoDatePicker");
		if (!callout.length || !datePicker) return;
		callout.removeClass("k-callout-n").addClass("k-callout-s");
		message[0].style.removeProperty("right");
		message[0].style.removeProperty("inset-inline-end");
		message[0].style.setProperty("left", datePicker.wrapper.position().left + "px");
		message[0].style.setProperty("inset-block-start", "auto");
		message[0].style.setProperty("inset-block-end", "calc(100% + " + callout.outerHeight() / 2 + "px)");
		message[0].style.setProperty("margin-block-start", "0px");
	}, RECURRENCEEDITOR = function(container, options) {
		$("<div " + kendo.attr("bind") + "=\"value:" + options.field + "\" />").attr({
			name: options.field,
			"aria-label": options.title
		}).appendTo(container).kendoRecurrenceEditor({
			start: options.model.start,
			timezone: options.timezone,
			messages: options.messages,
			recurrenceRuleLabelTemplate: options.recurrenceRuleLabelTemplate
		});
	}, MOBILERECURRENCEEDITOR = function(container, options) {
		$("<div " + kendo.attr("bind") + "=\"value:" + options.field + "\" />").attr({ name: options.field }).appendTo(container).kendoMobileRecurrenceEditor({
			start: options.model.start,
			timezone: options.timezone,
			messages: options.messages,
			pane: options.pane,
			value: options.model[options.field]
		});
	}, MOBILEISALLDAYEDITOR = function(container, options) {
		$("<input type=\"checkbox\" data-role=\"switch\"" + kendo.attr("bind") + "=\"value:" + options.field + "\" />").attr(kendo.attr("messages"), "{\"checked\":\"\",\"unchecked\":\"\"}").appendTo(container);
	}, ISALLDAYEDITOR = function(container, options) {
		var wrapper = $("<div class=\"k-scheduler-edit-form-row\"></div>").appendTo(container);
		$("<input type=\"checkbox\" data-role=\"switch\"" + kendo.attr("bind") + "=\"value:" + options.field + "\" />").attr({
			id: options.field,
			name: options.field,
			title: options.title ? options.title : options.field,
			"aria-label": options.title ? options.title : options.field
		}).attr(kendo.attr("messages"), "{\"checked\":\"\",\"unchecked\":\"\"}").appendTo(wrapper);
		$("<span></span>").text(options.title || options.field).appendTo(wrapper);
	}, MOBILETIMEZONEPOPUP = function(container, options) {
		var text = timezoneButtonText(options.model, options.messages.noTimezone);
		$("<span class=\"k-timezone-label\"></span>").text(text).appendTo(container);
		$(kendo.ui.icon("arrow-chevron-right")).appendTo(container);
		container.closest("li.k-item label").on(CLICK, options.click);
	}, TIMEZONEBUTTON = function(container, options) {
		let startContainer = $(container).parent().parent().find(".k-scheduler-datetime-grid");
		if (startContainer.length) startContainer = startContainer.find("div[data-container-for='start']").length ? startContainer.find("div[data-container-for='start']") : startContainer;
		setTimezoneButtonState($("<a href=\"#\" class=\"k-col-span-2 k-button k-button-flat k-button-primary k-icon-button k-timezone-btn\" title=\"" + encode(options.messages.timezone) + "\" data-bind=\"invisible:isAllDay\"><span class=\"k-button-text\">" + encode(options.messages.timezoneEditorButton) + "</span></a>").append($(kendo.ui.icon("globe")).addClass("k-button-icon")).on(CLICK, options.click).appendTo(startContainer), !options.model.isTimezoneInvisible, options.messages);
		$(container).parent(".k-form-field").remove();
	}, MOBILETIMEZONEEDITOR = function(container, options) {
		$("<div class=\"k-mobiletimezoneeditor\" " + kendo.attr("bind") + "=\"value:" + options.field + "\" />").attr({ name: options.field }).appendTo(container).kendoMobileTimezoneEditor({ optionLabel: options.noTimezone });
	}, TIMEZONEEDITOR = function(container, options) {
		container.attr(kendo.attr("bind"), "invisible: isTimezoneInvisible");
		$("<div " + kendo.attr("bind") + "=\"value:" + options.field + "\"  />").attr({ name: options.field }).appendTo(container).kendoTimezoneEditor({
			optionLabel: options.noTimezone,
			title: options.title
		});
	};
	function setTimezoneButtonState(timezoneBtn, active, messages) {
		timezoneBtn.find(".k-button-text").toggleClass("k-hidden", active);
		timezoneBtn.toggleClass("k-col-span-2", !active);
		timezoneBtn.attr("title", active ? messages.resetTimezoneWindowTitle : messages.timezone);
		if (active) timezoneBtn.attr("aria-label", messages.resetTimezoneWindowTitle);
		else timezoneBtn.removeAttr("aria-label");
	}
	function timezoneButtonText(model, message) {
		message = message || "";
		if (model.startTimezone) {
			message = model.startTimezone;
			if (model.endTimezone) message += " | " + model.endTimezone;
		}
		return message;
	}
	function appendTimezoneAttr(attrs, options) {
		var timezone = options.timezone;
		if (timezone) attrs[kendo.attr("timezone")] = timezone;
	}
	function appendValidDateValidator(attrs, options) {
		var validationRules = options.model.fields[options.field].validation;
		if (validationRules) {
			var validDateRule = validationRules.validDateValidator;
			if (validDateRule && isPlainObject(validDateRule) && validDateRule.message) attrs[kendo.attr("validDate-msg")] = validDateRule.message;
		}
	}
	function appendDateCompareValidator(attrs, options) {
		var validationRules = options.model.fields[options.field].validation;
		if (validationRules) {
			var dateCompareRule = validationRules.dateCompare;
			if (dateCompareRule && isPlainObject(dateCompareRule) && dateCompareRule.message) attrs[kendo.attr("dateCompare-msg")] = dateCompareRule.message;
		}
	}
	function wrapDataAccess(originalFunction, timezone) {
		return function(data) {
			data = originalFunction(data);
			convertData(data, "apply", timezone);
			return data || [];
		};
	}
	function wrapDataSerialization(originalFunction, timezone) {
		return function(data) {
			if (data) {
				if (toString.call(data) !== "[object Array]" && !(data instanceof kendo.data.ObservableArray)) data = [data];
			}
			convertData(data, "remove", timezone, true);
			data = originalFunction(data);
			return data || [];
		};
	}
	function convertData(data, method, timezone, removeUid) {
		var event, idx, length, startOffset, endOffset;
		data = data || [];
		for (idx = 0, length = data.length; idx < length; idx++) {
			event = data[idx];
			startOffset = event.start ? event.start.getTimezoneOffset() : null;
			endOffset = event.start ? event.end.getTimezoneOffset() : null;
			if (removeUid) {
				if (event.startTimezone || event.endTimezone) if (timezone) {
					event.start = kendo.timezone.convert(event.start, event.startTimezone || event.endTimezone, timezone);
					event.end = kendo.timezone.convert(event.end, event.endTimezone || event.startTimezone, timezone);
					event.start = kendo.timezone[method](event.start, timezone);
					event.end = kendo.timezone[method](event.end, timezone);
				} else {
					event.start = kendo.timezone[method](event.start, event.startTimezone || event.endTimezone);
					event.end = kendo.timezone[method](event.end, event.endTimezone || event.startTimezone);
				}
				else if (timezone) {
					event.start = kendo.timezone[method](event.start, timezone);
					event.end = kendo.timezone[method](event.end, timezone);
				}
			} else if (event.startTimezone || event.endTimezone) {
				event.start = kendo.timezone[method](event.start, event.startTimezone || event.endTimezone);
				event.end = kendo.timezone[method](event.end, event.endTimezone || event.startTimezone);
				if (timezone) {
					event.start = kendo.timezone.convert(event.start, event.startTimezone || event.endTimezone, timezone);
					event.end = kendo.timezone.convert(event.end, event.endTimezone || event.startTimezone, timezone);
				}
			} else if (timezone) {
				event.start = kendo.timezone[method](event.start, timezone);
				event.end = kendo.timezone[method](event.end, timezone);
			}
			if (removeUid) delete event.uid;
			if (method === "remove" && event.start && startOffset && startOffset !== event.start.getTimezoneOffset()) event.start = new Date(event.start.getTime() + (startOffset - event.start.getTimezoneOffset()) * 6e4);
			if (method === "remove" && event.end && endOffset && endOffset !== event.end.getTimezoneOffset()) event.end = new Date(event.end.getTime() + (endOffset - event.end.getTimezoneOffset()) * 6e4);
		}
		return data;
	}
	function getOccurrenceByUid(data, uid) {
		var length = data.length, idx = 0, event;
		for (; idx < length; idx++) {
			event = data[idx];
			if (event.uid === uid) return event;
		}
	}
	var SchedulerDataReader = kendo.Class.extend({
		init: function(schema, reader) {
			var timezone = schema.timezone;
			this.reader = reader;
			if (reader.model) this.model = reader.model;
			this.timezone = timezone;
			this.data = wrapDataAccess(this.data.bind(this), timezone);
			this.serialize = wrapDataSerialization(this.serialize.bind(this), timezone);
		},
		errors: function(data) {
			return this.reader.errors(data);
		},
		parse: function(data) {
			return this.reader.parse(data);
		},
		data: function(data) {
			return this.reader.data(data);
		},
		total: function(data) {
			return this.reader.total(data);
		},
		groups: function(data) {
			return this.reader.groups(data);
		},
		aggregates: function(data) {
			return this.reader.aggregates(data);
		},
		serialize: function(data) {
			return this.reader.serialize(data);
		}
	});
	function applyZone(date, fromZone, toZone) {
		if (toZone) date = kendo.timezone.convert(date, fromZone, toZone);
		else date = kendo.timezone.remove(date, fromZone);
		return date;
	}
	function schedulerEditable(input) {
		var editable;
		input.parents().each(function() {
			editable = $(this).data("kendoEditable");
			return !editable;
		});
		return editable;
	}
	function validDateValidator(input) {
		if (input.filter("[data-scheduler-date-part=owner]").length) {
			var editable = schedulerEditable(input);
			var value = editable && editable._validationEventInProgress ? input.data("schedulerValue") : editable && editable.options.model.get(input.attr("name"));
			return value instanceof Date && !isNaN(value.getTime());
		}
		if (input.filter("[name=start]").length && input.filter("[title=Start]").length || input.filter("[name=end]").length && input.filter("[title=End]").length || input.filter(".k-recur-until").length) {
			var date;
			var picker = kendo.widgetInstance(input, kendo.ui);
			if (picker) {
				date = kendo.parseDate(input.val(), picker.options.format);
				return !!date && picker.value();
			} else {
				date = kendo.parseDate(input.val());
				return !!date;
			}
		}
		return true;
	}
	function dateCompareValidator(input) {
		if (input.filter("[data-scheduler-date-part=owner][name=end]").length) {
			var editable = schedulerEditable(input);
			if (editable && editable._validationEventInProgress) return true;
			var model = editable && editable.options.model;
			var start = model && model.get("start");
			var end = model && model.get("end");
			if (start instanceof Date && end instanceof Date) {
				var timezone = input.attr(kendo.attr("timezone"));
				var startTimezone = model.startTimezone;
				var endTimezone = model.endTimezone;
				startTimezone = startTimezone || endTimezone;
				endTimezone = endTimezone || startTimezone;
				if (startTimezone) {
					start = applyZone(start, startTimezone, timezone);
					end = applyZone(end, endTimezone, timezone);
				}
				return start <= end;
			}
			return true;
		}
		if (input.filter("[name=end]").length) {
			var container = input.closest(".k-scheduler-edit-form");
			var startInput = container.find("[name=start]:visible");
			var endInput = container.find("[name=end]:visible");
			if (endInput[0] && startInput[0]) {
				var start, end;
				var startPicker = kendo.widgetInstance(startInput, kendo.ui);
				var endPicker = kendo.widgetInstance(endInput, kendo.ui);
				var editable = container.data("kendoEditable");
				var model = editable ? editable.options.model : null;
				if (startPicker && endPicker) {
					start = startPicker.value();
					end = endPicker.value();
				} else {
					start = kendo.parseDate(startInput.val());
					end = kendo.parseDate(endInput.val());
				}
				if (start && end) {
					if (model) {
						var timezone = startInput.attr(kendo.attr("timezone"));
						var startTimezone = model.startTimezone;
						var endTimezone = model.endTimezone;
						startTimezone = startTimezone || endTimezone;
						endTimezone = endTimezone || startTimezone;
						if (startTimezone) {
							start = applyZone(start, startTimezone, timezone);
							end = applyZone(end, endTimezone, timezone);
						}
					}
					return start <= end;
				}
			}
		}
		return true;
	}
	function untilDateCompareValidator(input) {
		var untilPicker, until, container, startInput, start, startPicker;
		if (input.filter(".k-recur-until").length) {
			untilPicker = kendo.widgetInstance(input, kendo.ui);
			until = untilPicker.value();
			container = input.closest(".k-scheduler-edit-form");
			startInput = container.find("[name=start]:visible");
			if (startInput[0]) {
				startPicker = kendo.widgetInstance(startInput, kendo.ui);
				if (startPicker) start = startPicker.value();
				else start = kendo.parseDate(startInput.val());
				if (start && until) return start <= until;
			}
		}
		return true;
	}
	var SchedulerEvent = kendo.data.Model.define({
		init: function(value) {
			var that = this;
			kendo.data.Model.fn.init.call(that, value);
			that._defaultId = that.defaults[that.idField];
		},
		_time: function(field) {
			var date = this[field];
			var fieldTime = "_" + field + "Time";
			if (this[fieldTime]) return this[fieldTime] - kendo.date.toUtcTime(kendo.date.getDate(date));
			return getMilliseconds(date);
		},
		_date: function(field) {
			var fieldTime = "_" + field + "Time";
			if (this[fieldTime]) return this[fieldTime] - this._time(field);
			return kendo.date.getDate(this[field]);
		},
		clone: function(options, updateUid) {
			var uid = this.uid, event = new this.constructor($.extend({}, this.toJSON(), options));
			if (!updateUid) event.uid = uid;
			return event;
		},
		duration: function() {
			var end = this.end;
			var start = this.start;
			var offset = (end.getTimezoneOffset() - start.getTimezoneOffset()) * kendo.date.MS_PER_MINUTE;
			return end - start - offset;
		},
		expand: function(start, end, zone) {
			return recurrence ? recurrence.expand(this, start, end, zone) : [this];
		},
		update: function(eventInfo) {
			for (var field in eventInfo) this.set(field, eventInfo[field]);
			if (this._startTime) this.set("_startTime", kendo.date.toUtcTime(this.start));
			if (this._endTime) this.set("_endTime", kendo.date.toUtcTime(this.end));
		},
		isMultiDay: function() {
			return this.isAllDay || this.duration() >= kendo.date.MS_PER_DAY;
		},
		isException: function() {
			return !this.isNew() && this.recurrenceId;
		},
		isOccurrence: function() {
			return this.isNew() && this.recurrenceId;
		},
		isRecurring: function() {
			return !!(this.recurrenceRule || this.recurrenceId);
		},
		isRecurrenceHead: function() {
			return !!(this.id && this.recurrenceRule);
		},
		toOccurrence: function(options) {
			options = $.extend(options, {
				recurrenceException: null,
				recurrenceRule: null,
				recurrenceId: this.id || this.recurrenceId
			});
			options[this.idField] = this.defaults[this.idField];
			return this.clone(options, true);
		},
		toJSON: function() {
			var obj = kendo.data.Model.fn.toJSON.call(this);
			obj.uid = this.uid;
			delete obj._startTime;
			delete obj._endTime;
			return obj;
		},
		shouldSerialize: function(field) {
			return kendo.data.Model.fn.shouldSerialize.call(this, field) && field !== "_defaultId";
		},
		set: function(key, value) {
			var isAllDay = this.isAllDay || false;
			kendo.data.Model.fn.set.call(this, key, value);
			if (key == "isAllDay" && value != isAllDay) {
				var start = kendo.date.getDate(this.start);
				var end = new Date(this.end);
				var milliseconds = kendo.date.getMilliseconds(end);
				if (milliseconds === 0 && value) milliseconds = MS_PER_DAY;
				this._normalizingAllDay = true;
				try {
					this.set("start", start);
					if (value === true) {
						kendo.date.setTime(end, -milliseconds);
						if (end < start) end = start;
					} else kendo.date.setTime(end, MS_PER_DAY - milliseconds);
					this.set("end", end);
				} finally {
					delete this._normalizingAllDay;
				}
			}
		},
		id: "id",
		fields: {
			id: { type: "number" },
			title: {
				defaultValue: "",
				type: "string"
			},
			start: {
				type: "date",
				validation: {
					required: true,
					validDate: { value: validDateValidator }
				}
			},
			startTimezone: { type: "string" },
			end: {
				type: "date",
				validation: {
					required: true,
					validDate: { value: validDateValidator },
					dateCompare: { value: dateCompareValidator }
				}
			},
			endTimezone: { type: "string" },
			recurrenceRule: {
				defaultValue: "",
				type: "string",
				validation: {
					validDate: { value: validDateValidator },
					untilDateCompare: { value: untilDateCompareValidator }
				}
			},
			recurrenceException: {
				defaultValue: "",
				type: "string"
			},
			isReadonly: {
				type: "boolean",
				defaultValue: false
			},
			isAllDay: {
				type: "boolean",
				defaultValue: false
			},
			description: { type: "string" }
		}
	});
	var SchedulerDataSource = DataSource.extend({
		init: function(options) {
			DataSource.fn.init.call(this, extend(true, {}, { schema: {
				modelBase: SchedulerEvent,
				model: SchedulerEvent
			} }, options));
			this.reader = new SchedulerDataReader(this.options.schema, this.reader);
		},
		expand: function(start, end) {
			var data = this.view(), filter = {}, endOffset;
			if (start && end) {
				endOffset = end.getTimezoneOffset();
				end = /* @__PURE__ */ new Date(end.getTime() + MS_PER_DAY - 1);
				if (end.getTimezoneOffset() !== endOffset) end = kendo.timezone.apply(end, endOffset);
				filter = {
					logic: "or",
					filters: [{
						logic: "and",
						filters: [
							{
								field: "start",
								operator: "gte",
								value: start
							},
							{
								field: "end",
								operator: "gte",
								value: start
							},
							{
								field: "start",
								operator: "lte",
								value: end
							}
						]
					}, {
						logic: "and",
						filters: [{
							field: "start",
							operator: "lte",
							value: /* @__PURE__ */ new Date(start.getTime() + MS_PER_DAY - 1)
						}, {
							field: "end",
							operator: "gte",
							value: start
						}]
					}]
				};
				data = new kendo.data.Query(expandAll(data, start, end, this.reader.timezone)).filter(filter).toArray();
			}
			return data;
		},
		cancelChanges: function(model) {
			if (model && model.isOccurrence()) this._removeExceptionDate(model);
			DataSource.fn.cancelChanges.call(this, model);
		},
		insert: function(index, model) {
			if (!model) return;
			if (!(model instanceof SchedulerEvent)) {
				var eventInfo = model;
				model = this._createNewModel();
				model.accept(eventInfo);
			}
			if (!this._pushCreated && model.isRecurrenceHead() || model.recurrenceId) {
				model = model.recurrenceId ? model : model.toOccurrence();
				this._addExceptionDate(model);
			}
			return DataSource.fn.insert.call(this, index, model);
		},
		pushCreate: function(items) {
			this._pushCreated = true;
			DataSource.fn.pushCreate.call(this, items);
			this._pushCreated = false;
		},
		remove: function(model) {
			if (model.isRecurrenceHead()) this._removeExceptions(model);
			else if (model.isRecurring()) this._addExceptionDate(model);
			return DataSource.fn.remove.call(this, model);
		},
		_removeExceptions: function(model) {
			var data = this.data().slice(0), item = data.shift(), id = model.id;
			while (item) {
				if (item.recurrenceId === id) DataSource.fn.remove.call(this, item);
				item = data.shift();
			}
			model.set(RECURRENCE_EXCEPTION, "");
		},
		_removeExceptionDate: function(model) {
			if (model.recurrenceId) {
				var head = this.get(model.recurrenceId);
				if (head) {
					var start = model.defaults.start;
					var replaceRegExp = new RegExp("(\\" + EXCEPTION_SEPARATOR + "?)" + recurrence.toExceptionString(start, this.reader.timezone));
					var recurrenceException = (head.recurrenceException || "").replace(OLD_EXCEPTION_SEPARATOR_REGEXP, EXCEPTION_SEPARATOR).replace(/\,$/, "");
					if (replaceRegExp.test(recurrenceException)) head.set(RECURRENCE_EXCEPTION, recurrenceException.replace(replaceRegExp, ""));
					else {
						start = model.start;
						replaceRegExp = new RegExp("(\\" + EXCEPTION_SEPARATOR + "?)" + recurrence.toExceptionString(start, this.reader.timezone));
						head.set(RECURRENCE_EXCEPTION, recurrenceException.replace(replaceRegExp, ""));
					}
				}
			}
		},
		_addExceptionDate: function(model) {
			var start = model.start;
			var zone = this.reader.timezone;
			var head = this.get(model.recurrenceId);
			var recurrenceException = (head.recurrenceException || "").replace(OLD_EXCEPTION_SEPARATOR_REGEXP, EXCEPTION_SEPARATOR).replace(/\,$/, "");
			if (!recurrence.isException(recurrenceException, start, zone)) {
				var newException = recurrence.toExceptionString(start, zone);
				model.defaults.start = start;
				head.set(RECURRENCE_EXCEPTION, recurrenceException + (recurrenceException && newException ? EXCEPTION_SEPARATOR : "") + newException);
			}
		}
	});
	function expandAll(events, start, end, zone) {
		var length = events.length, data = [], idx = 0;
		for (; idx < length; idx++) data = data.concat(events[idx].expand(start, end, zone));
		return data;
	}
	SchedulerDataSource.create = function(options) {
		if (isArray(options) || options instanceof kendo.data.ObservableArray) options = { data: options };
		var dataSource = options || {};
		dataSource.data = dataSource.data;
		if (!(dataSource instanceof SchedulerDataSource) && dataSource instanceof kendo.data.DataSource) throw new Error("Incorrect DataSource type. Only SchedulerDataSource instances are supported");
		return dataSource instanceof SchedulerDataSource ? dataSource : new SchedulerDataSource(dataSource);
	};
	extend(true, kendo.data, {
		SchedulerDataSource,
		SchedulerDataReader,
		SchedulerEvent
	});
	var defaultCommands = {
		update: {
			text: "Save",
			className: "k-button-primary k-scheduler-update"
		},
		canceledit: {
			text: "Cancel",
			className: "k-scheduler-cancel"
		},
		destroy: {
			text: "Delete",
			icon: "trash",
			imageClass: "k-i-trash",
			className: "k-button-primary k-scheduler-delete",
			iconClass: "k-icon"
		}
	};
	function trimOptions(options, overrideOptions) {
		delete options.name;
		delete options.prefix;
		delete options.remove;
		delete options.edit;
		delete options.add;
		delete options.navigate;
		for (var key in overrideOptions) options[key] = overrideOptions[key];
		return options;
	}
	function descriptionEditor(options) {
		var attr = createValidationAttributes(options.model, options.field);
		return function(container, model) {
			$("<textarea name=\"description\" placeholder=\"Add Description\" class=\"k-input-inner !k-resize-y\" title=\"" + model.title + "\"/>").attr(attr).appendTo(container).wrap("<span class=\"k-input k-textarea\"></span>");
		};
	}
	function createValidationAttributes(model, field) {
		var modelField = (model.fields || model)[field];
		var specialRules = [
			"url",
			"email",
			"number",
			"date",
			"boolean"
		];
		var validation = modelField ? modelField.validation : {};
		var datatype = kendo.attr("type");
		var inArray = $.inArray;
		var ruleName;
		var rule;
		var attr = {};
		for (ruleName in validation) {
			rule = validation[ruleName];
			if (inArray(ruleName, specialRules) >= 0) attr[datatype] = ruleName;
			else if (!kendo.isFunction(rule)) attr[ruleName] = isPlainObject(rule) ? rule.value || ruleName : rule;
			attr[kendo.attr(ruleName + "-msg")] = rule.message;
		}
		return attr;
	}
	function filterResourceEditorData(editor, parentValue, parentValueField, valueField) {
		var editorValue = editor.value(), isMs = Array.isArray(editorValue), valueArray;
		if (isMs) valueArray = JSON.parse(JSON.stringify(editorValue));
		else valueArray = [editorValue.toString()];
		editor.dataSource.data().forEach(function(item) {
			if (item[parentValueField] === null || item[parentValueField] === undefined || item[parentValueField] == parentValue) item.set(DISABLED, false);
			else {
				var currentValue = item.get(valueField);
				item.set(DISABLED, true);
				if (valueArray.indexOf(currentValue) >= 0 || valueArray.indexOf(currentValue.toString()) >= 0) if (isMs) valueArray.splice(valueArray.indexOf(currentValue), 1);
				else {
					editor.value(null);
					editor.trigger(CHANGE);
				}
			}
		});
		if (isMs && valueArray.length < editorValue.length) {
			editor.value(valueArray);
			editor.trigger(CHANGE);
		}
	}
	function bindParentValueChangeHandler(container, currentEditor, resource, parent) {
		var parentElement = container.closest(".k-scheduler-edit-form, .k-edit-form-container").find("[data-" + kendo.ns + "bind='value:" + parent + "']");
		var parentWidget = parentElement.getKendoDropDownList();
		if (parentWidget) parentWidget.bind(CHANGE, function(ev) {
			filterResourceEditorData(currentEditor, ev.sender.value(), resource.dataParentValueField, resource.dataValueField);
		});
		else parentElement.on(CHANGE, function(ev) {
			var parentValue = ev.target.value;
			filterResourceEditorData(currentEditor, parentValue, resource.dataParentValueField, resource.dataValueField);
		});
	}
	function filterMobileResourceEditorData(resource, currentEditor, parentSelectedValue) {
		var options = currentEditor.find(OPTION), editorValue = currentEditor.val(), isMs = Array.isArray(editorValue), valueArray;
		if (isMs) valueArray = JSON.parse(JSON.stringify(editorValue));
		else valueArray = [editorValue];
		resource.dataSource.view().forEach(function(item, index) {
			var itemParentValue = kendo.getter(resource.dataParentValueField)(item);
			if (itemParentValue === null || itemParentValue === undefined || itemParentValue == parentSelectedValue) options[index].removeAttribute(DISABLED);
			else {
				options[index].setAttribute(DISABLED, DISABLED);
				var currentValue = "" + item.get(resource.dataValueField);
				if (valueArray.indexOf(currentValue) >= 0) if (isMs) valueArray.splice(valueArray.indexOf(currentValue), 1);
				else {
					currentEditor.val(null);
					currentEditor.trigger(CHANGE);
				}
			}
		});
		if (isMs && valueArray.length < editorValue.length) {
			currentEditor.val(valueArray);
			currentEditor.trigger(CHANGE);
		}
	}
	function dropDownResourceEditor(resource, model, parent) {
		var attr = createValidationAttributes(model, resource.field);
		var ariaAttribute = resource.icon ? "aria-label=\"" + encode(resource.title || resource.field) + "\"" : "aria-labelledby=\"" + resource.field + "_label\"";
		return function(container) {
			var currentEditor;
			if (parent) setTimeout(function() {
				filterResourceEditorData(currentEditor, model[parent], resource.dataParentValueField, resource.dataValueField);
				bindParentValueChangeHandler(container, currentEditor, resource, parent);
			});
			currentEditor = $(kendo.format("<select " + ariaAttribute + " data-{0}bind=\"value:{1}\" title=\"" + model.title + "\">", kendo.ns, resource.field)).appendTo(container).attr(attr).kendoDropDownList({
				dataTextField: resource.dataTextField,
				dataValueField: resource.dataValueField,
				dataSource: resource.dataSource.data(),
				valuePrimitive: resource.valuePrimitive,
				optionLabel: "None",
				template: (data) => `<span ${data.disabled ? "data-disabled" : ""}><span class="k-scheduler-mark" ${kendo.attr("style-background-color")}="${data[resource.dataColorField] || "none"}"></span>${data[resource.dataTextField]}</span>`,
				select: function(e) {
					if (e.dataItem && e.dataItem.disabled) e.preventDefault();
				},
				dataBound: function(e) {
					let options = e.sender.list.find("li");
					for (let i = 0; i < options.length; i++) {
						var element = options.eq(i);
						if (element.find("[data-disabled]").length > 0) element.addClass("k-disabled");
					}
				}
			}).data("kendoDropDownList");
		};
	}
	function dropDownResourceEditorMobile(resource, model, parent) {
		var attr = createValidationAttributes(model, resource.field);
		return function(container) {
			var options = "";
			var view = resource.dataSource.view();
			for (var idx = 0, length = view.length; idx < length; idx++) options += kendo.format("<option value=\"{0}\">{1}</option>", kendo.getter(resource.dataValueField)(view[idx]), kendo.getter(resource.dataTextField)(view[idx]));
			var currentEditor = $(kendo.format("<select aria-labelledby=\"" + resource.field + "_label\" data-{0}bind=\"value:{1}\">{2}</select>", kendo.ns, resource.field, options)).appendTo(container).attr(attr);
			if (parent) setTimeout(function() {
				var parentElement = container.closest(".k-stretched-view").find("[data-" + kendo.ns + "bind='value:" + parent + "']");
				var parentSelectedValue = model[parent];
				filterMobileResourceEditorData(resource, currentEditor, parentSelectedValue);
				parentElement.on(CHANGE, function(ev) {
					var parentValue = ev.target.value;
					filterMobileResourceEditorData(resource, currentEditor, parentValue);
				});
			});
		};
	}
	function multiSelectResourceEditor(resource, model, parent) {
		var attr = createValidationAttributes(model, resource.field);
		var ariaAttribute = resource.icon ? "aria-label=\"" + encode(resource.title || resource.field) + "\"" : "aria-labelledby=\"" + resource.field + "_label\"";
		return function(container) {
			var currentEditor;
			if (parent) setTimeout(function() {
				filterResourceEditorData(currentEditor, model[parent], resource.dataParentValueField, resource.dataValueField);
				bindParentValueChangeHandler(container, currentEditor, resource, parent);
			});
			currentEditor = $(kendo.format("<select " + ariaAttribute + " data-{0}bind=\"value:{1}\">", kendo.ns, resource.field)).appendTo(container).attr(attr).kendoMultiSelect({
				dataTextField: resource.dataTextField,
				dataValueField: resource.dataValueField,
				dataSource: resource.dataSource.data(),
				valuePrimitive: resource.valuePrimitive,
				itemTemplate: (data) => `<span ${data.disabled ? "data-disabled" : ""}><span class="k-scheduler-mark" ${kendo.attr("style-background-color")}="${data[resource.dataColorField] || "none"}"></span>${data[resource.dataTextField]}</span>`,
				tagTemplate: (data) => `<span class="k-scheduler-mark" ${kendo.attr("style-background-color")}="${data[resource.dataColorField] || "none"}"></span>${data[resource.dataTextField]}`,
				select: function(e) {
					if (e.dataItem && e.dataItem.disabled) e.preventDefault();
				},
				dataBound: function(e) {
					let options = e.sender.list.find("li");
					for (let i = 0; i < options.length; i++) {
						let element = options.eq(i);
						if (element.find("[data-disabled]").length > 0) element.addClass("k-disabled");
					}
				}
			}).data("kendoMultiSelect");
		};
	}
	function multiSelectResourceEditorMobile(resource, model, parent) {
		var attr = createValidationAttributes(model, resource.field);
		return function(container) {
			var options = "";
			var view = resource.dataSource.view();
			for (var idx = 0, length = view.length; idx < length; idx++) options += kendo.format("<option value=\"{0}\">{1}</option>", kendo.getter(resource.dataValueField)(view[idx]), kendo.getter(resource.dataTextField)(view[idx]));
			var currentEditor = $(kendo.format("<select aria-labelledby=\"" + resource.field + "_label\" data-{0}bind=\"value:{1}\" multiple=\"multiple\">{2}</select>", kendo.ns, resource.field, options)).appendTo(container).attr(attr);
			if (parent) setTimeout(function() {
				var parentElement = container.closest(".k-stretched-view").find("[data-" + kendo.ns + "bind='value:" + parent + "']");
				var parentSelectedValue = model[parent];
				filterMobileResourceEditorData(resource, currentEditor, parentSelectedValue);
				parentElement.on(CHANGE, function(ev) {
					var parentValue = ev.target.value;
					filterMobileResourceEditorData(resource, currentEditor, parentValue);
				});
			});
		};
	}
	function moveEventRange(event, distance) {
		var duration = event.end.getTime() - event.start.getTime();
		var start = new Date(event.start.getTime());
		kendo.date.setTime(start, distance);
		var end = new Date(start.getTime());
		kendo.date.setTime(end, duration, true);
		return {
			start,
			end
		};
	}
	var editors = {
		mobile: {
			dateRange: MOBILEDATERANGEEDITOR,
			timezonePopUp: MOBILETIMEZONEPOPUP,
			timezone: MOBILETIMEZONEEDITOR,
			recurrence: MOBILERECURRENCEEDITOR,
			description: descriptionEditor,
			multipleResources: multiSelectResourceEditorMobile,
			resources: dropDownResourceEditorMobile,
			isAllDay: MOBILEISALLDAYEDITOR
		},
		desktop: {
			dateRange: DATERANGEEDITOR,
			timezonePopUp: TIMEZONEBUTTON,
			timezone: TIMEZONEEDITOR,
			recurrence: RECURRENCEEDITOR,
			description: descriptionEditor,
			multipleResources: multiSelectResourceEditor,
			resources: dropDownResourceEditor,
			isAllDay: ISALLDAYEDITOR
		}
	};
	var Editor = kendo.Observable.extend({
		init: function(element, options) {
			kendo.Observable.fn.init.call(this);
			this.element = element;
			this.options = extend(true, {}, this.options, options);
			this.createButton = this.options.createButton;
			this.toggleDateValidationHandler = this._toggleDateValidation.bind(this);
		},
		_editorTitle: function(model) {
			var editorMessages = this.options.messages.editor || {};
			if (model && model.isNew && model.isNew()) return editorMessages.newEvent || editorMessages.editorTitle;
			return editorMessages.editEvent || editorMessages.editorTitle;
		},
		_toggleDateValidation: function(e) {
			if (e.field == "isAllDay") {
				var container = this.container, isAllDay = this.editable.options.model.isAllDay, isMobile = this.options.mobile, bindAttribute = kendo.attr("bind"), element, isDateTimeInput, shouldValidate;
				container.find("[" + bindAttribute + "*=end],[" + bindAttribute + "*=start]").each(function() {
					element = $(this);
					if (valueStartEndBoundRegex.test(element.attr(bindAttribute))) {
						isDateTimeInput = element.is("[" + kendo.attr("role") + "=datetimepicker],[" + kendo.attr("role") + "=timepicker],[type*=datetime],[type=time]");
						shouldValidate = isDateTimeInput ? !isAllDay : isMobile ? isAllDay : true;
						element.attr(kendo.attr("validate"), shouldValidate.toString());
					}
				});
			}
		},
		_initDateRangeEditors: function(model) {
			var that = this;
			var container = that.container;
			var validator = container.data("kendoValidator");
			var start = model.get("start");
			var end = model.get("end");
			that._dateRangeWidgets = [];
			that._dateRangeDuration = start instanceof Date && end instanceof Date ? kendo.isFunction(model.duration) ? model.duration() : end.getTime() - start.getTime() : null;
			if (validator && !kendo.isFunction(validator.options.rules.dateCompare)) validator.options.rules.dateCompare = dateCompareValidator;
			["start", "end"].forEach(function(field) {
				var dateInput = container.find("[data-scheduler-field='" + field + "'][data-scheduler-date-part=date]");
				var timeInput = container.find("[data-scheduler-field='" + field + "'][data-scheduler-date-part=time]");
				var datePicker = dateInput.data("kendoDatePicker");
				var timePicker = timeInput.data("kendoTimePicker");
				if (!datePicker || !timePicker) return;
				if (validator) {
					var owner = container.find("[data-scheduler-date-part=owner][name='" + field + "']");
					var requiredMessage = validator.options.messages.required;
					requiredMessage = kendo.isFunction(requiredMessage) ? requiredMessage(owner) : requiredMessage;
					owner.attr(kendo.attr("required-msg"), kendo.format(requiredMessage, owner.attr("title")));
				}
				var dateChange = function() {
					that._setDateRangePart(model, field, "date", datePicker.value());
				};
				var timeChange = function() {
					that._setDateRangePart(model, field, "time", timePicker.value());
				};
				datePicker.value(model.get(field));
				timePicker.value(model.get(field));
				datePicker.bind(CHANGE, dateChange);
				timePicker.bind(CHANGE, timeChange);
				that._dateRangeWidgets.push({
					field,
					datePicker,
					timePicker,
					dateChange,
					timeChange
				});
			});
			if (!that._dateRangeWidgets.length) {
				that._dateRangeWidgets = null;
				return;
			}
			that._dateRangeModel = model;
			that._dateRangeValidator = validator;
			that._dateRangeValidateProxy = function(e) {
				if (!model._normalizingAllDay || e.field !== "start" && e.field !== "end") that.editable._validateProxy(e);
			};
			if (validator) {
				that._dateRangeValidateInput = validator.validateInput;
				validator.validateInput = function(input) {
					var valid = that._dateRangeValidateInput.call(this, input);
					var owner = $(input);
					if (!valid && owner.is("[data-scheduler-date-part=owner]")) {
						var field = owner.attr("name");
						positionDateRangeValidationMessage(container.find(".k-invalid-msg[" + kendo.attr("for") + "='" + field + "']"));
					}
					return valid;
				};
			}
			that._dateRangeModelChangeHandler = function(e) {
				if (e.field !== "start" && e.field !== "end") return;
				var value = model.get(e.field);
				var owner = container.find("[data-scheduler-date-part=owner][name='" + e.field + "']");
				var datePicker = container.find("[data-scheduler-field='" + e.field + "'][data-scheduler-date-part=date]").data("kendoDatePicker");
				var timePicker = container.find("[data-scheduler-field='" + e.field + "'][data-scheduler-date-part=time]").data("kendoTimePicker");
				owner.val(value || "");
				if (datePicker) datePicker.value(value);
				if (timePicker) timePicker.value(value);
			};
			that._dateRangeValidationHandler = function(e) {
				if (!e.input.is("[data-scheduler-date-part=owner]")) return;
				var field = e.input.attr("name");
				var isAllDay = model.get("isAllDay");
				var dateInput = container.find("[data-scheduler-field='" + field + "'][data-scheduler-date-part=date]");
				var timeInput = container.find("[data-scheduler-field='" + field + "'][data-scheduler-date-part=time]");
				var dateWrapper = dateInput.data("kendoDatePicker").wrapper;
				var timeWrapper = timeInput.data("kendoTimePicker").wrapper;
				var message = container.find(".k-invalid-msg[" + kendo.attr("for") + "='" + field + "']");
				var messageId = message.attr("id");
				if (!e.valid) positionDateRangeValidationMessage(message);
				dateWrapper.toggleClass("k-invalid", !e.valid);
				timeWrapper.toggleClass("k-invalid", !e.valid && !isAllDay);
				dateInput.attr("aria-invalid", (!e.valid).toString());
				timeInput.attr("aria-invalid", (!e.valid && !isAllDay).toString());
				dateWrapper.attr("aria-invalid", (!e.valid).toString());
				timeWrapper.attr("aria-invalid", (!e.valid && !isAllDay).toString());
				if (!e.valid && messageId) {
					dateInput.attr("aria-describedby", messageId);
					if (!isAllDay) timeInput.attr("aria-describedby", messageId);
				} else {
					dateInput.removeAttr("aria-describedby");
					timeInput.removeAttr("aria-describedby");
				}
			};
			that._dateRangeModelSetHandler = function(e) {
				if (e.field === "start" || e.field === "end") container.find("[data-scheduler-date-part=owner][name='" + e.field + "']").val(e.value || "").data("schedulerValue", e.value);
			};
			model.unbind("set", that.editable._validateProxy);
			model.unbind("equalSet", that.editable._validateProxy);
			model.bind("set", that._dateRangeModelSetHandler);
			model.bind("set", that._dateRangeValidateProxy);
			model.bind("equalSet", that._dateRangeValidateProxy);
			model.bind(CHANGE, that._dateRangeModelChangeHandler);
			if (validator) validator.bind("validateInput", that._dateRangeValidationHandler);
		},
		_setDateRangePart: function(model, field, part, value) {
			if (!(value instanceof Date) || isNaN(value.getTime())) {
				model.set(field, null);
				return;
			}
			var current = model.get(field);
			var result = current instanceof Date && !isNaN(current.getTime()) ? new Date(current.getTime()) : new Date(value.getTime());
			var duration = field === "start" ? this._dateRangeDuration : null;
			if (part === "date") result.setFullYear(value.getFullYear(), value.getMonth(), value.getDate());
			else result.setHours(value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds());
			model.set(field, result);
			if (duration !== null) {
				var shiftedEnd = new Date(result.getTime());
				kendo.date.setTime(shiftedEnd, duration);
				model.set("end", shiftedEnd);
			}
			var endOwner = this.container && this.container.find("[data-scheduler-date-part=owner][name='end']");
			if (this._dateRangeValidator && endOwner && endOwner.length) {
				var endMessage = this.container.find(".k-invalid-msg[" + kendo.attr("for") + "='end']");
				this._dateRangeValidator.validateInput(endOwner);
				var renderedMessage = this.container.find(".k-invalid-msg[" + kendo.attr("for") + "='end']");
				if (endMessage.length && renderedMessage.length && endMessage[0] !== renderedMessage[0]) {
					endMessage.attr("class", renderedMessage.attr("class")).attr("id", renderedMessage.attr("id")).removeAttr("style").empty().append(renderedMessage.contents());
					renderedMessage.replaceWith(endMessage);
					positionDateRangeValidationMessage(endMessage);
				}
			}
		},
		_destroyDateRangeEditors: function() {
			var that = this;
			if (that._dateRangeWidgets) {
				that._dateRangeWidgets.forEach(function(item) {
					item.datePicker.unbind(CHANGE, item.dateChange);
					item.timePicker.unbind(CHANGE, item.timeChange);
				});
				that._dateRangeWidgets = null;
			}
			var model = that._dateRangeModel;
			var validator = that._dateRangeValidator;
			if (model && that._dateRangeModelChangeHandler) model.unbind(CHANGE, that._dateRangeModelChangeHandler);
			if (model && that._dateRangeModelSetHandler) model.unbind("set", that._dateRangeModelSetHandler);
			if (model && that._dateRangeValidateProxy) {
				model.unbind("set", that._dateRangeValidateProxy);
				model.unbind("equalSet", that._dateRangeValidateProxy);
			}
			if (validator && that._dateRangeValidationHandler) validator.unbind("validateInput", that._dateRangeValidationHandler);
			if (validator && that._dateRangeValidateInput) validator.validateInput = that._dateRangeValidateInput;
			that._dateRangeModel = null;
			that._dateRangeValidator = null;
			that._dateRangeDuration = null;
			that._dateRangeValidateInput = null;
			that._dateRangeValidateProxy = null;
			that._dateRangeModelChangeHandler = null;
			that._dateRangeModelSetHandler = null;
			that._dateRangeValidationHandler = null;
		},
		fields: function(editors, model) {
			var that = this;
			var messages = that.options.messages;
			var timezone = that.options.timezone;
			var click = function() {
				that._toggleTimeZones(that.editable.element, model);
			};
			var change = function(e) {
				var editorEl = $(that.editable.element);
				var separator = editorEl.find("span[data-separator-for=\"start\"]");
				var startRow = editorEl.find("div[data-container-for=\"start\"] > .k-scheduler-edit-form-row");
				var endRow = editorEl.find("div[data-container-for=\"end\"] > .k-scheduler-edit-form-row");
				if (e.checked) {
					separator.text("to");
					model.set("isTimezoneInvisible", true);
					var timezoneBtn = editorEl.find(".k-timezone-btn");
					if (timezoneBtn.length) setTimezoneButtonState(timezoneBtn, false, messages.editor);
					var endDate = startRow.add(endRow).find("[data-scheduler-field=end][data-scheduler-date-part=date]").closest(".k-datepicker");
					var endMessage = editorEl.find(".k-invalid-msg[" + kendo.attr("for") + "=end]");
					endMessage.insertAfter(separator);
					endDate.insertAfter(endMessage);
				} else {
					separator.text("from");
					var endDate = startRow.find("[data-scheduler-field=end][data-scheduler-date-part=date]").closest(".k-datepicker");
					var endMessage = editorEl.find(".k-invalid-msg[" + kendo.attr("for") + "=end]");
					endDate.add(endMessage).prependTo(endRow);
				}
			};
			var fields = [
				{
					field: "title",
					title: messages.editor.title
				},
				{
					field: "isAllDay",
					title: messages.editor.allDayEvent,
					editor: editors.isAllDay,
					change
				},
				{
					field: "start",
					title: messages.editor.start,
					editor: editors.dateRange,
					timezone
				},
				{
					field: "end",
					title: messages.editor.end,
					editor: editors.dateRange,
					timezone
				}
			];
			var checkHierarchical = function(item) {
				return !!item[resource.dataParentValueField];
			};
			if (kendo.timezone.windows_zones) {
				fields.push({
					field: "timezone",
					title: messages.editor.timezone,
					editor: editors.timezonePopUp,
					click,
					messages: messages.editor,
					model
				});
				model._set("isTimezoneInvisible", !(model.startTimezone || model.endTimezone));
				fields.push({
					field: "startTimezone",
					title: messages.editor.startTimezone,
					editor: editors.timezone,
					noTimezone: messages.editor.noTimezone
				});
				fields.push({
					field: "endTimezone",
					title: messages.editor.endTimezone,
					editor: editors.timezone,
					noTimezone: messages.editor.noTimezone
				});
			}
			if (!model.recurrenceId) fields.push({
				field: "recurrenceRule",
				title: messages.editor.repeat,
				editor: editors.recurrence,
				timezone,
				messages: messages.recurrenceEditor,
				pane: this.pane,
				recurrenceRuleLabelTemplate: that.options.recurrenceRuleLabelTemplate
			});
			if ("description" in model) fields.push({
				field: "description",
				title: messages.editor.description,
				editor: editors.description({
					model,
					field: "description"
				})
			});
			for (var resourceIndex = 0; resourceIndex < this.options.resources.length; resourceIndex++) {
				var resource = this.options.resources[resourceIndex];
				var hasParent = resource.dataSource.view().some(checkHierarchical);
				var parentResource, parent;
				if (hasParent) {
					parentResource = this.options.resources[resourceIndex - 1];
					if (parentResource) parent = parentResource.field;
				}
				fields.push({
					field: resource.field,
					title: resource.title,
					icon: resource.icon,
					editor: resource.multiple ? editors.multipleResources(resource, model, parent) : editors.resources(resource, model, parent)
				});
			}
			return fields;
		},
		end: function() {
			var that = this;
			if (that._dateRangeWidgets) that._dateRangeWidgets.map(function(item) {
				return {
					item,
					dateValue: item.datePicker.value() || kendo.parseDate(item.datePicker.element.val(), item.datePicker.options.parseFormats, item.datePicker.options.culture),
					timeValue: item.timePicker.value() || kendo.parseDate(item.timePicker.element.val(), item.timePicker.options.parseFormats, item.timePicker.options.culture)
				};
			}).forEach(function(values) {
				var item = values.item;
				var dateValue = values.dateValue;
				var timeValue = values.timeValue;
				if (dateValue && timeValue) {
					that._setDateRangePart(that._dateRangeModel, item.field, "date", dateValue);
					that._setDateRangePart(that._dateRangeModel, item.field, "time", timeValue);
				} else that._dateRangeModel.set(item.field, null);
				var value = that._dateRangeModel.get(item.field);
				that.container.find("[data-scheduler-date-part=owner][name='" + item.field + "']").val(value || "").data("schedulerValue", value);
			});
			return this.editable.end();
		},
		_buildDesktopEditTemplate: function(model, fields, editableFields) {
			this.options.messages;
			const editableField = (fieldName) => {
				if (!model.editable || model.editable(fieldName)) return `<div ${kendo.attr("container-for")}="${fieldName}" class="k-form-field-wrap"></div>`;
				else return `<div class="k-form-field-wrap">${fieldName && kendo.getter(fieldName)(model) || ""}</div>`;
			};
			let datetimeGroupOpen = false;
			const datetimeGroupFields = /* @__PURE__ */ new Set([
				"isAllDay",
				"start",
				"end",
				"timezone",
				"startTimezone",
				"endTimezone",
				"recurrenceRule"
			]);
			const generateFields = (field) => {
				const fieldName = field.field;
				const fieldTitle = field.title;
				const isEditable = !model.editable || model.editable(fieldName);
				if (isEditable) editableFields.push(field);
				let prefix = "";
				if (datetimeGroupOpen && !datetimeGroupFields.has(fieldName)) {
					prefix = "</div></div></div>";
					datetimeGroupOpen = false;
				}
				if (fieldName === "isAllDay") {
					datetimeGroupOpen = true;
					return `<div class="k-form-field"><label class="k-label k-form-label" id="${fieldName}_label" aria-hidden="true">${kendo.ui.icon({
						icon: "clock",
						size: "xlarge"
					})}</label><div class="k-form-field-wrap"><div class="k-scheduler-datetime-section">${editableField(fieldName)}`;
				}
				if ((fieldName === "start" || fieldName === "end") && datetimeGroupOpen) {
					const containerHtml = isEditable ? `<div ${kendo.attr("container-for")}="${fieldName}" class="k-form-field-wrap" style="display:contents"></div>` : `<div class="k-form-field-wrap" style="display:contents">${kendo.getter(fieldName)(model) || ""}</div>`;
					if (fieldName === "end") return containerHtml + "</div>";
					return `<div class="k-scheduler-datetime-grid" ${kendo.attr("style-grid-template-columns")}="minmax(0, 2.5fr) minmax(0, 1fr) min-content">` + containerHtml;
				}
				if (fieldName === "startTimezone" || fieldName === "endTimezone") return `${editableField(fieldName)}`;
				if (fieldName === "recurrenceRule") {
					datetimeGroupOpen = false;
					return `<div class='k-scheduler-edit-form-row'>${editableField(fieldName)}</div></div></div></div>`;
				}
				const label = `<label class="k-label k-form-label" for="${fieldName}" id="${fieldName}_label" ${field.icon ? "aria-hidden=\"true\"" : ""}>
                            ${kendo.isPresent(field.icon) ? kendo.ui.icon({
					icon: field.icon,
					size: "xlarge"
				}) : fieldTitle || fieldName || ""}
                </label>`;
				return prefix + `<div class="k-form-field">${label}${editableField(fieldName)}</div>`;
			};
			return `<div class="k-scheduler-edit-form k-form k-form-horizontal">${fields.map(generateFields).join("")}${datetimeGroupOpen ? "</div></div></div>" : ""}</div>`;
		},
		_buildMobileEditTemplate: function(model, fields, editableFields) {
			var messages = this.options.messages;
			const startTimezone = `<div class="k-popup-edit-form k-scheduler-edit-form k-scheduler-timezones" ${kendo.attr("style-display")}="none"><ul class="k-listgroup k-listgroup-flush"><li class="k-item k-listgroup-item"><label class="k-label k-listgroup-form-row"><span class="k-item-title k-listgroup-form-row">` + encode(messages.editor.separateTimezones) + "</span><span class=\"k-listgroup-form-field-wrapper\"><input class=\"k-timezone-toggle\" data-role=\"switch\" type=\"checkbox\" /></span></label></li>";
			const editableField = (field) => {
				const fieldName = field.field;
				const fieldTitle = field.title;
				const isEditable = !model.editable || model.editable(fieldName);
				let midPart;
				if (isEditable) midPart = `${fieldName === "timezone" ? `<label class="k-label k-listgroup-form-row" data-bind="css: { k-disabled: isAllDay }">` : `<label class="k-label k-listgroup-form-row">`}<span class="k-item-title k-listgroup-form-field-label">${fieldTitle || fieldName || ""}</span><div class="k-listgroup-form-field-wrapper" ${kendo.attr("container-for")}="${fieldName}"></div>`;
				else midPart = `<li class="k-item k-listgroup-item"><label class="k-label k-no-click k-listgroup-form-row"><span class="k-item-title k-listgroup-form-field-label">${fieldTitle || fieldName || ""}</span><span class="k-no-editor k-listgroup-form-field-wrapper">${fieldName && kendo.getter(fieldName)(model) || ""}</span>`;
				return `<li class="k-item k-listgroup-item">` + midPart + `</label></li>`;
			};
			const generateFields = (field) => {
				const fieldName = field.field;
				if (!model.editable || model.editable(fieldName)) editableFields.push(field);
				return (fieldName === "timezone" || fieldName === "recurrenceRule" ? "</ul><ul class=\"k-listgroup k-listgroup-flush\">" : "") + (fieldName === "startTimezone" ? startTimezone : "") + editableField(field) + (fieldName === "recurrenceRule" ? "</ul><ul class=\"k-listgroup k-listgroup-flush\">" : "") + (fieldName === "endTimezone" ? "</ul></div>" : "");
			};
			return `<ul class="k-listgroup k-listgroup-flush">` + fields.map(generateFields).join("") + `</ul>`;
		},
		_buildEditTemplate: function(model, fields, editableFields, isMobile) {
			var settings = extend({}, kendo.Template, this.options.templateSettings);
			var template = this.options.editable.template;
			var html = "";
			if (template) {
				if (typeof template === STRING) template = kendo.unescape(template);
				html += kendo.template(template, settings)(model);
			} else if (isMobile) html += "<div data-role=\"content\">" + this._buildMobileEditTemplate(model, fields, editableFields) + "</div>";
			else html += this._buildDesktopEditTemplate(model, fields, editableFields);
			return html;
		},
		_revertTimezones: function(model) {
			model.set("startTimezone", this._startTimezone);
			model.set("endTimezone", this._endTimezone);
			delete this._startTimezone;
			delete this._endTimezone;
		}
	});
	var MobileEditor = Editor.extend({
		init: function() {
			Editor.fn.init.apply(this, arguments);
			this.pane = kendo.Pane.wrap(this.element, { viewEngine: { viewOptions: {
				renderOnInit: true,
				wrap: false,
				wrapInSections: true,
				detachOnHide: false,
				detachOnDestroy: false
			} } });
			this.pane.element.parent().css("height", this.options.height);
			this.view = this.pane.view();
		},
		options: { animations: {
			left: "slide",
			right: "slide:right"
		} },
		destroy: function() {
			this.close();
			this.unbind();
			this.pane.destroy();
		},
		_toggleTimeZones: function(container, model) {
			this._initTimezoneEditor(model);
		},
		_initTimezoneEditor: function(model) {
			var that = this;
			var pane = that.pane;
			var messages = that.options.messages;
			var timezoneView = that.timezoneView;
			var container = timezoneView ? timezoneView.content.find(".k-scheduler-timezones") : that.container.find(".k-scheduler-timezones");
			var kSwitch = container.find("input.k-timezone-toggle").data("kendoSwitch");
			var endTimezoneRow = container.find("li.k-item:not(.k-zonepicker)").last();
			var startTimezoneChange = function(e) {
				if (e.field === "startTimezone") {
					var value = model.startTimezone;
					kSwitch.enable(value);
					if (!value) {
						endTimezoneRow.hide();
						model.set("endTimezone", "");
						kSwitch.value(false);
					}
				}
			};
			that._startTimezone = model.startTimezone || "";
			that._endTimezone = model.endTimezone || "";
			if (!timezoneView) {
				var html = "<div data-role=\"view\" class=\"k-popup-edit-form k-scheduler-edit-form\"><div data-role=\"header\" class=\"k-appbar k-appbar-primary\">" + kendo.html.renderButton(`<button class="k-header-cancel k-scheduler-cancel" title="${messages.cancel}" aria-label="${messages.cancel}"></button>`, {
					fillMode: "flat",
					icon: "chevron-left"
				}) + `<span class="k-spacer"></span><span>${encode(messages.editor.timezoneTitle)}</span><span class="k-spacer"></span>` + encode(messages.editor.timezoneTitle) + kendo.html.renderButton(`<button class="k-header-done k-scheduler-update" title="${messages.save}" aria-label="${messages.save}"></button>`, {
					fillMode: "flat",
					icon: "check"
				}) + "</div><div data-role=\"content\"></div>";
				this.timezoneView = timezoneView = pane.append(html);
				timezoneView.contentElement.append(container.show());
				timezoneView.element.on(CLICK + NS, ".k-scheduler-cancel, .k-scheduler-update", function(e) {
					e.preventDefault();
					e.stopPropagation();
					if ($(this).hasClass("k-scheduler-cancel")) that._revertTimezones(model);
					var editView = that._editPane;
					var text = timezoneButtonText(model, messages.editor.noTimezone);
					editView.content.find(".k-timezone-label").text(text);
					pane.navigate(editView, that.options.animations.right);
				});
				kSwitch.bind(CHANGE, function(ev) {
					endTimezoneRow.toggle(ev.checked);
					model.set("endTimezone", "");
				});
				model.bind(CHANGE, startTimezoneChange);
			}
			kSwitch.value(!!model.endTimezone);
			kSwitch.enable(!!model.startTimezone);
			if (model.endTimezone) endTimezoneRow.show();
			else endTimezoneRow.hide();
			pane.navigate(timezoneView, that.options.animations.left);
		},
		showDialog: function(options) {
			var actions = options.buttons.map(function(button) {
				return {
					text: button.text,
					action: button.click
				};
			});
			actions.push({
				text: this.options.messages.cancel,
				primary: true
			});
			$("<div />").appendTo(document.body).kendoDialog({
				close: function() {
					this.destroy();
				},
				modal: { preventScroll: true },
				closable: false,
				title: false,
				content: options.text,
				actions
			});
		},
		editEvent: function(model) {
			var pane = this.pane;
			var html = "";
			var messages = this.options.messages;
			var updateText = messages.save;
			var removeText = messages.destroy;
			var cancelText = messages.cancel;
			var titleText = messages.editor.editorTitle;
			var resetSeries = messages.resetSeries;
			html += "<div data-role=\"view\" class=\"k-popup-edit-form k-scheduler-edit-form\"" + kendo.attr("uid") + "=\"" + model.uid + "\"><div data-role=\"header\" class=\"k-appbar k-appbar-primary\">" + kendo.html.renderButton(`<button class="k-header-cancel k-scheduler-cancel" title="${cancelText}" aria-label="${cancelText}"></button>`, {
				fillMode: "flat",
				icon: "chevron-left"
			}) + `<span class="k-spacer"></span><span>${encode(titleText)}</span><span class="k-spacer"></span>` + kendo.html.renderButton(`<button class="k-header-done k-scheduler-update" title="${updateText}" aria-label="${updateText}"></button>`, {
				fillMode: "flat",
				icon: "check"
			}) + "</div>";
			var fields = this.fields(editors.mobile, model);
			var that = this;
			var editableFields = [];
			html += this._buildEditTemplate(model, fields, editableFields, true);
			html += "</div>";
			var view = pane.append(html);
			if (!model.isNew() && this.options.editable && this.options.editable.destroy !== false && model.isRecurrenceHead() && model.recurrenceException) {
				var resetSeriesBtn = "<ul class=\"k-edit-buttons k-listgroup k-listgroup-flush\"><li class=\"k-item k-listgroup-item\"><span class=\"k-scheduler-resetSeries k-link k-label\" aria-label=\"" + resetSeries + "\">" + resetSeries + "</span></li></ul>";
				view.contentElement.append(resetSeriesBtn);
			}
			if (!model.isNew() && this.options.editable && this.options.editable.destroy !== false) {
				var deleteBtn = "<ul class=\"k-edit-buttons k-listgroup k-listgroup-flush\"><li class=\"k-item k-listgroup-item\"><span class=\"k-scheduler-delete k-link k-label\" aria-label=\"" + removeText + "\">" + removeText + "</span></li></ul>";
				view.contentElement.append(deleteBtn);
			}
			this._editPane = view;
			var container = this.container = view.element;
			this.editable = container.kendoEditable({
				fields: editableFields,
				model,
				clearContainer: false,
				target: that.options.target,
				validateOnBlur: true
			}).data("kendoEditable");
			if (!this.trigger("edit", {
				container,
				model
			})) {
				container.on(CLICK + NS, "a.k-scheduler-edit, .k-scheduler-cancel, .k-scheduler-update, span.k-scheduler-delete, span.k-scheduler-resetSeries", function(e) {
					e.preventDefault();
					e.stopPropagation();
					var button = $(this);
					if (!button.hasClass("k-scheduler-edit")) {
						var name = "cancel";
						if (button.hasClass("k-scheduler-update")) name = "save";
						else if (button.hasClass("k-scheduler-delete")) name = "remove";
						else if (button.hasClass("k-scheduler-resetSeries")) name = RESET;
						that.trigger(name, {
							container,
							model
						});
					} else pane.navigate(this._editPane, that.options.animations.right);
				});
				pane.navigate(view, that.options.animations.left);
				model.bind(CHANGE, that.toggleDateValidationHandler);
			} else this.trigger("cancel", {
				container,
				model
			});
			return this.editable;
		},
		_views: function() {
			return this.pane.element.find(kendo.roleSelector("view")).not(this.view.element);
		},
		close: function() {
			if (this.container) {
				this.pane.navigate("", this.options.animations.right);
				var views = this._views();
				var view;
				for (var idx = 0, length = views.length; idx < length; idx++) {
					view = views.eq(idx).data("kendoView");
					if (view) view.purge();
				}
				views.remove();
				this.container = null;
				if (this.editable) {
					this.editable.options.model.unbind(CHANGE, this.toggleDateValidationHandler);
					this.editable.destroy();
					this.editable = null;
				}
				this.timezoneView = null;
			}
		}
	});
	var PopupEditor = Editor.extend({
		destroy: function() {
			this.close();
			this.unbind();
		},
		editEvent: function(model) {
			var that = this;
			var editable = that.options.editable;
			var html = "<div " + kendo.attr("uid") + "=\"" + model.uid + "\">";
			var $html;
			var messages = that.options.messages;
			var updateText = messages.save;
			var cancelText = messages.cancel;
			var deleteText = messages.destroy;
			var deleteIcon = "trash";
			var resetSeries = messages.resetSeries;
			var fields = this.fields(editors.desktop, model);
			var editableFields = [];
			var fieldName;
			html += this._buildEditTemplate(model, fields, editableFields, false);
			var attr;
			var options = isPlainObject(editable) ? editable.window : {};
			html += "<div class=\"k-actions k-actions-end k-actions-horizontal k-window-actions k-dialog-actions\">";
			if ((!model.isNew() || model.isRecurring()) && editable.destroy !== false) html += this.createButton({
				name: "delete",
				text: deleteText,
				attr,
				icon: deleteIcon,
				fillMode: "flat",
				themeColor: "primary"
			});
			html += this.createButton({
				name: "canceledit",
				text: cancelText,
				attr
			}) + this.createButton({
				name: "update",
				text: updateText,
				attr
			});
			if (!model.isNew() && editable.destroy !== false && model.isRecurrenceHead() && model.recurrenceException) html += this.createButton({
				name: "resetSeries",
				text: resetSeries,
				attr
			});
			html += "</div></div>";
			$html = $(html);
			kendo.applyStylesFromKendoAttributes($html, ["display", "grid-template-columns"]);
			var container = this.container = $html.appendTo(that.element).eq(0).kendoDialog(extend({
				title: that._editorTitle(model),
				modal: true,
				width: 800,
				closable: true,
				actions: [],
				visible: false,
				close: function(e) {
					if (e.userTriggered) {
						if (that.trigger(CANCEL, {
							container,
							model
						})) e.preventDefault();
					}
				}
			}, options));
			that.editable = container.kendoEditable({
				fields: editableFields,
				model,
				clearContainer: false,
				validateOnBlur: true,
				target: that.options.target
			}).data("kendoEditable");
			that._initDateRangeEditors(model);
			for (var field in editableFields) {
				if (editableFields[field].field !== "recurrenceRule") {
					fieldName = editableFields[field].field;
					var inputs = container.find("[name='" + fieldName + "']");
					if ([
						"title",
						"isAllDay",
						"start",
						"end",
						"startTimezone",
						"endTimezone",
						"description"
					].includes(fieldName)) inputs.removeAttr("aria-labelledby").each(function() {
						var input = $(this);
						var inputLabel = input.attr("aria-label");
						var fieldTitle = editableFields[field].title;
						input.attr("aria-label", inputLabel && inputLabel !== fieldTitle ? fieldTitle + " " + inputLabel : fieldTitle);
					});
					else inputs.attr("aria-labelledby", fieldName + "_label");
				}
				if (editableFields[field].field === "title") container.find("label[for='" + fieldName + "']").text("").removeAttr("for").attr("aria-hidden", "true").prepend(kendo.ui.icon({
					icon: "right-double-quotes",
					size: "xlarge"
				}));
				if (editableFields[field].field === "description") container.find("label[for='" + fieldName + "']").text("").removeAttr("for").attr("aria-hidden", "true").prepend(kendo.ui.icon({
					icon: "comment",
					size: "xlarge"
				}));
				if (editableFields[field].field === "startTimezone" || editableFields[field].field === "endTimezone") {
					let editableField = editableFields[field].field, startEndSelector = editableField === "startTimezone" ? "start" : "end", timeZoneContainer = container.find(`div[data-container-for='${fieldName}']`);
					if (editableField === "startTimezone") {
						let timezoneBtn = container.find(`div[data-container-for='${startEndSelector}']`).find(".k-timezone-btn");
						timeZoneContainer.insertBefore(timezoneBtn);
						that._startTimezoneChangeHandler = function(e) {
							if (e.field === "startTimezone") model.set("endTimezone", model.startTimezone);
						};
						model.bind(CHANGE, that._startTimezoneChangeHandler);
					} else {
						let startEndContainer = container.find(`div[data-container-for='${startEndSelector}']`);
						timeZoneContainer.appendTo(startEndContainer);
					}
				}
				if (editableFields[field].field === "isAllDay") {
					container.find("label[for='" + fieldName + "']").attr("id", fieldName + "_label");
					let kSwitch = container.find(`div[data-container-for='${fieldName}']`).find("input").getKendoSwitch();
					kSwitch.bind("change", editableFields[field].change);
					if (kSwitch.value()) editableFields[field].change({ checked: true });
				}
			}
			if (!that.trigger(EDIT, {
				container,
				model
			})) {
				container.data("kendoDialog").open();
				container.on(CLICK + NS, "button.k-scheduler-cancel", function(e) {
					e.preventDefault();
					e.stopPropagation();
					that.trigger(CANCEL, {
						container,
						model
					});
				});
				container.on(CLICK + NS, "button.k-scheduler-update", function(e) {
					e.preventDefault();
					e.stopPropagation();
					that.trigger("save", {
						container,
						model
					});
				});
				container.on(CLICK + NS, "button.k-scheduler-delete", function(e) {
					e.preventDefault();
					e.stopPropagation();
					that.trigger(REMOVE, {
						container,
						model
					});
				});
				container.on(CLICK + NS, "button.k-scheduler-resetSeries", function(e) {
					e.preventDefault();
					e.stopPropagation();
					that.trigger(RESET, {
						container,
						model
					});
				});
				kendo.cycleForm(container);
				model.bind(CHANGE, that.toggleDateValidationHandler);
			} else that.trigger(CANCEL, {
				container,
				model
			});
			return that.editable;
		},
		close: function() {
			var that = this;
			var destroy = function() {
				if (that.editable) {
					var model = that.editable.options.model;
					that._destroyDateRangeEditors();
					model.unbind(CHANGE, that.toggleDateValidationHandler);
					if (that._startTimezoneChangeHandler) {
						model.unbind(CHANGE, that._startTimezoneChangeHandler);
						that._startTimezoneChangeHandler = null;
					}
					that.editable.destroy();
					that.editable = null;
					that.container = null;
				}
				if (that.popup) {
					that.popup.destroy();
					that.popup = null;
				}
			};
			if (that.editable) if (that.container.is(":visible")) that.container.data("kendoDialog").bind("hide", destroy).close();
			else destroy();
			else destroy();
		},
		showDialog: function(options) {
			var actions = options.buttons.map(function(button) {
				return {
					text: button.text,
					action: button.click,
					primary: kendo.isPresent(button.primary) ? button.primary : false
				};
			});
			$("<div />").appendTo(document.body).kendoDialog({
				close: function() {
					this.destroy();
				},
				modal: { preventScroll: true },
				closable: kendo.isPresent(options.closable) ? options.closable : false,
				title: options.title,
				content: options.text,
				actions
			}).data("kendoDialog").open();
		},
		_toggleTimeZones: function(container, model) {
			var that = this;
			var messages = that.options.messages;
			var editable = that.options.editable;
			let timezoneBtn = container.find(".k-timezone-btn");
			if (timezoneBtn.length) {
				let textContainer = timezoneBtn.find(".k-button-text");
				if (textContainer.length && !textContainer.hasClass("k-hidden")) {
					setTimezoneButtonState(timezoneBtn, true, messages.editor);
					model.set("isTimezoneInvisible", false);
				} else if (textContainer.length && textContainer.hasClass("k-hidden")) if (editable === true || editable.confirmation !== false) that.showDialog({
					title: messages.editor.resetTimezoneWindowTitle,
					closable: true,
					text: RESETTIMEZONECONFIRM,
					buttons: [{
						name: "canceledit",
						text: messages.editor.cancelTimezoneReset,
						primary: false,
						click: function() {}
					}, {
						name: "resettimezone",
						text: messages.editor.resetTimezone,
						primary: true,
						click: function() {
							setTimezoneButtonState(timezoneBtn, false, messages.editor);
							model.set("startTimezone", "");
							model.set("endTimezone", "");
							model.set("isTimezoneInvisible", true);
						}
					}]
				});
				else {
					setTimezoneButtonState(timezoneBtn, false, messages.editor);
					model.set("isTimezoneInvisible", true);
				}
			}
		}
	});
	var Scheduler = DataBoundWidget.extend({
		init: function(element, options) {
			var that = this;
			Widget.fn.init.call(that, element, options);
			if (!that.options.views || !that.options.views.length) that.options.views = ["day", "week"];
			that.resources = [];
			that._initModel();
			that._wrapper();
			if (that.options.selectable) that._tabindex();
			that._views();
			that._toolbar();
			that._dataSource();
			that._resources();
			that._resizeHandler = function() {
				that.resize();
			};
			that.wrapper.on(MOUSEDOWN + NS + " selectstart" + NS, function(e) {
				var target = $(e.target);
				if (!target.is(":kendoFocusable") && target.closest(".k-button").length === 0) e.preventDefault();
			});
			if (that.options.editable && that.options.editable.resize !== false) that._resizable();
			that._movable();
			that._bindResize();
			if (that.options.messages && that.options.messages.recurrence) recurrence.options = that.options.messages.recurrence;
			that._navigation();
			that._selectable();
			that._touchHandlers();
			that._ariaId = kendo.guid();
			that._createEditor();
			that.mediaQueryList = kendo.mediaQuery(MIN_SCREEN);
			that.mediaQueryList.onChange(that._onMediaChange.bind(that));
			if (that._showWatermarkOverlay) that._showWatermarkOverlay(that.element[0]);
			Widget.fn.endInit.call(that);
		},
		_onMediaChange: function(e) {
			const that = this;
			const view = that._selectedView;
			const toolbarEl = that.toolbar;
			const toolbar = toolbarEl.getKendoToolBar();
			if (that._viewsDropDownButton) return;
			const segmentedControlEl = toolbarEl.find(".k-scheduler-views");
			if (e.matches) {
				toolbar.hide(toolbarEl.find(".k-views-dropdown"));
				segmentedControlEl.show();
			} else {
				toolbar.show(toolbarEl.find(".k-views-dropdown"));
				segmentedControlEl.hide();
			}
			that._model.set("formattedDate", e.matches ? view.dateForTitle() : view.shortDateForTitle());
		},
		_bindResize: function() {
			$(window).on("resize" + NS, this._resizeHandler);
		},
		_unbindResize: function() {
			$(window).off("resize" + NS, this._resizeHandler);
		},
		dataItems: function() {
			var that = this;
			var items = that.items();
			var events = that._data;
			var eventsUids = $.map(items, function(item) {
				return $(item).attr("data-uid");
			});
			var i;
			var key;
			var dict = {};
			var eventsUidsLength = eventsUids.length;
			for (i = 0; i < eventsUidsLength; i++) dict[eventsUids[i]] = null;
			var eventsCount = events.length;
			for (i = 0; i < eventsCount; i++) {
				var event = events[i];
				if (dict[event.uid] !== undefined) dict[event.uid] = event;
			}
			var sortedData = [];
			for (key in dict) sortedData.push(dict[key]);
			return sortedData;
		},
		_isMobile: function() {
			var options = this.options;
			return options.mobile === true && kendo.support.mobileOS || options.mobile === "phone" || options.mobile === "tablet";
		},
		_isTouch: function(event) {
			return /touch/.test(event.type) || event.originalEvent && /touch/.test(event.originalEvent.pointerType);
		},
		_isInverseColor: function(eventElement) {
			return eventElement.hasClass(INVERSECOLORCLASS);
		},
		_groupsByResource: function(resources, groupIndex, groupsArray, parentFieldValue, parentField) {
			if (!groupsArray) groupsArray = [];
			var resource = resources[0];
			if (resource) {
				var group;
				var data = resource.dataSource.view();
				var prevIndex = 0;
				for (var dataIndex = 0; dataIndex < data.length; dataIndex++) {
					var fieldValue = kendo.getter(resource.dataValueField)(data[dataIndex]);
					var currentGroupIndex = groupIndex + prevIndex + dataIndex;
					group = this._groupsByResource(resources.slice(1), currentGroupIndex, groupsArray, fieldValue, resource.field);
					group[resource.field] = fieldValue;
					prevIndex = group.groupIndex;
					if (parentField && parentFieldValue) group[parentField] = parentFieldValue;
					if (resources.length === 1) {
						group.groupIndex = groupIndex + dataIndex;
						groupsArray.push(group);
					}
				}
				return group;
			} else return {};
		},
		data: function() {
			return this._data;
		},
		select: function(options) {
			var that = this;
			var view = that.view();
			var selection = that._selection;
			var groups = view.groups;
			var selectedGroups;
			if (options === undefined) {
				var selectedEvents;
				var slots = view._selectedSlots;
				if (!selection) return [];
				if (selection && selection.events) selectedEvents = that._selectedEvents();
				return {
					start: selection.start,
					end: selection.end,
					events: selectedEvents,
					slots,
					resources: view._resourceBySlot(selection)
				};
			}
			if (!options) {
				that._selection = null;
				that._old = null;
				view.clearSelection();
				return;
			}
			if (Array.isArray(options)) options = { events: options.splice(0) };
			if (options.resources) {
				var fieldName;
				var filters = [];
				var groupsByResource = [];
				if (view.groupedResources) that._groupsByResource(view.groupedResources, 0, groupsByResource);
				for (fieldName in options.resources) filters.push({
					field: fieldName,
					operator: "eq",
					value: options.resources[fieldName]
				});
				selectedGroups = new kendo.data.Query(groupsByResource).filter(filters).toArray();
			}
			if (options.events && options.events.length) {
				that._selectEvents(options.events, selectedGroups);
				that._select();
				return;
			}
			if (groups && options.start && options.end) {
				var rangeStart = getDate(view._startDate);
				var rangeEnd = kendo.date.addDays(getDate(view._endDate), 1);
				var group;
				var ranges;
				if (options.start < rangeEnd && rangeStart <= options.end) {
					if (selectedGroups && selectedGroups.length) group = groups[selectedGroups[0].groupIndex];
					else group = groups[0];
					if (!group.timeSlotCollectionCount()) options.isAllDay = true;
					ranges = group.ranges(options.start, options.end, options.isAllDay, false);
					if (ranges.length) {
						that._selection = {
							start: kendo.timezone.toLocalDate(ranges[0].start.start),
							end: kendo.timezone.toLocalDate(ranges[ranges.length - 1].end.end),
							groupIndex: ranges[0].start.groupIndex,
							index: ranges[0].start.index,
							isAllDay: ranges[0].start.isDaySlot,
							events: []
						};
						that._select();
					}
				}
			}
		},
		_selectEvents: function(eventsUids, selectedGroups) {
			var that = this;
			var idx;
			var view = that.view();
			var groups = view.groups;
			var eventsLength = eventsUids.length;
			var isGrouped = selectedGroups && selectedGroups.length;
			var ctrlKey = that._ctrlKey;
			that._ctrlKey = true;
			for (idx = 0; idx < eventsLength; idx++) if (groups && isGrouped) {
				var currentGroup = groups[selectedGroups[0].groupIndex];
				var events = [];
				var timeSlotCollectionCount = currentGroup.timeSlotCollectionCount();
				var daySlotCollectionCount = currentGroup.daySlotCollectionCount();
				for (var collIdx = 0; collIdx < timeSlotCollectionCount; collIdx++) events = events.concat(currentGroup.getTimeSlotCollection(collIdx).events());
				for (var dayCollIdx = 0; dayCollIdx < daySlotCollectionCount; dayCollIdx++) events = events.concat(currentGroup.getDaySlotCollection(dayCollIdx).events());
				events = new kendo.data.Query(events).filter({
					field: (event) => event.element[0].getAttribute("data-uid"),
					operator: "eq",
					value: eventsUids[idx]
				}).toArray();
				if (events[0]) that._createSelection(events[0].element);
			} else {
				var element = view.element.find(kendo.format(".k-event[data-uid={0}], .k-task[data-uid={0}]", eventsUids[idx]));
				if (element.length) that._createSelection(element[0]);
			}
			that._ctrlKey = ctrlKey;
		},
		_touchHandlers: function() {
			var that = this;
			var startX;
			var startY;
			var endX;
			var endY;
			var timeStamp;
			var wrapper = that.wrapper;
			var touchMoveHandler = that._touchMove.bind(that);
			wrapper.on(TOUCHSTART + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td, .k-event", function(e) {
				var content = that.wrapper.find(".k-scheduler-content");
				if (!that._isTouch(e)) return;
				content.stop(true, false);
				that._touchPosX = startX = that._tapPosition(e, "X");
				that._touchPosY = startY = that._tapPosition(e, "Y");
				that._userTouched = true;
				that.view()._scrolling = false;
				timeStamp = Date.now();
				wrapper.on(TOUCHMOVE + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td, .k-event", touchMoveHandler);
			});
			wrapper.on("contextmenu" + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td, .k-event", function(e) {
				that._preventFocus = true;
			});
			wrapper.on(TOUCHEND + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td, .k-event", function(e) {
				if (!that._isTouch(e)) return;
				var delta = Date.now() - timeStamp;
				var content = that.wrapper.find(".k-scheduler-content");
				var amplitude = -that._amplitude * (3e3 / delta);
				endX = that._tapPosition(e, "X");
				endY = that._tapPosition(e, "Y");
				if (that._dragging) return;
				if (that.options.selectable && (Math.abs(endX - startX) <= 10 || Math.abs(endY - startY) <= 10)) that._mouseDownSelection(e);
				if (!kendo.support.kineticScrollNeeded && delta < 200 && Math.abs(endX - startX) > 10) content.animate({ scrollTop: content[0].scrollTop + amplitude });
				wrapper.off(TOUCHMOVE + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td", touchMoveHandler);
			});
		},
		_navigation: function() {
			var that = this, wrapper = that.wrapper;
			wrapper.on("focus" + NS, function() {
				var selection = that._selection;
				setTimeout(function() {
					if (!that._preventFocus) {
						if ((!selection || selection.events.length > 0 && wrapper.find("[data-uid='" + selection.events[0] + "']").length === 0) && !that._userTouched && !that._mouseDown) that._initialFocus();
						else that._mouseDown = false;
						that._select();
					} else that._preventFocus = false;
				}, 300);
			});
			wrapper.on("focusout" + NS, function() {
				that._ctrlKey = that._shiftKey = false;
			});
			wrapper.on("keydown" + NS, that, that._keydown.bind(that));
			wrapper.on("keyup" + NS, function(e) {
				that._ctrlKey = e.ctrlKey;
				that._shiftKey = e.shiftKey;
			});
		},
		_selectable: function() {
			var that = this;
			var wrapper = that.wrapper;
			if (!that.options.selectable) return;
			wrapper.on(MOUSEDOWN + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td, .k-event, .k-scheduler-body td .k-link", function(e) {
				if (that._isTouch(e)) return;
				that._mouseDownSelection(e);
			});
			var mouseMoveHandler = that._mouseMove.bind(that);
			wrapper.on(MOUSEDOWN + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td", function(e) {
				var which = e.which;
				var button = e.button;
				var isRight = which && which === 3 || button && button == 2;
				if (that._isTouch(e)) return;
				if (!isRight) wrapper.on(MOUSEMOVE + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td", mouseMoveHandler);
			});
			wrapper.on("mouseup" + NS + " mousecancel" + NS, function() {
				wrapper.off(MOUSEMOVE + NS, ".k-scheduler-header-all-day td, .k-scheduler-content td", mouseMoveHandler);
			});
		},
		_mouseDownSelection: function(e) {
			var which = e.which;
			var button = e.button;
			if (!(which && which === 3 || button && button == 2)) {
				if (e.ctrlKey) this._ctrlKey = e.ctrlKey;
				if (e.shiftKey) this._shiftKey = e.shiftKey;
				this._mouseDown = true;
				this._createSelection(e.currentTarget);
				if ($(e.currentTarget).hasClass("k-event")) this._selection.eventElement = e.currentTarget;
			}
			if (this.view().name !== "year" && kendo._activeElement() !== this.wrapper.get(0)) kendo.focusElement(this.wrapper);
			else this._select();
			if (this.toolbar) this.toolbar.find("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE);
		},
		_selectFirstSlot: function() {
			var firstAllDay = this.wrapper.find(".k-scheduler-header-all-day").find("td").first(), firstContent = this.wrapper.find(".k-scheduler-content").find("td").first(), firstSlot;
			if (firstAllDay.length > 0) firstSlot = firstAllDay;
			else if (firstContent.length > 0) firstSlot = firstContent;
			else firstSlot = this.wrapper.find(".k-scheduler-body").find(".k-link").first();
			this._createSelection(firstSlot);
		},
		_firstEvent: function() {
			var firstEventInAllDay = this.wrapper.find(".k-scheduler-header-wrap .k-event, .k-task").first(), firstEventInContent = this.wrapper.find(".k-scheduler-content .k-event").first(), firstEvent, allDayEvent, contentEvent;
			if (firstEventInAllDay.length > 0) if (firstEventInContent.length > 0) {
				allDayEvent = this.occurrenceByUid(firstEventInAllDay.data("uid"));
				contentEvent = this.occurrenceByUid(firstEventInContent.data("uid"));
				firstEvent = allDayEvent.start <= contentEvent.start ? firstEventInAllDay : firstEventInContent;
			} else firstEvent = firstEventInAllDay;
			else if (firstEventInContent) firstEvent = firstEventInContent;
			return firstEvent;
		},
		_initialFocus: function() {
			var firstEvent = this._firstEvent();
			if (this.options.selectable) if (firstEvent && firstEvent.length > 0) {
				this._createSelection(firstEvent);
				this._selection.eventElement = firstEvent[0];
			} else this._selectFirstSlot();
			else if (this.toolbar && this.toolbar.find("." + FOCUSEDSTATE).length === 0) this._focusToolbar();
			else if (this.toolbar) this.toolbar.find("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE);
		},
		_select: function() {
			const that = this, view = that.view(), wrapper = that.wrapper, selection = that._selection, oldSelection = that._old ? that._old.selection : null, oldEventsLength = that._old ? that._old.eventsLength : null;
			let current = view.current();
			if (!selection) return;
			if (current) {
				current.removeAttribute("id");
				wrapper.removeAttr("aria-activedescendant");
			}
			view.select(selection);
			that._selection.eventElement = null;
			current = view.current();
			if (current) {
				current.setAttribute("id", that._ariaId);
				wrapper.attr("aria-activedescendant", that._ariaId);
				const oldSelectionStart = that._old ? that._old.selectionStart.getTime() : null;
				const oldSelectionEnd = that._old ? that._old.selectionEnd.getTime() : null;
				const selectionRangeChanged = selection.start.getTime() !== oldSelectionStart || selection.end.getTime() !== oldSelectionEnd;
				if (oldSelection !== current || selection.events && oldEventsLength !== selection.events.length || selectionRangeChanged) {
					var currentUid = $(current).data("uid");
					if (that._old && currentUid && currentUid === $(that._old.selection).data("uid") && selection.events && that._old.eventsLength === selection.events.length) return;
					var events = that._selectedEvents();
					var slots = view._selectedSlots;
					that._old = {
						selection: current,
						eventsLength: events.length,
						selectionStart: selection.start,
						selectionEnd: selection.end
					};
					that.trigger(CHANGE, {
						start: selection.start,
						end: selection.end,
						events,
						slots,
						resources: view._resourceBySlot(selection)
					});
				}
			}
		},
		_selectedEvents: function() {
			var uids = this._selection.events;
			var length = uids.length;
			var idx = 0;
			var event;
			var events = [];
			for (; idx < length; idx++) {
				event = this.occurrenceByUid(uids[idx]);
				if (event) events.push(event);
			}
			return events;
		},
		_tapPosition: function(event, coordinate) {
			return /touch/.test(event.type) ? (event.originalEvent || event).changedTouches[0]["page" + coordinate] : event["page" + coordinate];
		},
		_touchMove: function(e) {
			var that = this;
			var content = that.wrapper.find(".k-scheduler-content");
			var verticalScroll = content[0].scrollHeight > content[0].clientHeight;
			var horizontalScroll = content[0].scrollWidth > content[0].clientWidth;
			var endY = that._tapPosition(e, "Y");
			var endX = that._tapPosition(e, "X");
			var scrollTop = content[0].scrollTop - Math.round(endY - that._touchPosY);
			var scrollLeft = content[0].scrollLeft - Math.round(endX - that._touchPosX);
			var applyVerticalScroll = verticalScroll && Math.abs(endY - that._touchPosY) > 10;
			var applyhorizontalScroll = horizontalScroll && Math.abs(endY - that._touchPosY) > 10;
			if (that._dragging || kendo.support.kineticScrollNeeded || !that._isTouch(e)) return;
			if (applyVerticalScroll || applyhorizontalScroll) {
				that._amplitude = Math.round(endY - that._touchPosY);
				that._touchPosY = endY;
				that._touchPosX = endX;
				content.animate({
					scrollTop,
					scrollLeft
				}, 0);
				that.view()._scrolling = true;
			}
		},
		_mouseMove: function(e) {
			var that = this;
			clearTimeout(that._moveTimer);
			if (that._isTouch(e)) return;
			that._moveTimer = setTimeout(function() {
				var view = that.view();
				var selection = that._selection;
				if (selection) {
					var slot = view.selectionByElement($(e.currentTarget));
					if (slot && selection.groupIndex === slot.groupIndex) {
						var startDate = slot.startDate();
						var endDate = slot.endDate();
						if (startDate >= selection.end) selection.backward = false;
						else if (endDate <= selection.start) selection.backward = true;
						if (selection.backward) selection.start = startDate;
						else selection.end = endDate;
						that._select();
					}
				}
			}, 5);
		},
		_viewByIndex: function(index) {
			var view;
			for (view in this.views) {
				if (!index) return view;
				index--;
			}
		},
		_keydownToolbar: function(e) {
			var key = e.keyCode;
			if (e.altKey && key === keys.DOWN && this.toolbar.find(".k-nav-current").hasClass(FOCUSEDSTATE)) {
				this._showCalendar();
				e.preventDefault();
				return;
			} else if (key === keys.DOWN) {
				if (this._selectedViewName === "year") this.view().calendar.focus();
				else if (document.activeElement !== this.element[0]) this.element.focus();
				e.preventDefault();
				return;
			}
		},
		_keydownView: function(e) {
			var key = e.keyCode, isModifier = key === 16 || key === 18 || key === 17 || key === 91 || key === 92, selection = this._selection, view = this.view(), editable = view.options.editable, arrowKeys = [
				keys.LEFT,
				keys.RIGHT,
				keys.UP,
				keys.DOWN
			], isRtl = kendo.support.isRtl(this.element), previous, content, cell;
			if (isModifier) return;
			if (!selection) return;
			if (key === keys.ENTER || key === keys.SPACEBAR) {
				if (view.activateMoreEvents && view.activateMoreEvents()) e.preventDefault();
				else if (key === keys.ENTER && selection.events.length && editable) {
					if (editable.update !== false) this.editEvent(selection.events[0]);
				}
			} else if ((key === keys.DELETE || key === keys.BACKSPACE) && editable !== false && editable.destroy !== false) this.removeEvent(selection.events[0]);
			else if (arrowKeys.indexOf(key) > -1) {
				previous = key === keys.UP || key === keys.LEFT && !isRtl || key === keys.RIGHT && isRtl;
				view._navigationKey = key;
				var movedToEvent = view.moveToEvent(selection, previous);
				view._navigationKey = null;
				if (movedToEvent) {
					this._select();
					if (document.activeElement !== this.element[0]) this.element.trigger("focus");
					e.preventDefault();
				}
			} else if (key === keys.HOME || key === keys.END) {
				e.preventDefault();
				content = this.view().content.eq(0);
				if (key === keys.HOME) cell = content.find(".k-scheduler-table td").first();
				else cell = content.find(".k-scheduler-table td").last();
				this.view()._scrollTo(cell[0], content[0]);
			}
		},
		_keydownShortcut: function(key) {
			var currentDate = /* @__PURE__ */ new Date(), timezone = this.options.timezone, editable = this.view().options.editable;
			if (key === 66 && !!this.view().toggleFullDay) this.view().toggleFullDay();
			else if (key === 67 && editable && editable.create !== false) this.addEvent(extend({}, {
				start: this.date(),
				end: this.date()
			}));
			else if (key === 84) {
				if (timezone) {
					var timezoneOffset = kendo.timezone.offset(currentDate, timezone);
					date = kendo.timezone.convert(currentDate, currentDate.getTimezoneOffset(), timezoneOffset);
				} else date = currentDate;
				if (!this.trigger("navigate", {
					view: this._selectedViewName,
					action: "today",
					date
				})) this.date(date);
			}
		},
		_keydownYearView: function(e) {
			var view = this.view(), selection = this._selection, key = e.keyCode;
			if (key === keys.TAB) return;
			if (key === keys.F10) {
				this._focusToolbar();
				e.preventDefault();
			} else {
				this.toolbar.find("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE);
				view.calendar.focus();
			}
			if (selection) this._adjustSelectedDate();
			e.preventDefault();
		},
		_keydownAgendaView: function(e) {
			var key = e.keyCode, view = this.view(), selection = this._selection, content, cell;
			if (view.move(selection, key)) {
				e.preventDefault();
				this.toolbar.find("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE);
				this._select();
			} else if (key === keys.HOME || key === keys.END) {
				e.preventDefault();
				content = this.view().content.eq(0);
				if (key === keys.HOME) cell = content.find(".k-scheduler-table td").first();
				else cell = content.find(".k-scheduler-table td").last();
				this.view()._scrollTo(cell[0], content[0]);
			}
		},
		_keydownChangeView: function(key) {
			var viewIndex = key - 49, viewByIndex;
			if (viewIndex === -1) viewIndex = 9;
			viewByIndex = this._viewByIndex(viewIndex);
			if (viewByIndex && !this.trigger("navigate", {
				view: viewByIndex,
				action: "changeView",
				date: this.date()
			})) this.view(viewByIndex);
		},
		_keydownChangeDate: function(key) {
			var isRtl = kendo.support.isRtl(this.element), direction = isRtl && key === keys.LEFT || !isRtl && key === keys.RIGHT ? "next" : "previous";
			if (direction === "next") date = this.view().nextDate();
			else date = this.view().previousDate();
			if (!this.trigger("navigate", {
				view: this._selectedViewName,
				action: direction,
				date
			})) {
				this.date(date);
				this._initialFocus();
				this._select();
			}
		},
		_keydown: function(e) {
			var key = e.keyCode, shortcutKeys = [
				66,
				67,
				84
			], toolbarIsFocused = $(e.target).closest(".k-toolbar").length > 0, altKey = e.altKey;
			this._ctrlKey = e.ctrlKey;
			this._shiftKey = e.shiftKey;
			if (key === keys.ESC && this.popup && this.popup.visible()) {
				this.popup.close();
				e.preventDefault();
				return;
			}
			if ((key === keys.LEFT || key === keys.RIGHT) && this._shiftKey) {
				this._keydownChangeDate(key);
				return;
			}
			if (altKey && key >= 48 && key <= 57) {
				this._keydownChangeView(key);
				return;
			}
			if (shortcutKeys.indexOf(key) > -1) {
				if (!$(e.target).hasClass("k-scheduler-search-input")) this._keydownShortcut(key);
				return;
			}
			if (toolbarIsFocused) this._keydownToolbar(e);
			else {
				if (this._selectedViewName === "year") {
					this._keydownYearView(e);
					return;
				}
				if (key === keys.F10) {
					this._focusToolbar();
					e.preventDefault();
					return;
				}
				if (this._selectedViewName === "agenda") {
					this._keydownAgendaView(e);
					return;
				}
				this._keydownView(e);
			}
		},
		_focusToolbar: function() {
			this.toolbar.find("[tabindex=0]").first().trigger("focus").addClass(FOCUSEDSTATE);
		},
		_createSelection: function(item) {
			var selection = this._selection, uid, slot;
			item = $(item);
			if (item.is(".k-event")) {
				uid = item.attr(kendo.attr("uid"));
				if (selection && selection.events.indexOf(uid) !== -1 && !this._ctrlKey) return;
			}
			if (!selection || !this._ctrlKey && !this._shiftKey) selection = this._selection = {
				events: [],
				groupIndex: 0
			};
			slot = this.view().selectionByElement(item);
			if (slot) selection.groupIndex = slot.groupIndex || 0;
			if (uid) slot = getOccurrenceByUid(this._data, uid);
			if (slot && slot.uid) uid = [slot.uid];
			this._updateSelection(slot, uid);
			this._adjustSelectedDate();
		},
		_updateSelection: function(dataItem, events, groupIndex) {
			var selection = this._selection;
			if (dataItem && selection) {
				var view = this.view();
				if (dataItem.uid) dataItem = view._updateEventForSelection(dataItem);
				if (this._shiftKey && selection.start && selection.end) {
					var backward = dataItem.end < selection.end;
					selection.end = dataItem.endDate ? dataItem.endDate() : dataItem.end;
					if (backward && view._timeSlotInterval) kendo.date.setTime(selection.end, -view._timeSlotInterval());
				} else {
					selection.start = dataItem.startDate ? dataItem.startDate() : dataItem.start;
					selection.end = dataItem.endDate ? dataItem.endDate() : dataItem.end;
				}
				if ("isDaySlot" in dataItem) selection.isAllDay = dataItem.isDaySlot;
				else selection.isAllDay = dataItem.isAllDay;
				if (groupIndex !== null && groupIndex !== undefined) selection.groupIndex = groupIndex;
				selection.index = dataItem.index;
				if (this._ctrlKey) {
					var indexOfEvent = events && events.length ? selection.events.indexOf(events[0]) : -1;
					if (indexOfEvent > -1) selection.events.splice(indexOfEvent, 1);
					else selection.events = selection.events.concat(events || []);
				} else selection.events = events || [];
			}
		},
		options: {
			name: "Scheduler",
			date: TODAY,
			editable: true,
			autoBind: true,
			snap: true,
			mobile: false,
			timezone: "",
			allDaySlot: true,
			min: new Date(1900, 0, 1),
			max: new Date(2099, 11, 31),
			toolbar: null,
			workWeekStart: 1,
			workWeekEnd: 5,
			workDays: null,
			showWorkHours: false,
			startTime: TODAY,
			endTime: TODAY,
			currentTimeMarker: {
				updateInterval: 1e4,
				useLocalTimezone: true
			},
			ongoingEvents: {
				cssClass: ONGOING_CLASS,
				enabled: false,
				updateInterval: 6e4,
				useLocalTimezone: true
			},
			footer: {},
			messages: {
				today: "Today",
				pdf: "Export to PDF",
				save: "Save",
				cancel: "Cancel",
				destroy: "Delete",
				resetSeries: "Reset Series",
				deleteWindowTitle: "Delete event",
				next: "Next",
				previous: "Previous",
				refresh: "Refresh",
				selectView: "Select view",
				ariaSlotLabel: "Selected from {0:t} to {1:t}",
				ariaEventLabel: {
					on: "on",
					at: "at",
					to: "to",
					allDay: "(all day)",
					prefix: ""
				},
				search: "Search...",
				moreEventsPopover: {
					eventsLabel: "Events",
					noEvents: "No events on this date."
				},
				views: {
					day: "Day",
					week: "Week",
					workWeek: "Work Week",
					agenda: "Agenda",
					month: "Month",
					timeline: "Timeline",
					timelineWeek: "Timeline Week",
					timelineWorkWeek: "Timeline Work Week",
					timelineMonth: "Timeline Month",
					year: "Year"
				},
				recurrenceMessages: {
					deleteWindowTitle: "Delete Recurring Item",
					resetSeriesWindowTitle: "Reset Series",
					deleteWindowOccurrence: "Delete current occurrence",
					deleteWindowSeries: "Delete the series",
					editWindowTitle: "Edit Recurring Item",
					editWindowOccurrence: "Edit current occurrence",
					editWindowSeries: "Edit the series"
				},
				editable: { confirmation: DELETECONFIRM },
				editor: {
					title: "Title",
					start: "Start",
					end: "End",
					allDayEvent: "All day",
					description: "Description",
					repeat: "Repeat",
					timezone: "Timezone",
					startTimezone: "Start timezone",
					endTimezone: "End timezone",
					separateTimezones: "Use separate start and end time zones",
					timezoneEditorTitle: "Timezones",
					timezoneEditorButton: "Time zone",
					timezoneTitle: "Time zones",
					noTimezone: "No timezone",
					editorTitle: "Event",
					newEvent: "New Event",
					editEvent: "Edit Event",
					resetTimezoneWindowTitle: "Reset Timezone",
					cancelTimezoneReset: "No",
					resetTimezone: "Yes"
				}
			},
			height: null,
			width: null,
			resources: [],
			group: {
				resources: [],
				orientation: "horizontal"
			},
			views: [],
			selectable: false,
			recurrenceRuleLabelTemplate: null
		},
		events: [
			REMOVE,
			EDIT,
			CANCEL,
			SAVE,
			"add",
			"dataBinding",
			"dataBound",
			"moveStart",
			"move",
			"moveEnd",
			"resizeStart",
			"resize",
			"resizeEnd",
			"navigate",
			CHANGE,
			"kendoKeydown"
		],
		destroy: function() {
			var that = this, element;
			Widget.fn.destroy.call(that);
			if (that.dataSource) {
				that.dataSource.unbind(CHANGE, that._refreshHandler);
				that.dataSource.unbind(PROGRESS, that._progressHandler);
				that.dataSource.unbind(ERROR, that._errorHandler);
			}
			if (that._resourceRefreshHandler) for (var idx = 0; idx < that.resources.length; idx++) {
				var resourceDS = that.resources[idx].dataSource;
				resourceDS.unbind(CHANGE, that._resourceRefreshHandler);
				resourceDS.unbind(PROGRESS, that._resourceProgressHandler);
				resourceDS.unbind(ERROR, that._resourceErrorHandler);
			}
			if (that.calendar) {
				that.calendar.destroy();
				that.popup.destroy();
			}
			if (that.view()) that.view().destroy();
			if (that._editor) that._editor.destroy();
			if (this._moveDraggable) this._moveDraggable.destroy();
			if (this._resizeDraggable) this._resizeDraggable.destroy();
			if (that.mediaQueryList) that.mediaQueryList.destroy();
			if (that._viewsSegmentedControl) {
				that._viewsSegmentedControl.destroy();
				that._viewsSegmentedControl = null;
			}
			if (that._viewsDropDownButton) {
				that._viewsDropDownButton.destroy();
				that._viewsDropDownButton = null;
			}
			if (that._toolbarResizeObserver) {
				that._toolbarResizeObserver.disconnect();
				that._toolbarResizeObserver = null;
			}
			element = that.element.add(that.wrapper).add(that.toolbar).add(that.popup);
			element.off(NS);
			clearTimeout(that._moveTimer);
			that._model = null;
			that.toolbar = null;
			that.element = null;
			$(window).off("resize" + NS, that._resizeHandler);
			kendo.destroy(that.wrapper);
		},
		setDataSource: function(dataSource) {
			this.options.dataSource = dataSource;
			this._dataSource();
			if (this.options.autoBind && dataSource.fetch) dataSource.fetch();
			else if (isArray(dataSource)) this.view(this._selectedView);
		},
		items: function() {
			var content = this.wrapper.find(".k-scheduler-content");
			var view = this.view();
			if (view && view.options.name === "agenda") return content.find(".k-task");
			else return content.find(".k-event").add(this.wrapper.find(".k-scheduler-header-wrap").find(".k-scheduler-header-all-day").siblings());
		},
		_movable: function() {
			var startSlot;
			var endSlot;
			var startResources;
			var startTime;
			var endTime;
			var event;
			var clonedEvent;
			var that = this;
			var originSlot;
			var originStartTime;
			var distance = 0;
			var clonedEvents = [];
			var cachedEvents = [];
			var isMobile = that._isMobile();
			var movable = that.options.editable && that.options.editable.move !== false;
			var resizable = that.options.editable && that.options.editable.resize !== false;
			if (movable || resizable && isMobile) {
				that._dragging = false;
				if (isMobile && kendo.support.mobileOS.android) distance = 5;
				that._moveDraggable = new kendo.ui.Draggable(that.element, {
					distance,
					filter: ".k-event",
					ignore: ".k-resize-handle, .k-readonly",
					holdToDrag: isMobile,
					autoScroll: true
				});
				if (movable) that._moveDraggable.bind("dragstart", function(e) {
					var view = that.view();
					var eventElement = e.currentTarget;
					var isTouch = that._isTouch(e);
					that._dragging = true;
					if (!view.options.editable || view.options.editable.move === false) {
						that._dragging = false;
						e.preventDefault();
						return;
					}
					if (isTouch && !eventElement.hasClass("k-event-active")) {
						that._dragging = false;
						that.element.find(".k-event-active").removeClass("k-event-active");
						e.preventDefault();
						return;
					}
					event = that.occurrenceByUid(eventElement.attr(kendo.attr("uid")));
					if (event && event.isReadonly) {
						that._dragging = false;
						e.preventDefault();
						return;
					}
					clonedEvent = event.clone();
					event.clone();
					clonedEvent.update(view._eventOptionsForMove(clonedEvent));
					clonedEvent.inverseColor = that._isInverseColor(eventElement);
					clonedEvents = [];
					if (that._selection) {
						var events = that._selection.events;
						for (var i = 0; i < events.length; i++) {
							var selectedEvent = that.occurrenceByUid(events[i]);
							if (selectedEvent.isReadonly) continue;
							var evtClone = selectedEvent.clone();
							var evtCloneElement = this.element.find("div.k-event[data-uid=\"" + evtClone.uid + "\"]").eq(0);
							evtClone.update(view._eventOptionsForMove(evtClone));
							if (evtCloneElement.length) evtClone.inverseColor = that._isInverseColor(evtCloneElement);
							clonedEvents.push(evtClone);
						}
					} else clonedEvents.push(clonedEvent);
					startSlot = view._slotByPosition(e.x.startLocation, e.y.startLocation);
					startResources = view._resourceBySlot(startSlot);
					const eventUtcStart = kendo.date.toUtcTime(event.start);
					let snapOffset = 0;
					if (that.options.snap && !startSlot.isDaySlot) {
						const slotDuration = startSlot.end - startSlot.start;
						if (slotDuration > 0) snapOffset = ((eventUtcStart - startSlot.start) % slotDuration + slotDuration) % slotDuration;
					}
					originStartTime = startTime = startSlot.startOffset(e.x.startLocation, e.y.startLocation, that.options.snap) + snapOffset;
					endSlot = startSlot;
					originSlot = startSlot;
					if (!startSlot || that.trigger("moveStart", { event })) e.preventDefault();
				}).bind("drag", function(e) {
					var view = that.view();
					var slot = view._slotByPosition(e.x.location, e.y.location);
					var distance;
					var range;
					var i;
					if (!slot) return;
					endTime = slot.startOffset(e.x.location, e.y.location, that.options.snap);
					if (slot.isDaySlot !== startSlot.isDaySlot) if (slot.isDaySlot !== originSlot.isDaySlot) {
						var slotIndex = $(startSlot.element).index();
						var targetSlotElement = $(slot.element).parent().children().eq(slotIndex);
						startSlot = view._slotByPosition(targetSlotElement.offset().left, targetSlotElement.offset().top);
						startTime = startSlot.startOffset(e.x.location, e.y.location, true);
						cachedEvents = clonedEvents.map(function(event) {
							return event.clone();
						});
						for (i = 0; i < clonedEvents.length; i++) if (clonedEvents[i].isAllDay != slot.isDaySlot) {
							clonedEvents[i].isAllDay = slot.isDaySlot;
							clonedEvents[i].end = kendo.date.getDate(clonedEvents[i].start);
							clonedEvents[i].start = kendo.date.getDate(clonedEvents[i].start);
							if (!slot.isDaySlot) {
								kendo.date.setTime(clonedEvents[i].start, kendo.date.getMilliseconds(view.startTime()));
								kendo.date.setTime(clonedEvents[i].end, kendo.date.getMilliseconds(view.startTime()) + view._timeSlotInterval());
							}
						}
					} else {
						startSlot = $.extend(true, {}, originSlot);
						startTime = originStartTime;
						clonedEvents = cachedEvents;
					}
					distance = endTime - startTime;
					for (i = 0; i < clonedEvents.length; i++) view._updateMoveHint(clonedEvents[i], slot.groupIndex, distance);
					range = moveEventRange(clonedEvent, distance);
					if (!that.trigger("move", {
						event,
						slot: {
							element: slot.element,
							start: slot.startDate(),
							end: slot.endDate(),
							isDaySlot: slot.isDaySlot
						},
						resources: view._resourceBySlot(slot),
						start: range.start,
						end: range.end
					})) endSlot = slot;
					else for (i = 0; i < clonedEvents.length; i++) view._updateMoveHint(clonedEvents[i], slot.groupIndex, distance);
				}).bind("dragend", function(e) {
					that.view()._removeMoveHint();
					var distance = endTime - startTime;
					var range = moveEventRange(clonedEvent, distance);
					var start = range.start;
					var end = range.end;
					that._dragging = false;
					var endResources = that.view()._resourceBySlot(endSlot);
					if (!that.trigger("moveEnd", {
						event,
						slot: {
							element: endSlot.element,
							start: endSlot.startDate(),
							end: endSlot.endDate()
						},
						start,
						end,
						resources: endResources
					}) && (event.start.getTime() !== start.getTime() || event.end.getTime() !== end.getTime() || originSlot.isDaySlot !== endSlot.isDaySlot || kendo.stringify(endResources) !== kendo.stringify(startResources))) {
						that._isMultiDrag = clonedEvents.length > 1;
						for (var i = 0; i < clonedEvents.length; i++) {
							var evt = clonedEvents[i];
							range = moveEventRange(evt, distance);
							var updatedEventOptions = that.view()._eventOptionsForMove(evt);
							var eventOptions = $.extend({
								isAllDay: evt.isAllDay,
								start: range.start,
								end: range.end
							}, updatedEventOptions, endResources);
							that._updateEvent(null, evt, eventOptions);
						}
						if (that._isMultiDrag) {
							that.dataSource.sync();
							that._isMultiDrag = false;
						}
					}
					e.currentTarget.removeClass("k-event-active");
					this.cancelHold();
					clonedEvents = [];
					cachedEvents = [];
				}).bind("dragcancel", function() {
					that.view()._removeMoveHint();
					this.cancelHold();
					clonedEvents = [];
					cachedEvents = [];
				});
				that._moveDraggable.bind("hold", function(e) {
					if (that._isTouch(e)) {
						that.element.find(".k-event-active").removeClass("k-event-active");
						if (that.options.selectable) that._createSelection(e.currentTarget);
						e.currentTarget.addClass("k-event-active");
					}
				});
			}
		},
		_resizable: function() {
			var startTime;
			var endTime;
			var event;
			var clonedEvent;
			var slot;
			var that = this;
			var distance = 0;
			const isRtl = kendo.support.isRtl(that.element);
			function direction(handle) {
				var directions = {
					"k-resize-e": isRtl ? "west" : "east",
					"k-resize-w": isRtl ? "east" : "west",
					"k-resize-n": "north",
					"k-resize-s": "south"
				};
				for (var key in directions) if (handle.hasClass(key)) return directions[key];
			}
			if (that._isMobile() && kendo.support.mobileOS.android) distance = 5;
			that._resizeDraggable = new kendo.ui.Draggable(that.element, {
				distance,
				filter: ".k-resize-handle",
				autoScroll: true,
				dragstart: function(e) {
					var uid = $(e.currentTarget).closest(".k-event").attr(kendo.attr("uid"));
					var view = that.view();
					that._dragging = true;
					event = that.occurrenceByUid(uid);
					if (event && event.isReadonly) {
						that._dragging = false;
						e.preventDefault();
						return;
					}
					clonedEvent = event.clone();
					view._updateEventForResize(clonedEvent);
					slot = view._slotByPosition(e.x.startLocation, e.y.startLocation);
					if (that.trigger("resizeStart", { event })) e.preventDefault();
					startTime = kendo.date.toUtcTime(clonedEvent.start);
					endTime = kendo.date.toUtcTime(clonedEvent.end);
				},
				drag: function(e) {
					if (!slot) return;
					var dir = direction($(e.currentTarget));
					var view = that.view();
					var currentSlot = view._slotByPosition(e.x.location, e.y.location);
					if (!currentSlot || slot.groupIndex != currentSlot.groupIndex) return;
					slot = currentSlot;
					var originalStart = startTime;
					var originalEnd = endTime;
					if (dir == "south") {
						if (!slot.isDaySlot && slot.end - kendo.date.toUtcTime(clonedEvent.start) >= view._timeSlotInterval()) if (clonedEvent.isAllDay) endTime = slot.startOffset(e.x.location, e.y.location, that.options.snap);
						else endTime = slot.endOffset(e.x.location, e.y.location, that.options.snap);
					} else if (dir == "north") {
						if (!slot.isDaySlot && kendo.date.toUtcTime(clonedEvent.end) - slot.start >= view._timeSlotInterval()) startTime = slot.startOffset(e.x.location, e.y.location, that.options.snap);
					} else if (dir == "east") {
						if (slot.isDaySlot && kendo.date.toUtcTime(kendo.date.getDate(slot.endDate())) >= kendo.date.toUtcTime(kendo.date.getDate(clonedEvent.start))) if (clonedEvent.isAllDay) endTime = slot.startOffset(e.x.location, e.y.location, that.options.snap);
						else endTime = slot.endOffset(e.x.location, e.y.location, that.options.snap);
						else if (!slot.isDaySlot && slot.end - kendo.date.toUtcTime(clonedEvent.start) >= view._timeSlotInterval()) endTime = slot.endOffset(e.x.location, e.y.location, that.options.snap);
					} else if (dir == "west") {
						if (slot.isDaySlot && kendo.date.toUtcTime(kendo.date.getDate(clonedEvent.end)) >= kendo.date.toUtcTime(kendo.date.getDate(slot.startDate()))) startTime = slot.startOffset(e.x.location, e.y.location, that.options.snap);
						else if (!slot.isDaySlot && kendo.date.toUtcTime(clonedEvent.end) - slot.start >= view._timeSlotInterval()) startTime = slot.startOffset(e.x.location, e.y.location, that.options.snap);
					}
					if (!that.trigger("resize", {
						event,
						slot: {
							element: slot.element,
							start: slot.startDate(),
							end: slot.endDate()
						},
						start: kendo.timezone.toLocalDate(startTime),
						end: kendo.timezone.toLocalDate(endTime),
						resources: view._resourceBySlot(slot)
					})) view._updateResizeHint(clonedEvent, slot.groupIndex, startTime, endTime);
					else {
						startTime = originalStart;
						endTime = originalEnd;
					}
				},
				dragend: function(e) {
					var dragHandle = $(e.currentTarget);
					var start = new Date(clonedEvent.start.getTime());
					var end = new Date(clonedEvent.end.getTime());
					var dir = direction(dragHandle);
					that._dragging = false;
					that.view()._removeResizeHint();
					if (dir == "south") end = kendo.timezone.toLocalDate(endTime);
					else if (dir == "north") start = kendo.timezone.toLocalDate(startTime);
					else if (dir == "east") if (slot.isDaySlot) end = kendo.date.getDate(kendo.timezone.toLocalDate(endTime));
					else end = kendo.timezone.toLocalDate(endTime);
					else if (dir == "west") if (slot.isDaySlot) {
						start = new Date(kendo.timezone.toLocalDate(startTime));
						start.setHours(0);
						start.setMinutes(0);
					} else start = kendo.timezone.toLocalDate(startTime);
					if (!that.trigger("resizeEnd", {
						event,
						slot: {
							element: slot.element,
							start: slot.startDate(),
							end: slot.endDate()
						},
						start,
						end,
						resources: that.view()._resourceBySlot(slot)
					}) && end.getTime() >= start.getTime()) {
						if (clonedEvent.start.getTime() != start.getTime() || clonedEvent.end.getTime() != end.getTime()) {
							that.view()._updateEventForResize(event);
							that._updateEvent(dir, event, {
								start,
								end
							});
						}
					}
					slot = null;
					event = null;
				},
				dragcancel: function() {
					that._dragging = false;
					that.view()._removeResizeHint();
					slot = null;
					event = null;
				}
			});
		},
		_updateEvent: function(dir, event, eventInfo) {
			var that = this;
			var updateEvent = function(event, callback) {
				var start;
				try {
					that._preventRefresh = true;
					event.update(eventInfo);
					that._convertDates(event);
					start = event.start;
					if (dir && event.duration() % MS_PER_DAY === 0 && start.getHours() === 0 && start.getMinutes() === 0 && start.getSeconds() === 0 && start.getMilliseconds() === 0) event.set("isAllDay", true);
				} finally {
					that._preventRefresh = false;
				}
				if (!that.trigger(SAVE, { event })) {
					if (callback) callback();
					if (!that._isMultiDrag) that.dataSource.sync();
				}
			};
			var recurrenceHead = function(event) {
				if (event.recurrenceRule) return that.dataSource.getByUid(event.uid);
				else return that.dataSource.get(event.recurrenceId);
			};
			var updateSeries = function() {
				var head = recurrenceHead(event);
				if (dir == "south" || dir == "north") {
					if (eventInfo.start) {
						var start = kendo.date.getDate(head.start);
						kendo.date.setTime(start, getMilliseconds(eventInfo.start));
						eventInfo.start = start;
					}
					if (eventInfo.end) {
						var end = kendo.date.getDate(head.end);
						kendo.date.setTime(end, getMilliseconds(eventInfo.end));
						eventInfo.end = end;
					}
				}
				that.dataSource._removeExceptions(head);
				updateEvent(head);
			};
			var updateOccurrence = function() {
				var head = recurrenceHead(event);
				var eventUid;
				var callback = function() {
					that._convertDates(head);
					if (that._selection) that._selection.events.push(eventUid);
				};
				var exception = head.toOccurrence({
					start: event.start,
					end: event.end
				});
				eventUid = exception.uid;
				updateEvent(that.dataSource.add(exception), callback);
			};
			if (event.recurrenceRule || event.isOccurrence()) {
				var recurrenceMessages = that.options.messages.recurrenceMessages;
				that._showRecurringDialog(event, updateOccurrence, updateSeries, {
					title: recurrenceMessages.editWindowTitle,
					text: recurrenceMessages.editRecurring ? recurrenceMessages.editRecurring : EDITRECURRING,
					occurrenceText: recurrenceMessages.editWindowOccurrence,
					seriesText: recurrenceMessages.editWindowSeries
				});
			} else updateEvent(that.dataSource.getByUid(event.uid));
		},
		_modelForContainer: function(container) {
			container = $(container).closest("[" + kendo.attr("uid") + "]");
			return this.dataSource.getByUid(container.attr(kendo.attr("uid")));
		},
		showDialog: function(options) {
			this.toolbar.find("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE);
			this._editor.showDialog(options);
		},
		focus: function() {
			this.wrapper.trigger("focus");
		},
		_confirmation: function(callback, model, isResetSeries) {
			var editable = this.options.editable;
			if (editable === true || editable.confirmation !== false) {
				var messages = this.options.messages;
				var title = messages.deleteWindowTitle;
				var text = typeof editable.confirmation === STRING ? editable.confirmation : messages.editable.confirmation;
				if (this._isEditorOpened() && model.isRecurring()) {
					var recurrenceMessages = this.options.messages.recurrenceMessages;
					title = recurrenceMessages.deleteWindowTitle;
					if (model.isException() || model.isNew()) text = recurrenceMessages.deleteRecurringConfirmation ? recurrenceMessages.deleteRecurringConfirmation : DELETERECURRINGCONFIRM;
					else text = recurrenceMessages.deleteSeriesConfirmation ? recurrenceMessages.deleteSeriesConfirmation : DELETESERIESCONFIRM;
					if (isResetSeries) {
						title = recurrenceMessages.resetSeriesWindowTitle;
						text = recurrenceMessages.resetSeriesConfirmation ? recurrenceMessages.resetSeriesConfirmation : RESETSERIESCONFIRM;
					}
				}
				var buttons = [{
					name: "destroy",
					text: isResetSeries ? messages.resetSeries : messages.destroy,
					click: function() {
						callback();
					}
				}];
				if (!(this._isMobile() && kendo.Pane)) buttons.push({
					name: "canceledit",
					text: messages.cancel,
					click: function() {
						callback(true);
					}
				});
				this._unbindResize();
				this.showDialog({
					model,
					text,
					title,
					buttons
				});
				this._bindResize();
			} else callback();
		},
		addEvent: function(eventInfo) {
			var editable = this._editor.editable;
			var dataSource = this.dataSource;
			var event;
			eventInfo = eventInfo || {};
			if (!this.trigger("add", { event: eventInfo }) && (editable && editable.end() || !editable)) {
				this.cancelEvent();
				if (eventInfo && eventInfo.toJSON) eventInfo = eventInfo.toJSON();
				event = dataSource.add(eventInfo);
				if (event) {
					this.cancelEvent();
					this._editEvent(event);
				}
			}
		},
		saveEvent: function() {
			var that = this;
			var editor = that._editor;
			var dataSource = that.dataSource;
			if (!editor) return;
			var editable = editor.editable;
			var container = editor.container;
			var model = that._modelForContainer(container);
			var events, i, event;
			if (container && editable && editor.end() && !that.trigger(SAVE, {
				container,
				event: model
			})) {
				if (!model.isOccurrence() && !!model.recurrenceException && !model.recurrenceRule) {
					events = dataSource.data();
					for (i = events.length - 1; i >= 0; i -= 1) {
						event = events[i];
						if (event && event.recurrenceId === model.id) dataSource.remove(event);
					}
					model.set("recurrenceException", "");
				}
				if (!model.dirty && !model.isOccurrence()) that._convertDates(model, "remove");
				dataSource.sync();
			}
		},
		cancelEvent: function() {
			var editor = this._editor;
			var container = editor.container;
			var model;
			if (container) {
				model = this._modelForContainer(container);
				if (model && model.isOccurrence()) {
					this._convertDates(model, "remove");
					this._convertDates(this.dataSource.get(model.recurrenceId), "remove");
				}
				this.dataSource.cancelChanges(model);
				editor.close();
			}
		},
		editEvent: function(uid) {
			var model = typeof uid == "string" ? this.occurrenceByUid(uid) : uid;
			if (!model || model.isReadonly) return;
			this.cancelEvent();
			if (model.isRecurring()) this._editRecurringDialog(model);
			else this._editEvent(model);
		},
		_editEvent: function(model) {
			this._preventRefresh = true;
			this._unbindResize();
			this._createPopupEditor(model);
			this.toolbar.find("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE);
			this._bindResize();
		},
		_editRecurringDialog: function(model) {
			var that = this;
			var editOccurrence = function() {
				if (model.isException()) that._editEvent(model);
				else that.addEvent(model);
			};
			var editSeries = function() {
				if (model.recurrenceId) model = that.dataSource.get(model.recurrenceId);
				that._editEvent(model);
			};
			var recurrenceMessages = that.options.messages.recurrenceMessages;
			that._showRecurringDialog(model, editOccurrence, editSeries, {
				title: recurrenceMessages.editWindowTitle,
				text: recurrenceMessages.editRecurring ? recurrenceMessages.editRecurring : EDITRECURRING,
				occurrenceText: recurrenceMessages.editWindowOccurrence,
				seriesText: recurrenceMessages.editWindowSeries
			});
		},
		_showRecurringDialog: function(model, editOccurrence, editSeries, messages) {
			var editable = this.options.editable;
			var editRecurringMode = isPlainObject(editable) ? editable.editRecurringMode : "dialog";
			if (editRecurringMode === "occurrence" || this._isMultiDrag) editOccurrence();
			else if (editRecurringMode === "series") editSeries();
			else {
				this._unbindResize();
				this.showDialog({
					model,
					title: messages.title,
					text: messages.text,
					buttons: [{
						text: messages.occurrenceText,
						click: editOccurrence
					}, {
						text: messages.seriesText,
						click: editSeries
					}]
				});
				this._bindResize();
			}
		},
		_createButton: function(command) {
			var template = command.template || COMMANDBUTTONTMPL, commandName = typeof command === STRING ? command : command.name || command.text, options = {
				className: "k-scheduler-" + (commandName || "").replace(/\s/g, ""),
				text: commandName,
				attr: ""
			};
			if (!commandName && !(isPlainObject(command) && command.template)) throw new Error("Custom commands should have name specified");
			if (isPlainObject(command)) {
				if (command.className) command.className += " " + options.className;
				if (commandName === "edit" && isPlainObject(command.text)) {
					command = extend(true, {}, command);
					command.text = command.text.edit;
				}
				options = extend(true, options, defaultCommands[commandName], command);
			} else options = extend(true, options, defaultCommands[commandName]);
			return kendo.template(template)(options);
		},
		_convertDates: function(model, method) {
			var timezone = this.dataSource.reader.timezone;
			var startTimezone = model.startTimezone;
			var endTimezone = model.endTimezone;
			var start = model.start;
			var end = model.start;
			method = method || "apply";
			startTimezone = startTimezone || endTimezone;
			endTimezone = endTimezone || startTimezone;
			if (startTimezone) {
				if (timezone) if (method === "apply") {
					start = kendo.timezone.convert(model.start, timezone, startTimezone);
					end = kendo.timezone.convert(model.end, timezone, endTimezone);
				} else {
					start = kendo.timezone.convert(model.start, startTimezone, timezone);
					end = kendo.timezone.convert(model.end, endTimezone, timezone);
				}
				else {
					start = kendo.timezone[method](model.start, startTimezone);
					end = kendo.timezone[method](model.end, endTimezone);
				}
				model._set("start", start);
				model._set("end", end);
			}
		},
		_createEditor: function() {
			var that = this;
			var editor;
			if (this._isMobile() && kendo.Pane) editor = that._editor = new MobileEditor(this.wrapper, extend({}, this.options, {
				target: this,
				timezone: that.dataSource.reader.timezone,
				resources: that.resources,
				createButton: this._createButton.bind(this)
			}));
			else editor = that._editor = new PopupEditor(this.wrapper, extend({}, this.options, {
				target: this,
				createButton: this._createButton.bind(this),
				timezone: that.dataSource.reader.timezone,
				resources: that.resources
			}));
			editor.bind("cancel", function(e) {
				if (that.trigger("cancel", {
					container: e.container,
					event: e.model
				})) {
					e.preventDefault();
					return;
				}
				that._preventRefresh = false;
				that.cancelEvent();
				if (that._attemptRefresh) that.refresh();
				var todayButton = !that.options.selectable && that.toolbar.find("[ref-nav-today]").first();
				if (todayButton && todayButton.length) {
					that.toolbar.find("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE);
					todayButton.trigger("focus").addClass(FOCUSEDSTATE);
				} else that.focus();
			});
			editor.bind("edit", function(e) {
				if (that.trigger(EDIT, {
					container: e.container,
					event: e.model
				})) e.preventDefault();
			});
			editor.bind("save", function() {
				that._preventRefresh = false;
				that.saveEvent();
			});
			editor.bind("remove", function(e) {
				that._preventRefresh = false;
				that.removeEvent(e.model);
			});
			editor.bind("resetSeries", function(e) {
				that._confirmation(function(cancel) {
					that._preventRefresh = false;
					if (!cancel) {
						that.dataSource._removeExceptions(e.model);
						that.saveEvent();
					}
				}, e.model, true);
			});
		},
		_createPopupEditor: function(model) {
			var editor = this._editor;
			if (!model.isNew() || model.isOccurrence()) {
				if (model.isOccurrence()) this._convertDates(model.recurrenceId ? this.dataSource.get(model.recurrenceId) : model);
				this._convertDates(model);
			}
			this.editable = editor.editEvent(model);
		},
		removeEvent: function(uid) {
			var that = this, model = typeof uid == "string" ? that.occurrenceByUid(uid) : uid;
			if (!model || model.isReadonly) return;
			if (model.isRecurring()) that._deleteRecurringDialog(model);
			else that._confirmation(function(cancel) {
				if (!cancel) that._removeEvent(model);
			}, model);
		},
		occurrenceByUid: function(uid) {
			var occurrence = this.dataSource.getByUid(uid);
			if (!occurrence) occurrence = getOccurrenceByUid(this._data, uid);
			return occurrence;
		},
		occurrencesInRange: function(start, end) {
			return new kendo.data.Query(this._data).filter({
				logic: "or",
				filters: [{
					logic: "and",
					filters: [
						{
							field: "start",
							operator: "gte",
							value: start
						},
						{
							field: "end",
							operator: "gte",
							value: start
						},
						{
							field: "start",
							operator: "lt",
							value: end
						}
					]
				}, {
					logic: "and",
					filters: [{
						field: "start",
						operator: "lte",
						value: start
					}, {
						field: "end",
						operator: "gt",
						value: start
					}]
				}]
			}).toArray();
		},
		_removeEvent: function(model) {
			if (!this.trigger(REMOVE, { event: model })) {
				if (this.dataSource.remove(model)) this.dataSource.sync();
			}
		},
		_deleteRecurringDialog: function(model) {
			var that = this;
			var currentModel = model;
			var editable = that.options.editable;
			var deleteOccurrence;
			var deleteSeries;
			var createException;
			var deleteOccurrenceConfirmation;
			var deleteSeriesConfirmation;
			var createExceptionConfirmation;
			var editRecurringMode = isPlainObject(editable) ? editable.editRecurringMode : "dialog";
			deleteOccurrence = function() {
				var occurrence = currentModel.recurrenceId ? currentModel : currentModel.toOccurrence();
				var head = that.dataSource.get(occurrence.recurrenceId);
				that._convertDates(head);
				that._removeEvent(occurrence);
			};
			deleteSeries = function() {
				if (currentModel.recurrenceId) currentModel = that.dataSource.get(currentModel.recurrenceId);
				that._removeEvent(currentModel);
			};
			createException = function() {
				that.dataSource.remove(currentModel);
				that.dataSource.sync();
			};
			if (editRecurringMode != "dialog" || that._isEditorOpened()) {
				deleteOccurrenceConfirmation = function() {
					that._confirmation(function(cancel) {
						if (!cancel) deleteOccurrence();
					}, currentModel);
				};
				deleteSeriesConfirmation = function() {
					that._confirmation(function(cancel) {
						if (!cancel) deleteSeries();
					}, currentModel);
				};
				createExceptionConfirmation = function() {
					that._confirmation(function(cancel) {
						if (!cancel) createException();
					}, currentModel);
				};
			}
			var seriesCallback = deleteSeriesConfirmation || deleteSeries;
			var occurrenceCallback = deleteOccurrenceConfirmation || deleteOccurrence;
			var exeptionCallback = createExceptionConfirmation || createException;
			if (that._isEditorOpened()) if (model.isException()) occurrenceCallback();
			else if (model.isNew()) exeptionCallback();
			else seriesCallback();
			else {
				var recurrenceMessages = that.options.messages.recurrenceMessages;
				that._showRecurringDialog(model, occurrenceCallback, seriesCallback, {
					title: recurrenceMessages.deleteWindowTitle,
					text: recurrenceMessages.deleteRecurring ? recurrenceMessages.deleteRecurring : DELETERECURRING,
					occurrenceText: recurrenceMessages.deleteWindowOccurrence,
					seriesText: recurrenceMessages.deleteWindowSeries
				});
			}
		},
		_isEditorOpened: function() {
			return !!this._editor.container;
		},
		_unbindView: function(view) {
			view.destroy();
		},
		_bindView: function(view) {
			var that = this;
			if (that.options.editable) {
				if (that._viewRemoveHandler) view.unbind(REMOVE, that._viewRemoveHandler);
				that._viewRemoveHandler = function(e) {
					that.removeEvent(e.uid);
				};
				view.bind(REMOVE, that._viewRemoveHandler);
				if (that._viewAddHandler) view.unbind(ADD, that._viewAddHandler);
				that._viewAddHandler = function(e) {
					that.addEvent(e.eventInfo);
				};
				view.bind(ADD, this._viewAddHandler);
				if (that._viewEditHandler) view.unbind(EDIT, that._viewEditHandler);
				that._viewEditHandler = function(e) {
					that.editEvent(e.uid);
				};
				view.bind(EDIT, this._viewEditHandler);
			}
			if (that._viewNavigateHandler) view.unbind("navigate", that._viewNavigateHandler);
			that._viewNavigateHandler = function(e) {
				if (e.action) {
					if (!that.trigger("navigate", {
						view: e.view,
						isWorkDay: e.isWorkDay,
						action: e.action,
						date: e.date
					})) that.date(e.date);
				} else if (e.view) {
					var switchWorkDay = "isWorkDay" in e;
					var action = switchWorkDay ? "changeWorkDay" : "changeView";
					if (!that.trigger("navigate", {
						view: e.view,
						isWorkDay: e.isWorkDay,
						action,
						date: e.date
					})) {
						if (switchWorkDay) that._workDayMode = e.isWorkDay;
						that._selectView(e.view);
						that.date(e.date);
					}
				}
			};
			view.bind("navigate", that._viewNavigateHandler);
			if (that._viewActivateHandler) view.unbind("activate", that._viewActivateHandler);
			that._viewActivateHandler = function() {
				var view = this;
				if (that._selection) {
					view.constrainSelection(that._selection);
					if ($(document.activeElement).closest(".k-scheduler-toolbar").length === 0) if (document.activeElement !== that.wrapper[0]) that.element.trigger("focus");
					else that._select();
					that._adjustSelectedDate();
				}
			};
			view.bind("activate", that._viewActivateHandler);
		},
		_selectView: function(name) {
			var that = this;
			if (name && that.views[name]) {
				if (that._selectedView) that._unbindView(that._selectedView);
				that._selectedView = that._renderView(name);
				that._selectedViewName = name;
				if (this._initialSize) {
					this._initialSize = false;
					this._onMediaChange(window.matchMedia(MIN_SCREEN));
				}
				if (that._viewsCount > 1 && !that._isMobile()) {
					that.toolbar.find(".k-views-dropdown").val(name);
					if (that._viewsSegmentedControl) that._viewsSegmentedControl.value(name);
				} else if (that._viewsCount > 1) that.toolbar.find(".k-scheduler-mobile-views").find("[value=" + name.replace(/\./g, "\\.") + "]").prop("selected", "selected");
			}
		},
		view: function(name) {
			var that = this;
			if (name) {
				if (name === "year") that.wrapper.removeAttr("tabindex");
				else that.wrapper.attr("tabindex", 0);
				that._selectView(name);
				that.rebind();
				return;
			}
			return that._selectedView;
		},
		viewName: function() {
			return this.view().name;
		},
		_renderView: function(name) {
			var view = this._initializeView(name);
			this._bindView(view);
			if (kendo.support.mouseAndTouchPresent || kendo.support.pointers) {
				view.content.css("-ms-touch-action", "pinch-zoom");
				view.content.css("touch-action", "pinch-zoom");
			}
			this._model.set("formattedDate", view.dateForTitle());
			this._model.set("formattedShortDate", view.shortDateForTitle());
			this._model.set("formattedMobileDate", view.mobileDateForTitle ? view.mobileDateForTitle() : view.shortDateForTitle());
			this._model.set("formattedYear", view.mobileYearForTitle ? view.mobileYearForTitle() : kendo.format("{0:yyyy}", view.startDate()));
			this._updateToolbarDate();
			if (this._viewsDropDownButton) {
				var viewTitle = this.views[name] ? this.views[name].title : name;
				this._viewsDropDownButton.element.find(".k-button-text").first().text(viewTitle);
			}
			return view;
		},
		resize: function(force) {
			var size = this.getSize();
			var currentSize = this._size;
			var view = this.view();
			if (!view || !view.groups) return;
			if (force || !currentSize || size.width !== currentSize.width || size.height !== currentSize.height) {
				this.refresh({ action: "resize" });
				this._size = size;
			}
		},
		_adjustSelectedDate: function() {
			var date = this._model.selectedDate, selection = this._selection, start = selection.start;
			if (start && !kendo.date.isInDateRange(date, getDate(start), getDate(selection.end))) date.setFullYear(start.getFullYear(), start.getMonth(), start.getDate());
		},
		_initializeView: function(name) {
			var view = this.views[name];
			if (view) {
				var isSettings = isPlainObject(view), overrideOptions = {}, type = view.type;
				if (typeof type === STRING) type = kendo.getter(view.type)(window);
				if (isSettings && view.workDays && view.workDays.length) overrideOptions.workDays = view.workDays;
				if (type) view = new type(this.wrapper, trimOptions(extend(true, {}, this.options, isSettings ? view : {}, {
					resources: this.resources,
					date: this.date(),
					startTime: kendo.parseDate(view.startTime) || kendo.parseDate(this.options.startTime),
					endTime: kendo.parseDate(view.endTime) || kendo.parseDate(this.options.endTime),
					showWorkHours: this._workDayMode
				}), overrideOptions));
				else throw new Error("There is no such view");
			}
			return view;
		},
		_views: function() {
			var views = this.options.views;
			var view;
			var defaultView;
			var selected;
			var isSettings;
			var name;
			var type;
			var idx;
			var length;
			this.views = {};
			this._viewsCount = 0;
			for (idx = 0, length = views.length; idx < length; idx++) {
				var hasType = false;
				view = views[idx];
				isSettings = isPlainObject(view);
				if (isSettings) {
					type = name = view.type ? view.type : view;
					if (typeof type !== STRING) {
						name = view.name || view.title;
						hasType = true;
					}
				} else {
					type = name = view;
					view = {};
				}
				defaultView = defaultViews[name];
				if (defaultView && !hasType) {
					view.type = defaultView.type;
					defaultView.title = this.options.messages.views[name];
					if (defaultView.type === "day") defaultView.messages = { allDay: this.options.messages.allDay };
					else if (defaultView.type === "agenda") defaultView.messages = {
						event: this.options.messages.event,
						date: this.options.messages.date,
						time: this.options.messages.time
					};
				}
				view = extend({ title: name }, defaultView, isSettings ? view : {});
				if (name) {
					this.views[name] = view;
					this._viewsCount++;
					if (!selected || view.selected) selected = name;
				}
			}
			if (selected) this._selectedViewName = selected;
		},
		rebind: function() {
			var that = this, resources = that.resources, resourceFetchArray = [];
			if (that._preventRebind) {
				that._preventRebind = false;
				return;
			}
			if (that.options.autoBind === false && resources && resources.length > 0) {
				resources.forEach(function(resource) {
					if (resource.dataSource.data().length === 0) {
						that._preventRebind = true;
						resourceFetchArray.push(resource.dataSource.fetch());
					}
				});
				$.when.apply(null, resourceFetchArray).then(function() {
					that.dataSource.fetch();
					that._preventRebind = false;
				});
			} else that.dataSource.fetch();
		},
		_dataSource: function() {
			var that = this, options = that.options, dataSource = options.dataSource;
			dataSource = isArray(dataSource) ? { data: dataSource } : dataSource;
			if (options.timezone && !(dataSource instanceof SchedulerDataSource)) dataSource = extend(true, dataSource, { schema: { timezone: options.timezone } });
			else if (dataSource instanceof SchedulerDataSource) options.timezone = dataSource.options.schema ? dataSource.options.schema.timezone : "";
			if (that.dataSource && that._refreshHandler) that.dataSource.unbind(CHANGE, that._refreshHandler).unbind(PROGRESS, that._progressHandler).unbind(ERROR, that._errorHandler);
			else {
				that._refreshHandler = that.refresh.bind(that);
				that._progressHandler = that._requestStart.bind(that);
				that._errorHandler = that._error.bind(that);
			}
			that.dataSource = kendo.data.SchedulerDataSource.create(dataSource).bind(CHANGE, that._refreshHandler).bind(PROGRESS, that._progressHandler).bind(ERROR, that._errorHandler);
			that.options.dataSource = that.dataSource;
		},
		_error: function() {
			this._progress(false);
		},
		_requestStart: function() {
			this._progress(true);
		},
		_progress: function(toggle) {
			var element = this.element.find(".k-scheduler-content");
			kendo.ui.progress(element, toggle);
		},
		_resources: function() {
			var that = this;
			var resources = that.options.resources;
			var resourcePromises = [];
			for (var idx = 0; idx < resources.length; idx++) {
				var resource = resources[idx];
				var field = resource.field;
				var name = resource.name || field;
				var dataSource = resource.dataSource;
				if (!field || !dataSource) throw new Error("The \"field\" and \"dataSource\" options of the scheduler resource are mandatory.");
				that.resources.push({
					field,
					name,
					title: resource.title || field,
					icon: resource.icon,
					dataTextField: resource.dataTextField || "text",
					dataValueField: resource.dataValueField || "value",
					dataColorField: resource.dataColorField || "color",
					dataParentValueField: resource.dataParentValueField || "parentValue",
					valuePrimitive: resource.valuePrimitive != null ? resource.valuePrimitive : true,
					multiple: resource.multiple || false,
					dataSource: that._resourceDataSource(dataSource, name, resourcePromises)
				});
			}
			if (!that.options.autoBind) that._selectView(that._selectedViewName);
			else $.when.apply(null, resourcePromises).then(function() {
				that.view(that._selectedViewName);
			});
		},
		_resourceDataSource: function(resourceDS, groupName, promises) {
			var that = this;
			var dataSource = isArray(resourceDS) ? { data: resourceDS } : resourceDS;
			var dataSourceInstance = kendo.data.DataSource.create(dataSource);
			if (that.options.autoBind) promises.push(dataSourceInstance.fetch(function() {
				that._bindResourceEvents(this, groupName);
			}));
			else that._bindResourceEvents(dataSourceInstance, groupName);
			return dataSourceInstance;
		},
		_bindResourceEvents: function(resourceDS, groupName) {
			var that = this;
			var isResourceGrouped = that.options.group && that.options.group.resources.length && that.options.group.resources.indexOf(groupName) > -1;
			if (!that._resourceRefreshHandler && isResourceGrouped) {
				that._resourceRefreshHandler = that._refreshResource.bind(that);
				that._resourceErrorHandler = that._error.bind(that);
			}
			if (isResourceGrouped) resourceDS.bind(CHANGE, that._resourceRefreshHandler).bind(ERROR, that._resourceErrorHandler);
		},
		_refreshResource: function() {
			var that = this;
			if (!(that._editor && that._editor.editable || that._preventRefresh)) that.view(that._selectedViewName);
		},
		_initModel: function() {
			var that = this;
			that._model = kendo.observable({
				selectedDate: new Date(this.options.date),
				formattedDate: "",
				formattedShortDate: "",
				formattedToolbarDate: ""
			});
			that._model.bind(CHANGE, function(e) {
				if (e.field === "selectedDate") that.view(that._selectedViewName);
			});
		},
		_wrapper: function() {
			var that = this;
			var options = that.options;
			var height = options.height;
			var width = options.width;
			that.wrapper = that.element.addClass("k-scheduler");
			if (that._isMobile()) that.wrapper.addClass("k-scheduler-mobile");
			if (height) that.wrapper.height(height);
			if (width) that.wrapper.width(width);
		},
		date: function(value) {
			if (value != null && getDate(value) >= getDate(this.options.min) && getDate(value) <= getDate(this.options.max)) this._model.set("selectedDate", value);
			return getDate(this._model.get("selectedDate"));
		},
		_toolbarEventInfo: function() {
			var currentDate = /* @__PURE__ */ new Date();
			var timezone = this.options.timezone;
			var view = this.view();
			var interval = view && view._timeSlotInterval ? view._timeSlotInterval() : 30 * kendo.date.MS_PER_MINUTE;
			if (timezone) {
				var timezoneOffset = kendo.timezone.offset(currentDate, timezone);
				currentDate = kendo.timezone.convert(currentDate, currentDate.getTimezoneOffset(), timezoneOffset);
			}
			var start = new Date(this.date());
			var startTime = Math.ceil(getMilliseconds(currentDate) / interval) * interval;
			kendo.date.setTime(start, startTime);
			var end = new Date(start);
			kendo.date.setTime(end, interval);
			return {
				start,
				end
			};
		},
		_processHandlers: function(defaults) {
			var that = this;
			that._pdfClickHandler = (e) => {
				e.preventDefault();
				that.saveAsPDF();
			};
			that._createClickHandler = (e) => {
				e.preventDefault();
				that.addEvent(that._isMobile() ? undefined : that._toolbarEventInfo());
			};
			that._calendarClickHandler = that._currentClickHandler = (e) => {
				e.preventDefault();
				that._showCalendar(e.target);
			};
			that._todayClickHandler = (e) => {
				e.preventDefault();
				var timezone = that.options.timezone, currentDate = /* @__PURE__ */ new Date(), date;
				if (timezone) {
					var timezoneOffset = kendo.timezone.offset(currentDate, timezone);
					date = kendo.timezone.convert(currentDate, currentDate.getTimezoneOffset(), timezoneOffset);
				} else date = currentDate;
				if (!that.trigger("navigate", {
					view: that._selectedViewName,
					action: "today",
					date
				})) that.date(date);
			};
			that._previousClickHandler = (e) => {
				e.preventDefault();
				var date = that.view().previousDate();
				if (!that.trigger("navigate", {
					view: that._selectedViewName,
					action: "previous",
					date
				})) that.date(date);
			};
			that._nextClickHandler = (e) => {
				e.preventDefault();
				var date = that.view().nextDate();
				if (!that.trigger("navigate", {
					view: that._selectedViewName,
					action: "next",
					date
				})) that.date(date);
			};
			that._refreshClickHandler = (e) => {
				e.preventDefault();
				var name = that.view().name;
				if (!that.trigger("navigate", {
					view: name,
					action: "changeView",
					date: that.date()
				})) that.view(name);
			};
			that._viewClickHandler = (e) => {
				var name = e.target.attr(kendo.attr("name"));
				if (!that.trigger("navigate", {
					view: name,
					action: "changeView",
					date: that.date()
				})) that.view(name);
			};
			Object.values(defaults).map((t) => {
				if (t.name) t.click = that["_" + t.name + "ClickHandler"];
			});
		},
		_processDefaults: function() {
			var views = this.views, defaults = $.extend(true, {}, DEFAULT_TOOLS), viewsButtons = [], isRtl = kendo.support.isRtl(this.wrapper), viewsDdl, viewsMobile;
			Object.keys(views).map((name) => {
				viewsButtons.push(name);
			});
			if (viewsButtons.length > 1) {
				viewsDdl = VIEWS_DROPDOWN_TEMPLATE({
					views: this.views,
					label: this.options.messages.selectView,
					type: "k-views-dropdown"
				});
				viewsMobile = VIEWS_DROPDOWN_TEMPLATE({
					views: this.views,
					label: this.options.messages.selectView,
					type: "k-scheduler-mobile-views"
				});
			}
			defaults.viewsDdl = { template: viewsDdl };
			defaults.viewsMobile = { template: viewsMobile };
			defaults.viewsSegmentedControl = { template: "<div class=\"k-scheduler-views\"></div>" };
			this._viewsButtons = viewsButtons;
			if (isRtl) {
				defaults.previous.icon = "chevron-right";
				defaults.next.icon = "chevron-left";
			}
			return defaults;
		},
		_processToolbarArray: function() {
			var options = this.options, toolbarOptions = options.toolbar, commands = [], isMobile = this._isMobile(), tools, pdf, search;
			if (toolbarOptions) commands = Array.isArray(toolbarOptions) ? toolbarOptions : [toolbarOptions];
			pdf = $.grep(commands, function(item) {
				return item == "pdf" || item.name == "pdf";
			}).length > 0;
			search = $.grep(commands, function(item) {
				return item == "search" || item.name == "search";
			}).length > 0;
			if (isMobile) {
				tools = [...defaultMobileToolsFirst];
				if (options.editable) tools[0].push("createMobile");
			} else tools = [...defaultDesktopTools];
			if (search) tools.push("search");
			if (pdf) if (isMobile) tools[0].unshift("pdfMobile");
			else tools.unshift("pdf");
			if (this._viewsCount === 1) tools.push("refresh");
			else if (this._viewsCount > 1) if (isMobile) tools.push("viewsMobile");
			else {
				tools.push("viewsDdl");
				tools.push("viewsSegmentedControl");
			}
			return tools;
		},
		_processViewTools: function(items) {
			var result = items.map((item) => {
				if (Array.isArray(item)) return this._processViewTools(item);
				if ($.isPlainObject(item) && item.name && item.template) {
					item = $.extend({}, item);
					delete item.name;
				}
				return item;
			}), viewsIndex = -1;
			result.some((item, index) => {
				if (item === "views" || item && item.name === "views") {
					viewsIndex = index;
					return true;
				}
				return false;
			});
			if (viewsIndex > -1) result.splice(viewsIndex, 1, "viewsDdl", "viewsSegmentedControl");
			return result;
		},
		_processToolbarItems: function() {
			var desktopItems = this.options.toolbar.items.desktop || this.options.toolbar.items, mobileItems = this.options.toolbar.items.mobile || this.options.toolbar.items;
			if (!this._isMobile()) {
				if (desktopItems.main) if (desktopItems.navigation) desktopItems = desktopItems.main.concat(desktopItems.navigation);
				else desktopItems = desktopItems.main;
				if (this._viewsCount > 1 && !desktopItems.some((item) => item === "views" || item && item.name === "views")) desktopItems = desktopItems.concat("views");
				return { tools: this._processViewTools(desktopItems) };
			} else if (Array.isArray(mobileItems)) return {
				tools: this._processViewTools(mobileItems),
				navigation: []
			};
			else return {
				tools: this._processViewTools(mobileItems.main),
				navigation: this._processViewTools(mobileItems.navigation)
			};
		},
		_processTools: function() {
			var toolbarOptions = this.options.toolbar;
			if (toolbarOptions && toolbarOptions.items) return this._processToolbarItems();
			else return { tools: this._processToolbarArray() };
		},
		_toolbar: function() {
			var that = this;
			var options = that.options;
			var defaults = that._processDefaults();
			var { tools, navigation } = that._processTools();
			var toolbar = $("<div class='k-scheduler-toolbar'>");
			var secondToolbar;
			that._processHandlers(defaults);
			that.wrapper.append(toolbar);
			that.toolbar = toolbar;
			toolbar.kendoToolBar({
				resizable: false,
				tools,
				defaultTools: defaults,
				parentMessages: options.messages
			});
			that._initViewsSegmentedControl();
			if (that._isMobile() && (!navigation || navigation.length !== 0)) {
				secondToolbar = $("<div class='k-scheduler-toolbar'>");
				that.wrapper.append(secondToolbar);
				that.toolbar = that.toolbar.add(secondToolbar);
				secondToolbar.kendoToolBar({
					resizable: false,
					tools: navigation || [...defaultMobileToolsSecond],
					defaultTools: defaults,
					parentMessages: options.messages
				});
			}
			that.toolbar.find(".k-nav-current .k-button-text").attr("data-" + kendo.ns + "bind", "text: formattedToolbarDate");
			that.toolbar.find(".k-m-date-format").attr("data-" + kendo.ns + "bind", "text: formattedMobileDate");
			that.toolbar.find(".k-y-date-format").attr("data-" + kendo.ns + "bind", "text: formattedYear");
			kendo.bind(that.toolbar, that._model);
			that.toolbar.find(".k-scheduler-search-input").attr({
				placeholder: options.messages.search,
				title: options.messages.search
			});
			toolbar.on("input" + NS, ".k-scheduler-search-input", kendo.throttle(function(e) {
				that.dataSource.filter({
					logic: "or",
					filters: [{
						field: "title",
						operator: "contains",
						value: e.target.value
					}, {
						field: "description",
						operator: "contains",
						value: e.target.value
					}]
				});
			}, 250));
			toolbar.on(CHANGE + NS, ".k-views-dropdown, .k-scheduler-mobile-views", function() {
				var name = this.value;
				if (!that.trigger("navigate", {
					view: name,
					action: "changeView",
					date: that.date()
				})) that.view(name);
			});
			that._initViewsDropDownButton();
			if (!that._isMobile()) {
				that._toolbarLevel = 0;
				that._toolbarBreakpoints = [
					Infinity,
					Infinity,
					Infinity
				];
				that.toolbar.first().css("flex-wrap", "nowrap");
				if (typeof ResizeObserver !== "undefined") {
					that._toolbarResizeObserver = new ResizeObserver(function() {
						that._toolbarResize();
					});
					that._toolbarResizeObserver.observe(that.toolbar.first()[0]);
				}
			}
			that._initialSize = true;
		},
		_initViewsSegmentedControl: function() {
			const that = this;
			const views = that.views;
			const viewNames = Object.keys(views);
			const container = that.toolbar.find(".k-scheduler-views");
			if (!container.length || viewNames.length <= 1) return;
			var segParent = container.parent();
			segParent.attr("ref-toolbar-tool", "");
			that._toolbarSegmentedContainer = segParent.is(that.toolbar.first()) ? container : segParent;
			const items = viewNames.map(function(name) {
				return {
					value: name,
					text: views[name].title
				};
			});
			that._viewsSegmentedControl = container.kendoSegmentedControl({
				items,
				selectedValue: that._selectedViewName,
				change: function(e) {
					if (!that.trigger("navigate", {
						view: e.value,
						action: "changeView",
						date: that.date()
					})) {
						that.view(e.value);
						(that.element.find(".k-segmented-control-button")?.filter(`[data-value="${e.value}"]`))?.focus();
					}
				}
			}).data("kendoSegmentedControl");
		},
		_initViewsDropDownButton: function() {
			var that = this;
			var views = that.views;
			var viewNames = Object.keys(views);
			var toolbar = that.toolbar.first();
			if (!toolbar.find(".k-scheduler-views").length || viewNames.length <= 1) return;
			var currentTitle = views[that._selectedViewName] ? views[that._selectedViewName].title : viewNames[0];
			var items = viewNames.map(function(name) {
				return {
					text: views[name].title,
					click: function() {
						if (!that.trigger("navigate", {
							view: name,
							action: "changeView",
							date: that.date()
						})) that.view(name);
					}
				};
			});
			that._toolbarDropDownContainer = $("<div class=\"k-toolbar-views-dropdown\"></div>").hide().appendTo(toolbar);
			that._viewsDropDownButton = $("<button type=\"button\"></button>").text(currentTitle).appendTo(that._toolbarDropDownContainer).kendoDropDownButton({
				fillMode: "flat",
				showArrowButton: true,
				items
			}).data("kendoDropDownButton");
			that._viewsDropDownButton.element.addClass("k-toolbar-menu-button");
			that._toolbarViewsDdlContainer = toolbar.find(".k-views-dropdown").parent();
			if (that._toolbarViewsDdlContainer.length) that._toolbarViewsDdlContainer.hide();
			that._toolbarCreateBtn = toolbar.find("[ref-toolbar-create]");
			that._toolbarNavGroup = toolbar.find("[ref-nav-prev]").closest(".k-button-group");
			that._toolbarTodayBtn = toolbar.find("[ref-nav-today]");
		},
		_updateToolbarDate: function() {
			if (!this._model || this._isMobile()) return;
			var date = (this._toolbarLevel || 0) >= 2 ? this._model.get("formattedShortDate") : this._model.get("formattedDate");
			this._model.set("formattedToolbarDate", date);
		},
		_toolbarResize: function() {
			var that = this;
			if (that._toolbarResizing) return;
			var toolbar = that.toolbar && that.toolbar.first();
			if (!toolbar || !toolbar.is(":visible") || that._isMobile()) return;
			that._toolbarResizing = true;
			toolbar.css("overflow", "hidden");
			var el = toolbar[0];
			var containerWidth = el.clientWidth;
			if (!containerWidth) {
				that._toolbarResizing = false;
				return;
			}
			var level = that._toolbarLevel || 0;
			var breakpoints = that._toolbarBreakpoints;
			var iterations = 0;
			var changed = true;
			while (changed && iterations < 4) {
				changed = false;
				iterations++;
				if (that._measureToolbarContent(toolbar) > containerWidth && level < 3) {
					breakpoints[level] = containerWidth;
					level++;
					changed = true;
					that._applyToolbarLevel(level);
				} else if (level > 0) {
					that._applyToolbarLevel(level - 1);
					if (that._measureToolbarContent(toolbar) <= containerWidth - TOOLBAR_HYSTERESIS) {
						level--;
						changed = true;
					} else that._applyToolbarLevel(level);
				}
			}
			if (level !== (that._toolbarLevel || 0)) {
				that._toolbarLevel = level;
				that._updateToolbarDate();
			}
			toolbar.css("overflow", "");
			if (level >= 3 && that._measureToolbarContent(toolbar) > el.clientWidth) toolbar.css("flex-wrap", "wrap");
			else toolbar.css("flex-wrap", "nowrap");
			that._toolbarResizing = false;
		},
		_measureToolbarContent: function(toolbar) {
			var gap = parseInt(toolbar.css("gap")) || 0;
			var contentWidth = 0;
			var visibleCount = 0;
			toolbar.children().each(function() {
				if (this.offsetWidth > 0 && !$(this).hasClass("k-spacer")) {
					contentWidth += this.offsetWidth;
					visibleCount++;
				}
			});
			if (visibleCount > 1) contentWidth += gap * (visibleCount - 1);
			return contentWidth;
		},
		_applyToolbarLevel: function(level) {
			var that = this;
			var segContainer = that._toolbarSegmentedContainer;
			var sepEl = that._toolbarViewsSeparator;
			var ddlEl = that._toolbarDropDownContainer;
			var createBtn = that._toolbarCreateBtn;
			var todayBtn = that._toolbarTodayBtn;
			var navGroup = that._toolbarNavGroup;
			if (segContainer) if (level === 0) segContainer.show();
			else segContainer.hide();
			if (sepEl) if (level === 1) sepEl.show();
			else sepEl.hide();
			if (ddlEl) if (level >= 1) ddlEl.show();
			else ddlEl.hide();
			if (createBtn) if (level >= 2) {
				createBtn.addClass("k-icon-button");
				createBtn.children(".k-button-text").hide();
			} else {
				createBtn.removeClass("k-icon-button");
				createBtn.children(".k-button-text").show();
			}
			if (todayBtn && todayBtn.length) if (level >= 2) todayBtn.hide();
			else todayBtn.show();
			if (navGroup && navGroup.length) if (level >= 3) navGroup.hide();
			else navGroup.show();
		},
		_showCalendar: function(targetElm) {
			var that = this, target = targetElm || that.toolbar.find(".k-nav-current"), html = $("<div class=\"k-calendar-container\"><div class=\"k-scheduler-calendar\"></div></div>");
			if (!that.popup) that.popup = new Popup(html, {
				anchor: target,
				isRtl: kendo.support.isRtl(that.element),
				activate: function() {
					if (that.popup && that.calendar) {
						that.popup._toggleResize(false);
						that.calendar.focus();
						that.popup._toggleResize(true);
					}
				},
				open: function() {
					if (!that.calendar) that.calendar = new Calendar(this.element.find(".k-scheduler-calendar"), {
						change: function() {
							var date = this.value();
							if (!that.trigger("navigate", {
								view: that._selectedViewName,
								action: "changeDate",
								date
							})) {
								that.date(date);
								that.popup.close();
							}
							if (!that._isMobile()) {
								that._selectedView.element.trigger("focus");
								that.toolbar.find(".k-nav-current").trigger("focus").addClass(FOCUSEDSTATE);
							}
						},
						min: that.options.min,
						max: that.options.max
					});
					that.calendar.element.on("keydown" + NS, function(e) {
						if (e.keyCode === keys.ESC || e.keyCode === keys.TAB) {
							that.popup.close();
							that._selectedView.element.trigger("focus");
							that.toolbar.find(".k-nav-current").trigger("focus").addClass(FOCUSEDSTATE);
						}
					});
					that.calendar.setOptions({
						start: that._selectedViewName === "year" ? "decade" : "month",
						depth: that._selectedViewName === "year" ? "decade" : "month"
					});
					that.calendar.value(that.date());
				},
				copyAnchorStyles: false
			});
			that.popup.open();
		},
		refresh: function(e) {
			var view = this.view();
			var preventRefresh = e && e.action === "itemchange" && (this._editor.editable || this._preventRefresh) || this.dataSource.options.type === "signalr" && this._preventRefresh;
			this._progress(false);
			e = e || {};
			if (!view) return;
			if (preventRefresh) {
				this._attemptRefresh = this.dataSource.options.type === "signalr";
				return;
			}
			if (this.trigger("dataBinding", {
				action: e.action || "rebind",
				index: e.index,
				items: e.items
			})) return;
			if (!(e && e.action === "resize") && this._editor) this._editor.close();
			this._data = this.dataSource.expand(view.startDate(), view.visibleEndDate());
			view.refreshLayout();
			view.render(this._data);
			view._readonlyEvents(this._data);
			this.trigger("dataBound");
			this._attemptRefresh = false;
		},
		slotByPosition: function(x, y) {
			var view = this.view();
			if (!view._slotByPosition) return null;
			var slot = view._slotByPosition(x, y);
			if (!slot) return null;
			return {
				startDate: slot.startDate(),
				endDate: slot.endDate(),
				groupIndex: slot.groupIndex,
				element: slot.element,
				isDaySlot: slot.isDaySlot
			};
		},
		slotByElement: function(element) {
			var el = $(element), offset = el.offset(), width = el.width(), height = el.height(), centerX = offset.left + width / 2, centerY = offset.top + height / 2, offset = $(element).offset();
			return this.slotByPosition(centerX, centerY);
		},
		resourcesBySlot: function(slot) {
			return this.view()._resourceBySlot(slot);
		}
	});
	var defaultViews = {
		day: { type: "kendo.ui.DayView" },
		week: { type: "kendo.ui.WeekView" },
		workWeek: { type: "kendo.ui.WorkWeekView" },
		agenda: { type: "kendo.ui.AgendaView" },
		month: { type: "kendo.ui.MonthView" },
		timeline: { type: "kendo.ui.TimelineView" },
		timelineWeek: { type: "kendo.ui.TimelineWeekView" },
		timelineWorkWeek: { type: "kendo.ui.TimelineWorkWeekView" },
		timelineMonth: { type: "kendo.ui.TimelineMonthView" },
		year: { type: "kendo.ui.YearView" }
	};
	ui.plugin(Scheduler);
	if (kendo.PDFMixin) {
		kendo.PDFMixin.extend(Scheduler.prototype);
		var SCHEDULER_EXPORT = "k-scheduler-pdf-export";
		Scheduler.fn._drawPDF = function(progress) {
			var wrapper = this.wrapper;
			var styles = wrapper[0].style.cssText;
			wrapper.css({
				width: wrapper.width(),
				height: wrapper.height()
			});
			wrapper.addClass(SCHEDULER_EXPORT);
			var scheduler = this;
			var promise = new $.Deferred();
			var table = wrapper.find(".k-scheduler-content").find("table").css("table-layout", "auto");
			setTimeout(function() {
				table.css("table-layout", "fixed");
				scheduler.resize(true);
				scheduler._drawPDFShadow({}, { avoidLinks: scheduler.options.pdf.avoidLinks }).done(function(group) {
					var args = {
						page: group,
						pageNumber: 1,
						progress: 1,
						totalPages: 1
					};
					progress.notify(args);
					promise.resolve(args.page);
				}).fail(function(err) {
					promise.reject(err);
				}).always(function() {
					wrapper[0].style.cssText = styles;
					wrapper.removeClass(SCHEDULER_EXPORT);
					scheduler.resize(true);
					scheduler.resize(true);
				});
			});
			return promise;
		};
	}
	var TimezoneEditor = Widget.extend({
		init: function(element, options) {
			var that = this, zones = kendo.timezone.windows_zones;
			if (!zones || !kendo.timezone.zones_titles) throw new Error("kendo.timezones.min.js is not included.");
			Widget.fn.init.call(that, element, options);
			that.wrapper = that.element;
			that._zonesQuery = new kendo.data.Query(zones);
			that._zoneTitleId = kendo.guid();
			that._zoneTitlePicker();
			that._zonePicker();
			that._zoneTitle.bind("cascade", function() {
				if (!this.value()) that._zone.wrapper.hide();
			});
			that._zone.bind("cascade", function() {
				that._value = this.value();
				that.trigger(CHANGE);
			});
			that.value(that.options.value);
			Widget.fn.endInit.call(this);
		},
		options: {
			name: "TimezoneEditor",
			value: "",
			optionLabel: "No timezone"
		},
		events: [CHANGE],
		_zoneTitlePicker: function() {
			var that = this, zoneTitle = $("<input id=\"" + that._zoneTitleId + "\" aria-label=\"" + that.options.title + "\"/>").appendTo(that.wrapper), zones = [{
				name: that.options.optionLabel,
				other_zone: ""
			}].concat(kendo.timezone.zones_titles);
			that._zoneTitle = new kendo.ui.DropDownList(zoneTitle, {
				dataSource: zones,
				dataValueField: "other_zone",
				dataTextField: "name",
				filter: "contains"
			});
		},
		_zonePicker: function() {
			var that = this, zone = $("<input aria-label=\"" + that.options.title + "\"/>").appendTo(this.wrapper);
			that._zone = new kendo.ui.DropDownList(zone, {
				dataValueField: "zone",
				dataTextField: "territory",
				dataSource: that._zonesQuery.data,
				cascadeFrom: that._zoneTitleId,
				filter: "contains",
				dataBound: function() {
					that._value = this.value();
					this.wrapper.toggle(this.dataSource.view().length > 1);
				}
			});
			that._zone.wrapper.hide();
		},
		destroy: function() {
			Widget.fn.destroy.call(this);
			kendo.destroy(this.wrapper);
		},
		value: function(value) {
			var that = this, zone;
			if (value === undefined) return that._value;
			zone = that._zonesQuery.filter({
				field: "zone",
				operator: "eq",
				value
			}).data[0];
			if (zone) {
				that._zoneTitle.value(zone.other_zone);
				that._zone.value(zone.zone);
			} else that._zoneTitle.select(0);
		}
	});
	ui.plugin(TimezoneEditor);
	var ZONETITLEOPTIONTEMPLATE = kendo.template(({ name, other_zone }) => `<option value="${other_zone}">${name}</option>`);
	var ZONEOPTIONTEMPLATE = kendo.template(({ zone, territory }) => `<option value="${zone}">${territory}</option>`);
	var MobileTimezoneEditor = Widget.extend({
		init: function(element, options) {
			var that = this, zones = kendo.timezone.windows_zones;
			if (!zones || !kendo.timezone.zones_titles) throw new Error("kendo.timezones.min.js is not included.");
			Widget.fn.init.call(that, element, options);
			that.wrapper = that.element;
			that._zonesQuery = new kendo.data.Query(zones);
			that._zoneTitlePicker();
			that._zonePicker();
			that.value(that.options.value);
			Widget.fn.endInit.call(this);
		},
		options: {
			name: "MobileTimezoneEditor",
			optionLabel: "No timezone",
			value: ""
		},
		events: [CHANGE],
		_bindZones: function(value) {
			var data = value ? this._filter(value) : [];
			this._zone.html(this._options(data, ZONEOPTIONTEMPLATE));
		},
		_filter: function(value) {
			return this._zonesQuery.filter({
				field: "other_zone",
				operator: "eq",
				value
			}).data;
		},
		_options: function(data, template, optionLabel) {
			var idx = 0;
			var html = "";
			var length = data.length;
			if (optionLabel) html += template({
				other_zone: "",
				name: optionLabel
			});
			for (; idx < length; idx++) html += template(data[idx]);
			return html;
		},
		_zoneTitlePicker: function() {
			var that = this;
			that._zoneTitle = $("<select>" + that._options(kendo.timezone.zones_titles, ZONETITLEOPTIONTEMPLATE, that.options.optionLabel) + "</select>").appendTo(that.wrapper).on("change", function() {
				var value = this.value;
				var zone = that._zonePickerLabel;
				var zoneSelect = zone.find("select");
				that._bindZones(value);
				if (value && zoneSelect.children().length > 1) zone.show();
				else zone.hide();
				that._value = that._zone[0].value;
				that.trigger(CHANGE);
			});
		},
		_zonePicker: function() {
			var that = this;
			that._zonePickerLabel = $("<li class='k-item k-listgroup-item k-zonepicker'><label class='k-label k-listgroup-form-row'><span class='k-item-title k-listgroup-form-field-label'></span><div class='k-listgroup-form-field-wrapper'></div></label></li>").hide();
			that._zone = $("<select></select>").appendTo(that._zonePickerLabel.find("div")).on("change", function() {
				that._value = this.value;
				that.trigger(CHANGE);
			});
			this.wrapper.closest(".k-item").after(that._zonePickerLabel);
			that._bindZones(that._zoneTitle.val());
			that._value = that._zone[0].value;
		},
		destroy: function() {
			Widget.fn.destroy.call(this);
			kendo.destroy(this.wrapper);
		},
		value: function(value) {
			var that = this;
			var zonePicker = that._zone;
			var other_zone = "";
			var zone_value = "";
			var zone;
			if (value === undefined) return that._value;
			zone = that._zonesQuery.filter({
				field: "zone",
				operator: "eq",
				value
			}).data[0];
			if (zone) {
				zone_value = zone.zone;
				other_zone = zone.other_zone;
			}
			that._zoneTitle.val(other_zone);
			that._bindZones(other_zone);
			zonePicker.val(zone_value);
			zone_value = zonePicker[0].value;
			if (zone_value && zonePicker.children.length > 1) that._zonePickerLabel.show();
			else that._zonePickerLabel.hide();
			that._value = zone_value;
		}
	});
	ui.plugin(MobileTimezoneEditor);
})(window.kendo.jQuery);
var kendo_scheduler_default = kendo;
//#endregion
exports.__meta__ = __meta__;
exports.default = kendo_scheduler_default;