diff --git a/.gitignore b/.gitignore index 86eb146..8157fcc 100755 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .elasticbeanstalk/ .DS_Store /public/data +/public/assets *.png coverage .tags diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index aa51d07..fd0a477 100755 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -13,19 +13,16 @@ //= require jquery //= require jquery_ujs //= require turbolinks -//= require wysiwyg/wysihtml5-0.3.0.js //= require jquery.min.js //= require jquery.scrollUp.js //= require bootstrap.js -//= require wysiwyg/bootstrap-wysihtml5.js //= require bootstrap-colorpicker.js //= require date-picker/date.js //= require date-picker/daterangepicker.js //= require bootstrap-timepicker.js //= require jquery.bootstrap.wizard.js -//= require jquery.sparkline.js //= require tiny-scrollbar.js -//= require jquery.validate.js +//= require jquery.validate.min.js //= require jquery.snippet.js //= require jquery.easy-pie-chart.js //= require jquery-fileupload/basic diff --git a/app/assets/javascripts/fullcalendar.js b/app/assets/javascripts/fullcalendar.js deleted file mode 100755 index 0d43e58..0000000 --- a/app/assets/javascripts/fullcalendar.js +++ /dev/null @@ -1,5378 +0,0 @@ -/*! - * FullCalendar v1.6.1 - * Docs & License: http://arshaw.com/fullcalendar/ - * (c) 2013 Adam Shaw - */ - -/* - * Use fullcalendar.css for basic styling. - * For event drag & drop, requires jQuery UI draggable. - * For event resizing, requires jQuery UI resizable. - */ - -(function($, undefined) { - - -;; - -var defaults = { - - // display - defaultView: 'month', - aspectRatio: 1.35, - header: { - left: 'title', - center: '', - right: 'today prev,next' - }, - weekends: true, - weekNumbers: false, - weekNumberCalculation: 'iso', - weekNumberTitle: 'W', - - // editing - //editable: false, - //disableDragging: false, - //disableResizing: false, - - allDayDefault: true, - ignoreTimezone: true, - - // event ajax - lazyFetching: true, - startParam: 'start', - endParam: 'end', - - // time formats - titleFormat: { - month: 'MMMM yyyy', - week: "MMM d[ yyyy]{ '—'[ MMM] d yyyy}", - day: 'dddd, MMM d, yyyy' - }, - columnFormat: { - month: 'ddd', - week: 'ddd M/d', - day: 'dddd M/d' - }, - timeFormat: { // for event elements - '': 'h(:mm)t' // default - }, - - // locale - isRTL: false, - firstDay: 0, - monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'], - dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'], - dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'], - buttonText: { - prev: "", - next: "", - prevYear: "«", - nextYear: "»", - today: 'today', - month: 'month', - week: 'week', - day: 'day' - }, - - // jquery-ui theming - theme: false, - buttonIcons: { - prev: 'circle-triangle-w', - next: 'circle-triangle-e' - }, - - //selectable: false, - unselectAuto: true, - - dropAccept: '*' - -}; - -// right-to-left defaults -var rtlDefaults = { - header: { - left: 'next,prev today', - center: '', - right: 'title' - }, - buttonText: { - prev: "", - next: "", - prevYear: "»", - nextYear: "«" - }, - buttonIcons: { - prev: 'circle-triangle-e', - next: 'circle-triangle-w' - } -}; - - - -;; - -var fc = $.fullCalendar = { version: "1.6.1" }; -var fcViews = fc.views = {}; - - -$.fn.fullCalendar = function(options) { - - - // method calling - if (typeof options == 'string') { - var args = Array.prototype.slice.call(arguments, 1); - var res; - this.each(function() { - var calendar = $.data(this, 'fullCalendar'); - if (calendar && $.isFunction(calendar[options])) { - var r = calendar[options].apply(calendar, args); - if (res === undefined) { - res = r; - } - if (options == 'destroy') { - $.removeData(this, 'fullCalendar'); - } - } - }); - if (res !== undefined) { - return res; - } - return this; - } - - - // would like to have this logic in EventManager, but needs to happen before options are recursively extended - var eventSources = options.eventSources || []; - delete options.eventSources; - if (options.events) { - eventSources.push(options.events); - delete options.events; - } - - - options = $.extend(true, {}, - defaults, - (options.isRTL || options.isRTL===undefined && defaults.isRTL) ? rtlDefaults : {}, - options - ); - - - this.each(function(i, _element) { - var element = $(_element); - var calendar = new Calendar(element, options, eventSources); - element.data('fullCalendar', calendar); // TODO: look into memory leak implications - calendar.render(); - }); - - - return this; - -}; - - -// function for adding/overriding defaults -function setDefaults(d) { - $.extend(true, defaults, d); -} - - - -;; - - -function Calendar(element, options, eventSources) { - var t = this; - - - // exports - t.options = options; - t.render = render; - t.destroy = destroy; - t.refetchEvents = refetchEvents; - t.reportEvents = reportEvents; - t.reportEventChange = reportEventChange; - t.rerenderEvents = rerenderEvents; - t.changeView = changeView; - t.select = select; - t.unselect = unselect; - t.prev = prev; - t.next = next; - t.prevYear = prevYear; - t.nextYear = nextYear; - t.today = today; - t.gotoDate = gotoDate; - t.incrementDate = incrementDate; - t.formatDate = function(format, date) { return formatDate(format, date, options) }; - t.formatDates = function(format, date1, date2) { return formatDates(format, date1, date2, options) }; - t.getDate = getDate; - t.getView = getView; - t.option = option; - t.trigger = trigger; - - - // imports - EventManager.call(t, options, eventSources); - var isFetchNeeded = t.isFetchNeeded; - var fetchEvents = t.fetchEvents; - - - // locals - var _element = element[0]; - var header; - var headerElement; - var content; - var tm; // for making theme classes - var currentView; - var viewInstances = {}; - var elementOuterWidth; - var suggestedViewHeight; - var absoluteViewElement; - var resizeUID = 0; - var ignoreWindowResize = 0; - var date = new Date(); - var events = []; - var _dragElement; - - - - /* Main Rendering - -----------------------------------------------------------------------------*/ - - - setYMD(date, options.year, options.month, options.date); - - - function render(inc) { - if (!content) { - initialRender(); - }else{ - calcSize(); - markSizesDirty(); - markEventsDirty(); - renderView(inc); - } - } - - - function initialRender() { - tm = options.theme ? 'ui' : 'fc'; - element.addClass('fc'); - if (options.isRTL) { - element.addClass('fc-rtl'); - } - else { - element.addClass('fc-ltr'); - } - if (options.theme) { - element.addClass('ui-widget'); - } - content = $("
") - .prependTo(element); - header = new Header(t, options); - headerElement = header.render(); - if (headerElement) { - element.prepend(headerElement); - } - changeView(options.defaultView); - $(window).resize(windowResize); - // needed for IE in a 0x0 iframe, b/c when it is resized, never triggers a windowResize - if (!bodyVisible()) { - lateRender(); - } - } - - - // called when we know the calendar couldn't be rendered when it was initialized, - // but we think it's ready now - function lateRender() { - setTimeout(function() { // IE7 needs this so dimensions are calculated correctly - if (!currentView.start && bodyVisible()) { // !currentView.start makes sure this never happens more than once - renderView(); - } - },0); - } - - - function destroy() { - $(window).unbind('resize', windowResize); - header.destroy(); - content.remove(); - element.removeClass('fc fc-rtl ui-widget'); - } - - - - function elementVisible() { - return _element.offsetWidth !== 0; - } - - - function bodyVisible() { - return $('body')[0].offsetWidth !== 0; - } - - - - /* View Rendering - -----------------------------------------------------------------------------*/ - - // TODO: improve view switching (still weird transition in IE, and FF has whiteout problem) - - function changeView(newViewName) { - if (!currentView || newViewName != currentView.name) { - ignoreWindowResize++; // because setMinHeight might change the height before render (and subsequently setSize) is reached - - unselect(); - - var oldView = currentView; - var newViewElement; - - if (oldView) { - (oldView.beforeHide || noop)(); // called before changing min-height. if called after, scroll state is reset (in Opera) - setMinHeight(content, content.height()); - oldView.element.hide(); - }else{ - setMinHeight(content, 1); // needs to be 1 (not 0) for IE7, or else view dimensions miscalculated - } - content.css('overflow', 'hidden'); - - currentView = viewInstances[newViewName]; - if (currentView) { - currentView.element.show(); - }else{ - currentView = viewInstances[newViewName] = new fcViews[newViewName]( - newViewElement = absoluteViewElement = - $("
") - .appendTo(content), - t // the calendar object - ); - } - - if (oldView) { - header.deactivateButton(oldView.name); - } - header.activateButton(newViewName); - - renderView(); // after height has been set, will make absoluteViewElement's position=relative, then set to null - - content.css('overflow', ''); - if (oldView) { - setMinHeight(content, 1); - } - - if (!newViewElement) { - (currentView.afterShow || noop)(); // called after setting min-height/overflow, so in final scroll state (for Opera) - } - - ignoreWindowResize--; - } - } - - - - function renderView(inc) { - if (elementVisible()) { - ignoreWindowResize++; // because renderEvents might temporarily change the height before setSize is reached - - unselect(); - - if (suggestedViewHeight === undefined) { - calcSize(); - } - - var forceEventRender = false; - if (!currentView.start || inc || date < currentView.start || date >= currentView.end) { - // view must render an entire new date range (and refetch/render events) - currentView.render(date, inc || 0); // responsible for clearing events - setSize(true); - forceEventRender = true; - } - else if (currentView.sizeDirty) { - // view must resize (and rerender events) - currentView.clearEvents(); - setSize(); - forceEventRender = true; - } - else if (currentView.eventsDirty) { - currentView.clearEvents(); - forceEventRender = true; - } - currentView.sizeDirty = false; - currentView.eventsDirty = false; - updateEvents(forceEventRender); - - elementOuterWidth = element.outerWidth(); - - header.updateTitle(currentView.title); - var today = new Date(); - if (today >= currentView.start && today < currentView.end) { - header.disableButton('today'); - }else{ - header.enableButton('today'); - } - - ignoreWindowResize--; - currentView.trigger('viewDisplay', _element); - } - } - - - - /* Resizing - -----------------------------------------------------------------------------*/ - - - function updateSize() { - markSizesDirty(); - if (elementVisible()) { - calcSize(); - setSize(); - unselect(); - currentView.clearEvents(); - currentView.renderEvents(events); - currentView.sizeDirty = false; - } - } - - - function markSizesDirty() { - $.each(viewInstances, function(i, inst) { - inst.sizeDirty = true; - }); - } - - - function calcSize() { - if (options.contentHeight) { - suggestedViewHeight = options.contentHeight; - } - else if (options.height) { - suggestedViewHeight = options.height - (headerElement ? headerElement.height() : 0) - vsides(content); - } - else { - suggestedViewHeight = Math.round(content.width() / Math.max(options.aspectRatio, .5)); - } - } - - - function setSize(dateChanged) { // todo: dateChanged? - ignoreWindowResize++; - currentView.setHeight(suggestedViewHeight, dateChanged); - if (absoluteViewElement) { - absoluteViewElement.css('position', 'relative'); - absoluteViewElement = null; - } - currentView.setWidth(content.width(), dateChanged); - ignoreWindowResize--; - } - - - function windowResize() { - if (!ignoreWindowResize) { - if (currentView.start) { // view has already been rendered - var uid = ++resizeUID; - setTimeout(function() { // add a delay - if (uid == resizeUID && !ignoreWindowResize && elementVisible()) { - if (elementOuterWidth != (elementOuterWidth = element.outerWidth())) { - ignoreWindowResize++; // in case the windowResize callback changes the height - updateSize(); - currentView.trigger('windowResize', _element); - ignoreWindowResize--; - } - } - }, 200); - }else{ - // calendar must have been initialized in a 0x0 iframe that has just been resized - lateRender(); - } - } - } - - - - /* Event Fetching/Rendering - -----------------------------------------------------------------------------*/ - - - // fetches events if necessary, rerenders events if necessary (or if forced) - function updateEvents(forceRender) { - if (!options.lazyFetching || isFetchNeeded(currentView.visStart, currentView.visEnd)) { - refetchEvents(); - } - else if (forceRender) { - rerenderEvents(); - } - } - - - function refetchEvents() { - fetchEvents(currentView.visStart, currentView.visEnd); // will call reportEvents - } - - - // called when event data arrives - function reportEvents(_events) { - events = _events; - rerenderEvents(); - } - - - // called when a single event's data has been changed - function reportEventChange(eventID) { - rerenderEvents(eventID); - } - - - // attempts to rerenderEvents - function rerenderEvents(modifiedEventID) { - markEventsDirty(); - if (elementVisible()) { - currentView.clearEvents(); - currentView.renderEvents(events, modifiedEventID); - currentView.eventsDirty = false; - } - } - - - function markEventsDirty() { - $.each(viewInstances, function(i, inst) { - inst.eventsDirty = true; - }); - } - - - - /* Selection - -----------------------------------------------------------------------------*/ - - - function select(start, end, allDay) { - currentView.select(start, end, allDay===undefined ? true : allDay); - } - - - function unselect() { // safe to be called before renderView - if (currentView) { - currentView.unselect(); - } - } - - - - /* Date - -----------------------------------------------------------------------------*/ - - - function prev() { - renderView(-1); - } - - - function next() { - renderView(1); - } - - - function prevYear() { - addYears(date, -1); - renderView(); - } - - - function nextYear() { - addYears(date, 1); - renderView(); - } - - - function today() { - date = new Date(); - renderView(); - } - - - function gotoDate(year, month, dateOfMonth) { - if (year instanceof Date) { - date = cloneDate(year); // provided 1 argument, a Date - }else{ - setYMD(date, year, month, dateOfMonth); - } - renderView(); - } - - - function incrementDate(years, months, days) { - if (years !== undefined) { - addYears(date, years); - } - if (months !== undefined) { - addMonths(date, months); - } - if (days !== undefined) { - addDays(date, days); - } - renderView(); - } - - - function getDate() { - return cloneDate(date); - } - - - - /* Misc - -----------------------------------------------------------------------------*/ - - - function getView() { - return currentView; - } - - - function option(name, value) { - if (value === undefined) { - return options[name]; - } - if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') { - options[name] = value; - updateSize(); - } - } - - - function trigger(name, thisObj) { - if (options[name]) { - return options[name].apply( - thisObj || _element, - Array.prototype.slice.call(arguments, 2) - ); - } - } - - - - /* External Dragging - ------------------------------------------------------------------------*/ - - if (options.droppable) { - $(document) - .bind('dragstart', function(ev, ui) { - var _e = ev.target; - var e = $(_e); - if (!e.parents('.fc').length) { // not already inside a calendar - var accept = options.dropAccept; - if ($.isFunction(accept) ? accept.call(_e, e) : e.is(accept)) { - _dragElement = _e; - currentView.dragStart(_dragElement, ev, ui); - } - } - }) - .bind('dragstop', function(ev, ui) { - if (_dragElement) { - currentView.dragStop(_dragElement, ev, ui); - _dragElement = null; - } - }); - } - - -} - -;; - -function Header(calendar, options) { - var t = this; - - - // exports - t.render = render; - t.destroy = destroy; - t.updateTitle = updateTitle; - t.activateButton = activateButton; - t.deactivateButton = deactivateButton; - t.disableButton = disableButton; - t.enableButton = enableButton; - - - // locals - var element = $([]); - var tm; - - - - function render() { - tm = options.theme ? 'ui' : 'fc'; - var sections = options.header; - if (sections) { - element = $("") - .append( - $("") - .append(renderSection('left')) - .append(renderSection('center')) - .append(renderSection('right')) - ); - return element; - } - } - - - function destroy() { - element.remove(); - } - - - function renderSection(position) { - var e = $("" + - ""; - - if (showWeekNumbers) { - s += ""; - } - - for (i=0; i"; // fc- needed for setDayID - } - s += - "" + - "" + - "" + - "" + - "" + - ""; - for (i=0; i" + // fc- needed for setDayID - "
" + - "
" + - "
 
" + - "
" + - "
" + - ""; - } - s += - "
" + - "" + - "" + - "
"); - var buttonStr = options.header[position]; - if (buttonStr) { - $.each(buttonStr.split(' '), function(i) { - if (i > 0) { - e.append(""); - } - var prevButton; - $.each(this.split(','), function(j, buttonName) { - if (buttonName == 'title') { - e.append("

 

"); - if (prevButton) { - prevButton.addClass(tm + '-corner-right'); - } - prevButton = null; - }else{ - var buttonClick; - if (calendar[buttonName]) { - buttonClick = calendar[buttonName]; // calendar method - } - else if (fcViews[buttonName]) { - buttonClick = function() { - button.removeClass(tm + '-state-hover'); // forget why - calendar.changeView(buttonName); - }; - } - if (buttonClick) { - var icon = options.theme ? smartProperty(options.buttonIcons, buttonName) : null; // why are we using smartProperty here? - var text = smartProperty(options.buttonText, buttonName); // why are we using smartProperty here? - var button = $( - "" + - (icon ? - "" + - "" + - "" : - text - ) + - "" - ) - .click(function() { - if (!button.hasClass(tm + '-state-disabled')) { - buttonClick(); - } - }) - .mousedown(function() { - button - .not('.' + tm + '-state-active') - .not('.' + tm + '-state-disabled') - .addClass(tm + '-state-down'); - }) - .mouseup(function() { - button.removeClass(tm + '-state-down'); - }) - .hover( - function() { - button - .not('.' + tm + '-state-active') - .not('.' + tm + '-state-disabled') - .addClass(tm + '-state-hover'); - }, - function() { - button - .removeClass(tm + '-state-hover') - .removeClass(tm + '-state-down'); - } - ) - .appendTo(e); - disableTextSelection(button); - if (!prevButton) { - button.addClass(tm + '-corner-left'); - } - prevButton = button; - } - } - }); - if (prevButton) { - prevButton.addClass(tm + '-corner-right'); - } - }); - } - return e; - } - - - function updateTitle(html) { - element.find('h2') - .html(html); - } - - - function activateButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .addClass(tm + '-state-active'); - } - - - function deactivateButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .removeClass(tm + '-state-active'); - } - - - function disableButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .addClass(tm + '-state-disabled'); - } - - - function enableButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .removeClass(tm + '-state-disabled'); - } - - -} - -;; - -fc.sourceNormalizers = []; -fc.sourceFetchers = []; - -var ajaxDefaults = { - dataType: 'json', - cache: false -}; - -var eventGUID = 1; - - -function EventManager(options, _sources) { - var t = this; - - - // exports - t.isFetchNeeded = isFetchNeeded; - t.fetchEvents = fetchEvents; - t.addEventSource = addEventSource; - t.removeEventSource = removeEventSource; - t.updateEvent = updateEvent; - t.renderEvent = renderEvent; - t.removeEvents = removeEvents; - t.clientEvents = clientEvents; - t.normalizeEvent = normalizeEvent; - - - // imports - var trigger = t.trigger; - var getView = t.getView; - var reportEvents = t.reportEvents; - - - // locals - var stickySource = { events: [] }; - var sources = [ stickySource ]; - var rangeStart, rangeEnd; - var currentFetchID = 0; - var pendingSourceCnt = 0; - var loadingLevel = 0; - var cache = []; - - - for (var i=0; i<_sources.length; i++) { - _addEventSource(_sources[i]); - } - - - - /* Fetching - -----------------------------------------------------------------------------*/ - - - function isFetchNeeded(start, end) { - return !rangeStart || start < rangeStart || end > rangeEnd; - } - - - function fetchEvents(start, end) { - rangeStart = start; - rangeEnd = end; - cache = []; - var fetchID = ++currentFetchID; - var len = sources.length; - pendingSourceCnt = len; - for (var i=0; i)), return null instead - return null; -} - - -function parseISO8601(s, ignoreTimezone) { // ignoreTimezone defaults to false - // derived from http://delete.me.uk/2005/03/iso8601.html - // TODO: for a know glitch/feature, read tests/issue_206_parseDate_dst.html - var m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2})(:?([0-9]{2}))?))?)?)?)?$/); - if (!m) { - return null; - } - var date = new Date(m[1], 0, 1); - if (ignoreTimezone || !m[13]) { - var check = new Date(m[1], 0, 1, 9, 0); - if (m[3]) { - date.setMonth(m[3] - 1); - check.setMonth(m[3] - 1); - } - if (m[5]) { - date.setDate(m[5]); - check.setDate(m[5]); - } - fixDate(date, check); - if (m[7]) { - date.setHours(m[7]); - } - if (m[8]) { - date.setMinutes(m[8]); - } - if (m[10]) { - date.setSeconds(m[10]); - } - if (m[12]) { - date.setMilliseconds(Number("0." + m[12]) * 1000); - } - fixDate(date, check); - }else{ - date.setUTCFullYear( - m[1], - m[3] ? m[3] - 1 : 0, - m[5] || 1 - ); - date.setUTCHours( - m[7] || 0, - m[8] || 0, - m[10] || 0, - m[12] ? Number("0." + m[12]) * 1000 : 0 - ); - if (m[14]) { - var offset = Number(m[16]) * 60 + (m[18] ? Number(m[18]) : 0); - offset *= m[15] == '-' ? 1 : -1; - date = new Date(+date + (offset * 60 * 1000)); - } - } - return date; -} - - -function parseTime(s) { // returns minutes since start of day - if (typeof s == 'number') { // an hour - return s * 60; - } - if (typeof s == 'object') { // a Date object - return s.getHours() * 60 + s.getMinutes(); - } - var m = s.match(/(\d+)(?::(\d+))?\s*(\w+)?/); - if (m) { - var h = parseInt(m[1], 10); - if (m[3]) { - h %= 12; - if (m[3].toLowerCase().charAt(0) == 'p') { - h += 12; - } - } - return h * 60 + (m[2] ? parseInt(m[2], 10) : 0); - } -} - - - -/* Date Formatting ------------------------------------------------------------------------------*/ -// TODO: use same function formatDate(date, [date2], format, [options]) - - -function formatDate(date, format, options) { - return formatDates(date, null, format, options); -} - - -function formatDates(date1, date2, format, options) { - options = options || defaults; - var date = date1, - otherDate = date2, - i, len = format.length, c, - i2, formatter, - res = ''; - for (i=0; ii; i2--) { - if (formatter = dateFormatters[format.substring(i, i2)]) { - if (date) { - res += formatter(date, options); - } - i = i2 - 1; - break; - } - } - if (i2 == i) { - if (date) { - res += c; - } - } - } - } - return res; -}; - - -var dateFormatters = { - s : function(d) { return d.getSeconds() }, - ss : function(d) { return zeroPad(d.getSeconds()) }, - m : function(d) { return d.getMinutes() }, - mm : function(d) { return zeroPad(d.getMinutes()) }, - h : function(d) { return d.getHours() % 12 || 12 }, - hh : function(d) { return zeroPad(d.getHours() % 12 || 12) }, - H : function(d) { return d.getHours() }, - HH : function(d) { return zeroPad(d.getHours()) }, - d : function(d) { return d.getDate() }, - dd : function(d) { return zeroPad(d.getDate()) }, - ddd : function(d,o) { return o.dayNamesShort[d.getDay()] }, - dddd: function(d,o) { return o.dayNames[d.getDay()] }, - M : function(d) { return d.getMonth() + 1 }, - MM : function(d) { return zeroPad(d.getMonth() + 1) }, - MMM : function(d,o) { return o.monthNamesShort[d.getMonth()] }, - MMMM: function(d,o) { return o.monthNames[d.getMonth()] }, - yy : function(d) { return (d.getFullYear()+'').substring(2) }, - yyyy: function(d) { return d.getFullYear() }, - t : function(d) { return d.getHours() < 12 ? 'a' : 'p' }, - tt : function(d) { return d.getHours() < 12 ? 'am' : 'pm' }, - T : function(d) { return d.getHours() < 12 ? 'A' : 'P' }, - TT : function(d) { return d.getHours() < 12 ? 'AM' : 'PM' }, - u : function(d) { return formatDate(d, "yyyy-MM-dd'T'HH:mm:ss'Z'") }, - S : function(d) { - var date = d.getDate(); - if (date > 10 && date < 20) { - return 'th'; - } - return ['st', 'nd', 'rd'][date%10-1] || 'th'; - }, - w : function(d, o) { // local - return o.weekNumberCalculation(d); - }, - W : function(d) { // ISO - return iso8601Week(d); - } -}; -fc.dateFormatters = dateFormatters; - - -/* thanks jQuery UI (https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js) - * - * Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. - * @param date Date - the date to get the week for - * @return number - the number of the week within the year that contains this date - */ -function iso8601Week(date) { - var time; - var checkDate = new Date(date.getTime()); - - // Find Thursday of this week starting on Monday - checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); - - time = checkDate.getTime(); - checkDate.setMonth(0); // Compare with Jan 1 - checkDate.setDate(1); - return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; -} - - -;; - -fc.applyAll = applyAll; - - -/* Event Date Math ------------------------------------------------------------------------------*/ - - -function exclEndDay(event) { - if (event.end) { - return _exclEndDay(event.end, event.allDay); - }else{ - return addDays(cloneDate(event.start), 1); - } -} - - -function _exclEndDay(end, allDay) { - end = cloneDate(end); - return allDay || end.getHours() || end.getMinutes() ? addDays(end, 1) : clearTime(end); -} - - -function segCmp(a, b) { - return (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start); -} - - -function segsCollide(seg1, seg2) { - return seg1.end > seg2.start && seg1.start < seg2.end; -} - - - -/* Event Sorting ------------------------------------------------------------------------------*/ - - -// event rendering utilities -function sliceSegs(events, visEventEnds, start, end) { - var segs = [], - i, len=events.length, event, - eventStart, eventEnd, - segStart, segEnd, - isStart, isEnd; - for (i=0; i start && eventStart < end) { - if (eventStart < start) { - segStart = cloneDate(start); - isStart = false; - }else{ - segStart = eventStart; - isStart = true; - } - if (eventEnd > end) { - segEnd = cloneDate(end); - isEnd = false; - }else{ - segEnd = eventEnd; - isEnd = true; - } - segs.push({ - event: event, - start: segStart, - end: segEnd, - isStart: isStart, - isEnd: isEnd, - msLength: segEnd - segStart - }); - } - } - return segs.sort(segCmp); -} - - -// event rendering calculation utilities -function stackSegs(segs) { - var levels = [], - i, len = segs.length, seg, - j, collide, k; - for (i=0; i=0; i--) { - res = obj[parts[i].toLowerCase()]; - if (res !== undefined) { - return res; - } - } - return obj['']; -} - - -function htmlEscape(s) { - return s.replace(/&/g, '&') - .replace(//g, '>') - .replace(/'/g, ''') - .replace(/"/g, '"') - .replace(/\n/g, '
'); -} - - -function cssKey(_element) { - return _element.id + '/' + _element.className + '/' + _element.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig, ''); -} - - -function disableTextSelection(element) { - element - .attr('unselectable', 'on') - .css('MozUserSelect', 'none') - .bind('selectstart.ui', function() { return false; }); -} - - -/* -function enableTextSelection(element) { - element - .attr('unselectable', 'off') - .css('MozUserSelect', '') - .unbind('selectstart.ui'); -} -*/ - - -function markFirstLast(e) { - e.children() - .removeClass('fc-first fc-last') - .filter(':first-child') - .addClass('fc-first') - .end() - .filter(':last-child') - .addClass('fc-last'); -} - - -function setDayID(cell, date) { - cell.each(function(i, _cell) { - _cell.className = _cell.className.replace(/^fc-\w*/, 'fc-' + dayIDs[date.getDay()]); - // TODO: make a way that doesn't rely on order of classes - }); -} - - -function getSkinCss(event, opt) { - var source = event.source || {}; - var eventColor = event.color; - var sourceColor = source.color; - var optionColor = opt('eventColor'); - var backgroundColor = - event.backgroundColor || - eventColor || - source.backgroundColor || - sourceColor || - opt('eventBackgroundColor') || - optionColor; - var borderColor = - event.borderColor || - eventColor || - source.borderColor || - sourceColor || - opt('eventBorderColor') || - optionColor; - var textColor = - event.textColor || - source.textColor || - opt('eventTextColor'); - var statements = []; - if (backgroundColor) { - statements.push('background-color:' + backgroundColor); - } - if (borderColor) { - statements.push('border-color:' + borderColor); - } - if (textColor) { - statements.push('color:' + textColor); - } - return statements.join(';'); -} - - -function applyAll(functions, thisObj, args) { - if ($.isFunction(functions)) { - functions = [ functions ]; - } - if (functions) { - var i; - var ret; - for (i=0; i") - .appendTo(element); - } - - - - function buildTable(showNumbers) { - var html = ''; - var i, j; - var headerClass = tm + "-widget-header"; - var contentClass = tm + "-widget-content"; - var month = t.start.getMonth(); - var today = clearTime(new Date()); - var cellDate; // not to be confused with local function. TODO: better names - var cellClasses; - var cell; - - html += "" + - "" + - ""; - - if (showWeekNumbers) { - html += "" + - "" + - ""; - - for (i=0; i" + - "
" + - ""; - } - - for (j=0; j" + - "
"; - if (showNumbers) { - html += "
" + cellDate.getDate() + "
"; - } - html += "
" + - "
 
" + - "
" + - "
" + - ""; - } - - html += ""; - } - html += "
" + - "
"; - } - - for (i=0; i"; - } - - html += "
"; - - lockHeight(); // the unlock happens later, in setHeight()... - if (table) { - table.remove(); - } - table = $(html).appendTo(element); - - head = table.find('thead'); - headCells = head.find('.fc-day-header'); - body = table.find('tbody'); - bodyRows = body.find('tr'); - bodyCells = body.find('.fc-day'); - bodyFirstCells = bodyRows.find('td:first-child'); - bodyCellTopInners = bodyRows.eq(0).find('.fc-day-content > div'); - - markFirstLast(head.add(head.find('tr'))); // marks first+last tr/th's - markFirstLast(bodyRows); // marks first+last td's - bodyRows.eq(0).addClass('fc-first'); - bodyRows.filter(':last').addClass('fc-last'); - - if (showWeekNumbers) { - head.find('.fc-week-number').text(weekNumberTitle); - } - - headCells.each(function(i, _cell) { - var date = indexDate(i); - $(_cell).text(formatDate(date, colFormat)); - }); - - if (showWeekNumbers) { - body.find('.fc-week-number > div').each(function(i, _cell) { - var weekStart = _cellDate(i, 0); - $(_cell).text(formatDate(weekStart, weekNumberFormat)); - }); - } - - bodyCells.each(function(i, _cell) { - var date = indexDate(i); - trigger('dayRender', t, date, $(_cell)); - }); - - dayBind(bodyCells); - } - - - - function setHeight(height) { - viewHeight = height; - - var bodyHeight = viewHeight - head.height(); - var rowHeight; - var rowHeightLast; - var cell; - - if (opt('weekMode') == 'variable') { - rowHeight = rowHeightLast = Math.floor(bodyHeight / (rowCnt==1 ? 2 : 6)); - }else{ - rowHeight = Math.floor(bodyHeight / rowCnt); - rowHeightLast = bodyHeight - rowHeight * (rowCnt-1); - } - - bodyFirstCells.each(function(i, _cell) { - if (i < rowCnt) { - cell = $(_cell); - setMinHeight( - cell.find('> div'), - (i==rowCnt-1 ? rowHeightLast : rowHeight) - vsides(cell) - ); - } - }); - - unlockHeight(); - } - - - function setWidth(width) { - viewWidth = width; - colContentPositions.clear(); - - weekNumberWidth = 0; - if (showWeekNumbers) { - weekNumberWidth = head.find('th.fc-week-number').outerWidth(); - } - - colWidth = Math.floor((viewWidth - weekNumberWidth) / colCnt); - setOuterWidth(headCells.slice(0, -1), colWidth); - } - - - - /* Day clicking and binding - -----------------------------------------------------------*/ - - - function dayBind(days) { - days.click(dayClick) - .mousedown(daySelectionMousedown); - } - - - function dayClick(ev) { - if (!opt('selectable')) { // if selectable, SelectionManager will worry about dayClick - var date = parseISO8601($(this).data('date')); - trigger('dayClick', this, date, true, ev); - } - } - - - - /* Semi-transparent Overlay Helpers - ------------------------------------------------------*/ - - - function renderDayOverlay(overlayStart, overlayEnd, refreshCoordinateGrid) { // overlayEnd is exclusive - if (refreshCoordinateGrid) { - coordinateGrid.build(); - } - var rowStart = cloneDate(t.visStart); - var rowEnd = addDays(cloneDate(rowStart), colCnt); - for (var i=0; i" + - "
"; - } - else { - s += "  
  
"; - dayTable = $(s).appendTo(element); - dayHead = dayTable.find('thead'); - dayHeadCells = dayHead.find('th').slice(1, -1); - dayBody = dayTable.find('tbody'); - dayBodyCells = dayBody.find('td').slice(0, -1); - dayBodyCellInners = dayBodyCells.find('div.fc-day-content div'); - dayBodyFirstCell = dayBodyCells.eq(0); - dayBodyFirstCellStretcher = dayBodyFirstCell.find('> div'); - - markFirstLast(dayHead.add(dayHead.find('tr'))); - markFirstLast(dayBody.add(dayBody.find('tr'))); - - axisFirstCells = dayHead.find('th:first'); - gutterCells = dayTable.find('.fc-agenda-gutter'); - - slotLayer = - $("
") - .appendTo(element); - - if (opt('allDaySlot')) { - - daySegmentContainer = - $("
") - .appendTo(slotLayer); - - s = - "" + - "" + - "" + - "" + - "" + - "" + - "
" + opt('allDayText') + "" + - "
" + - "
 
"; - allDayTable = $(s).appendTo(slotLayer); - allDayRow = allDayTable.find('tr'); - - dayBind(allDayRow.find('td')); - - axisFirstCells = axisFirstCells.add(allDayTable.find('th:first')); - gutterCells = gutterCells.add(allDayTable.find('th.fc-agenda-gutter')); - - slotLayer.append( - "
" + - "
" + - "
" - ); - - }else{ - - daySegmentContainer = $([]); // in jQuery 1.4, we can just do $() - - } - - slotScroller = - $("
") - .appendTo(slotLayer); - - slotContent = - $("
") - .appendTo(slotScroller); - - slotSegmentContainer = - $("
") - .appendTo(slotContent); - - s = - "" + - ""; - d = zeroDate(); - maxd = addMinutes(cloneDate(d), maxMinute); - addMinutes(d, minMinute); - slotCnt = 0; - for (i=0; d < maxd; i++) { - minutes = d.getMinutes(); - s += - "" + - "" + - "" + - ""; - addMinutes(d, opt('slotMinutes')); - slotCnt++; - } - s += - "" + - "
" + - ((!slotNormal || !minutes) ? formatDate(d, opt('axisFormat')) : ' ') + - "" + - "
 
" + - "
"; - slotTable = $(s).appendTo(slotContent); - slotTableFirstInner = slotTable.find('div:first'); - - slotBind(slotTable.find('td')); - - axisFirstCells = axisFirstCells.add(slotTable.find('th:first')); - } - - - - function updateCells() { - var i; - var headCell; - var bodyCell; - var date; - var today = clearTime(new Date()); - - if (showWeekNumbers) { - var weekText = formatDate(colDate(0), weekNumberFormat); - if (rtl) { - weekText = weekText + weekNumberTitle; - } - else { - weekText = weekNumberTitle + weekText; - } - dayHead.find('.fc-week-number').text(weekText); - } - - for (i=0; i= 0) { - addMinutes(d, minMinute + slotIndex * snapMinutes); - } - return d; - } - - - function colDate(col) { // returns dates with 00:00:00 - return addDays(cloneDate(t.visStart), col*dis+dit); - } - - - function cellIsAllDay(cell) { - return opt('allDaySlot') && !cell.row; - } - - - function dayOfWeekCol(dayOfWeek) { - return ((dayOfWeek - Math.max(firstDay, nwe) + colCnt) % colCnt)*dis+dit; - } - - - - - // get the Y coordinate of the given time on the given day (both Date objects) - function timePosition(day, time) { // both date objects. day holds 00:00 of current day - day = cloneDate(day, true); - if (time < addMinutes(cloneDate(day), minMinute)) { - return 0; - } - if (time >= addMinutes(cloneDate(day), maxMinute)) { - return slotTable.height(); - } - var slotMinutes = opt('slotMinutes'), - minutes = time.getHours()*60 + time.getMinutes() - minMinute, - slotI = Math.floor(minutes / slotMinutes), - slotTop = slotTopCache[slotI]; - if (slotTop === undefined) { - slotTop = slotTopCache[slotI] = slotTable.find('tr:eq(' + slotI + ') td div')[0].offsetTop; //.position().top; // need this optimization??? - } - return Math.max(0, Math.round( - slotTop - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes) - )); - } - - - function allDayBounds() { - return { - left: axisWidth, - right: viewWidth - gutterWidth - } - } - - - function getAllDayRow(index) { - return allDayRow; - } - - - function defaultEventEnd(event) { - var start = cloneDate(event.start); - if (event.allDay) { - return start; - } - return addMinutes(start, opt('defaultEventMinutes')); - } - - - - /* Selection - ---------------------------------------------------------------------------------*/ - - - function defaultSelectionEnd(startDate, allDay) { - if (allDay) { - return cloneDate(startDate); - } - return addMinutes(cloneDate(startDate), opt('slotMinutes')); - } - - - function renderSelection(startDate, endDate, allDay) { // only for all-day - if (allDay) { - if (opt('allDaySlot')) { - renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); - } - }else{ - renderSlotSelection(startDate, endDate); - } - } - - - function renderSlotSelection(startDate, endDate) { - var helperOption = opt('selectHelper'); - coordinateGrid.build(); - if (helperOption) { - var col = dayDiff(startDate, t.visStart) * dis + dit; - if (col >= 0 && col < colCnt) { // only works when times are on same day - var rect = coordinateGrid.rect(0, col, 0, col, slotContent); // only for horizontal coords - var top = timePosition(startDate, startDate); - var bottom = timePosition(startDate, endDate); - if (bottom > top) { // protect against selections that are entirely before or after visible range - rect.top = top; - rect.height = bottom - top; - rect.left += 2; - rect.width -= 5; - if ($.isFunction(helperOption)) { - var helperRes = helperOption(startDate, endDate); - if (helperRes) { - rect.position = 'absolute'; - rect.zIndex = 8; - selectionHelper = $(helperRes) - .css(rect) - .appendTo(slotContent); - } - }else{ - rect.isStart = true; // conside rect a "seg" now - rect.isEnd = true; // - selectionHelper = $(slotSegHtml( - { - title: '', - start: startDate, - end: endDate, - className: ['fc-select-helper'], - editable: false - }, - rect - )); - selectionHelper.css('opacity', opt('dragOpacity')); - } - if (selectionHelper) { - slotBind(selectionHelper); - slotContent.append(selectionHelper); - setOuterWidth(selectionHelper, rect.width, true); // needs to be after appended - setOuterHeight(selectionHelper, rect.height, true); - } - } - } - }else{ - renderSlotOverlay(startDate, endDate); - } - } - - - function clearSelection() { - clearOverlays(); - if (selectionHelper) { - selectionHelper.remove(); - selectionHelper = null; - } - } - - - function slotSelectionMousedown(ev) { - if (ev.which == 1 && opt('selectable')) { // ev.which==1 means left mouse button - unselect(ev); - var dates; - hoverListener.start(function(cell, origCell) { - clearSelection(); - if (cell && cell.col == origCell.col && !cellIsAllDay(cell)) { - var d1 = cellDate(origCell); - var d2 = cellDate(cell); - dates = [ - d1, - addMinutes(cloneDate(d1), snapMinutes), // calculate minutes depending on selection slot minutes - d2, - addMinutes(cloneDate(d2), snapMinutes) - ].sort(cmp); - renderSlotSelection(dates[0], dates[3]); - }else{ - dates = null; - } - }, ev); - $(document).one('mouseup', function(ev) { - hoverListener.stop(); - if (dates) { - if (+dates[0] == +dates[1]) { - reportDayClick(dates[0], false, ev); - } - reportSelection(dates[0], dates[3], false, ev); - } - }); - } - } - - - function reportDayClick(date, allDay, ev) { - trigger('dayClick', dayBodyCells[dayOfWeekCol(date.getDay())], date, allDay, ev); - } - - - - /* External Dragging - --------------------------------------------------------------------------------*/ - - - function dragStart(_dragElement, ev, ui) { - hoverListener.start(function(cell) { - clearOverlays(); - if (cell) { - if (cellIsAllDay(cell)) { - renderCellOverlay(cell.row, cell.col, cell.row, cell.col); - }else{ - var d1 = cellDate(cell); - var d2 = addMinutes(cloneDate(d1), opt('defaultEventMinutes')); - renderSlotOverlay(d1, d2); - } - } - }, ev); - } - - - function dragStop(_dragElement, ev, ui) { - var cell = hoverListener.stop(); - clearOverlays(); - if (cell) { - trigger('drop', _dragElement, cellDate(cell), cellIsAllDay(cell), ev, ui); - } - } - - -} - -;; - -function AgendaEventRenderer() { - var t = this; - - - // exports - t.renderEvents = renderEvents; - t.compileDaySegs = compileDaySegs; // for DayEventRenderer - t.clearEvents = clearEvents; - t.slotSegHtml = slotSegHtml; - t.bindDaySeg = bindDaySeg; - - - // imports - DayEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - //var setOverflowHidden = t.setOverflowHidden; - var isEventDraggable = t.isEventDraggable; - var isEventResizable = t.isEventResizable; - var eventEnd = t.eventEnd; - var reportEvents = t.reportEvents; - var reportEventClear = t.reportEventClear; - var eventElementHandlers = t.eventElementHandlers; - var setHeight = t.setHeight; - var getDaySegmentContainer = t.getDaySegmentContainer; - var getSlotSegmentContainer = t.getSlotSegmentContainer; - var getHoverListener = t.getHoverListener; - var getMaxMinute = t.getMaxMinute; - var getMinMinute = t.getMinMinute; - var timePosition = t.timePosition; - var colContentLeft = t.colContentLeft; - var colContentRight = t.colContentRight; - var renderDaySegs = t.renderDaySegs; - var resizableDayEvent = t.resizableDayEvent; // TODO: streamline binding architecture - var getColCnt = t.getColCnt; - var getColWidth = t.getColWidth; - var getSnapHeight = t.getSnapHeight; - var getSnapMinutes = t.getSnapMinutes; - var getBodyContent = t.getBodyContent; - var reportEventElement = t.reportEventElement; - var showEvents = t.showEvents; - var hideEvents = t.hideEvents; - var eventDrop = t.eventDrop; - var eventResize = t.eventResize; - var renderDayOverlay = t.renderDayOverlay; - var clearOverlays = t.clearOverlays; - var calendar = t.calendar; - var formatDate = calendar.formatDate; - var formatDates = calendar.formatDates; - - - - /* Rendering - ----------------------------------------------------------------------------*/ - - - function renderEvents(events, modifiedEventId) { - reportEvents(events); - var i, len=events.length, - dayEvents=[], - slotEvents=[]; - for (i=0; i" + - "
" + - "
" + - htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) + - "
" + - "
" + - htmlEscape(event.title) + - "
" + - "
" + - "
"; - if (seg.isEnd && isEventResizable(event)) { - html += - "
=
"; - } - html += - ""; - return html; - } - - - function bindDaySeg(event, eventElement, seg) { - if (isEventDraggable(event)) { - draggableDayEvent(event, eventElement, seg.isStart); - } - if (seg.isEnd && isEventResizable(event)) { - resizableDayEvent(event, eventElement, seg); - } - eventElementHandlers(event, eventElement); - // needs to be after, because resizableDayEvent might stopImmediatePropagation on click - } - - - function bindSlotSeg(event, eventElement, seg) { - var timeElement = eventElement.find('div.fc-event-time'); - if (isEventDraggable(event)) { - draggableSlotEvent(event, eventElement, timeElement); - } - if (seg.isEnd && isEventResizable(event)) { - resizableSlotEvent(event, eventElement, timeElement); - } - eventElementHandlers(event, eventElement); - } - - - - /* Dragging - -----------------------------------------------------------------------------------*/ - - - // when event starts out FULL-DAY - - function draggableDayEvent(event, eventElement, isStart) { - var origWidth; - var revert; - var allDay=true; - var dayDelta; - var dis = opt('isRTL') ? -1 : 1; - var hoverListener = getHoverListener(); - var colWidth = getColWidth(); - var snapHeight = getSnapHeight(); - var snapMinutes = getSnapMinutes(); - var minMinute = getMinMinute(); - eventElement.draggable({ - zIndex: 9, - opacity: opt('dragOpacity', 'month'), // use whatever the month view was using - revertDuration: opt('dragRevertDuration'), - start: function(ev, ui) { - trigger('eventDragStart', eventElement, event, ev, ui); - hideEvents(event, eventElement); - origWidth = eventElement.width(); - hoverListener.start(function(cell, origCell, rowDelta, colDelta) { - clearOverlays(); - if (cell) { - //setOverflowHidden(true); - revert = false; - dayDelta = colDelta * dis; - if (!cell.row) { - // on full-days - renderDayOverlay( - addDays(cloneDate(event.start), dayDelta), - addDays(exclEndDay(event), dayDelta) - ); - resetElement(); - }else{ - // mouse is over bottom slots - if (isStart) { - if (allDay) { - // convert event to temporary slot-event - eventElement.width(colWidth - 10); // don't use entire width - setOuterHeight( - eventElement, - snapHeight * Math.round( - (event.end ? ((event.end - event.start) / MINUTE_MS) : opt('defaultEventMinutes')) / - snapMinutes - ) - ); - eventElement.draggable('option', 'grid', [colWidth, 1]); - allDay = false; - } - }else{ - revert = true; - } - } - revert = revert || (allDay && !dayDelta); - }else{ - resetElement(); - //setOverflowHidden(false); - revert = true; - } - eventElement.draggable('option', 'revert', revert); - }, ev, 'drag'); - }, - stop: function(ev, ui) { - hoverListener.stop(); - clearOverlays(); - trigger('eventDragStop', eventElement, event, ev, ui); - if (revert) { - // hasn't moved or is out of bounds (draggable has already reverted) - resetElement(); - eventElement.css('filter', ''); // clear IE opacity side-effects - showEvents(event, eventElement); - }else{ - // changed! - var minuteDelta = 0; - if (!allDay) { - minuteDelta = Math.round((eventElement.offset().top - getBodyContent().offset().top) / snapHeight) - * snapMinutes - + minMinute - - (event.start.getHours() * 60 + event.start.getMinutes()); - } - eventDrop(this, event, dayDelta, minuteDelta, allDay, ev, ui); - } - //setOverflowHidden(false); - } - }); - function resetElement() { - if (!allDay) { - eventElement - .width(origWidth) - .height('') - .draggable('option', 'grid', null); - allDay = true; - } - } - } - - - // when event starts out IN TIMESLOTS - - function draggableSlotEvent(event, eventElement, timeElement) { - var origPosition; - var allDay=false; - var dayDelta; - var minuteDelta; - var prevMinuteDelta; - var dis = opt('isRTL') ? -1 : 1; - var hoverListener = getHoverListener(); - var colCnt = getColCnt(); - var colWidth = getColWidth(); - var snapHeight = getSnapHeight(); - var snapMinutes = getSnapMinutes(); - eventElement.draggable({ - zIndex: 9, - scroll: false, - grid: [colWidth, snapHeight], - axis: colCnt==1 ? 'y' : false, - opacity: opt('dragOpacity'), - revertDuration: opt('dragRevertDuration'), - start: function(ev, ui) { - trigger('eventDragStart', eventElement, event, ev, ui); - hideEvents(event, eventElement); - origPosition = eventElement.position(); - minuteDelta = prevMinuteDelta = 0; - hoverListener.start(function(cell, origCell, rowDelta, colDelta) { - eventElement.draggable('option', 'revert', !cell); - clearOverlays(); - if (cell) { - dayDelta = colDelta * dis; - if (opt('allDaySlot') && !cell.row) { - // over full days - if (!allDay) { - // convert to temporary all-day event - allDay = true; - timeElement.hide(); - eventElement.draggable('option', 'grid', null); - } - renderDayOverlay( - addDays(cloneDate(event.start), dayDelta), - addDays(exclEndDay(event), dayDelta) - ); - }else{ - // on slots - resetElement(); - } - } - }, ev, 'drag'); - }, - drag: function(ev, ui) { - minuteDelta = Math.round((ui.position.top - origPosition.top) / snapHeight) * snapMinutes; - if (minuteDelta != prevMinuteDelta) { - if (!allDay) { - updateTimeText(minuteDelta); - } - prevMinuteDelta = minuteDelta; - } - }, - stop: function(ev, ui) { - var cell = hoverListener.stop(); - clearOverlays(); - trigger('eventDragStop', eventElement, event, ev, ui); - if (cell && (dayDelta || minuteDelta || allDay)) { - // changed! - eventDrop(this, event, dayDelta, allDay ? 0 : minuteDelta, allDay, ev, ui); - }else{ - // either no change or out-of-bounds (draggable has already reverted) - resetElement(); - eventElement.css('filter', ''); // clear IE opacity side-effects - eventElement.css(origPosition); // sometimes fast drags make event revert to wrong position - updateTimeText(0); - showEvents(event, eventElement); - } - } - }); - function updateTimeText(minuteDelta) { - var newStart = addMinutes(cloneDate(event.start), minuteDelta); - var newEnd; - if (event.end) { - newEnd = addMinutes(cloneDate(event.end), minuteDelta); - } - timeElement.text(formatDates(newStart, newEnd, opt('timeFormat'))); - } - function resetElement() { - // convert back to original slot-event - if (allDay) { - timeElement.css('display', ''); // show() was causing display=inline - eventElement.draggable('option', 'grid', [colWidth, snapHeight]); - allDay = false; - } - } - } - - - - /* Resizing - --------------------------------------------------------------------------------------*/ - - - function resizableSlotEvent(event, eventElement, timeElement) { - var snapDelta, prevSnapDelta; - var snapHeight = getSnapHeight(); - var snapMinutes = getSnapMinutes(); - eventElement.resizable({ - handles: { - s: '.ui-resizable-handle' - }, - grid: snapHeight, - start: function(ev, ui) { - snapDelta = prevSnapDelta = 0; - hideEvents(event, eventElement); - eventElement.css('z-index', 9); - trigger('eventResizeStart', this, event, ev, ui); - }, - resize: function(ev, ui) { - // don't rely on ui.size.height, doesn't take grid into account - snapDelta = Math.round((Math.max(snapHeight, eventElement.height()) - ui.originalSize.height) / snapHeight); - if (snapDelta != prevSnapDelta) { - timeElement.text( - formatDates( - event.start, - (!snapDelta && !event.end) ? null : // no change, so don't display time range - addMinutes(eventEnd(event), snapMinutes*snapDelta), - opt('timeFormat') - ) - ); - prevSnapDelta = snapDelta; - } - }, - stop: function(ev, ui) { - trigger('eventResizeStop', this, event, ev, ui); - if (snapDelta) { - eventResize(this, event, 0, snapMinutes*snapDelta, ev, ui); - }else{ - eventElement.css('z-index', 8); - showEvents(event, eventElement); - // BUG: if event was really short, need to put title back in span - } - } - }); - } - - -} - - -function countForwardSegs(levels) { - var i, j, k, level, segForward, segBack; - for (i=levels.length-1; i>0; i--) { - level = levels[i]; - for (j=0; j"); - var elements; - var segmentContainer = getDaySegmentContainer(); - var i; - var segCnt = segs.length; - var element; - tempContainer[0].innerHTML = daySegHTML(segs); // faster than .html() - elements = tempContainer.children(); - segmentContainer.append(elements); - daySegElementResolve(segs, elements); - daySegCalcHSides(segs); - daySegSetWidths(segs); - daySegCalcHeights(segs); - daySegSetTops(segs, getRowTops(getRowDivs())); - elements = []; - for (i=0; i" + - "
"; - if (!event.allDay && seg.isStart) { - html += - "" + - htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) + - ""; - } - html += - "" + htmlEscape(event.title) + "" + - "
"; - if (seg.isEnd && isEventResizable(event)) { - html += - "
" + - "   " + // makes hit area a lot better for IE6/7 - "
"; - } - html += - ""; - seg.left = left; - seg.outerWidth = right - left; - seg.startCol = leftCol; - seg.endCol = rightCol + 1; // needs to be exclusive - } - return html; - } - - - function daySegElementResolve(segs, elements) { // sets seg.element - var i; - var segCnt = segs.length; - var seg; - var event; - var element; - var triggerRes; - for (i=0; i div'); // optimal selector? - } - return rowDivs; - } - - - function getRowTops(rowDivs) { - var i; - var rowCnt = rowDivs.length; - var tops = []; - for (i=0; i selection for IE - element - .mousedown(function(ev) { // prevent native selection for others - ev.preventDefault(); - }) - .click(function(ev) { - if (isResizing) { - ev.preventDefault(); // prevent link from being visited (only method that worked in IE6) - ev.stopImmediatePropagation(); // prevent fullcalendar eventClick handler from being called - // (eventElementHandlers needs to be bound after resizableDayEvent) - } - }); - - handle.mousedown(function(ev) { - if (ev.which != 1) { - return; // needs to be left mouse button - } - isResizing = true; - var hoverListener = t.getHoverListener(); - var rowCnt = getRowCnt(); - var colCnt = getColCnt(); - var dis = rtl ? -1 : 1; - var dit = rtl ? colCnt-1 : 0; - var elementTop = element.css('top'); - var dayDelta; - var helpers; - var eventCopy = $.extend({}, event); - var minCell = dateCell(event.start); - clearSelection(); - $('body') - .css('cursor', direction + '-resize') - .one('mouseup', mouseup); - trigger('eventResizeStart', this, event, ev); - hoverListener.start(function(cell, origCell) { - if (cell) { - var r = Math.max(minCell.row, cell.row); - var c = cell.col; - if (rowCnt == 1) { - r = 0; // hack for all-day area in agenda views - } - if (r == minCell.row) { - if (rtl) { - c = Math.min(minCell.col, c); - }else{ - c = Math.max(minCell.col, c); - } - } - dayDelta = (r*7 + c*dis+dit) - (origCell.row*7 + origCell.col*dis+dit); - var newEnd = addDays(eventEnd(event), dayDelta, true); - if (dayDelta) { - eventCopy.end = newEnd; - var oldHelpers = helpers; - helpers = renderTempDaySegs(compileDaySegs([eventCopy]), seg.row, elementTop); - helpers.find('*').css('cursor', direction + '-resize'); - if (oldHelpers) { - oldHelpers.remove(); - } - hideEvents(event); - }else{ - if (helpers) { - showEvents(event); - helpers.remove(); - helpers = null; - } - } - clearOverlays(); - renderDayOverlay(event.start, addDays(cloneDate(newEnd), 1)); // coordinate grid already rebuild at hoverListener.start - } - }, ev); - - function mouseup(ev) { - trigger('eventResizeStop', this, event, ev); - $('body').css('cursor', ''); - hoverListener.stop(); - clearOverlays(); - if (dayDelta) { - eventResize(this, event, dayDelta, 0, ev); - // event redraw will clear helpers - } - // otherwise, the drag handler already restored the old events - - setTimeout(function() { // make this happen after the element's click event - isResizing = false; - },0); - } - - }); - } - - -} - -;; - -//BUG: unselect needs to be triggered when events are dragged+dropped - -function SelectionManager() { - var t = this; - - - // exports - t.select = select; - t.unselect = unselect; - t.reportSelection = reportSelection; - t.daySelectionMousedown = daySelectionMousedown; - - - // imports - var opt = t.opt; - var trigger = t.trigger; - var defaultSelectionEnd = t.defaultSelectionEnd; - var renderSelection = t.renderSelection; - var clearSelection = t.clearSelection; - - - // locals - var selected = false; - - - - // unselectAuto - if (opt('selectable') && opt('unselectAuto')) { - $(document).mousedown(function(ev) { - var ignore = opt('unselectCancel'); - if (ignore) { - if ($(ev.target).parents(ignore).length) { // could be optimized to stop after first match - return; - } - } - unselect(ev); - }); - } - - - function select(startDate, endDate, allDay) { - unselect(); - if (!endDate) { - endDate = defaultSelectionEnd(startDate, allDay); - } - renderSelection(startDate, endDate, allDay); - reportSelection(startDate, endDate, allDay); - } - - - function unselect(ev) { - if (selected) { - selected = false; - clearSelection(); - trigger('unselect', null, ev); - } - } - - - function reportSelection(startDate, endDate, allDay, ev) { - selected = true; - trigger('select', null, startDate, endDate, allDay, ev); - } - - - function daySelectionMousedown(ev) { // not really a generic manager method, oh well - var cellDate = t.cellDate; - var cellIsAllDay = t.cellIsAllDay; - var hoverListener = t.getHoverListener(); - var reportDayClick = t.reportDayClick; // this is hacky and sort of weird - if (ev.which == 1 && opt('selectable')) { // which==1 means left mouse button - unselect(ev); - var _mousedownElement = this; - var dates; - hoverListener.start(function(cell, origCell) { // TODO: maybe put cellDate/cellIsAllDay info in cell - clearSelection(); - if (cell && cellIsAllDay(cell)) { - dates = [ cellDate(origCell), cellDate(cell) ].sort(cmp); - renderSelection(dates[0], dates[1], true); - }else{ - dates = null; - } - }, ev); - $(document).one('mouseup', function(ev) { - hoverListener.stop(); - if (dates) { - if (+dates[0] == +dates[1]) { - reportDayClick(dates[0], true, ev); - } - reportSelection(dates[0], dates[1], true, ev); - } - }); - } - } - - -} - -;; - -function OverlayManager() { - var t = this; - - - // exports - t.renderOverlay = renderOverlay; - t.clearOverlays = clearOverlays; - - - // locals - var usedOverlays = []; - var unusedOverlays = []; - - - function renderOverlay(rect, parent) { - var e = unusedOverlays.shift(); - if (!e) { - e = $("
"); - } - if (e[0].parentNode != parent[0]) { - e.appendTo(parent); - } - usedOverlays.push(e.css(rect).show()); - return e; - } - - - function clearOverlays() { - var e; - while (e = usedOverlays.shift()) { - unusedOverlays.push(e.hide().unbind()); - } - } - - -} - -;; - -function CoordinateGrid(buildFunc) { - - var t = this; - var rows; - var cols; - - - t.build = function() { - rows = []; - cols = []; - buildFunc(rows, cols); - }; - - - t.cell = function(x, y) { - var rowCnt = rows.length; - var colCnt = cols.length; - var i, r=-1, c=-1; - for (i=0; i= rows[i][0] && y < rows[i][1]) { - r = i; - break; - } - } - for (i=0; i= cols[i][0] && x < cols[i][1]) { - c = i; - break; - } - } - return (r>=0 && c>=0) ? { row:r, col:c } : null; - }; - - - t.rect = function(row0, col0, row1, col1, originElement) { // row1,col1 is inclusive - var origin = originElement.offset(); - return { - top: rows[row0][0] - origin.top, - left: cols[col0][0] - origin.left, - width: cols[col1][1] - cols[col0][0], - height: rows[row1][1] - rows[row0][0] - }; - }; - -} - -;; - -function HoverListener(coordinateGrid) { - - - var t = this; - var bindType; - var change; - var firstCell; - var cell; - - - t.start = function(_change, ev, _bindType) { - change = _change; - firstCell = cell = null; - coordinateGrid.build(); - mouse(ev); - bindType = _bindType || 'mousemove'; - $(document).bind(bindType, mouse); - }; - - - function mouse(ev) { - _fixUIEvent(ev); // see below - var newCell = coordinateGrid.cell(ev.pageX, ev.pageY); - if (!newCell != !cell || newCell && (newCell.row != cell.row || newCell.col != cell.col)) { - if (newCell) { - if (!firstCell) { - firstCell = newCell; - } - change(newCell, firstCell, newCell.row-firstCell.row, newCell.col-firstCell.col); - }else{ - change(newCell, firstCell); - } - cell = newCell; - } - } - - - t.stop = function() { - $(document).unbind(bindType, mouse); - return cell; - }; - - -} - - - -// this fix was only necessary for jQuery UI 1.8.16 (and jQuery 1.7 or 1.7.1) -// upgrading to jQuery UI 1.8.17 (and using either jQuery 1.7 or 1.7.1) fixed the problem -// but keep this in here for 1.8.16 users -// and maybe remove it down the line - -function _fixUIEvent(event) { // for issue 1168 - if (event.pageX === undefined) { - event.pageX = event.originalEvent.pageX; - event.pageY = event.originalEvent.pageY; - } -} -;; - -function HorizontalPositionCache(getElement) { - - var t = this, - elements = {}, - lefts = {}, - rights = {}; - - function e(i) { - return elements[i] = elements[i] || getElement(i); - } - - t.left = function(i) { - return lefts[i] = lefts[i] === undefined ? e(i).position().left : lefts[i]; - }; - - t.right = function(i) { - return rights[i] = rights[i] === undefined ? t.left(i) + e(i).width() : rights[i]; - }; - - t.clear = function() { - elements = {}; - lefts = {}; - rights = {}; - }; - -} - -;; - -})(jQuery); \ No newline at end of file diff --git a/app/assets/javascripts/fullcalendar.min.js b/app/assets/javascripts/fullcalendar.min.js new file mode 100644 index 0000000..f43a7f3 --- /dev/null +++ b/app/assets/javascripts/fullcalendar.min.js @@ -0,0 +1,11 @@ +/*! + * FullCalendar v3.6.1 + * Docs & License: https://fullcalendar.io/ + * (c) 2017 Adam Shaw + */ +!function(t){"function"==typeof define&&define.amd?define(["jquery","moment"],t):"object"==typeof exports?module.exports=t(require("jquery"),require("moment")):t(jQuery,moment)}(function(t,e){function n(t){return j(t,qt)}function i(t,e){e.left&&t.css({"border-left-width":1,"margin-left":e.left-1}),e.right&&t.css({"border-right-width":1,"margin-right":e.right-1})}function r(t){t.css({"margin-left":"","margin-right":"","border-left-width":"","border-right-width":""})}function s(){t("body").addClass("fc-not-allowed")}function o(){t("body").removeClass("fc-not-allowed")}function a(e,n,i){var r=Math.floor(n/e.length),s=Math.floor(n-r*(e.length-1)),o=[],a=[],u=[],c=0;l(e),e.each(function(n,i){var l=n===e.length-1?s:r,h=t(i).outerHeight(!0);h *").each(function(e,i){var r=t(i).outerWidth();r>n&&(n=r)}),n++,e.width(n),n}function c(t,e){var n,i=t.add(e);return i.css({position:"relative",left:-1}),n=t.outerHeight()-e.outerHeight(),i.css({position:"",left:""}),n}function h(e){var n=e.css("position"),i=e.parents().filter(function(){var e=t(this);return/(auto|scroll)/.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==n&&i.length?i:t(e[0].ownerDocument||document)}function d(t,e){var n=t.offset(),i=n.left-(e?e.left:0),r=n.top-(e?e.top:0);return{left:i,right:i+t.outerWidth(),top:r,bottom:r+t.outerHeight()}}function f(t,e){var n=t.offset(),i=p(t),r=n.left+w(t,"border-left-width")+i.left-(e?e.left:0),s=n.top+w(t,"border-top-width")+i.top-(e?e.top:0);return{left:r,right:r+t[0].clientWidth,top:s,bottom:s+t[0].clientHeight}}function g(t,e){var n=t.offset(),i=n.left+w(t,"border-left-width")+w(t,"padding-left")-(e?e.left:0),r=n.top+w(t,"border-top-width")+w(t,"padding-top")-(e?e.top:0);return{left:i,right:i+t.width(),top:r,bottom:r+t.height()}}function p(t){var e,n=t[0].offsetWidth-t[0].clientWidth,i=t[0].offsetHeight-t[0].clientHeight;return n=v(n),i=v(i),e={left:0,right:0,top:0,bottom:i},m()&&"rtl"==t.css("direction")?e.left=n:e.right=n,e}function v(t){return t=Math.max(0,t),t=Math.round(t)}function m(){return null===Yt&&(Yt=y()),Yt}function y(){var e=t("
").css({position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}).appendTo("body"),n=e.children(),i=n.offset().left>e.offset().left;return e.remove(),i}function w(t,e){return parseFloat(t.css(e))||0}function D(t){return 1==t.which&&!t.ctrlKey}function b(t){var e=t.originalEvent.touches;return e&&e.length?e[0].pageX:t.pageX}function E(t){var e=t.originalEvent.touches;return e&&e.length?e[0].pageY:t.pageY}function S(t){return/^touch/.test(t.type)}function C(t){t.addClass("fc-unselectable").on("selectstart",T)}function R(t){t.removeClass("fc-unselectable").off("selectstart",T)}function T(t){t.preventDefault()}function I(t,e){var n={left:Math.max(t.left,e.left),right:Math.min(t.right,e.right),top:Math.max(t.top,e.top),bottom:Math.min(t.bottom,e.bottom)};return n.left=1&&at(r)));n++);return i}function N(t,e){var n=O(t);return"week"===n&&"object"==typeof e&&e.days&&(n="day"),n}function V(t,n,i){return null!=i?i.diff(n,t,!0):e.isDuration(n)?n.as(t):n.end.diff(n.start,t,!0)}function G(t,e,n){var i;return _(n)?(e-t)/n:(i=n.asMonths(),Math.abs(i)>=1&&at(i)?e.diff(t,"months",!0)/i:e.diff(t,"days",!0)/n.asDays())}function U(t,e){var n,i;return _(t)||_(e)?t/e:(n=t.asMonths(),i=e.asMonths(),Math.abs(n)>=1&&at(n)&&Math.abs(i)>=1&&at(i)?n/i:t.asDays()/e.asDays())}function W(t,n){var i;return _(t)?e.duration(t*n):(i=t.asMonths(),Math.abs(i)>=1&&at(i)?e.duration({months:i*n}):e.duration({days:t.asDays()*n}))}function _(t){return Boolean(t.hours()||t.minutes()||t.seconds()||t.milliseconds())}function q(t){return"[object Date]"===Object.prototype.toString.call(t)||t instanceof Date}function Y(t){return"string"==typeof t&&/^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(t)}function j(t,e){var n,i,r,s,o,a,l={};if(e)for(n=0;n=0;s--)if("object"==typeof(o=t[s][i]))r.unshift(o);else if(void 0!==o){l[i]=o;break}r.length&&(l[i]=j(r))}for(n=t.length-1;n>=0;n--){a=t[n];for(i in a)i in l||(l[i]=a[i])}return l}function Z(t,e){for(var n in t)Q(t,n)&&(e[n]=t[n])}function Q(t,e){return Qt.call(t,e)}function $(e,n,i){if(t.isFunction(e)&&(e=[e]),e){var r,s;for(r=0;r/g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g,"
")}function nt(t){return t.replace(/&.*?;/g,"")}function it(e){var n=[];return t.each(e,function(t,e){null!=e&&n.push(t+":"+e)}),n.join(";")}function rt(e){var n=[];return t.each(e,function(t,e){null!=e&&n.push(t+'="'+et(e)+'"')}),n.join(" ")}function st(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ot(t,e){return t-e}function at(t){return t%1==0}function lt(t,e){var n=t[e];return function(){return n.apply(t,arguments)}}function ut(t,e,n){var i,r,s,o,a,l=function(){var u=+new Date-o;u"),g.append(o("left")).append(o("right")).append(o("center")).append('
')):s()}function s(){g&&(g.remove(),g=f.el=null)}function o(i){var r=e.theme,s=t('
'),o=n.layout[i],a=e.opt("customButtons")||{},l=e.overrides.buttonText||{},u=e.opt("buttonText")||{};return o&&t.each(o.split(" "),function(n){var i,o=t(),c=!0;t.each(this.split(","),function(n,i){var s,h,d,f,g,v,m,y;"title"==i?(o=o.add(t("

 

")),c=!1):((s=a[i])?(d=function(t){s.click&&s.click.call(y[0],t)},(f=r.getCustomButtonIconClass(s))||(f=r.getIconClass(i))||(g=s.text)):(h=e.getViewSpec(i))?(p.push(i),d=function(){e.changeView(i)},(g=h.buttonTextOverride)||(f=r.getIconClass(i))||(g=h.buttonTextDefault)):e[i]&&(d=function(){e[i]()},(g=l[i])||(f=r.getIconClass(i))||(g=u[i])),d&&(m=["fc-"+i+"-button",r.getClass("button"),r.getClass("stateDefault")],g?v=et(g):f&&(v=""),y=t('").click(function(t){y.hasClass(r.getClass("stateDisabled"))||(d(t),(y.hasClass(r.getClass("stateActive"))||y.hasClass(r.getClass("stateDisabled")))&&y.removeClass(r.getClass("stateHover")))}).mousedown(function(){y.not("."+r.getClass("stateActive")).not("."+r.getClass("stateDisabled")).addClass(r.getClass("stateDown"))}).mouseup(function(){y.removeClass(r.getClass("stateDown"))}).hover(function(){y.not("."+r.getClass("stateActive")).not("."+r.getClass("stateDisabled")).addClass(r.getClass("stateHover"))},function(){y.removeClass(r.getClass("stateHover")).removeClass(r.getClass("stateDown"))}),o=o.add(y)))}),c&&o.first().addClass(r.getClass("cornerLeft")).end().last().addClass(r.getClass("cornerRight")).end(),o.length>1?(i=t("
"),c&&i.addClass(r.getClass("buttonGroup")),i.append(o),s.append(i)):s.append(o)}),s}function a(t){g&&g.find("h2").text(t)}function l(t){g&&g.find(".fc-"+t+"-button").addClass(e.theme.getClass("stateActive"))}function u(t){g&&g.find(".fc-"+t+"-button").removeClass(e.theme.getClass("stateActive"))}function c(t){g&&g.find(".fc-"+t+"-button").prop("disabled",!0).addClass(e.theme.getClass("stateDisabled"))}function h(t){g&&g.find(".fc-"+t+"-button").prop("disabled",!1).removeClass(e.theme.getClass("stateDisabled"))}function d(){return p}var f=this;f.setToolbarOptions=i,f.render=r,f.removeElement=s,f.updateTitle=a,f.activateButton=l,f.deactivateButton=u,f.disableButton=c,f.enableButton=h,f.getViewsWithButtons=d,f.el=null;var g,p=[]}function Et(t,e,n){var i;for(i=0;is&&r.push(new Ue(s,i.startMs)),i.endMs>s&&(s=i.endMs);return s=t.leftCol)return!0;return!1}function At(t,e){return t.leftCol-e.leftCol}function Lt(t){var e,n,i,r=[];for(e=0;ee.top&&t.tops&&(!l[o]||u.isSame(c,l[o]))&&(o-1!==s||"."!==f[o]);o--)v=f[o]+v;for(a=s;a<=o;a++)m+=f[a],y+=g[a];return(m||y)&&(w=r?y+i+m:m+i+y),d(p+w+v)}function r(t){return D[t]||(D[t]=s(t))}function s(t){var e=o(t);return{fakeFormatString:l(e),sameUnits:u(e)}}function o(t){for(var e,n=[],i=/\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;e=i.exec(t);)e[1]?n.push.apply(n,a(e[1])):e[2]?n.push({maybe:o(e[2])}):e[3]?n.push({token:e[3]}):e[5]&&n.push.apply(n,a(e[5]));return n}function a(t){return". "===t?["."," "]:[t]}function l(t){var e,n,i=[];for(e=0;er.value)&&(r=i);return r?r.unit:null}Wt.formatDate=t,Wt.formatRange=n,Wt.oldMomentFormat=e,Wt.queryMostGranularFormatUnit=f;var g="\v",p="",v="",m=new RegExp(v+"([^"+v+"]*)"+v,"g"),y={t:function(t){return e(t,"a").charAt(0)},T:function(t){return e(t,"A").charAt(0)}},w={Y:{value:1,unit:"year"},M:{value:2,unit:"month"},W:{value:3,unit:"week"},w:{value:3,unit:"week"},D:{value:4,unit:"day"},d:{value:4,unit:"day"}},D={}}();var ee=Wt.formatDate,ne=Wt.formatRange,ie=Wt.oldMomentFormat;Wt.Class=dt,dt.extend=function(){var t,e={};for(t=0;t0}},se=Wt.ListenerMixin=function(){var e=0;return{listenerId:null,listenTo:function(e,n,i){if("object"==typeof n)for(var r in n)n.hasOwnProperty(r)&&this.listenTo(e,r,n[r]);else"string"==typeof n&&e.on(n+"."+this.getListenerNamespace(),t.proxy(i,this))},stopListeningTo:function(t,e){t.off((e||"")+"."+this.getListenerNamespace())},getListenerNamespace:function(){return null==this.listenerId&&(this.listenerId=e++),"_listener"+this.listenerId}}}(),oe={standardPropMap:{},applyProps:function(t){var e,n=this.standardPropMap,i={},r={};for(e in t)!0===n[e]?this[e]=t[e]:!1===n[e]?i[e]=t[e]:r[e]=t[e];return this.applyMiscProps(r),this.applyManualStandardProps(i)},applyManualStandardProps:function(t){return!0},applyMiscProps:function(t){},isStandardProp:function(t){return t in this.standardPropMap}},ae=function(t){var e=this.prototype;e.hasOwnProperty("standardPropMap")||(e.standardPropMap=Object.create(e.standardPropMap)),Z(t,e.standardPropMap)},le=function(t,e){var n,i=this.prototype.standardPropMap;for(n in i)null!=t[n]&&!0===i[n]&&(e[n]=t[n])},ue=dt.extend(re,se,{_props:null,_watchers:null,_globalWatchArgs:{},constructor:function(){this._watchers={},this._props={},this.applyGlobalWatchers(),this.constructed()},constructed:function(){},applyGlobalWatchers:function(){var t,e=this._globalWatchArgs;for(t in e)this.watch.apply(this,e[t])},has:function(t){return t in this._props},get:function(t){return void 0===t?this._props:this._props[t]},set:function(t,e){var n;"string"==typeof t?(n={},n[t]=void 0===e?null:e):n=t,this.setProps(n)},reset:function(t){var e,n=this._props,i={};for(e in n)i[e]=void 0;for(e in t)i[e]=t[e];this.setProps(i)},unset:function(t){var e,n,i={};for(e="string"==typeof t?[t]:t,n=0;n=0;e--)switch(n=i[e],n.type){case"init":r=!1;case"add":case"remove":i.splice(e,1)}return r&&i.push(t),r}});Wt.RenderQueue=de;var fe=dt.extend(se,{isHidden:!0,options:null,el:null,margin:10,constructor:function(t){this.options=t||{}},show:function(){this.isHidden&&(this.el||this.render(),this.el.show(),this.position(),this.isHidden=!1,this.trigger("show"))},hide:function(){this.isHidden||(this.el.hide(),this.isHidden=!0,this.trigger("hide"))},render:function(){var e=this,n=this.options;this.el=t('
').addClass(n.className||"").css({top:0,left:0}).append(n.content).appendTo(n.parentEl),this.el.on("click",".fc-close",function(){e.hide()}),n.autoHide&&this.listenTo(t(document),"mousedown",this.documentMousedown)},documentMousedown:function(e){this.el&&!t(e.target).closest(this.el).length&&this.hide()},removeElement:function(){this.hide(),this.el&&(this.el.remove(),this.el=null),this.stopListeningTo(t(document),"mousedown")},position:function(){var e,n,i,r,s,o=this.options,a=this.el.offsetParent().offset(),l=this.el.outerWidth(),u=this.el.outerHeight(),c=t(window),d=h(this.el);r=o.top||0,s=void 0!==o.left?o.left:void 0!==o.right?o.right-l:0,d.is(window)||d.is(document)?(d=c,e=0,n=0):(i=d.offset(),e=i.top,n=i.left),e+=c.scrollTop(),n+=c.scrollLeft(),!1!==o.viewportConstrain&&(r=Math.min(r,e+d.outerHeight()-u-this.margin),r=Math.max(r,e+this.margin),s=Math.min(s,n+d.outerWidth()-l-this.margin),s=Math.max(s,n+this.margin)),this.el.css({top:r-a.top,left:s-a.left})},trigger:function(t){this.options[t]&&this.options[t].apply(this,Array.prototype.slice.call(arguments,1))}}),ge=Wt.CoordCache=dt.extend({els:null,forcedOffsetParentEl:null,origin:null,boundingRect:null,isHorizontal:!1,isVertical:!1,lefts:null,rights:null,tops:null,bottoms:null,constructor:function(e){this.els=t(e.els),this.isHorizontal=e.isHorizontal,this.isVertical=e.isVertical,this.forcedOffsetParentEl=e.offsetParent?t(e.offsetParent):null},build:function(){var t=this.forcedOffsetParentEl;!t&&this.els.length>0&&(t=this.els.eq(0).offsetParent()),this.origin=t?t.offset():null,this.boundingRect=this.queryBoundingRect(),this.isHorizontal&&this.buildElHorizontals(),this.isVertical&&this.buildElVerticals()},clear:function(){this.origin=null,this.boundingRect=null,this.lefts=null,this.rights=null,this.tops=null,this.bottoms=null},ensureBuilt:function(){this.origin||this.build()},buildElHorizontals:function(){var e=[],n=[];this.els.each(function(i,r){var s=t(r),o=s.offset().left,a=s.outerWidth();e.push(o),n.push(o+a)}),this.lefts=e,this.rights=n},buildElVerticals:function(){var e=[],n=[];this.els.each(function(i,r){var s=t(r),o=s.offset().top,a=s.outerHeight();e.push(o),n.push(o+a)}),this.tops=e,this.bottoms=n},getHorizontalIndex:function(t){this.ensureBuilt();var e,n=this.lefts,i=this.rights,r=n.length;for(e=0;e=n[e]&&t=n[e]&&t0&&(t=h(this.els.eq(0)),!t.is(document))?f(t):null},isPointInBounds:function(t,e){return this.isLeftInBounds(t)&&this.isTopInBounds(e)},isLeftInBounds:function(t){return!this.boundingRect||t>=this.boundingRect.left&&t=this.boundingRect.top&&t=i*i&&this.handleDistanceSurpassed(t),this.isDragging&&this.handleDrag(e,n,t)},handleDrag:function(t,e,n){this.trigger("drag",t,e,n),this.updateAutoScroll(n)},endDrag:function(t){this.isDragging&&(this.isDragging=!1,this.handleDragEnd(t))},handleDragEnd:function(t){this.trigger("dragEnd",t)},startDelay:function(t){var e=this;this.delay?this.delayTimeoutId=setTimeout(function(){e.handleDelayEnd(t)},this.delay):this.handleDelayEnd(t)},handleDelayEnd:function(t){this.isDelayEnded=!0,this.isDistanceSurpassed&&this.startDrag(t)},handleDistanceSurpassed:function(t){this.isDistanceSurpassed=!0,this.isDelayEnded&&this.startDrag(t)},handleTouchMove:function(t){this.isDragging&&this.shouldCancelTouchScroll&&t.preventDefault(),this.handleMove(t)},handleMouseMove:function(t){this.handleMove(t)},handleTouchScroll:function(t){this.isDragging&&!this.scrollAlwaysKills||this.endInteraction(t,!0)},trigger:function(t){this.options[t]&&this.options[t].apply(this,Array.prototype.slice.call(arguments,1)),this["_"+t]&&this["_"+t].apply(this,Array.prototype.slice.call(arguments,1))}});pe.mixin({isAutoScroll:!1,scrollBounds:null,scrollTopVel:null,scrollLeftVel:null,scrollIntervalId:null,scrollSensitivity:30,scrollSpeed:200,scrollIntervalMs:50,initAutoScroll:function(){var t=this.scrollEl;this.isAutoScroll=this.options.scroll&&t&&!t.is(window)&&!t.is(document),this.isAutoScroll&&this.listenTo(t,"scroll",ut(this.handleDebouncedScroll,100))},destroyAutoScroll:function(){this.endAutoScroll(),this.isAutoScroll&&this.stopListeningTo(this.scrollEl,"scroll")},computeScrollBounds:function(){this.isAutoScroll&&(this.scrollBounds=d(this.scrollEl))},updateAutoScroll:function(t){var e,n,i,r,s=this.scrollSensitivity,o=this.scrollBounds,a=0,l=0;o&&(e=(s-(E(t)-o.top))/s,n=(s-(o.bottom-E(t)))/s,i=(s-(b(t)-o.left))/s,r=(s-(o.right-b(t)))/s,e>=0&&e<=1?a=e*this.scrollSpeed*-1:n>=0&&n<=1&&(a=n*this.scrollSpeed),i>=0&&i<=1?l=i*this.scrollSpeed*-1:r>=0&&r<=1&&(l=r*this.scrollSpeed)),this.setScrollVel(a,l)},setScrollVel:function(t,e){this.scrollTopVel=t,this.scrollLeftVel=e,this.constrainScrollVel(),!this.scrollTopVel&&!this.scrollLeftVel||this.scrollIntervalId||(this.scrollIntervalId=setInterval(lt(this,"scrollIntervalFunc"),this.scrollIntervalMs))},constrainScrollVel:function(){var t=this.scrollEl;this.scrollTopVel<0?t.scrollTop()<=0&&(this.scrollTopVel=0):this.scrollTopVel>0&&t.scrollTop()+t[0].clientHeight>=t[0].scrollHeight&&(this.scrollTopVel=0),this.scrollLeftVel<0?t.scrollLeft()<=0&&(this.scrollLeftVel=0):this.scrollLeftVel>0&&t.scrollLeft()+t[0].clientWidth>=t[0].scrollWidth&&(this.scrollLeftVel=0)},scrollIntervalFunc:function(){var t=this.scrollEl,e=this.scrollIntervalMs/1e3;this.scrollTopVel&&t.scrollTop(t.scrollTop()+this.scrollTopVel*e),this.scrollLeftVel&&t.scrollLeft(t.scrollLeft()+this.scrollLeftVel*e),this.constrainScrollVel(),this.scrollTopVel||this.scrollLeftVel||this.endAutoScroll()},endAutoScroll:function(){this.scrollIntervalId&&(clearInterval(this.scrollIntervalId),this.scrollIntervalId=null,this.handleScrollEnd())},handleDebouncedScroll:function(){this.scrollIntervalId||this.handleScrollEnd()},handleScrollEnd:function(){}});var ve=pe.extend({component:null,origHit:null,hit:null,coordAdjust:null,constructor:function(t,e){pe.call(this,e),this.component=t},handleInteractionStart:function(t){var e,n,i,r=this.subjectEl;this.component.hitsNeeded(),this.computeScrollBounds(),t?(n={left:b(t),top:E(t)},i=n,r&&(e=d(r),i=H(i,e)),this.origHit=this.queryHit(i.left,i.top),r&&this.options.subjectCenter&&(this.origHit&&(e=I(this.origHit,e)||e),i=M(e)),this.coordAdjust=x(i,n)):(this.origHit=null,this.coordAdjust=null),pe.prototype.handleInteractionStart.apply(this,arguments)},handleDragStart:function(t){var e;pe.prototype.handleDragStart.apply(this,arguments),(e=this.queryHit(b(t),E(t)))&&this.handleHitOver(e)},handleDrag:function(t,e,n){var i;pe.prototype.handleDrag.apply(this,arguments),i=this.queryHit(b(n),E(n)),vt(i,this.hit)||(this.hit&&this.handleHitOut(),i&&this.handleHitOver(i))},handleDragEnd:function(){this.handleHitDone(),pe.prototype.handleDragEnd.apply(this,arguments)},handleHitOver:function(t){var e=vt(t,this.origHit);this.hit=t,this.trigger("hitOver",this.hit,e,this.origHit)},handleHitOut:function(){this.hit&&(this.trigger("hitOut",this.hit),this.handleHitDone(),this.hit=null)},handleHitDone:function(){this.hit&&this.trigger("hitDone",this.hit)},handleInteractionEnd:function(){pe.prototype.handleInteractionEnd.apply(this,arguments),this.origHit=null,this.hit=null,this.component.hitsNotNeeded()},handleScrollEnd:function(){pe.prototype.handleScrollEnd.apply(this,arguments),this.isDragging&&(this.component.releaseHits(),this.component.prepareHits())},queryHit:function(t,e){return this.coordAdjust&&(t+=this.coordAdjust.left,e+=this.coordAdjust.top),this.component.queryHit(t,e)}});Wt.touchMouseIgnoreWait=500;var me=dt.extend(se,re,{isTouching:!1,mouseIgnoreDepth:0,handleScrollProxy:null,bind:function(){var e=this;this.listenTo(t(document),{touchstart:this.handleTouchStart,touchcancel:this.handleTouchCancel,touchend:this.handleTouchEnd,mousedown:this.handleMouseDown,mousemove:this.handleMouseMove,mouseup:this.handleMouseUp,click:this.handleClick,selectstart:this.handleSelectStart,contextmenu:this.handleContextMenu}),window.addEventListener("touchmove",this.handleTouchMoveProxy=function(n){e.handleTouchMove(t.Event(n))},{passive:!1}),window.addEventListener("scroll",this.handleScrollProxy=function(n){e.handleScroll(t.Event(n))},!0)},unbind:function(){this.stopListeningTo(t(document)),window.removeEventListener("touchmove",this.handleTouchMoveProxy),window.removeEventListener("scroll",this.handleScrollProxy,!0)},handleTouchStart:function(t){this.stopTouch(t,!0),this.isTouching=!0,this.trigger("touchstart",t)},handleTouchMove:function(t){this.isTouching&&this.trigger("touchmove",t)},handleTouchCancel:function(t){this.isTouching&&(this.trigger("touchcancel",t),this.stopTouch(t))},handleTouchEnd:function(t){this.stopTouch(t)},handleMouseDown:function(t){this.shouldIgnoreMouse()||this.trigger("mousedown",t)},handleMouseMove:function(t){this.shouldIgnoreMouse()||this.trigger("mousemove",t)},handleMouseUp:function(t){this.shouldIgnoreMouse()||this.trigger("mouseup",t)},handleClick:function(t){this.shouldIgnoreMouse()||this.trigger("click",t)},handleSelectStart:function(t){this.trigger("selectstart",t)},handleContextMenu:function(t){this.trigger("contextmenu",t)},handleScroll:function(t){this.trigger("scroll",t)},stopTouch:function(t,e){this.isTouching&&(this.isTouching=!1,this.trigger("touchend",t),e||this.startTouchMouseIgnore())},startTouchMouseIgnore:function(){var t=this,e=Wt.touchMouseIgnoreWait;e&&(this.mouseIgnoreDepth++,setTimeout(function(){t.mouseIgnoreDepth--},e))},shouldIgnoreMouse:function(){return this.isTouching||Boolean(this.mouseIgnoreDepth)}});!function(){var t=null,e=0;me.get=function(){return t||(t=new me,t.bind()),t},me.needed=function(){me.get(),e++},me.unneeded=function(){--e||(t.unbind(),t=null)}}();var ye=dt.extend(se,{options:null,sourceEl:null,el:null,parentEl:null,top0:null,left0:null,y0:null,x0:null,topDelta:null,leftDelta:null,isFollowing:!1,isHidden:!1,isAnimating:!1,constructor:function(e,n){this.options=n=n||{},this.sourceEl=e,this.parentEl=n.parentEl?t(n.parentEl):e.parent()},start:function(e){this.isFollowing||(this.isFollowing=!0,this.y0=E(e),this.x0=b(e),this.topDelta=0,this.leftDelta=0,this.isHidden||this.updatePosition(),S(e)?this.listenTo(t(document),"touchmove",this.handleMove):this.listenTo(t(document),"mousemove",this.handleMove))},stop:function(e,n){function i(){r.isAnimating=!1,r.removeElement(),r.top0=r.left0=null,n&&n()}var r=this,s=this.options.revertDuration;this.isFollowing&&!this.isAnimating&&(this.isFollowing=!1,this.stopListeningTo(t(document)),e&&s&&!this.isHidden?(this.isAnimating=!0,this.el.animate({top:this.top0,left:this.left0},{duration:s,complete:i})):i())},getEl:function(){var t=this.el;return t||(t=this.el=this.sourceEl.clone().addClass(this.options.additionalClass||"").css({position:"absolute",visibility:"",display:this.isHidden?"none":"",margin:0,right:"auto",bottom:"auto",width:this.sourceEl.width(),height:this.sourceEl.height(),opacity:this.options.opacity||"",zIndex:this.options.zIndex}),t.addClass("fc-unselectable"),t.appendTo(this.parentEl)),t},removeElement:function(){this.el&&(this.el.remove(),this.el=null)},updatePosition:function(){var t,e;this.getEl(),null===this.top0&&(t=this.sourceEl.offset(),e=this.el.offsetParent().offset(),this.top0=t.top-e.top,this.left0=t.left-e.left),this.el.css({top:this.top0+this.topDelta,left:this.left0+this.leftDelta})},handleMove:function(t){this.topDelta=E(t)-this.y0,this.leftDelta=b(t)-this.x0,this.isHidden||this.updatePosition()},hide:function(){this.isHidden||(this.isHidden=!0,this.el&&this.el.hide())},show:function(){this.isHidden&&(this.isHidden=!1,this.updatePosition(),this.getEl().show())}}),we=Wt.Scroller=dt.extend({el:null,scrollEl:null,overflowX:null,overflowY:null,constructor:function(t){t=t||{},this.overflowX=t.overflowX||t.overflow||"auto",this.overflowY=t.overflowY||t.overflow||"auto"},render:function(){this.el=this.renderEl(),this.applyOverflow()},renderEl:function(){return this.scrollEl=t('
')},clear:function(){this.setHeight("auto"),this.applyOverflow()},destroy:function(){this.el.remove()},applyOverflow:function(){this.scrollEl.css({"overflow-x":this.overflowX,"overflow-y":this.overflowY})},lockOverflow:function(t){var e=this.overflowX,n=this.overflowY;t=t||this.getScrollbarWidths(),"auto"===e&&(e=t.top||t.bottom||this.scrollEl[0].scrollWidth-1>this.scrollEl[0].clientWidth?"scroll":"hidden"),"auto"===n&&(n=t.left||t.right||this.scrollEl[0].scrollHeight-1>this.scrollEl[0].clientHeight?"scroll":"hidden"),this.scrollEl.css({"overflow-x":e,"overflow-y":n})},setHeight:function(t){this.scrollEl.height(t)},getScrollTop:function(){return this.scrollEl.scrollTop()},setScrollTop:function(t){this.scrollEl.scrollTop(t)},getClientWidth:function(){return this.scrollEl[0].clientWidth},getClientHeight:function(){return this.scrollEl[0].clientHeight},getScrollbarWidths:function(){return p(this.scrollEl)}});yt.prototype.proxyCall=function(t){var e=Array.prototype.slice.call(arguments,1),n=[];return this.items.forEach(function(i){n.push(i[t].apply(i,e))}),n};var De=dt.extend({view:null,component:null,constructor:function(t){this.view=t._getView(),this.component=t},opt:function(t){return this.view.opt(t)},end:function(){}}),be=De.extend({dragListener:null,constructor:function(t){De.call(this,t),this.dragListener=this.buildDragListener()},end:function(){this.dragListener.endInteraction()},bindToEl:function(t){var e=this.component,n=this.dragListener;e.bindDateHandlerToEl(t,"mousedown",function(t){e.shouldIgnoreMouse()||n.startInteraction(t)}),e.bindDateHandlerToEl(t,"touchstart",function(t){e.shouldIgnoreTouch()||n.startInteraction(t)})},buildDragListener:function(){var t,e=this,n=this.component,i=new ve(n,{scroll:this.opt("dragScroll"),interactionStart:function(){t=i.origHit},hitOver:function(e,n,i){n||(t=null)},hitOut:function(){t=null},interactionEnd:function(i,r){var s;!r&&t&&(s=n.getSafeHitFootprint(t))&&e.view.triggerDayClick(s,n.getHitEl(t),i)}});return i.shouldCancelTouchScroll=!1,i.scrollAlwaysKills=!0,i}}),Ee=Wt.DateSelecting=De.extend({dragListener:null,constructor:function(t){De.call(this,t),this.dragListener=this.buildDragListener()},end:function(){this.dragListener.endInteraction()},getDelay:function(){var t=this.opt("selectLongPressDelay");return null==t&&(t=this.opt("longPressDelay")),t},bindToEl:function(t){var e=this,n=this.component,i=this.dragListener;n.bindDateHandlerToEl(t,"mousedown",function(t){e.opt("selectable")&&!n.shouldIgnoreMouse()&&i.startInteraction(t,{distance:e.opt("selectMinDistance")})}),n.bindDateHandlerToEl(t,"touchstart",function(t){e.opt("selectable")&&!n.shouldIgnoreTouch()&&i.startInteraction(t,{delay:e.getDelay()})}),C(t)},buildDragListener:function(){var t,e=this,n=this.component;return new ve(n,{scroll:this.opt("dragScroll"),interactionStart:function(){t=null},dragStart:function(t){e.view.unselect(t)},hitOver:function(i,r,o){var a,l;o&&(a=n.getSafeHitFootprint(o),l=n.getSafeHitFootprint(i),t=a&&l?e.computeSelection(a,l):null,t?n.renderSelectionFootprint(t):!1===t&&s())},hitOut:function(){t=null,n.unrenderSelection()},hitDone:function(){o()},interactionEnd:function(n,i){!i&&t&&e.view.reportSelection(t,n)}})},computeSelection:function(t,e){var n=this.computeSelectionFootprint(t,e);return!(n&&!this.isSelectionFootprintAllowed(n))&&n},computeSelectionFootprint:function(t,e){var n=[t.unzonedRange.startMs,t.unzonedRange.endMs,e.unzonedRange.startMs,e.unzonedRange.endMs];return n.sort(ot),new We(new Ue(n[0],n[3]),t.isAllDay)},isSelectionFootprintAllowed:function(t){return this.component.dateProfile.validUnzonedRange.containsRange(t.unzonedRange)&&this.view.calendar.isSelectionFootprintAllowed(t)}}),Se=Wt.EventDragging=De.extend({eventPointing:null,dragListener:null,isDragging:!1,constructor:function(t,e){De.call(this,t),this.eventPointing=e},end:function(){this.dragListener&&this.dragListener.endInteraction()},getSelectionDelay:function(){var t=this.opt("eventLongPressDelay");return null==t&&(t=this.opt("longPressDelay")),t},bindToEl:function(t){var e=this.component;e.bindSegHandlerToEl(t,"mousedown",this.handleMousedown.bind(this)),e.bindSegHandlerToEl(t,"touchstart",this.handleTouchStart.bind(this))},handleMousedown:function(t,e){this.component.canStartDrag(t,e)&&this.buildDragListener(t).startInteraction(e,{distance:5})},handleTouchStart:function(t,e){var n=this.component,i={delay:this.view.isEventDefSelected(t.footprint.eventDef)?0:this.getSelectionDelay()};n.canStartDrag(t,e)?this.buildDragListener(t).startInteraction(e,i):n.canStartSelection(t,e)&&this.buildSelectListener(t).startInteraction(e,i)},buildSelectListener:function(t){var e=this,n=this.view,i=t.footprint.eventDef,r=t.footprint.eventInstance;if(this.dragListener)return this.dragListener;var s=this.dragListener=new pe({dragStart:function(t){s.isTouch&&!n.isEventDefSelected(i)&&r&&n.selectEventInstance(r)},interactionEnd:function(t){e.dragListener=null}});return s},buildDragListener:function(t){var e,n,i,r=this,a=this.component,l=this.view,u=l.calendar,c=u.eventManager,h=t.el,d=t.footprint.eventDef,f=t.footprint.eventInstance;if(this.dragListener)return this.dragListener;var g=this.dragListener=new ve(l,{scroll:this.opt("dragScroll"),subjectEl:h,subjectCenter:!0,interactionStart:function(i){t.component=a,e=!1,n=new ye(t.el,{additionalClass:"fc-dragging",parentEl:l.el,opacity:g.isTouch?null:r.opt("dragOpacity"),revertDuration:r.opt("dragRevertDuration"),zIndex:2}),n.hide(),n.start(i)},dragStart:function(n){g.isTouch&&!l.isEventDefSelected(d)&&f&&l.selectEventInstance(f),e=!0,r.eventPointing.handleMouseout(t,n),r.segDragStart(t,n),l.hideEventsWithId(t.footprint.eventDef.id)},hitOver:function(e,o,h){var f,p,v,m=!0;t.hit&&(h=t.hit),f=h.component.getSafeHitFootprint(h),p=e.component.getSafeHitFootprint(e),f&&p?(i=r.computeEventDropMutation(f,p,d),i?(v=c.buildMutatedEventInstanceGroup(d.id,i),m=a.isEventInstanceGroupAllowed(v)):m=!1):m=!1,m||(i=null,s()),i&&l.renderDrag(a.eventRangesToEventFootprints(v.sliceRenderRanges(a.dateProfile.renderUnzonedRange,u)),t,g.isTouch)?n.hide():n.show(),o&&(i=null)},hitOut:function(){l.unrenderDrag(t),n.show(),i=null},hitDone:function(){o()},interactionEnd:function(s){delete t.component,n.stop(!i,function(){e&&(l.unrenderDrag(t),r.segDragStop(t,s)),l.showEventsWithId(t.footprint.eventDef.id),i&&l.reportEventDrop(f,i,h,s)}),r.dragListener=null}});return g},segDragStart:function(t,e){this.isDragging=!0,this.component.publiclyTrigger("eventDragStart",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,{},this.view]})},segDragStop:function(t,e){this.isDragging=!1,this.component.publiclyTrigger("eventDragStop",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,{},this.view]})},computeEventDropMutation:function(t,e,n){var i=new rn;return i.setDateMutation(this.computeEventDateMutation(t,e)),i},computeEventDateMutation:function(t,e){var n,i,r=t.unzonedRange.getStart(),s=e.unzonedRange.getStart(),o=!1,a=!1,l=!1;return t.isAllDay!==e.isAllDay&&(o=!0,e.isAllDay?(l=!0,r.stripTime()):a=!0),n=this.component.diffDates(s,r),i=new sn,i.clearEnd=o,i.forceTimed=a,i.forceAllDay=l,i.setDateDelta(n),i}}),Ce=Wt.EventResizing=De.extend({eventPointing:null,dragListener:null,isResizing:!1,constructor:function(t,e){De.call(this,t),this.eventPointing=e},end:function(){this.dragListener&&this.dragListener.endInteraction()},bindToEl:function(t){var e=this.component;e.bindSegHandlerToEl(t,"mousedown",this.handleMouseDown.bind(this)),e.bindSegHandlerToEl(t,"touchstart",this.handleTouchStart.bind(this))},handleMouseDown:function(e,n){this.component.canStartResize(e,n)&&this.buildDragListener(e,t(n.target).is(".fc-start-resizer")).startInteraction(n,{distance:5})},handleTouchStart:function(e,n){this.component.canStartResize(e,n)&&this.buildDragListener(e,t(n.target).is(".fc-start-resizer")).startInteraction(n)},buildDragListener:function(t,e){var n,i,r=this,a=this.component,l=this.view,u=l.calendar,c=u.eventManager,h=t.el,d=t.footprint.eventDef,f=t.footprint.eventInstance;return this.dragListener=new ve(a,{scroll:this.opt("dragScroll"),subjectEl:h,interactionStart:function(){n=!1},dragStart:function(e){n=!0,r.eventPointing.handleMouseout(t,e),r.segResizeStart(t,e)},hitOver:function(n,o,h){var f,g=!0,p=a.getSafeHitFootprint(h),v=a.getSafeHitFootprint(n);p&&v?(i=e?r.computeEventStartResizeMutation(p,v,t.footprint):r.computeEventEndResizeMutation(p,v,t.footprint),i?(f=c.buildMutatedEventInstanceGroup(d.id,i),g=a.isEventInstanceGroupAllowed(f)):g=!1):g=!1,g?i.isEmpty()&&(i=null):(i=null,s()),i&&(l.hideEventsWithId(t.footprint.eventDef.id),l.renderEventResize(a.eventRangesToEventFootprints(f.sliceRenderRanges(a.dateProfile.renderUnzonedRange,u)),t))},hitOut:function(){i=null},hitDone:function(){l.unrenderEventResize(t),l.showEventsWithId(t.footprint.eventDef.id),o()},interactionEnd:function(e){n&&r.segResizeStop(t,e),i&&l.reportEventResize(f,i,h,e),r.dragListener=null}})},segResizeStart:function(t,e){this.isResizing=!0,this.component.publiclyTrigger("eventResizeStart",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,{},this.view]})},segResizeStop:function(t,e){this.isResizing=!1,this.component.publiclyTrigger("eventResizeStop",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,{},this.view]})},computeEventStartResizeMutation:function(t,e,n){var i,r,s=n.componentFootprint.unzonedRange,o=this.component.diffDates(e.unzonedRange.getStart(),t.unzonedRange.getStart());return s.getStart().add(o)s.getStart()&&(i=new sn,i.setEndDelta(o),r=new rn,r.setDateMutation(i),r)}}),Re=Wt.ExternalDropping=De.extend(se,{dragListener:null,isDragging:!1,end:function(){this.dragListener&&this.dragListener.endInteraction()},bindToDocument:function(){this.listenTo(t(document),{dragstart:this.handleDragStart,sortstart:this.handleDragStart})},unbindFromDocument:function(){this.stopListeningTo(t(document))},handleDragStart:function(e,n){var i,r;this.opt("droppable")&&(i=t((n?n.item:null)||e.target),r=this.opt("dropAccept"),(t.isFunction(r)?r.call(i[0],i):i.is(r))&&(this.isDragging||this.listenToExternalDrag(i,e,n)))},listenToExternalDrag:function(t,e,n){var i,r=this,a=this.component,l=this.view,u=wt(t);(r.dragListener=new ve(a,{interactionStart:function(){r.isDragging=!0},hitOver:function(t){var e,n=!0,o=t.component.getSafeHitFootprint(t);o?(i=r.computeExternalDrop(o,u),i?(e=new Je(i.buildInstances()),n=u.eventProps?a.isEventInstanceGroupAllowed(e):a.isExternalInstanceGroupAllowed(e)):n=!1):n=!1,n||(i=null,s()),i&&a.renderDrag(a.eventRangesToEventFootprints(e.sliceRenderRanges(a.dateProfile.renderUnzonedRange,l.calendar)))},hitOut:function(){i=null},hitDone:function(){o(),a.unrenderDrag()},interactionEnd:function(e){i&&l.reportExternalDrop(i,Boolean(u.eventProps),Boolean(u.stick),t,e,n),r.isDragging=!1,r.dragListener=null}})).startDrag(e)},computeExternalDrop:function(e,n){var i,r=this.view.calendar,s=Wt.moment.utc(e.unzonedRange.startMs).stripZone();return e.isAllDay&&(n.startTime?s.time(n.startTime):s.stripTime()),n.duration&&(i=s.clone().add(n.duration)),s=r.applyTimezone(s),i&&(i=r.applyTimezone(i)),$e.parse(t.extend({},n.eventProps,{start:s,end:i}),new on(r))}});Wt.dataAttrPrefix="";var Te=Wt.EventPointing=De.extend({mousedOverSeg:null,bindToEl:function(t){var e=this.component;e.bindSegHandlerToEl(t,"click",this.handleClick.bind(this)),e.bindSegHandlerToEl(t,"mouseenter",this.handleMouseover.bind(this)),e.bindSegHandlerToEl(t,"mouseleave",this.handleMouseout.bind(this))},handleClick:function(t,e){!1===this.component.publiclyTrigger("eventClick",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,this.view]})&&e.preventDefault()},handleMouseover:function(t,e){me.get().shouldIgnoreMouse()||this.mousedOverSeg||(this.mousedOverSeg=t,this.view.isEventDefResizable(t.footprint.eventDef)&&t.el.addClass("fc-allow-mouse-resize"),this.component.publiclyTrigger("eventMouseover",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,this.view]}))},handleMouseout:function(t,e){this.mousedOverSeg&&(this.mousedOverSeg=null,this.view.isEventDefResizable(t.footprint.eventDef)&&t.el.removeClass("fc-allow-mouse-resize"),this.component.publiclyTrigger("eventMouseout",{context:t.el[0],args:[t.footprint.getEventLegacy(),e||{},this.view]}))},end:function(){this.mousedOverSeg&&this.handleMouseout(this.mousedOverSeg)}}),Ie=Wt.StandardInteractionsMixin={dateClickingClass:be,dateSelectingClass:Ee,eventPointingClass:Te,eventDraggingClass:Se,eventResizingClass:Ce,externalDroppingClass:Re},He=Wt.EventRenderer=dt.extend({view:null,component:null,fillRenderer:null,fgSegs:null,bgSegs:null,eventTimeFormat:null,displayEventTime:null,displayEventEnd:null,constructor:function(t,e){this.view=t._getView(),this.component=t,this.fillRenderer=e},opt:function(t){return this.view.opt(t)},rangeUpdated:function(){var t,e;this.eventTimeFormat=this.opt("eventTimeFormat")||this.opt("timeFormat")||this.computeEventTimeFormat(),t=this.opt("displayEventTime"),null==t&&(t=this.computeDisplayEventTime()),e=this.opt("displayEventEnd"),null==e&&(e=this.computeDisplayEventEnd()),this.displayEventTime=t,this.displayEventEnd=e},render:function(t){var e,n,i,r=this.component._getDateProfile(),s=[],o=[];for(e in t)n=t[e],i=n.sliceRenderRanges(r.activeUnzonedRange),n.getEventDef().hasBgRendering()?s.push.apply(s,i):o.push.apply(o,i);this.renderBgRanges(s),this.renderFgRanges(o)},unrender:function(){this.unrenderBgRanges(),this.unrenderFgRanges()},renderFgRanges:function(t){var e=this.component.eventRangesToEventFootprints(t),n=this.component.eventFootprintsToSegs(e);n=this.renderFgSegEls(n),!1!==this.renderFgSegs(n)&&(this.fgSegs=n)},unrenderFgRanges:function(){this.unrenderFgSegs(this.fgSegs||[]),this.fgSegs=null},renderBgRanges:function(t){var e=this.component.eventRangesToEventFootprints(t),n=this.component.eventFootprintsToSegs(e);!1!==this.renderBgSegs(n)&&(this.bgSegs=n)},unrenderBgRanges:function(){this.unrenderBgSegs(),this.bgSegs=null},getSegs:function(){return(this.bgSegs||[]).concat(this.fgSegs||[])},renderFgSegs:function(t){return!1},unrenderFgSegs:function(t){},renderBgSegs:function(t){var e=this;if(!this.fillRenderer)return!1;this.fillRenderer.renderSegs("bgEvent",t,{getClasses:function(t){return e.getBgClasses(t.footprint.eventDef)},getCss:function(t){return{"background-color":e.getBgColor(t.footprint.eventDef)}},filterEl:function(t,n){return e.filterEventRenderEl(t.footprint,n)}})},unrenderBgSegs:function(){this.fillRenderer&&this.fillRenderer.unrender("bgEvent")},renderFgSegEls:function(e,n){var i,r=this,s=this.view.hasPublicHandlers("eventRender"),o="",a=[];if(e.length){for(i=0;i"},attachSegEls:function(t,e){},reportEls:function(e,n){this.elsByFill[e]?this.elsByFill[e]=this.elsByFill[e].add(n):this.elsByFill[e]=t(n)}}),Pe=Wt.HelperRenderer=dt.extend({view:null,component:null,eventRenderer:null,helperEls:null,constructor:function(t,e){this.view=t._getView(),this.component=t,this.eventRenderer=e},renderComponentFootprint:function(t){this.renderEventFootprints([this.fabricateEventFootprint(t)])},renderEventDraggingFootprints:function(t,e,n){this.renderEventFootprints(t,e,"fc-dragging",n?null:this.view.opt("dragOpacity"))},renderEventResizingFootprints:function(t,e,n){this.renderEventFootprints(t,e,"fc-resizing")},renderEventFootprints:function(t,e,n,i){var r,s=this.component.eventFootprintsToSegs(t),o="fc-helper "+(n||"");for(s=this.eventRenderer.renderFgSegEls(s),r=0;r'+i+"
":""+i+""},getAllDayHtml:function(){return this.opt("allDayHtml")||et(this.opt("allDayText"))},getDayClasses:function(t,e){var n,i=this._getView(),r=[];return this.dateProfile.activeUnzonedRange.containsDate(t)?(r.push("fc-"+jt[t.day()]),i.isDateInOtherMonth(t,this.dateProfile)&&r.push("fc-other-month"),n=i.calendar.getNow(),t.isSame(n,"day")?(r.push("fc-today"),!0!==e&&r.push(i.calendar.theme.getClass("today"))):t=this.nextDayThreshold&&s.add(1,"days"),s<=n&&(s=n.clone().add(1,"days")),{start:n,end:s}},isMultiDayRange:function(t){var e=this.computeDayRange(t);return e.end.diff(e.start,"days")>1}});var ke=Wt.InteractiveDateComponent=Fe.extend({dateClickingClass:null,dateSelectingClass:null,eventPointingClass:null,eventDraggingClass:null,eventResizingClass:null,externalDroppingClass:null,dateClicking:null,dateSelecting:null,eventPointing:null,eventDragging:null,eventResizing:null,externalDropping:null,segSelector:".fc-event-container > *",largeUnit:null,constructor:function(){Fe.call(this),this.dateSelectingClass&&(this.dateClicking=new this.dateClickingClass(this)),this.dateSelectingClass&&(this.dateSelecting=new this.dateSelectingClass(this)),this.eventPointingClass&&(this.eventPointing=new this.eventPointingClass(this)),this.eventDraggingClass&&this.eventPointing&&(this.eventDragging=new this.eventDraggingClass(this,this.eventPointing)),this.eventResizingClass&&this.eventPointing&&(this.eventResizing=new this.eventResizingClass(this,this.eventPointing)),this.externalDroppingClass&&(this.externalDropping=new this.externalDroppingClass(this))},setElement:function(t){Fe.prototype.setElement.apply(this,arguments),this.dateClicking&&this.dateClicking.bindToEl(t),this.dateSelecting&&this.dateSelecting.bindToEl(t),this.bindAllSegHandlersToEl(t)},unrender:function(){this.endInteractions(),Fe.prototype.unrender.apply(this,arguments)},executeEventUnrender:function(){this.endInteractions(),Fe.prototype.executeEventUnrender.apply(this,arguments)},bindGlobalHandlers:function(){Fe.prototype.bindGlobalHandlers.apply(this,arguments),this.externalDropping&&this.externalDropping.bindToDocument()},unbindGlobalHandlers:function(){Fe.prototype.unbindGlobalHandlers.apply(this,arguments),this.externalDropping&&this.externalDropping.unbindFromDocument()},bindDateHandlerToEl:function(e,n,i){var r=this;this.el.on(n,function(e){if(!t(e.target).is(r.segSelector+","+r.segSelector+" *,.fc-more,a[data-goto]"))return i.call(r,e)})},bindAllSegHandlersToEl:function(t){[this.eventPointing,this.eventDragging,this.eventResizing].forEach(function(e){e&&e.bindToEl(t)})},bindSegHandlerToEl:function(e,n,i){var r=this;e.on(n,this.segSelector,function(e){var n=t(this).data("fc-seg");if(n&&!r.shouldIgnoreEventPointing())return i.call(r,n,e)})},shouldIgnoreMouse:function(){return me.get().shouldIgnoreMouse()},shouldIgnoreTouch:function(){var t=this._getView();return t.isSelected||t.selectedEvent},shouldIgnoreEventPointing:function(){return this.eventDragging&&this.eventDragging.isDragging||this.eventResizing&&this.eventResizing.isResizing},canStartSelection:function(t,e){return S(e)&&!this.canStartResize(t,e)&&(this.isEventDefDraggable(t.footprint.eventDef)||this.isEventDefResizable(t.footprint.eventDef))},canStartDrag:function(t,e){return!this.canStartResize(t,e)&&this.isEventDefDraggable(t.footprint.eventDef)},canStartResize:function(e,n){var i=this._getView(),r=e.footprint.eventDef;return(!S(n)||i.isEventDefSelected(r))&&this.isEventDefResizable(r)&&t(n.target).is(".fc-resizer")},endInteractions:function(){[this.dateClicking,this.dateSelecting,this.eventPointing,this.eventDragging,this.eventResizing].forEach(function(t){t&&t.end()})},isEventDefDraggable:function(t){return this.isEventDefStartEditable(t)},isEventDefStartEditable:function(t){var e=t.isStartExplicitlyEditable();return null==e&&null==(e=this.opt("eventStartEditable"))&&(e=this.isEventDefGenerallyEditable(t)),e},isEventDefGenerallyEditable:function(t){var e=t.isExplicitlyEditable();return null==e&&(e=this.opt("editable")),e},isEventDefResizableFromStart:function(t){return this.opt("eventResizableFromStart")&&this.isEventDefResizable(t)},isEventDefResizableFromEnd:function(t){return this.isEventDefResizable(t)},isEventDefResizable:function(t){var e=t.isDurationExplicitlyEditable();return null==e&&null==(e=this.opt("eventDurationEditable"))&&(e=this.isEventDefGenerallyEditable(t)),e},diffDates:function(t,e){return this.largeUnit?L(t,e,this.largeUnit):B(t,e)},isEventInstanceGroupAllowed:function(t){var e,n=this._getView(),i=this.dateProfile,r=this.eventRangesToEventFootprints(t.getAllEventRanges());for(e=0;e=e.length?e[e.length-1]+1:e[n]},computeColHeadFormat:function(){return this.rowCnt>1||this.colCnt>10?"ddd":this.colCnt>1?this.opt("dayOfMonthFormat"):"dddd"},sliceRangeByRow:function(t){var e,n,i,r,s,o=this.daysPerRow,a=this.view.computeDayRange(t),l=this.getDateDayIndex(a.start),u=this.getDateDayIndex(a.end.clone().subtract(1,"days")),c=[];for(e=0;e'+this.renderHeadTrHtml()+"
"},renderHeadIntroHtml:function(){return this.renderIntroHtml()},renderHeadTrHtml:function(){return""+(this.isRTL?"":this.renderHeadIntroHtml())+this.renderHeadDateCellsHtml()+(this.isRTL?this.renderHeadIntroHtml():"")+""},renderHeadDateCellsHtml:function(){var t,e,n=[];for(t=0;t1?' colspan="'+e+'"':"")+(n?" "+n:"")+">"+(r?i.buildGotoAnchorHtml({date:t,forceOff:this.rowCnt>1||1===this.colCnt},o):o)+""},renderBgTrHtml:function(t){return""+(this.isRTL?"":this.renderBgIntroHtml(t))+this.renderBgCellsHtml(t)+(this.isRTL?this.renderBgIntroHtml(t):"")+""},renderBgIntroHtml:function(t){return this.renderIntroHtml()},renderBgCellsHtml:function(t){var e,n,i=[];for(e=0;e"},renderIntroHtml:function(){},bookendCells:function(t){var e=this.renderIntroHtml();e&&(this.isRTL?t.append(e):t.prepend(e))}},Ae=Wt.View=ke.extend({type:null,name:null,title:null,calendar:null,viewSpec:null,options:null,renderQueue:null,batchRenderDepth:0,queuedScroll:null,isSelected:!1,selectedEventInstance:null,eventOrderSpecs:null,isHiddenDayHash:null,isNowIndicatorRendered:null,initialNowDate:null,initialNowQueriedMs:null,nowIndicatorTimeoutID:null,nowIndicatorIntervalID:null,constructor:function(t,e){this.calendar=t,this.viewSpec=e,this.type=e.type,this.options=e.options,this.name=this.type,ke.call(this),this.initRenderQueue(),this.initHiddenDays(),this.bindBaseRenderHandlers(),this.eventOrderSpecs=P(this.opt("eventOrder")),this.initialize&&this.initialize()},_getView:function(){return this},opt:function(t){return this.options[t]},initRenderQueue:function(){this.renderQueue=new de({event:this.opt("eventRenderWait")}),this.renderQueue.on("start",this.onRenderQueueStart.bind(this)),this.renderQueue.on("stop",this.onRenderQueueStop.bind(this)),this.on("before:change",this.startBatchRender),this.on("change",this.stopBatchRender)},onRenderQueueStart:function(){this.calendar.freezeContentHeight(),this.addScroll(this.queryScroll())},onRenderQueueStop:function(){this.calendar.updateViewSize()&&this.popScroll(),this.calendar.thawContentHeight()},startBatchRender:function(){this.batchRenderDepth++||this.renderQueue.pause()},stopBatchRender:function(){--this.batchRenderDepth||this.renderQueue.resume()},requestRender:function(t,e,n){this.renderQueue.queue(t,e,n)},whenSizeUpdated:function(t){this.renderQueue.isRunning?this.renderQueue.one("stop",t.bind(this)):t.call(this)},computeTitle:function(t){var e;return e=/^(year|month)$/.test(t.currentRangeUnit)?t.currentUnzonedRange:t.activeUnzonedRange,this.formatRange({start:this.calendar.msToMoment(e.startMs,t.isRangeAllDay),end:this.calendar.msToMoment(e.endMs,t.isRangeAllDay)},t.isRangeAllDay,this.opt("titleFormat")||this.computeTitleFormat(t),this.opt("titleRangeSeparator"))},computeTitleFormat:function(t){var e=t.currentRangeUnit;return"year"==e?"YYYY":"month"==e?this.opt("monthYearFormat"):t.currentUnzonedRange.as("days")>1?"ll":"LL"},setDate:function(t){var e=this.get("dateProfile"),n=this.buildDateProfile(t,null,!0);e&&e.activeUnzonedRange.equals(n.activeUnzonedRange)||this.set("dateProfile",n)},unsetDate:function(){this.unset("dateProfile")},fetchInitialEvents:function(t){var e=this.calendar,n=t.isRangeAllDay&&!this.usesMinMaxTime;return e.requestEvents(e.msToMoment(t.activeUnzonedRange.startMs,n),e.msToMoment(t.activeUnzonedRange.endMs,n))},bindEventChanges:function(){this.listenTo(this.calendar,"eventsReset",this.resetEvents)},unbindEventChanges:function(){this.stopListeningTo(this.calendar,"eventsReset")},setEvents:function(t){this.set("currentEvents",t),this.set("hasEvents",!0)},unsetEvents:function(){this.unset("currentEvents"),this.unset("hasEvents")},resetEvents:function(t){this.startBatchRender(),this.unsetEvents(),this.setEvents(t),this.stopBatchRender()},requestDateRender:function(t){var e=this;this.requestRender(function(){e.executeDateRender(t)},"date","init")},requestDateUnrender:function(){var t=this;this.requestRender(function(){t.executeDateUnrender()},"date","destroy")},executeDateRender:function(t){Fe.prototype.executeDateRender.apply(this,arguments),this.render&&this.render(),this.trigger("datesRendered"),this.addScroll({isDateInit:!0}),this.startNowIndicator()},executeDateUnrender:function(){this.unselect(),this.stopNowIndicator(),this.trigger("before:datesUnrendered"),this.destroy&&this.destroy(),Fe.prototype.executeDateUnrender.apply(this,arguments)},bindBaseRenderHandlers:function(){var t=this;this.on("datesRendered",function(){t.whenSizeUpdated(t.triggerViewRender)}),this.on("before:datesUnrendered",function(){t.triggerViewDestroy()})},triggerViewRender:function(){this.publiclyTrigger("viewRender",{context:this,args:[this,this.el]})},triggerViewDestroy:function(){this.publiclyTrigger("viewDestroy",{context:this,args:[this,this.el]})},requestEventsRender:function(t){var e=this;this.requestRender(function(){e.executeEventRender(t),e.whenSizeUpdated(e.triggerAfterEventsRendered)},"event","init")},requestEventsUnrender:function(){var t=this;this.requestRender(function(){t.triggerBeforeEventsDestroyed(),t.executeEventUnrender()},"event","destroy")},requestBusinessHoursRender:function(t){var e=this;this.requestRender(function(){e.renderBusinessHours(t)},"businessHours","init")},requestBusinessHoursUnrender:function(){var t=this;this.requestRender(function(){t.unrenderBusinessHours()},"businessHours","destroy")},bindGlobalHandlers:function(){ke.prototype.bindGlobalHandlers.apply(this,arguments),this.listenTo(me.get(),{touchstart:this.processUnselect,mousedown:this.handleDocumentMousedown})},unbindGlobalHandlers:function(){ke.prototype.unbindGlobalHandlers.apply(this,arguments),this.stopListeningTo(me.get())},startNowIndicator:function(){var t,n,i,r=this;this.opt("nowIndicator")&&(t=this.getNowIndicatorUnit())&&(n=lt(this,"updateNowIndicator"),this.initialNowDate=this.calendar.getNow(),this.initialNowQueriedMs=+new Date,i=this.initialNowDate.clone().startOf(t).add(1,t)-this.initialNowDate,this.nowIndicatorTimeoutID=setTimeout(function(){r.nowIndicatorTimeoutID=null,n(),i=+e.duration(1,t),i=Math.max(100,i),r.nowIndicatorIntervalID=setInterval(n,i)},i))},updateNowIndicator:function(){this.isDatesRendered&&this.initialNowDate&&(this.unrenderNowIndicator(),this.renderNowIndicator(this.initialNowDate.clone().add(new Date-this.initialNowQueriedMs)),this.isNowIndicatorRendered=!0)},stopNowIndicator:function(){this.isNowIndicatorRendered&&(this.nowIndicatorTimeoutID&&(clearTimeout(this.nowIndicatorTimeoutID),this.nowIndicatorTimeoutID=null),this.nowIndicatorIntervalID&&(clearTimeout(this.nowIndicatorIntervalID),this.nowIndicatorIntervalID=null),this.unrenderNowIndicator(),this.isNowIndicatorRendered=!1)},updateSize:function(t,e,n){this.setHeight?this.setHeight(t,e):ke.prototype.updateSize.apply(this,arguments),this.updateNowIndicator()},addScroll:function(e){var n=this.queuedScroll||(this.queuedScroll={});t.extend(n,e)},popScroll:function(){this.applyQueuedScroll(),this.queuedScroll=null},applyQueuedScroll:function(){this.queuedScroll&&this.applyScroll(this.queuedScroll)},queryScroll:function(){var e={};return this.isDatesRendered&&t.extend(e,this.queryDateScroll()),e},applyScroll:function(e){e.isDateInit&&this.isDatesRendered&&t.extend(e,this.computeInitialDateScroll()),this.isDatesRendered&&this.applyDateScroll(e)},computeInitialDateScroll:function(){return{}},queryDateScroll:function(){return{}},applyDateScroll:function(t){},reportEventDrop:function(t,n,i,r){var s=this.calendar.eventManager,o=s.mutateEventsWithId(t.def.id,n,this.calendar),a=n.dateMutation;a&&(t.dateProfile=a.buildNewDateProfile(t.dateProfile,this.calendar)),this.triggerEventDrop(t,a&&a.dateDelta||e.duration(),o,i,r)},triggerEventDrop:function(t,e,n,i,r){this.publiclyTrigger("eventDrop",{context:i[0],args:[t.toLegacy(),e,n,r,{},this]})},reportExternalDrop:function(t,e,n,i,r,s){e&&this.calendar.eventManager.addEventDef(t,n),this.triggerExternalDrop(t,e,i,r,s)},triggerExternalDrop:function(t,e,n,i,r){this.publiclyTrigger("drop",{context:n[0],args:[t.dateProfile.start.clone(),i,r,this]}),e&&this.publiclyTrigger("eventReceive",{context:this,args:[t.buildInstance().toLegacy(),this]})},reportEventResize:function(t,e,n,i){var r=this.calendar.eventManager,s=r.mutateEventsWithId(t.def.id,e,this.calendar);t.dateProfile=e.dateMutation.buildNewDateProfile(t.dateProfile,this.calendar),this.triggerEventResize(t,e.dateMutation.endDelta,s,n,i)},triggerEventResize:function(t,e,n,i,r){this.publiclyTrigger("eventResize",{context:i[0],args:[t.toLegacy(),e,n,r,{},this]})},select:function(t,e){this.unselect(e),this.renderSelectionFootprint(t),this.reportSelection(t,e)},renderSelectionFootprint:function(t,e){this.renderSelection?this.renderSelection(t.toLegacy(this.calendar)):ke.prototype.renderSelectionFootprint.apply(this,arguments)},reportSelection:function(t,e){this.isSelected=!0,this.triggerSelect(t,e)},triggerSelect:function(t,e){var n=this.calendar.footprintToDateProfile(t);this.publiclyTrigger("select",{context:this,args:[n.start,n.end,e,this]})},unselect:function(t){this.isSelected&&(this.isSelected=!1,this.destroySelection&&this.destroySelection(),this.unrenderSelection(),this.publiclyTrigger("unselect",{context:this,args:[t,this]}))},selectEventInstance:function(t){this.selectedEventInstance&&this.selectedEventInstance===t||(this.unselectEventInstance(),this.getEventSegs().forEach(function(e){e.footprint.eventInstance===t&&e.el&&e.el.addClass("fc-selected")}),this.selectedEventInstance=t)},unselectEventInstance:function(){this.selectedEventInstance&&(this.getEventSegs().forEach(function(t){t.el&&t.el.removeClass("fc-selected")}),this.selectedEventInstance=null)},isEventDefSelected:function(t){return this.selectedEventInstance&&this.selectedEventInstance.def.id===t.id},handleDocumentMousedown:function(t){D(t)&&this.processUnselect(t)},processUnselect:function(t){this.processRangeUnselect(t),this.processEventUnselect(t)},processRangeUnselect:function(e){var n;this.isSelected&&this.opt("unselectAuto")&&((n=this.opt("unselectCancel"))&&t(e.target).closest(n).length||this.unselect(e))},processEventUnselect:function(e){this.selectedEventInstance&&(t(e.target).closest(".fc-selected").length||this.unselectEventInstance())},triggerBaseRendered:function(){this.publiclyTrigger("viewRender",{context:this,args:[this,this.el]})},triggerBaseUnrendered:function(){this.publiclyTrigger("viewDestroy",{context:this,args:[this,this.el]})},triggerDayClick:function(t,e,n){var i=this.calendar.footprintToDateProfile(t);this.publiclyTrigger("dayClick",{context:e,args:[i.start,n,this]})}});Ae.watch("displayingDates",["isInDom","dateProfile"],function(t){this.requestDateRender(t.dateProfile)},function(){this.requestDateUnrender()}),Ae.watch("displayingBusinessHours",["displayingDates","businessHourGenerator"],function(t){this.requestBusinessHoursRender(t.businessHourGenerator)},function(){this.requestBusinessHoursUnrender()}),Ae.watch("initialEvents",["dateProfile"],function(t){return this.fetchInitialEvents(t.dateProfile)}),Ae.watch("bindingEvents",["initialEvents"],function(t){this.setEvents(t.initialEvents),this.bindEventChanges()},function(){this.unbindEventChanges(),this.unsetEvents()}),Ae.watch("displayingEvents",["displayingDates","hasEvents"],function(){this.requestEventsRender(this.get("currentEvents"))},function(){this.requestEventsUnrender()}),Ae.watch("title",["dateProfile"],function(t){return this.title=this.computeTitle(t.dateProfile)}),Ae.watch("legacyDateProps",["dateProfile"],function(t){var e=this.calendar,n=t.dateProfile;this.start=e.msToMoment(n.activeUnzonedRange.startMs,n.isRangeAllDay),this.end=e.msToMoment(n.activeUnzonedRange.endMs,n.isRangeAllDay),this.intervalStart=e.msToMoment(n.currentUnzonedRange.startMs,n.isRangeAllDay),this.intervalEnd=e.msToMoment(n.currentUnzonedRange.endMs,n.isRangeAllDay)}),Ae.mixin({usesMinMaxTime:!1,start:null,end:null,intervalStart:null,intervalEnd:null,buildPrevDateProfile:function(t){var e=this.get("dateProfile"),n=t.clone().startOf(e.currentRangeUnit).subtract(e.dateIncrement);return this.buildDateProfile(n,-1)},buildNextDateProfile:function(t){var e=this.get("dateProfile"),n=t.clone().startOf(e.currentRangeUnit).add(e.dateIncrement);return this.buildDateProfile(n,1)},buildDateProfile:function(t,n,i){var r,s,o,a,l,u,c=!t.hasTime(),h=null,d=null;return r=this.buildValidRange(),r=this.trimHiddenDays(r),i&&(t=this.calendar.msToUtcMoment(r.constrainDate(t),c)),s=this.buildCurrentRangeInfo(t,n),o=/^(year|month|week|day)$/.test(s.unit),a=this.buildRenderRange(this.trimHiddenDays(s.unzonedRange),s.unit,o),a=this.trimHiddenDays(a),l=a.clone(),this.opt("showNonCurrentDates")||(l=l.intersect(s.unzonedRange)),h=e.duration(this.opt("minTime")),d=e.duration(this.opt("maxTime")),l=this.adjustActiveRange(l,h,d),l=l.intersect(r),l&&(t=this.calendar.msToUtcMoment(l.constrainDate(t),c)),u=s.unzonedRange.intersectsWith(r),{validUnzonedRange:r,currentUnzonedRange:s.unzonedRange,currentRangeUnit:s.unit,isRangeAllDay:o,activeUnzonedRange:l,renderUnzonedRange:a,minTime:h,maxTime:d,isValid:u,date:t,dateIncrement:this.buildDateIncrement(s.duration)}},buildValidRange:function(){return this.getUnzonedRangeOption("validRange",this.calendar.getNow())||new Ue},buildCurrentRangeInfo:function(t,e){var n,i=null,r=null,s=null;return this.viewSpec.duration?(i=this.viewSpec.duration,r=this.viewSpec.durationUnit,s=this.buildRangeFromDuration(t,e,i,r)):(n=this.opt("dayCount"))?(r="day",s=this.buildRangeFromDayCount(t,e,n)):(s=this.buildCustomVisibleRange(t))?r=O(s.getStart(),s.getEnd()):(i=this.getFallbackDuration(),r=O(i),s=this.buildRangeFromDuration(t,e,i,r)),{duration:i,unit:r,unzonedRange:s}},getFallbackDuration:function(){return e.duration({days:1})},adjustActiveRange:function(t,e,n){var i=t.getStart(),r=t.getEnd();return this.usesMinMaxTime&&(e<0&&i.time(0).add(e),n>864e5&&r.time(n-864e5)),new Ue(i,r)},buildRangeFromDuration:function(t,n,i,r){var s,o,a,l=this.opt("dateAlignment"),u=t.clone();return i.as("days")<=1&&this.isHiddenDay(u)&&(u=this.skipHiddenDays(u,n),u.startOf("day")),l||(o=this.opt("dateIncrement"),o?(a=e.duration(o),l=a").prependTo(n),this.initToolbars(),this.renderHeader(),this.renderFooter(),this.renderView(this.opt("defaultView")),this.opt("handleWindowResize")&&t(window).resize(this.windowResizeProxy=ut(this.windowResize.bind(this),this.opt("windowResizeDelay")))},destroy:function(){this.view&&this.clearView(),this.toolbarsManager.proxyCall("removeElement"),this.contentEl.remove(),this.el.removeClass("fc fc-ltr fc-rtl"),this.optionsModel.unwatch("settingTheme"),this.optionsModel.unwatch("settingBusinessHourGenerator"),this.el.off(".fc"),this.windowResizeProxy&&(t(window).unbind("resize",this.windowResizeProxy),this.windowResizeProxy=null),me.unneeded()},elementVisible:function(){return this.el.is(":visible")},bindViewHandlers:function(t){var e=this;t.watch("titleForCalendar",["title"],function(n){t===e.view&&e.setToolbarsTitle(n.title)}),t.watch("dateProfileForCalendar",["dateProfile"],function(n){t===e.view&&(e.currentDate=n.dateProfile.date,e.updateToolbarButtons(n.dateProfile))})},unbindViewHandlers:function(t){this.stopListeningTo(t),t.unwatch("titleForCalendar"),t.unwatch("dateProfileForCalendar")},renderView:function(e){var n,i=this.view;this.freezeContentHeight(),i&&e&&i.type!==e&&this.clearView(),!this.view&&e&&(n=this.view=this.viewsByType[e]||(this.viewsByType[e]=this.instantiateView(e)),this.bindViewHandlers(n),n.setElement(t("
").appendTo(this.contentEl)),this.toolbarsManager.proxyCall("activateButton",e)),this.view&&(this.view.get("businessHourGenerator")!==this.businessHourGenerator&&this.view.set("businessHourGenerator",this.businessHourGenerator),this.view.setDate(this.currentDate)),this.thawContentHeight()},clearView:function(){var t=this.view;this.toolbarsManager.proxyCall("deactivateButton",t.type),this.unbindViewHandlers(t),t.removeElement(),this.view=null},reinitView:function(){var t=this.view,e=t.queryScroll();this.freezeContentHeight(),this.clearView(),this.calcSize(),this.renderView(t.type),this.view.applyScroll(e),this.thawContentHeight()},getSuggestedViewHeight:function(){return null===this.suggestedViewHeight&&this.calcSize(),this.suggestedViewHeight},isHeightAuto:function(){return"auto"===this.opt("contentHeight")||"auto"===this.opt("height")},updateViewSize:function(t){var e,n=this.view;if(!this.ignoreUpdateViewSize&&n)return t&&(this.calcSize(),e=n.queryScroll()),this.ignoreUpdateViewSize++,n.updateSize(this.getSuggestedViewHeight(),this.isHeightAuto(),t),this.ignoreUpdateViewSize--,t&&n.applyScroll(e),!0},calcSize:function(){this.elementVisible()&&this._calcSize()},_calcSize:function(){var t=this.opt("contentHeight"),e=this.opt("height");this.suggestedViewHeight="number"==typeof t?t:"function"==typeof t?t():"number"==typeof e?e-this.queryToolbarsHeight():"function"==typeof e?e()-this.queryToolbarsHeight():"parent"===e?this.el.parent().height()-this.queryToolbarsHeight():Math.round(this.contentEl.width()/Math.max(this.opt("aspectRatio"),.5))},windowResize:function(t){t.target===window&&this.view&&this.view.isDatesRendered&&this.updateViewSize(!0)&&this.publiclyTrigger("windowResize",[this.view])},freezeContentHeight:function(){this.freezeContentHeightDepth++||this.forceFreezeContentHeight()},forceFreezeContentHeight:function(){this.contentEl.css({width:"100%",height:this.contentEl.height(),overflow:"hidden"})},thawContentHeight:function(){this.freezeContentHeightDepth--,this.contentEl.css({width:"",height:"",overflow:""}),this.freezeContentHeightDepth&&this.forceFreezeContentHeight()}}),Le.mixin({header:null,footer:null,toolbarsManager:null,initToolbars:function(){this.header=new bt(this,this.computeHeaderOptions()),this.footer=new bt(this,this.computeFooterOptions()),this.toolbarsManager=new yt([this.header,this.footer])},computeHeaderOptions:function(){return{extraClasses:"fc-header-toolbar",layout:this.opt("header")}},computeFooterOptions:function(){return{extraClasses:"fc-footer-toolbar",layout:this.opt("footer")}},renderHeader:function(){var t=this.header;t.setToolbarOptions(this.computeHeaderOptions()),t.render(),t.el&&this.el.prepend(t.el)},renderFooter:function(){var t=this.footer;t.setToolbarOptions(this.computeFooterOptions()),t.render(),t.el&&this.el.append(t.el)},setToolbarsTitle:function(t){this.toolbarsManager.proxyCall("updateTitle",t)},updateToolbarButtons:function(t){var e=this.getNow(),n=this.view,i=n.buildDateProfile(e),r=n.buildPrevDateProfile(this.currentDate),s=n.buildNextDateProfile(this.currentDate);this.toolbarsManager.proxyCall(i.isValid&&!t.currentUnzonedRange.containsDate(e)?"enableButton":"disableButton","today"),this.toolbarsManager.proxyCall(r.isValid?"enableButton":"disableButton","prev"),this.toolbarsManager.proxyCall(s.isValid?"enableButton":"disableButton","next")},queryToolbarsHeight:function(){return this.toolbarsManager.items.reduce(function(t,e){return t+(e.el?e.el.outerHeight(!0):0)},0)}}),Le.prototype.isEventInstanceGroupAllowed=function(t){var e,n=t.getEventDef(),i=this.eventRangesToEventFootprints(t.getAllEventRanges()),r=this.getPeerEventInstances(n),s=r.map(Pt),o=this.eventRangesToEventFootprints(s),a=n.getConstraint(),l=n.getOverlap(),u=this.opt("eventAllow");for(e=0;et.startMs)&&(null===this.startMs||null===t.endMs||this.startMs=this.startMs)&&(null===this.endMs||null!==t.endMs&&t.endMs<=this.endMs)},containsDate:function(t){var e=t.valueOf();return(null===this.startMs||e>=this.startMs)&&(null===this.endMs||e=this.endMs&&(e=this.endMs-1),e},equals:function(t){return this.startMs===t.startMs&&this.endMs===t.endMs},clone:function(){var t=new Ue(this.startMs,this.endMs);return t.isStart=this.isStart,t.isEnd=this.isEnd,t},getStart:function(){if(null!==this.startMs)return Wt.moment.utc(this.startMs).stripZone()},getEnd:function(){if(null!==this.endMs)return Wt.moment.utc(this.endMs).stripZone()},as:function(t){return e.utc(this.endMs).diff(e.utc(this.startMs),t,!0)}}),We=Wt.ComponentFootprint=dt.extend({unzonedRange:null,isAllDay:!1,constructor:function(t,e){this.unzonedRange=t,this.isAllDay=e},toLegacy:function(t){return{start:t.msToMoment(this.unzonedRange.startMs,this.isAllDay),end:t.msToMoment(this.unzonedRange.endMs,this.isAllDay)}}}),_e=dt.extend(re,{start:null,end:null,timezone:null,unzonedRange:null,requestsByUid:null,pendingCnt:0,freezeDepth:0,stuntedReleaseCnt:0,releaseCnt:0,eventDefsByUid:null,eventDefsById:null,eventInstanceGroupsById:null,constructor:function(t,e,n){this.start=t,this.end=e,this.timezone=n,this.unzonedRange=new Ue(t.clone().stripZone(),e.clone().stripZone()),this.requestsByUid={},this.eventDefsByUid={},this.eventDefsById={},this.eventInstanceGroupsById={}},isWithinRange:function(t,e){return!t.isBefore(this.start)&&!e.isAfter(this.end)},requestSources:function(t){this.freeze();for(var e=0;e
'),s=r.find("tr"),a>0&&s.append(''),s.append(n.el.attr("colspan",l-a)),l'),this.component.bookendCells(s),r}}),mn=He.extend({dayGrid:null,rowStructs:null,constructor:function(t){He.apply(this,arguments),this.dayGrid=t},renderBgRanges:function(e){e=t.grep(e,function(t){return t.eventDef.isAllDay()}),He.prototype.renderBgRanges.call(this,e)},renderFgSegs:function(e){var n=this.rowStructs=this.renderSegRows(e);this.dayGrid.rowEls.each(function(e,i){t(i).find(".fc-content-skeleton > table").append(n[e].tbodyEl)})},unrenderFgSegs:function(){for(var t,e=this.rowStructs||[];t=e.pop();)t.tbodyEl.remove();this.rowStructs=null},renderSegRows:function(t){var e,n,i=[];for(e=this.groupSegRows(t),n=0;n"),a.append(c)),v[r][o]=c,m[r][o]=c,o++}var r,s,o,a,l,u,c,h=this.dayGrid.colCnt,d=this.buildSegLevels(n),f=Math.max(1,d.length),g=t(""),p=[],v=[],m=[];for(r=0;r"),p.push([]),v.push([]),m.push([]),s)for(l=0;l').append(u.el),u.leftCol!=u.rightCol?c.attr("colspan",u.rightCol-u.leftCol+1):m[r][o]=c;o<=u.rightCol;)v[r][o]=c,p[r][o]=u,o++;a.append(c)}i(h),this.dayGrid.bookendCells(a),g.append(a)}return{row:e,tbodyEl:g,cellMatrix:v,segMatrix:p,segLevels:d,segs:n}},buildSegLevels:function(t){var e,n,i,r=[];for(this.sortEventSegs(t),e=0;e'+et(n)+""),i=''+(et(s.title||"")||" ")+"",'
'+(this.isRTL?i+" "+d:d+" "+i)+"
"+(l?'
':"")+(u?'
':"")+""}}),yn=Pe.extend({renderSegs:function(e,n){var i,r=[];return i=this.eventRenderer.renderSegRows(e),this.component.rowEls.each(function(e,s){var o,a,l=t(s),u=t('
');n&&n.row===e?a=n.el.position().top:(o=l.find(".fc-content-skeleton tbody"),o.length||(o=l.find(".fc-content-skeleton table")),a=o.position().top),u.css("top",a).find("table").append(i[e].tbodyEl),l.append(u),r.push(u[0])}),t(r)}}),wn=Wt.DayGrid=ke.extend(Ie,Be,{eventRendererClass:mn,businessHourRendererClass:Me,helperRendererClass:yn,fillRendererClass:vn,view:null,helperRenderer:null,cellWeekNumbersVisible:!1,bottomCoordPadding:0,headContainerEl:null,rowEls:null,cellEls:null,rowCoordCache:null,colCoordCache:null,isRigid:!1,hasAllDayBusinessHours:!0,constructor:function(t){this.view=t,ke.call(this)},componentFootprintToSegs:function(t){var e,n,i=this.sliceRangeByRow(t.unzonedRange);for(e=0;e
'+this.renderBgTrHtml(t)+'
'+(this.getIsNumbersVisible()?""+this.renderNumberTrHtml(t)+"":"")+"
"},getIsNumbersVisible:function(){return this.getIsDayNumbersVisible()||this.cellWeekNumbersVisible},getIsDayNumbersVisible:function(){return this.rowCnt>1},renderNumberTrHtml:function(t){return""+(this.isRTL?"":this.renderNumberIntroHtml(t))+this.renderNumberCellsHtml(t)+(this.isRTL?this.renderNumberIntroHtml(t):"")+""},renderNumberIntroHtml:function(t){return this.renderIntroHtml()},renderNumberCellsHtml:function(t){var e,n,i=[];for(e=0;e",this.cellWeekNumbersVisible&&t.day()==n&&(r+=i.buildGotoAnchorHtml({date:t,type:"week"},{class:"fc-week-number"},t.format("w"))),o&&(r+=i.buildGotoAnchorHtml(t,{class:"fc-day-number"},t.date())),r+=""):""},prepareHits:function(){this.colCoordCache.build(),this.rowCoordCache.build(),this.rowCoordCache.bottoms[this.rowCnt-1]+=this.bottomCoordPadding},releaseHits:function(){this.colCoordCache.clear(),this.rowCoordCache.clear()},queryHit:function(t,e){if(this.colCoordCache.isLeftInBounds(t)&&this.rowCoordCache.isTopInBounds(e)){var n=this.colCoordCache.getHorizontalIndex(t),i=this.rowCoordCache.getVerticalIndex(e);if(null!=i&&null!=n)return this.getCellHit(i,n)}},getHitFootprint:function(t){var e=this.getCellRange(t.row,t.col);return new We(new Ue(e.start,e.end),!0)},getHitEl:function(t){return this.getCellEl(t.row,t.col)},getCellHit:function(t,e){return{row:t,col:e,component:this,left:this.colCoordCache.getLeftOffset(e),right:this.colCoordCache.getRightOffset(e),top:this.rowCoordCache.getTopOffset(t),bottom:this.rowCoordCache.getBottomOffset(t)}},getCellEl:function(t,e){return this.cellEls.eq(t*this.colCnt+e)},unrenderEvents:function(){this.removeSegPopover(),ke.prototype.unrenderEvents.apply(this,arguments)},getOwnEventSegs:function(){return ke.prototype.getOwnEventSegs.apply(this,arguments).concat(this.popoverSegs||[])},renderDrag:function(t,e,n){var i;for(i=0;i td > :first-child").each(n),r.position().top+s>a)return i;return!1},limitRow:function(e,n){function i(i){for(;E").append(y),d.append(m),b.push(m[0])),E++}var r,s,o,a,l,u,c,h,d,f,g,p,v,m,y,w=this,D=this.eventRenderer.rowStructs[e],b=[],E=0;if(n&&n').attr("rowspan",f),u=h[p],y=this.renderMoreLink(e,l.leftCol+p,[l].concat(u)),m=t("
").append(y),v.append(m),g.push(v[0]),b.push(v[0]);d.addClass("fc-limited").after(t(g)),o.push(d[0])}}i(this.colCnt),D.moreEls=t(b),D.limitedEls=t(o)}},unlimitRow:function(t){var e=this.eventRenderer.rowStructs[t];e.moreEls&&(e.moreEls.remove(),e.moreEls=null),e.limitedEls&&(e.limitedEls.removeClass("fc-limited"),e.limitedEls=null)},renderMoreLink:function(e,n,i){var r=this,s=this.view;return t('').text(this.getMoreLinkText(i.length)).on("click",function(o){var a=r.opt("eventLimitClick"),l=r.getCellDate(e,n),u=t(this),c=r.getCellEl(e,n),h=r.getCellSegs(e,n),d=r.resliceDaySegs(h,l),f=r.resliceDaySegs(i,l);"function"==typeof a&&(a=r.publiclyTrigger("eventLimitClick",{context:s,args:[{date:l.clone(),dayEl:c,moreEl:u,segs:d,hiddenSegs:f},o,s]})),"popover"===a?r.showSegPopover(e,n,u,d):"string"==typeof a&&s.calendar.zoomTo(l,a)})},showSegPopover:function(t,e,n,i){var r,s,o=this,a=this.view,l=n.parent();r=1==this.rowCnt?a.el:this.rowEls.eq(t),s={className:"fc-more-popover "+a.calendar.theme.getClass("popover"),content:this.renderSegPopoverContent(t,e,i),parentEl:a.el,top:r.offset().top,autoHide:!0,viewportConstrain:this.opt("popoverViewportConstrain"),hide:function(){o.popoverSegs&&o.triggerBeforeEventSegsDestroyed(o.popoverSegs),o.segPopover.removeElement(),o.segPopover=null,o.popoverSegs=null}},this.isRTL?s.right=l.offset().left+l.outerWidth()+1:s.left=l.offset().left-1,this.segPopover=new fe(s),this.segPopover.show(),this.bindAllSegHandlersToEl(this.segPopover.el),this.triggerAfterEventSegsRendered(i)},renderSegPopoverContent:function(e,n,i){var r,s=this.view,o=s.calendar.theme,a=this.getCellDate(e,n).format(this.opt("dayPopoverFormat")),l=t('
'+et(a)+'
'),u=l.find(".fc-event-container");for(i=this.eventRenderer.renderFgSegEls(i,!0),this.popoverSegs=i,r=0;r').appendTo(e),this.el.find(".fc-body > tr > td").append(e),this.dayGrid.headContainerEl=this.el.find(".fc-head-container"),this.dayGrid.setElement(n)},unrenderSkeleton:function(){this.dayGrid.removeElement(),this.scroller.destroy()},renderSkeletonHtml:function(){var t=this.calendar.theme;return''+(this.opt("columnHeader")?'':"")+'
 
'},weekNumberStyleAttr:function(){return null!==this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},hasRigidRows:function(){var t=this.opt("eventLimit");return t&&"number"!=typeof t},updateSize:function(t,e,n){var s,o,a=this.opt("eventLimit"),l=this.dayGrid.headContainerEl.find(".fc-row");if(!this.dayGrid.rowEls)return void(e||(s=this.computeScrollerHeight(t),this.scroller.setHeight(s)));Ae.prototype.updateSize.apply(this,arguments),this.dayGrid.colWeekNumbersVisible&&(this.weekNumberWidth=u(this.el.find(".fc-week-number"))),this.scroller.clear(),r(l),this.dayGrid.removeSegPopover(),a&&"number"==typeof a&&this.dayGrid.limitRows(a),s=this.computeScrollerHeight(t),this.setGridHeight(s,e),a&&"number"!=typeof a&&this.dayGrid.limitRows(a),e||(this.scroller.setHeight(s),o=this.scroller.getScrollbarWidths(),(o.left||o.right)&&(i(l,o),s=this.computeScrollerHeight(t),this.scroller.setHeight(s)),this.scroller.lockOverflow(o))},computeScrollerHeight:function(t){return t-c(this.el,this.scroller.el)},setGridHeight:function(t,e){e?l(this.dayGrid.rowEls):a(this.dayGrid.rowEls,t,!0)},computeInitialDateScroll:function(){return{top:0}},queryDateScroll:function(){return{top:this.scroller.getScrollTop()}},applyDateScroll:function(t){void 0!==t.top&&this.scroller.setScrollTop(t.top)}}),bn={colWeekNumbersVisible:!1,renderHeadIntroHtml:function(){var t=this.view;return this.colWeekNumbersVisible?'"+et(this.opt("weekNumberTitle"))+"":""},renderNumberIntroHtml:function(t){var e=this.view,n=this.getCellDate(t,0);return this.colWeekNumbersVisible?'"+e.buildGotoAnchorHtml({date:n,type:"week",forceOff:1===this.colCnt},n.format("w"))+"":""},renderBgIntroHtml:function(){var t=this.view;return this.colWeekNumbersVisible?'":""},renderIntroHtml:function(){var t=this.view +;return this.colWeekNumbersVisible?'":""},getIsNumbersVisible:function(){return wn.prototype.getIsNumbersVisible.apply(this,arguments)||this.colWeekNumbersVisible}},En=Wt.MonthView=Dn.extend({buildRenderRange:function(t,e,n){var i,r=Dn.prototype.buildRenderRange.apply(this,arguments),s=this.calendar.msToUtcMoment(r.startMs,n),o=this.calendar.msToUtcMoment(r.endMs,n);return this.isFixedWeeks()&&(i=Math.ceil(o.diff(s,"weeks",!0)),o.add(6-i,"weeks")),new Ue(s,o)},setGridHeight:function(t,e){e&&(t*=this.rowCnt/6),a(this.dayGrid.rowEls,t,!e)},isFixedWeeks:function(){return this.opt("fixedWeekCount")},isDateInOtherMonth:function(t,n){return t.month()!==e.utc(n.currentUnzonedRange.startMs).month()}});_t.basic={class:Dn},_t.basicDay={type:"basic",duration:{days:1}},_t.basicWeek={type:"basic",duration:{weeks:1}},_t.month={class:En,duration:{months:1},defaults:{fixedWeekCount:!0}};var Sn=xe.extend({attachSegEls:function(t,e){var n,i=this.component;return"bgEvent"===t?n=i.bgContainerEls:"businessHours"===t?n=i.businessContainerEls:"highlight"===t&&(n=i.highlightContainerEls),i.updateSegVerticals(e),i.attachSegsByCol(i.groupSegsByCol(e),n),e.map(function(t){return t.el[0]})}}),Cn=He.extend({timeGrid:null,constructor:function(t){He.apply(this,arguments),this.timeGrid=t},renderFgSegs:function(t){this.renderFgSegsIntoContainers(t,this.timeGrid.fgContainerEls)},renderFgSegsIntoContainers:function(t,e){var n,i;for(n=this.timeGrid.groupSegsByCol(t),i=0;i
'+(n?'
'+et(n)+"
":"")+(u.title?'
'+et(u.title)+"
":"")+'
'+(d?'
':"")+""},updateFgSegCoords:function(t){this.timeGrid.computeSegVerticals(t),this.computeFgSegHorizontals(t),this.timeGrid.assignSegVerticals(t),this.assignFgSegHorizontals(t)},computeFgSegHorizontals:function(t){var e,n,i;if(this.sortEventSegs(t),e=Lt(t),Ot(e),n=e[0]){for(i=0;i=0;n--)if(i=e.duration(Pn[n]),r=U(i,t),at(r)&&r>1)return i;return e.duration(t)},renderDates:function(t){this.dateProfile=t,this.updateDayTable(),this.renderSlats(),this.renderColumns()},renderSkeleton:function(){var t=this.view.calendar.theme;this.el.html('
'),this.bottomRuleEl=this.el.find("hr")},renderSlats:function(){var t=this.view.calendar.theme;this.slatContainerEl=this.el.find("> .fc-slats").html(''+this.renderSlatRowHtml()+"
"),this.slatEls=this.slatContainerEl.find("tr"),this.slatCoordCache=new ge({els:this.slatEls,isVertical:!0})},renderSlatRowHtml:function(){for(var t,n,i,r=this.view,s=r.calendar,o=s.theme,a=this.isRTL,l=this.dateProfile,u="",c=e.duration(+l.minTime),h=e.duration(0);c"+(n?""+et(t.format(this.labelFormat))+"":"")+"",u+='"+(a?"":i)+''+(a?i:"")+"",c.add(this.slotDuration),h.add(this.slotDuration);return u},renderColumns:function(){var t=this.dateProfile,e=this.view.calendar.theme;this.dayRanges=this.dayDates.map(function(e){return new Ue(e.clone().add(t.minTime),e.clone().add(t.maxTime))}),this.headContainerEl&&this.headContainerEl.html(this.renderHeadHtml()),this.el.find("> .fc-bg").html(''+this.renderBgTrHtml(0)+"
"),this.colEls=this.el.find(".fc-day, .fc-disabled-day"),this.colCoordCache=new ge({els:this.colEls,isHorizontal:!0}),this.renderContentSkeleton()},renderContentSkeleton:function(){var e,n,i="";for(e=0;e
';n=t('
'+i+"
"),this.colContainerEls=n.find(".fc-content-col"),this.helperContainerEls=n.find(".fc-helper-container"),this.fgContainerEls=n.find(".fc-event-container:not(.fc-helper-container)"),this.bgContainerEls=n.find(".fc-bgevent-container"),this.highlightContainerEls=n.find(".fc-highlight-container"),this.businessContainerEls=n.find(".fc-business-container"),this.bookendCells(n.find("tr")),this.el.append(n)},groupSegsByCol:function(t){var e,n=[];for(e=0;e
').css("top",r).appendTo(this.colContainerEls.eq(i[n].col))[0]);i.length>0&&s.push(t('
').css("top",r).appendTo(this.el.find(".fc-content-skeleton"))[0]),this.nowIndicatorEls=t(s)},unrenderNowIndicator:function(){this.nowIndicatorEls&&(this.nowIndicatorEls.remove(),this.nowIndicatorEls=null)},updateSize:function(t,e,n){ke.prototype.updateSize.apply(this,arguments),this.slatCoordCache.build(),n&&this.updateSegVerticals([].concat(this.eventRenderer.getSegs(),this.businessSegs||[]))},getTotalSlatHeight:function(){return this.slatContainerEl.outerHeight()},computeDateTop:function(t,n){return this.computeTimeTop(e.duration(t-n.clone().stripTime()))},computeTimeTop:function(t){var e,n,i=this.slatEls.length,r=this.dateProfile,s=(t-r.minTime)/this.slotDuration;return s=Math.max(0,s),s=Math.min(i,s),e=Math.floor(s),e=Math.min(e,i-1),n=s-e,this.slatCoordCache.getTopPosition(e)+this.slatCoordCache.getHeight(e)*n},updateSegVerticals:function(t){this.computeSegVerticals(t),this.assignSegVerticals(t)},computeSegVerticals:function(t){var e,n,i,r=this.opt("agendaEventMinHeight");for(e=0;e').appendTo(e),this.el.find(".fc-body > tr > td").append(e),this.timeGrid.headContainerEl=this.el.find(".fc-head-container"),this.timeGrid.setElement(n),this.dayGrid&&(this.dayGrid.setElement(this.el.find(".fc-day-grid")),this.dayGrid.bottomCoordPadding=this.dayGrid.el.next("hr").outerHeight())},unrenderSkeleton:function(){this.timeGrid.removeElement(),this.dayGrid&&this.dayGrid.removeElement(),this.scroller.destroy()},renderSkeletonHtml:function(){var t=this.calendar.theme;return''+(this.opt("columnHeader")?'':"")+'
 
'+(this.dayGrid?'

':"")+"
"},axisStyleAttr:function(){return null!==this.axisWidth?'style="width:'+this.axisWidth+'px"':""},getNowIndicatorUnit:function(){return this.timeGrid.getNowIndicatorUnit()},updateSize:function(t,e,n){var s,o,a;if(Ae.prototype.updateSize.apply(this,arguments),this.axisWidth=u(this.el.find(".fc-axis")),!this.timeGrid.colEls)return void(e||(o=this.computeScrollerHeight(t),this.scroller.setHeight(o)));var l=this.el.find(".fc-row:not(.fc-scroller *)");this.timeGrid.bottomRuleEl.hide(),this.scroller.clear(),r(l),this.dayGrid&&(this.dayGrid.removeSegPopover(),s=this.opt("eventLimit"),s&&"number"!=typeof s&&(s=xn),s&&this.dayGrid.limitRows(s)),e||(o=this.computeScrollerHeight(t),this.scroller.setHeight(o),a=this.scroller.getScrollbarWidths(),(a.left||a.right)&&(i(l,a),o=this.computeScrollerHeight(t),this.scroller.setHeight(o)),this.scroller.lockOverflow(a),this.timeGrid.getTotalSlatHeight()"+e.buildGotoAnchorHtml({date:i,type:"week",forceOff:this.colCnt>1},et(t))+""):'"},renderBgIntroHtml:function(){var t=this.view;return'"},renderIntroHtml:function(){return'"}},Mn={renderBgIntroHtml:function(){var t=this.view;return'"+t.getAllDayHtml()+""},renderIntroHtml:function(){return'"}},xn=5,Pn=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}];_t.agenda={class:In,defaults:{allDaySlot:!0,slotDuration:"00:30:00",slotEventOverlap:!0}},_t.agendaDay={type:"agenda",duration:{days:1}},_t.agendaWeek={type:"agenda",duration:{weeks:1}};var zn=Wt.ListView=Ae.extend({segSelector:".fc-list-item",scroller:null,contentEl:null,dayDates:null,dayRanges:null,constructor:function(){Ae.apply(this,arguments),this.scroller=new we({overflowX:"hidden",overflowY:"auto"})},renderSkeleton:function(){this.el.addClass("fc-list-view "+this.calendar.theme.getClass("listView")),this.scroller.render(),this.scroller.el.appendTo(this.el),this.contentEl=this.scroller.scrollEl},unrenderSkeleton:function(){this.scroller.destroy()},updateSize:function(t,e,n){this.scroller.setHeight(this.computeScrollerHeight(t))},computeScrollerHeight:function(t){return t-c(this.el,this.scroller.el)},renderDates:function(t){for(var e=this.calendar,n=e.msToUtcMoment(t.renderUnzonedRange.startMs,!0),i=e.msToUtcMoment(t.renderUnzonedRange.endMs,!0),r=[],s=[];n'+(this.displayEventTime?''+(e||"")+"":"")+'"+et(o.title||"")+""},computeEventTimeFormat:function(){return this.opt("mediumTimeFormat")}}),eventPointingClass:Te.extend({handleClick:function(e,n){var i;Te.prototype.handleClick.apply(this,arguments),t(n.target).closest("a[href]").length||(i=e.footprint.eventDef.url)&&!n.isDefaultPrevented()&&(window.location.href=i)}}),renderEmptyMessage:function(){this.contentEl.html('
'+et(this.opt("noEventsMessage"))+"
")},renderSegList:function(e){var n,i,r,s=this.groupSegsByDay(e),o=t('
'),a=o.find("tbody");for(n=0;n'+(e?this.buildGotoAnchorHtml(t,{class:"fc-list-heading-main"},et(t.format(e))):"")+(n?this.buildGotoAnchorHtml(t,{class:"fc-list-heading-alt"},et(t.format(n))):"")+""}});return _t.list={class:zn,buttonTextKey:"list",defaults:{buttonText:"list",listDayFormat:"LL",noEventsMessage:"No events to display"}},_t.listDay={type:"list",duration:{days:1},defaults:{listDayFormat:"dddd"}},_t.listWeek={type:"list",duration:{weeks:1},defaults:{listDayFormat:"dddd",listDayAltFormat:"LL"}},_t.listMonth={type:"list",duration:{month:1},defaults:{listDayAltFormat:"dddd"}},_t.listYear={type:"list",duration:{year:1},defaults:{listDayAltFormat:"dddd"}},Wt}); \ No newline at end of file diff --git a/app/assets/javascripts/jquery.dataTables.js b/app/assets/javascripts/jquery.dataTables.js deleted file mode 100755 index 1d8a220..0000000 --- a/app/assets/javascripts/jquery.dataTables.js +++ /dev/null @@ -1,12099 +0,0 @@ -/** - * @summary DataTables - * @description Paginate, search and sort HTML tables - * @version 1.9.4 - * @file jquery.dataTables.js - * @author Allan Jardine (www.sprymedia.co.uk) - * @contact www.sprymedia.co.uk/contact - * - * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. - * - * This source file is free software, under either the GPL v2 license or a - * BSD style license, available at: - * http://datatables.net/license_gpl2 - * http://datatables.net/license_bsd - * - * This source file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. - * - * For details please refer to: http://www.datatables.net - */ - -/*jslint evil: true, undef: true, browser: true */ -/*globals $, jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns*/ - -(/** @lends */function( window, document, undefined ) { - -(function( factory ) { - "use strict"; - - // Define as an AMD module if possible - if ( typeof define === 'function' && define.amd ) - { - define( ['jquery'], factory ); - } - /* Define using browser globals otherwise - * Prevent multiple instantiations if the script is loaded twice - */ - else if ( jQuery && !jQuery.fn.dataTable ) - { - factory( jQuery ); - } -} -(/** @lends */function( $ ) { - "use strict"; - /** - * DataTables is a plug-in for the jQuery Javascript library. It is a - * highly flexible tool, based upon the foundations of progressive - * enhancement, which will add advanced interaction controls to any - * HTML table. For a full list of features please refer to - * DataTables.net. - * - * Note that the DataTable object is not a global variable but is - * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which - * it may be accessed. - * - * @class - * @param {object} [oInit={}] Configuration object for DataTables. Options - * are defined by {@link DataTable.defaults} - * @requires jQuery 1.3+ - * - * @example - * // Basic initialisation - * $(document).ready( function { - * $('#example').dataTable(); - * } ); - * - * @example - * // Initialisation with configuration options - in this case, disable - * // pagination and sorting. - * $(document).ready( function { - * $('#example').dataTable( { - * "bPaginate": false, - * "bSort": false - * } ); - * } ); - */ - var DataTable = function( oInit ) - { - - - /** - * Add a column to the list used for the table with default values - * @param {object} oSettings dataTables settings object - * @param {node} nTh The th element for this column - * @memberof DataTable#oApi - */ - function _fnAddColumn( oSettings, nTh ) - { - var oDefaults = DataTable.defaults.columns; - var iCol = oSettings.aoColumns.length; - var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { - "sSortingClass": oSettings.oClasses.sSortable, - "sSortingClassJUI": oSettings.oClasses.sSortJUI, - "nTh": nTh ? nTh : document.createElement('th'), - "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', - "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], - "mData": oDefaults.mData ? oDefaults.oDefaults : iCol - } ); - oSettings.aoColumns.push( oCol ); - - /* Add a column specific filter */ - if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null ) - { - oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); - } - else - { - var oPre = oSettings.aoPreSearchCols[ iCol ]; - - /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ - if ( oPre.bRegex === undefined ) - { - oPre.bRegex = true; - } - - if ( oPre.bSmart === undefined ) - { - oPre.bSmart = true; - } - - if ( oPre.bCaseInsensitive === undefined ) - { - oPre.bCaseInsensitive = true; - } - } - - /* Use the column options function to initialise classes etc */ - _fnColumnOptions( oSettings, iCol, null ); - } - - - /** - * Apply options for a column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column index to consider - * @param {object} oOptions object with sType, bVisible and bSearchable etc - * @memberof DataTable#oApi - */ - function _fnColumnOptions( oSettings, iCol, oOptions ) - { - var oCol = oSettings.aoColumns[ iCol ]; - - /* User specified column options */ - if ( oOptions !== undefined && oOptions !== null ) - { - /* Backwards compatibility for mDataProp */ - if ( oOptions.mDataProp && !oOptions.mData ) - { - oOptions.mData = oOptions.mDataProp; - } - - if ( oOptions.sType !== undefined ) - { - oCol.sType = oOptions.sType; - oCol._bAutoType = false; - } - - $.extend( oCol, oOptions ); - _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); - - /* iDataSort to be applied (backwards compatibility), but aDataSort will take - * priority if defined - */ - if ( oOptions.iDataSort !== undefined ) - { - oCol.aDataSort = [ oOptions.iDataSort ]; - } - _fnMap( oCol, oOptions, "aDataSort" ); - } - - /* Cache the data get and set functions for speed */ - var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; - var mData = _fnGetObjectDataFn( oCol.mData ); - - oCol.fnGetData = function (oData, sSpecific) { - var innerData = mData( oData, sSpecific ); - - if ( oCol.mRender && (sSpecific && sSpecific !== '') ) - { - return mRender( innerData, sSpecific, oData ); - } - return innerData; - }; - oCol.fnSetData = _fnSetObjectDataFn( oCol.mData ); - - /* Feature sorting overrides column specific when off */ - if ( !oSettings.oFeatures.bSort ) - { - oCol.bSortable = false; - } - - /* Check that the class assignment is correct for sorting */ - if ( !oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableNone; - oCol.sSortingClassJUI = ""; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortable; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; - } - else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableAsc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableDesc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; - } - } - - - /** - * Adjust the table column widths for new data. Note: you would probably want to - * do a redraw after calling this function! - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnAdjustColumnSizing ( oSettings ) - { - /* Not interested in doing column width calculation if auto-width is disabled */ - if ( oSettings.oFeatures.bAutoWidth === false ) - { - return false; - } - - _fnCalculateColumnWidths( oSettings ); - for ( var i=0 , iLen=oSettings.aoColumns.length ; i
')[0]; - oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable ); - - /* - * All DataTables are wrapped in a div - */ - oSettings.nTableWrapper = $('
')[0]; - oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; - - /* Track where we want to insert the option */ - var nInsertNode = oSettings.nTableWrapper; - - /* Loop over the user set positioning and place the elements as needed */ - var aDom = oSettings.sDom.split(''); - var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j; - for ( var i=0 ; i
')[0]; - - /* Check to see if we should append an id and/or a class name to the container */ - cNext = aDom[i+1]; - if ( cNext == "'" || cNext == '"' ) - { - sAttr = ""; - j = 2; - while ( aDom[i+j] != cNext ) - { - sAttr += aDom[i+j]; - j++; - } - - /* Replace jQuery UI constants */ - if ( sAttr == "H" ) - { - sAttr = oSettings.oClasses.sJUIHeader; - } - else if ( sAttr == "F" ) - { - sAttr = oSettings.oClasses.sJUIFooter; - } - - /* The attribute can be in the format of "#id.class", "#id" or "class" This logic - * breaks the string into parts and applies them as needed - */ - if ( sAttr.indexOf('.') != -1 ) - { - var aSplit = sAttr.split('.'); - nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); - nNewNode.className = aSplit[1]; - } - else if ( sAttr.charAt(0) == "#" ) - { - nNewNode.id = sAttr.substr(1, sAttr.length-1); - } - else - { - nNewNode.className = sAttr; - } - - i += j; /* Move along the position array */ - } - - nInsertNode.appendChild( nNewNode ); - nInsertNode = nNewNode; - } - else if ( cOption == '>' ) - { - /* End container div */ - nInsertNode = nInsertNode.parentNode; - } - else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange ) - { - /* Length */ - nTmp = _fnFeatureHtmlLength( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'f' && oSettings.oFeatures.bFilter ) - { - /* Filter */ - nTmp = _fnFeatureHtmlFilter( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'r' && oSettings.oFeatures.bProcessing ) - { - /* pRocessing */ - nTmp = _fnFeatureHtmlProcessing( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 't' ) - { - /* Table */ - nTmp = _fnFeatureHtmlTable( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'i' && oSettings.oFeatures.bInfo ) - { - /* Info */ - nTmp = _fnFeatureHtmlInfo( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'p' && oSettings.oFeatures.bPaginate ) - { - /* Pagination */ - nTmp = _fnFeatureHtmlPaginate( oSettings ); - iPushFeature = 1; - } - else if ( DataTable.ext.aoFeatures.length !== 0 ) - { - /* Plug-in features */ - var aoFeatures = DataTable.ext.aoFeatures; - for ( var k=0, kLen=aoFeatures.length ; k') : - sSearchStr==="" ? '' : sSearchStr+' '; - - var nFilter = document.createElement( 'div' ); - nFilter.className = oSettings.oClasses.sFilter; - nFilter.innerHTML = ''; - if ( !oSettings.aanFeatures.f ) - { - nFilter.id = oSettings.sTableId+'_filter'; - } - - var jqFilter = $('input[type="text"]', nFilter); - - // Store a reference to the input element, so other input elements could be - // added to the filter wrapper if needed (submit button for example) - nFilter._DT_Input = jqFilter[0]; - - jqFilter.val( oPreviousSearch.sSearch.replace('"','"') ); - jqFilter.bind( 'keyup.DT', function(e) { - /* Update all other filter input elements for the new display */ - var n = oSettings.aanFeatures.f; - var val = this.value==="" ? "" : this.value; // mental IE8 fix :-( - - for ( var i=0, iLen=n.length ; i=0 ; i-- ) - { - var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ), - oSettings.aoColumns[iColumn].sType ); - if ( ! rpSearch.test( sData ) ) - { - oSettings.aiDisplay.splice( i, 1 ); - iIndexCorrector++; - } - } - } - - - /** - * Filter the data table based on user input and draw the table - * @param {object} oSettings dataTables settings object - * @param {string} sInput string to filter on - * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0) - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insenstive matching or not - * @memberof DataTable#oApi - */ - function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive ) - { - var i; - var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive ); - var oPrevSearch = oSettings.oPreviousSearch; - - /* Check if we are forcing or not - optional parameter */ - if ( !iForce ) - { - iForce = 0; - } - - /* Need to take account of custom filtering functions - always filter */ - if ( DataTable.ext.afnFiltering.length !== 0 ) - { - iForce = 1; - } - - /* - * If the input is blank - we want the full data set - */ - if ( sInput.length <= 0 ) - { - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - } - else - { - /* - * We are starting a new search or the new search string is smaller - * then the old one (i.e. delete). Search from the master array - */ - if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length || - oPrevSearch.sSearch.length > sInput.length || iForce == 1 || - sInput.indexOf(oPrevSearch.sSearch) !== 0 ) - { - /* Nuke the old display array - we are going to rebuild it */ - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - - /* Force a rebuild of the search array */ - _fnBuildSearchArray( oSettings, 1 ); - - /* Search through all records to populate the search array - * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1 - * mapping - */ - for ( i=0 ; i').html(sSearch).text(); - } - - // Strip newline characters - return sSearch.replace( /[\n\r]/g, " " ); - } - - /** - * Build a regular expression object suitable for searching a table - * @param {string} sSearch string to search for - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insensitive matching or not - * @returns {RegExp} constructed object - * @memberof DataTable#oApi - */ - function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive ) - { - var asSearch, sRegExpString; - - if ( bSmart ) - { - /* Generate the regular expression to use. Something along the lines of: - * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$ - */ - asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' ); - sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$'; - return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" ); - } - else - { - sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch ); - return new RegExp( sSearch, bCaseInsensitive ? "i" : "" ); - } - } - - - /** - * Convert raw data into something that the user can search on - * @param {string} sData data to be modified - * @param {string} sType data type - * @returns {string} search string - * @memberof DataTable#oApi - */ - function _fnDataToSearch ( sData, sType ) - { - if ( typeof DataTable.ext.ofnSearch[sType] === "function" ) - { - return DataTable.ext.ofnSearch[sType]( sData ); - } - else if ( sData === null ) - { - return ''; - } - else if ( sType == "html" ) - { - return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" ); - } - else if ( typeof sData === "string" ) - { - return sData.replace(/[\r\n]/g," "); - } - return sData; - } - - - /** - * scape a string such that it can be used in a regular expression - * @param {string} sVal string to escape - * @returns {string} escaped string - * @memberof DataTable#oApi - */ - function _fnEscapeRegex ( sVal ) - { - var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ]; - var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' ); - return sVal.replace(reReplace, '\\$1'); - } - - - /** - * Generate the node required for the info display - * @param {object} oSettings dataTables settings object - * @returns {node} Information element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlInfo ( oSettings ) - { - var nInfo = document.createElement( 'div' ); - nInfo.className = oSettings.oClasses.sInfo; - - /* Actions that are to be taken once only for this feature */ - if ( !oSettings.aanFeatures.i ) - { - /* Add draw callback */ - oSettings.aoDrawCallback.push( { - "fn": _fnUpdateInfo, - "sName": "information" - } ); - - /* Add id */ - nInfo.id = oSettings.sTableId+'_info'; - } - oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' ); - - return nInfo; - } - - - /** - * Update the information elements in the display - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnUpdateInfo ( oSettings ) - { - /* Show information about the table */ - if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 ) - { - return; - } - - var - oLang = oSettings.oLanguage, - iStart = oSettings._iDisplayStart+1, - iEnd = oSettings.fnDisplayEnd(), - iMax = oSettings.fnRecordsTotal(), - iTotal = oSettings.fnRecordsDisplay(), - sOut; - - if ( iTotal === 0 ) - { - /* Empty record set */ - sOut = oLang.sInfoEmpty; - } - else { - /* Normal record set */ - sOut = oLang.sInfo; - } - - if ( iTotal != iMax ) - { - /* Record set after filtering */ - sOut += ' ' + oLang.sInfoFiltered; - } - - // Convert the macros - sOut += oLang.sInfoPostFix; - sOut = _fnInfoMacros( oSettings, sOut ); - - if ( oLang.fnInfoCallback !== null ) - { - sOut = oLang.fnInfoCallback.call( oSettings.oInstance, - oSettings, iStart, iEnd, iMax, iTotal, sOut ); - } - - var n = oSettings.aanFeatures.i; - for ( var i=0, iLen=n.length ; i'; - var i, iLen; - var aLengthMenu = oSettings.aLengthMenu; - - if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' && - typeof aLengthMenu[1] === 'object' ) - { - for ( i=0, iLen=aLengthMenu[0].length ; i'+aLengthMenu[1][i]+''; - } - } - else - { - for ( i=0, iLen=aLengthMenu.length ; i'+aLengthMenu[i]+''; - } - } - sStdMenu += ''; - - var nLength = document.createElement( 'div' ); - if ( !oSettings.aanFeatures.l ) - { - nLength.id = oSettings.sTableId+'_length'; - } - nLength.className = oSettings.oClasses.sLength; - nLength.innerHTML = ''; - - /* - * Set the length to the current display length - thanks to Andrea Pavlovic for this fix, - * and Stefan Skopnik for fixing the fix! - */ - $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true); - - $('select', nLength).bind( 'change.DT', function(e) { - var iVal = $(this).val(); - - /* Update all other length options for the new display */ - var n = oSettings.aanFeatures.l; - for ( i=0, iLen=n.length ; i oSettings.aiDisplay.length || - oSettings._iDisplayLength == -1 ) - { - oSettings._iDisplayEnd = oSettings.aiDisplay.length; - } - else - { - oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength; - } - } - } - - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Note that most of the paging logic is done in - * DataTable.ext.oPagination - */ - - /** - * Generate the node required for default pagination - * @param {object} oSettings dataTables settings object - * @returns {node} Pagination feature node - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlPaginate ( oSettings ) - { - if ( oSettings.oScroll.bInfinite ) - { - return null; - } - - var nPaginate = document.createElement( 'div' ); - nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType; - - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate, - function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - ); - - /* Add a draw callback for the pagination on first instance, to update the paging display */ - if ( !oSettings.aanFeatures.p ) - { - oSettings.aoDrawCallback.push( { - "fn": function( oSettings ) { - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } ); - }, - "sName": "pagination" - } ); - } - return nPaginate; - } - - - /** - * Alter the display settings to change the page - * @param {object} oSettings dataTables settings object - * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" - * or page number to jump to (integer) - * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1 - * @memberof DataTable#oApi - */ - function _fnPageChange ( oSettings, mAction ) - { - var iOldStart = oSettings._iDisplayStart; - - if ( typeof mAction === "number" ) - { - oSettings._iDisplayStart = mAction * oSettings._iDisplayLength; - if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "first" ) - { - oSettings._iDisplayStart = 0; - } - else if ( mAction == "previous" ) - { - oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ? - oSettings._iDisplayStart - oSettings._iDisplayLength : - 0; - - /* Correct for under-run */ - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "next" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - /* Make sure we are not over running the display array */ - if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart += oSettings._iDisplayLength; - } - } - else - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "last" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1; - oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength; - } - else - { - oSettings._iDisplayStart = 0; - } - } - else - { - _fnLog( oSettings, 0, "Unknown paging action: "+mAction ); - } - $(oSettings.oInstance).trigger('page', oSettings); - - return iOldStart != oSettings._iDisplayStart; - } - - - - /** - * Generate the node required for the processing node - * @param {object} oSettings dataTables settings object - * @returns {node} Processing element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlProcessing ( oSettings ) - { - var nProcessing = document.createElement( 'div' ); - - if ( !oSettings.aanFeatures.r ) - { - nProcessing.id = oSettings.sTableId+'_processing'; - } - nProcessing.innerHTML = oSettings.oLanguage.sProcessing; - nProcessing.className = oSettings.oClasses.sProcessing; - oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable ); - - return nProcessing; - } - - - /** - * Display or hide the processing indicator - * @param {object} oSettings dataTables settings object - * @param {bool} bShow Show the processing indicator (true) or not (false) - * @memberof DataTable#oApi - */ - function _fnProcessingDisplay ( oSettings, bShow ) - { - if ( oSettings.oFeatures.bProcessing ) - { - var an = oSettings.aanFeatures.r; - for ( var i=0, iLen=an.length ; i 0 ) - { - nCaption = nCaption[0]; - if ( nCaption._captionSide === "top" ) - { - nScrollHeadTable.appendChild( nCaption ); - } - else if ( nCaption._captionSide === "bottom" && nTfoot ) - { - nScrollFootTable.appendChild( nCaption ); - } - } - - /* - * Sizing - */ - /* When x-scrolling add the width and a scroller to move the header with the body */ - if ( oSettings.oScroll.sX !== "" ) - { - nScrollHead.style.width = _fnStringToCss( oSettings.oScroll.sX ); - nScrollBody.style.width = _fnStringToCss( oSettings.oScroll.sX ); - - if ( nTfoot !== null ) - { - nScrollFoot.style.width = _fnStringToCss( oSettings.oScroll.sX ); - } - - /* When the body is scrolled, then we also want to scroll the headers */ - $(nScrollBody).scroll( function (e) { - nScrollHead.scrollLeft = this.scrollLeft; - - if ( nTfoot !== null ) - { - nScrollFoot.scrollLeft = this.scrollLeft; - } - } ); - } - - /* When yscrolling, add the height */ - if ( oSettings.oScroll.sY !== "" ) - { - nScrollBody.style.height = _fnStringToCss( oSettings.oScroll.sY ); - } - - /* Redraw - align columns across the tables */ - oSettings.aoDrawCallback.push( { - "fn": _fnScrollDraw, - "sName": "scrolling" - } ); - - /* Infinite scrolling event handlers */ - if ( oSettings.oScroll.bInfinite ) - { - $(nScrollBody).scroll( function() { - /* Use a blocker to stop scrolling from loading more data while other data is still loading */ - if ( !oSettings.bDrawing && $(this).scrollTop() !== 0 ) - { - /* Check if we should load the next data set */ - if ( $(this).scrollTop() + $(this).height() > - $(oSettings.nTable).height() - oSettings.oScroll.iLoadGap ) - { - /* Only do the redraw if we have to - we might be at the end of the data */ - if ( oSettings.fnDisplayEnd() < oSettings.fnRecordsDisplay() ) - { - _fnPageChange( oSettings, 'next' ); - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - } - } ); - } - - oSettings.nScrollHead = nScrollHead; - oSettings.nScrollFoot = nScrollFoot; - - return nScroller; - } - - - /** - * Update the various tables for resizing. It's a bit of a pig this function, but - * basically the idea to: - * 1. Re-create the table inside the scrolling div - * 2. Take live measurements from the DOM - * 3. Apply the measurements - * 4. Clean up - * @param {object} o dataTables settings object - * @returns {node} Node to add to the DOM - * @memberof DataTable#oApi - */ - function _fnScrollDraw ( o ) - { - var - nScrollHeadInner = o.nScrollHead.getElementsByTagName('div')[0], - nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0], - nScrollBody = o.nTable.parentNode, - i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis, - nTheadSize, nTfootSize, - iWidth, aApplied=[], aAppliedFooter=[], iSanityWidth, - nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null, - nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null, - ie67 = o.oBrowser.bScrollOversize, - zeroOut = function(nSizer) { - oStyle = nSizer.style; - oStyle.paddingTop = "0"; - oStyle.paddingBottom = "0"; - oStyle.borderTopWidth = "0"; - oStyle.borderBottomWidth = "0"; - oStyle.height = 0; - }; - - /* - * 1. Re-create the table inside the scrolling div - */ - - /* Remove the old minimised thead and tfoot elements in the inner table */ - $(o.nTable).children('thead, tfoot').remove(); - - /* Clone the current header and footer elements and then place it into the inner table */ - nTheadSize = $(o.nTHead).clone()[0]; - o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] ); - anHeadToSize = o.nTHead.getElementsByTagName('tr'); - anHeadSizers = nTheadSize.getElementsByTagName('tr'); - - if ( o.nTFoot !== null ) - { - nTfootSize = $(o.nTFoot).clone()[0]; - o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] ); - anFootToSize = o.nTFoot.getElementsByTagName('tr'); - anFootSizers = nTfootSize.getElementsByTagName('tr'); - } - - /* - * 2. Take live measurements from the DOM - do not alter the DOM itself! - */ - - /* Remove old sizing and apply the calculated column widths - * Get the unique column headers in the newly created (cloned) header. We want to apply the - * calculated sizes to this header - */ - if ( o.oScroll.sX === "" ) - { - nScrollBody.style.width = '100%'; - nScrollHeadInner.parentNode.style.width = '100%'; - } - - var nThs = _fnGetUniqueThs( o, nTheadSize ); - for ( i=0, iLen=nThs.length ; i nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth() - o.oScroll.iBarWidth); - } - } - else - { - if ( o.oScroll.sXInner !== "" ) - { - /* x scroll inner has been given - use it */ - o.nTable.style.width = _fnStringToCss(o.oScroll.sXInner); - } - else if ( iSanityWidth == $(nScrollBody).width() && - $(nScrollBody).height() < $(o.nTable).height() ) - { - /* There is y-scrolling - try to take account of the y scroll bar */ - o.nTable.style.width = _fnStringToCss( iSanityWidth-o.oScroll.iBarWidth ); - if ( $(o.nTable).outerWidth() > iSanityWidth-o.oScroll.iBarWidth ) - { - /* Not possible to take account of it */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - else - { - /* All else fails */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - - /* Recalculate the sanity width - now that we've applied the required width, before it was - * a temporary variable. This is required because the column width calculation is done - * before this table DOM is created. - */ - iSanityWidth = $(o.nTable).outerWidth(); - - /* We want the hidden header to have zero height, so remove padding and borders. Then - * set the width based on the real headers - */ - - // Apply all styles in one pass. Invalidates layout only once because we don't read any - // DOM properties. - _fnApplyToChildren( zeroOut, anHeadSizers ); - - // Read all widths in next pass. Forces layout only once because we do not change - // any DOM properties. - _fnApplyToChildren( function(nSizer) { - aApplied.push( _fnStringToCss( $(nSizer).width() ) ); - }, anHeadSizers ); - - // Apply all widths in final pass. Invalidates layout only once because we do not - // read any DOM properties. - _fnApplyToChildren( function(nToSize, i) { - nToSize.style.width = aApplied[i]; - }, anHeadToSize ); - - $(anHeadSizers).height(0); - - /* Same again with the footer if we have one */ - if ( o.nTFoot !== null ) - { - _fnApplyToChildren( zeroOut, anFootSizers ); - - _fnApplyToChildren( function(nSizer) { - aAppliedFooter.push( _fnStringToCss( $(nSizer).width() ) ); - }, anFootSizers ); - - _fnApplyToChildren( function(nToSize, i) { - nToSize.style.width = aAppliedFooter[i]; - }, anFootToSize ); - - $(anFootSizers).height(0); - } - - /* - * 3. Apply the measurements - */ - - /* "Hide" the header and footer that we used for the sizing. We want to also fix their width - * to what they currently are - */ - _fnApplyToChildren( function(nSizer, i) { - nSizer.innerHTML = ""; - nSizer.style.width = aApplied[i]; - }, anHeadSizers ); - - if ( o.nTFoot !== null ) - { - _fnApplyToChildren( function(nSizer, i) { - nSizer.innerHTML = ""; - nSizer.style.width = aAppliedFooter[i]; - }, anFootSizers ); - } - - /* Sanity check that the table is of a sensible width. If not then we are going to get - * misalignment - try to prevent this by not allowing the table to shrink below its min width - */ - if ( $(o.nTable).outerWidth() < iSanityWidth ) - { - /* The min width depends upon if we have a vertical scrollbar visible or not */ - var iCorrection = ((nScrollBody.scrollHeight > nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll")) ? - iSanityWidth+o.oScroll.iBarWidth : iSanityWidth; - - /* IE6/7 are a law unto themselves... */ - if ( ie67 && (nScrollBody.scrollHeight > - nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( iCorrection-o.oScroll.iBarWidth ); - } - - /* Apply the calculated minimum width to the table wrappers */ - nScrollBody.style.width = _fnStringToCss( iCorrection ); - o.nScrollHead.style.width = _fnStringToCss( iCorrection ); - - if ( o.nTFoot !== null ) - { - o.nScrollFoot.style.width = _fnStringToCss( iCorrection ); - } - - /* And give the user a warning that we've stopped the table getting too small */ - if ( o.oScroll.sX === "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. The table has been drawn at its minimum possible width." ); - } - else if ( o.oScroll.sXInner !== "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. Increase the sScrollXInner value or remove it to allow automatic"+ - " calculation" ); - } - } - else - { - nScrollBody.style.width = _fnStringToCss( '100%' ); - o.nScrollHead.style.width = _fnStringToCss( '100%' ); - - if ( o.nTFoot !== null ) - { - o.nScrollFoot.style.width = _fnStringToCss( '100%' ); - } - } - - - /* - * 4. Clean up - */ - if ( o.oScroll.sY === "" ) - { - /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting - * the scrollbar height from the visible display, rather than adding it on. We need to - * set the height in order to sort this. Don't want to do it in any other browsers. - */ - if ( ie67 ) - { - nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+o.oScroll.iBarWidth ); - } - } - - if ( o.oScroll.sY !== "" && o.oScroll.bCollapse ) - { - nScrollBody.style.height = _fnStringToCss( o.oScroll.sY ); - - var iExtra = (o.oScroll.sX !== "" && o.nTable.offsetWidth > nScrollBody.offsetWidth) ? - o.oScroll.iBarWidth : 0; - if ( o.nTable.offsetHeight < nScrollBody.offsetHeight ) - { - nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+iExtra ); - } - } - - /* Finally set the width's of the header and footer tables */ - var iOuterWidth = $(o.nTable).outerWidth(); - nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth ); - nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth ); - - // Figure out if there are scrollbar present - if so then we need a the header and footer to - // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar) - var bScrolling = $(o.nTable).height() > nScrollBody.clientHeight || $(nScrollBody).css('overflow-y') == "scroll"; - nScrollHeadInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; - - if ( o.nTFoot !== null ) - { - nScrollFootTable.style.width = _fnStringToCss( iOuterWidth ); - nScrollFootInner.style.width = _fnStringToCss( iOuterWidth ); - nScrollFootInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; - } - - /* Adjust the position of the header in case we loose the y-scrollbar */ - $(nScrollBody).scroll(); - - /* If sorting or filtering has occurred, jump the scrolling back to the top */ - if ( o.bSorted || o.bFiltered ) - { - nScrollBody.scrollTop = 0; - } - } - - - /** - * Apply a given function to the display child nodes of an element array (typically - * TD children of TR rows - * @param {function} fn Method to apply to the objects - * @param array {nodes} an1 List of elements to look through for display children - * @param array {nodes} an2 Another list (identical structure to the first) - optional - * @memberof DataTable#oApi - */ - function _fnApplyToChildren( fn, an1, an2 ) - { - var index=0, i=0, iLen=an1.length; - var nNode1, nNode2; - - while ( i < iLen ) - { - nNode1 = an1[i].firstChild; - nNode2 = an2 ? an2[i].firstChild : null; - while ( nNode1 ) - { - if ( nNode1.nodeType === 1 ) - { - if ( an2 ) - { - fn( nNode1, nNode2, index ); - } - else - { - fn( nNode1, index ); - } - index++; - } - nNode1 = nNode1.nextSibling; - nNode2 = an2 ? nNode2.nextSibling : null; - } - i++; - } - } - - /** - * Convert a CSS unit width to pixels (e.g. 2em) - * @param {string} sWidth width to be converted - * @param {node} nParent parent to get the with for (required for relative widths) - optional - * @returns {int} iWidth width in pixels - * @memberof DataTable#oApi - */ - function _fnConvertToWidth ( sWidth, nParent ) - { - if ( !sWidth || sWidth === null || sWidth === '' ) - { - return 0; - } - - if ( !nParent ) - { - nParent = document.body; - } - - var iWidth; - var nTmp = document.createElement( "div" ); - nTmp.style.width = _fnStringToCss( sWidth ); - - nParent.appendChild( nTmp ); - iWidth = nTmp.offsetWidth; - nParent.removeChild( nTmp ); - - return ( iWidth ); - } - - - /** - * Calculate the width of columns for the table - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnCalculateColumnWidths ( oSettings ) - { - var iTableWidth = oSettings.nTable.offsetWidth; - var iUserInputs = 0; - var iTmpWidth; - var iVisibleColumns = 0; - var iColums = oSettings.aoColumns.length; - var i, iIndex, iCorrector, iWidth; - var oHeaders = $('th', oSettings.nTHead); - var widthAttr = oSettings.nTable.getAttribute('width'); - var nWrapper = oSettings.nTable.parentNode; - - /* Convert any user input sizes into pixel sizes */ - for ( i=0 ; itd', nCalcTmp); - } - - /* Apply custom sizing to the cloned header */ - var nThs = _fnGetUniqueThs( oSettings, nTheadClone ); - iCorrector = 0; - for ( i=0 ; i 0 ) - { - oSettings.aoColumns[i].sWidth = _fnStringToCss( iWidth ); - } - iCorrector++; - } - } - - var cssWidth = $(nCalcTmp).css('width'); - oSettings.nTable.style.width = (cssWidth.indexOf('%') !== -1) ? - cssWidth : _fnStringToCss( $(nCalcTmp).outerWidth() ); - nCalcTmp.parentNode.removeChild( nCalcTmp ); - } - - if ( widthAttr ) - { - oSettings.nTable.style.width = _fnStringToCss( widthAttr ); - } - } - - - /** - * Adjust a table's width to take account of scrolling - * @param {object} oSettings dataTables settings object - * @param {node} n table node - * @memberof DataTable#oApi - */ - function _fnScrollingWidthAdjust ( oSettings, n ) - { - if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY !== "" ) - { - /* When y-scrolling only, we want to remove the width of the scroll bar so the table - * + scroll bar will fit into the area avaialble. - */ - var iOrigWidth = $(n).width(); - n.style.width = _fnStringToCss( $(n).outerWidth()-oSettings.oScroll.iBarWidth ); - } - else if ( oSettings.oScroll.sX !== "" ) - { - /* When x-scrolling both ways, fix the table at it's current size, without adjusting */ - n.style.width = _fnStringToCss( $(n).outerWidth() ); - } - } - - - /** - * Get the widest node - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {node} widest table node - * @memberof DataTable#oApi - */ - function _fnGetWidestNode( oSettings, iCol ) - { - var iMaxIndex = _fnGetMaxLenString( oSettings, iCol ); - if ( iMaxIndex < 0 ) - { - return null; - } - - if ( oSettings.aoData[iMaxIndex].nTr === null ) - { - var n = document.createElement('td'); - n.innerHTML = _fnGetCellData( oSettings, iMaxIndex, iCol, '' ); - return n; - } - return _fnGetTdNodes(oSettings, iMaxIndex)[iCol]; - } - - - /** - * Get the maximum strlen for each data column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {string} max string length for each column - * @memberof DataTable#oApi - */ - function _fnGetMaxLenString( oSettings, iCol ) - { - var iMax = -1; - var iMaxIndex = -1; - - for ( var i=0 ; i/g, "" ); - if ( s.length > iMax ) - { - iMax = s.length; - iMaxIndex = i; - } - } - - return iMaxIndex; - } - - - /** - * Append a CSS unit (only if required) to a string - * @param {array} aArray1 first array - * @param {array} aArray2 second array - * @returns {int} 0 if match, 1 if length is different, 2 if no match - * @memberof DataTable#oApi - */ - function _fnStringToCss( s ) - { - if ( s === null ) - { - return "0px"; - } - - if ( typeof s == 'number' ) - { - if ( s < 0 ) - { - return "0px"; - } - return s+"px"; - } - - /* Check if the last character is not 0-9 */ - var c = s.charCodeAt( s.length-1 ); - if (c < 0x30 || c > 0x39) - { - return s; - } - return s+"px"; - } - - - /** - * Get the width of a scroll bar in this browser being used - * @returns {int} width in pixels - * @memberof DataTable#oApi - */ - function _fnScrollBarWidth () - { - var inner = document.createElement('p'); - var style = inner.style; - style.width = "100%"; - style.height = "200px"; - style.padding = "0px"; - - var outer = document.createElement('div'); - style = outer.style; - style.position = "absolute"; - style.top = "0px"; - style.left = "0px"; - style.visibility = "hidden"; - style.width = "200px"; - style.height = "150px"; - style.padding = "0px"; - style.overflow = "hidden"; - outer.appendChild(inner); - - document.body.appendChild(outer); - var w1 = inner.offsetWidth; - outer.style.overflow = 'scroll'; - var w2 = inner.offsetWidth; - if ( w1 == w2 ) - { - w2 = outer.clientWidth; - } - - document.body.removeChild(outer); - return (w1 - w2); - } - - /** - * Change the order of the table - * @param {object} oSettings dataTables settings object - * @param {bool} bApplyClasses optional - should we apply classes or not - * @memberof DataTable#oApi - */ - function _fnSort ( oSettings, bApplyClasses ) - { - var - i, iLen, j, jLen, k, kLen, - sDataType, nTh, - aaSort = [], - aiOrig = [], - oSort = DataTable.ext.oSort, - aoData = oSettings.aoData, - aoColumns = oSettings.aoColumns, - oAria = oSettings.oLanguage.oAria; - - /* No sorting required if server-side or no sorting array */ - if ( !oSettings.oFeatures.bServerSide && - (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) ) - { - aaSort = ( oSettings.aaSortingFixed !== null ) ? - oSettings.aaSortingFixed.concat( oSettings.aaSorting ) : - oSettings.aaSorting.slice(); - - /* If there is a sorting data type, and a function belonging to it, then we need to - * get the data from the developer's function and apply it for this column - */ - for ( i=0 ; i/g, "" ); - nTh = aoColumns[i].nTh; - nTh.removeAttribute('aria-sort'); - nTh.removeAttribute('aria-label'); - - /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ - if ( aoColumns[i].bSortable ) - { - if ( aaSort.length > 0 && aaSort[0][0] == i ) - { - nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" ); - - var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ? - aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0]; - nTh.setAttribute('aria-label', sTitle+ - (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - else - { - nTh.setAttribute('aria-label', sTitle+ - (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - } - else - { - nTh.setAttribute('aria-label', sTitle); - } - } - - /* Tell the draw function that we have sorted the data */ - oSettings.bSorted = true; - $(oSettings.oInstance).trigger('sort', oSettings); - - /* Copy the master data into the draw array and re-draw */ - if ( oSettings.oFeatures.bFilter ) - { - /* _fnFilter() will redraw the table for us */ - _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 ); - } - else - { - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - oSettings._iDisplayStart = 0; /* reset display back to page 0 */ - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - - - /** - * Attach a sort handler (click) to a node - * @param {object} oSettings dataTables settings object - * @param {node} nNode node to attach the handler to - * @param {int} iDataIndex column sorting index - * @param {function} [fnCallback] callback function - * @memberof DataTable#oApi - */ - function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback ) - { - _fnBindAction( nNode, {}, function (e) { - /* If the column is not sortable - don't to anything */ - if ( oSettings.aoColumns[iDataIndex].bSortable === false ) - { - return; - } - - /* - * This is a little bit odd I admit... I declare a temporary function inside the scope of - * _fnBuildHead and the click handler in order that the code presented here can be used - * twice - once for when bProcessing is enabled, and another time for when it is - * disabled, as we need to perform slightly different actions. - * Basically the issue here is that the Javascript engine in modern browsers don't - * appear to allow the rendering engine to update the display while it is still executing - * it's thread (well - it does but only after long intervals). This means that the - * 'processing' display doesn't appear for a table sort. To break the js thread up a bit - * I force an execution break by using setTimeout - but this breaks the expected - * thread continuation for the end-developer's point of view (their code would execute - * too early), so we only do it when we absolutely have to. - */ - var fnInnerSorting = function () { - var iColumn, iNextSort; - - /* If the shift key is pressed then we are multiple column sorting */ - if ( e.shiftKey ) - { - /* Are we already doing some kind of sort on this column? */ - var bFound = false; - for ( var i=0 ; i 0 && sCurrentClass.indexOf(sNewClass) == -1 ) - { - /* We need to add a class */ - nTds[i].className = sCurrentClass + " " + sNewClass; - } - } - } - } - - - - /** - * Save the state of a table in a cookie such that the page can be reloaded - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnSaveState ( oSettings ) - { - if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying ) - { - return; - } - - /* Store the interesting variables */ - var i, iLen, bInfinite=oSettings.oScroll.bInfinite; - var oState = { - "iCreate": new Date().getTime(), - "iStart": (bInfinite ? 0 : oSettings._iDisplayStart), - "iEnd": (bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd), - "iLength": oSettings._iDisplayLength, - "aaSorting": $.extend( true, [], oSettings.aaSorting ), - "oSearch": $.extend( true, {}, oSettings.oPreviousSearch ), - "aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ), - "abVisCols": [] - }; - - for ( i=0, iLen=oSettings.aoColumns.length ; i 4096 ) /* Magic 10 for padding */ - { - for ( var i=0, iLen=aCookies.length ; i 4096 ) { - if ( aOldCookies.length === 0 ) { - // Deleted all DT cookies and still not enough space. Can't state save - return; - } - - var old = aOldCookies.pop(); - document.cookie = old.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+ - aParts.join('/') + "/"; - } - } - - document.cookie = sFullCookie; - } - - - /** - * Read an old cookie to get a cookie with an old table state - * @param {string} sName name of the cookie to read - * @returns {string} contents of the cookie - or null if no cookie with that name found - * @memberof DataTable#oApi - */ - function _fnReadCookie ( sName ) - { - var - aParts = window.location.pathname.split('/'), - sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase() + '=', - sCookieContents = document.cookie.split(';'); - - for( var i=0 ; i=0 ; i-- ) - { - aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) ); - } - - if ( sTrigger !== null ) - { - $(oSettings.oInstance).trigger(sTrigger, aArgs); - } - - return aRet; - } - - - /** - * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other - * library, then we use that as it is fast, safe and accurate. If the function isn't - * available then we need to built it ourselves - the inspiration for this function comes - * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is - * not perfect and absolutely should not be used as a replacement to json2.js - but it does - * do what we need, without requiring a dependency for DataTables. - * @param {object} o JSON object to be converted - * @returns {string} JSON string - * @memberof DataTable#oApi - */ - var _fnJsonString = (window.JSON) ? JSON.stringify : function( o ) - { - /* Not an object or array */ - var sType = typeof o; - if (sType !== "object" || o === null) - { - // simple data type - if (sType === "string") - { - o = '"'+o+'"'; - } - return o+""; - } - - /* If object or array, need to recurse over it */ - var - sProp, mValue, - json = [], - bArr = $.isArray(o); - - for (sProp in o) - { - mValue = o[sProp]; - sType = typeof mValue; - - if (sType === "string") - { - mValue = '"'+mValue+'"'; - } - else if (sType === "object" && mValue !== null) - { - mValue = _fnJsonString(mValue); - } - - json.push((bArr ? "" : '"'+sProp+'":') + mValue); - } - - return (bArr ? "[" : "{") + json + (bArr ? "]" : "}"); - }; - - - /** - * From some browsers (specifically IE6/7) we need special handling to work around browser - * bugs - this function is used to detect when these workarounds are needed. - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnBrowserDetect( oSettings ) - { - /* IE6/7 will oversize a width 100% element inside a scrolling element, to include the - * width of the scrollbar, while other browsers ensure the inner element is contained - * without forcing scrolling - */ - var n = $( - '
'+ - '
'+ - '
'+ - '
'+ - '
')[0]; - - document.body.appendChild( n ); - oSettings.oBrowser.bScrollOversize = $('#DT_BrowserTest', n)[0].offsetWidth === 100 ? true : false; - document.body.removeChild( n ); - } - - - /** - * Perform a jQuery selector action on the table's TR elements (from the tbody) and - * return the resulting jQuery object. - * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on - * @param {object} [oOpts] Optional parameters for modifying the rows to be included - * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter - * criterion ("applied") or all TR elements (i.e. no filter). - * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. - * Can be either 'current', whereby the current sorting of the table is used, or - * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page - * ("current") or not ("all"). If 'current' is given, then order is assumed to be - * 'current' and filter is 'applied', regardless of what they might be given as. - * @returns {object} jQuery object, filtered by the given selector. - * @dtopt API - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Highlight every second row - * oTable.$('tr:odd').css('backgroundColor', 'blue'); - * } ); - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Filter to rows with 'Webkit' in them, add a background colour and then - * // remove the filter, thus highlighting the 'Webkit' rows only. - * oTable.fnFilter('Webkit'); - * oTable.$('tr', {"filter": "applied"}).css('backgroundColor', 'blue'); - * oTable.fnFilter(''); - * } ); - */ - this.$ = function ( sSelector, oOpts ) - { - var i, iLen, a = [], tr; - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var aoData = oSettings.aoData; - var aiDisplay = oSettings.aiDisplay; - var aiDisplayMaster = oSettings.aiDisplayMaster; - - if ( !oOpts ) - { - oOpts = {}; - } - - oOpts = $.extend( {}, { - "filter": "none", // applied - "order": "current", // "original" - "page": "all" // current - }, oOpts ); - - // Current page implies that order=current and fitler=applied, since it is fairly - // senseless otherwise - if ( oOpts.page == 'current' ) - { - for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i - *
  • 1D array of data - add a single row with the data provided
  • - *
  • 2D array of arrays - add multiple rows in a single call
  • - *
  • object - data object when using mData
  • - *
  • array of objects - multiple data objects when using mData
  • - * - * @param {bool} [bRedraw=true] redraw the table or not - * @returns {array} An array of integers, representing the list of indexes in - * aoData ({@link DataTable.models.oSettings}) that have been added to - * the table. - * @dtopt API - * - * @example - * // Global var for counter - * var giCount = 2; - * - * $(document).ready(function() { - * $('#example').dataTable(); - * } ); - * - * function fnClickAddRow() { - * $('#example').dataTable().fnAddData( [ - * giCount+".1", - * giCount+".2", - * giCount+".3", - * giCount+".4" ] - * ); - * - * giCount++; - * } - */ - this.fnAddData = function( mData, bRedraw ) - { - if ( mData.length === 0 ) - { - return []; - } - - var aiReturn = []; - var iTest; - - /* Find settings from table node */ - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - - /* Check if we want to add multiple rows or not */ - if ( typeof mData[0] === "object" && mData[0] !== null ) - { - for ( var i=0 ; i= oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart -= oSettings._iDisplayLength; - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - - if ( bRedraw === undefined || bRedraw ) - { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - - return oData; - }; - - - /** - * Restore the table to it's original state in the DOM by removing all of DataTables - * enhancements, alterations to the DOM structure of the table and event listeners. - * @param {boolean} [bRemove=false] Completely remove the table from the DOM - * @dtopt API - * - * @example - * $(document).ready(function() { - * // This example is fairly pointless in reality, but shows how fnDestroy can be used - * var oTable = $('#example').dataTable(); - * oTable.fnDestroy(); - * } ); - */ - this.fnDestroy = function ( bRemove ) - { - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var nOrig = oSettings.nTableWrapper.parentNode; - var nBody = oSettings.nTBody; - var i, iLen; - - bRemove = (bRemove===undefined) ? false : bRemove; - - /* Flag to note that the table is currently being destroyed - no action should be taken */ - oSettings.bDestroying = true; - - /* Fire off the destroy callbacks for plug-ins etc */ - _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] ); - - /* If the table is not being removed, restore the hidden columns */ - if ( !bRemove ) - { - for ( i=0, iLen=oSettings.aoColumns.length ; itr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove(); - - /* When scrolling we had to break the table up - restore it */ - if ( oSettings.nTable != oSettings.nTHead.parentNode ) - { - $(oSettings.nTable).children('thead').remove(); - oSettings.nTable.appendChild( oSettings.nTHead ); - } - - if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode ) - { - $(oSettings.nTable).children('tfoot').remove(); - oSettings.nTable.appendChild( oSettings.nTFoot ); - } - - /* Remove the DataTables generated nodes, events and classes */ - oSettings.nTable.parentNode.removeChild( oSettings.nTable ); - $(oSettings.nTableWrapper).remove(); - - oSettings.aaSorting = []; - oSettings.aaSortingFixed = []; - _fnSortingClasses( oSettings ); - - $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') ); - - $('th, td', oSettings.nTHead).removeClass( [ - oSettings.oClasses.sSortable, - oSettings.oClasses.sSortableAsc, - oSettings.oClasses.sSortableDesc, - oSettings.oClasses.sSortableNone ].join(' ') - ); - if ( oSettings.bJUI ) - { - $('th span.'+oSettings.oClasses.sSortIcon - + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove(); - - $('th, td', oSettings.nTHead).each( function () { - var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this); - var kids = jqWrapper.contents(); - $(this).append( kids ); - jqWrapper.remove(); - } ); - } - - /* Add the TR elements back into the table in their original order */ - if ( !bRemove && oSettings.nTableReinsertBefore ) - { - nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore ); - } - else if ( !bRemove ) - { - nOrig.appendChild( oSettings.nTable ); - } - - for ( i=0, iLen=oSettings.aoData.length ; i