/*!
* FullCalendar v2.7.1
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
*/
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?// Node/CommonJS
module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){
// Merges an array of option objects into a single object
function c(a){return U(a,Va)}
// Given options specified for the calendar's constructor, massages any legacy options into a non-legacy form.
// Converts View-Option-Hashes into the View-Specific-Options format.
function d(b){var c,d={views:b.views||{}};
// iterate through all option override properties (except `views`)
return a.each(b,function(b,e){"views"!=b&&(
// could the value be a legacy View-Option-Hash?
a.isPlainObject(e)&&!/(time|duration|interval)$/i.test(b)&&-1==a.inArray(b,Va)?(c=null,a.each(e,function(a,e){/^(month|week|day|default|basic(Week|Day)?|agenda(Week|Day)?)$/.test(a)?(d.views[a]||(d.views[a]={}),d.views[a][b]=e):(c||(c={}),c[a]=e)}),c&&(d[b]=c)):d[b]=e)}),d}/* FullCalendar-specific DOM Utilities
----------------------------------------------------------------------------------------------------------------------*/
// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left
// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.
function e(a,b){b.left&&a.css({"border-left-width":1,"margin-left":b.left-1}),b.right&&a.css({"border-right-width":1,"margin-right":b.right-1})}
// Undoes compensateScroll and restores all borders/margins
function f(a){a.css({"margin-left":"","margin-right":"","border-left-width":"","border-right-width":""})}
// Make the mouse cursor express that an event is not allowed in the current area
function g(){a("body").addClass("fc-not-allowed")}
// Returns the mouse cursor to its original look
function h(){a("body").removeClass("fc-not-allowed")}
// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.
// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering
// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and
// reduces the available height.
function i(b,c,d){
// *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,
// and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.
var e=Math.floor(c/b.length),f=Math.floor(c-e*(b.length-1)),g=[],h=[],i=[],k=0;j(b),// give all elements their natural height
// find elements that are below the recommended height (expandable).
// important to query for heights in a single first pass (to avoid reflow oscillation).
b.each(function(c,d){var j=c===b.length-1?f:e,l=a(d).outerHeight(!0);j>l?(g.push(d),h.push(l),i.push(a(d).height())):
// this element stretches past recommended height (non-expandable). mark the space as occupied.
k+=l}),
// readjust the recommended height to only consider the height available to non-maxed-out rows.
d&&(c-=k,e=Math.floor(c/g.length),f=Math.floor(c-e*(g.length-1))),
// assign heights to all expandable elements
a(g).each(function(b,c){var d=b===g.length-1?f:e,j=h[b],k=i[b],l=d-(j-k);// subtract the margin/padding
d>j&&// we check this again because redistribution might have changed things
a(c).height(l)})}
// Undoes distrubuteHeight, restoring all els to their natural height
function j(a){a.height("")}
// Given `els`, a jQuery set of
cells, find the cell with the largest natural width and set the widths of all the
// cells to be that width.
// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline
function k(b){var c=0;// sometimes not accurate of width the text needs to stay on one line. insurance
return b.find("> span").each(function(b,d){var e=a(d).outerWidth();e>c&&(c=e)}),c++,b.width(c),c}
// Given one element that resides inside another,
// Subtracts the height of the inner element from the outer element.
function l(a,b){var c,d=a.add(b);// undo hack
// effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
// grab the dimensions
return d.css({position:"relative",// cause a reflow, which will force fresh dimension recalculation
left:-1}),c=a.outerHeight()-b.outerHeight(),d.css({position:"",left:""}),c}
// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51
function m(b){var c=b.css("position"),d=b.parents().filter(function(){var b=a(this);return/(auto|scroll)/.test(b.css("overflow")+b.css("overflow-y")+b.css("overflow-x"))}).eq(0);return"fixed"!==c&&d.length?d:a(b[0].ownerDocument||document)}
// Queries the outer bounding area of a jQuery element.
// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
// Origin is optional.
function n(a,b){var c=a.offset(),d=c.left-(b?b.left:0),e=c.top-(b?b.top:0);return{left:d,right:d+a.outerWidth(),top:e,bottom:e+a.outerHeight()}}
// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding.
// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
// Origin is optional.
// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
function o(a,b){var c=a.offset(),d=q(a),e=c.left+t(a,"border-left-width")+d.left-(b?b.left:0),f=c.top+t(a,"border-top-width")+d.top-(b?b.top:0);return{left:e,right:e+a[0].clientWidth,// clientWidth includes padding but NOT scrollbars
top:f,bottom:f+a[0].clientHeight}}
// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars.
// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
// Origin is optional.
function p(a,b){var c=a.offset(),d=c.left+t(a,"border-left-width")+t(a,"padding-left")-(b?b.left:0),e=c.top+t(a,"border-top-width")+t(a,"padding-top")-(b?b.top:0);return{left:d,right:d+a.width(),top:e,bottom:e+a.height()}}
// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element.
// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
function q(a){var b=a.innerWidth()-a[0].clientWidth,c={left:0,right:0,top:0,bottom:a.innerHeight()-a[0].clientHeight};// is the scrollbar on the left side?
return r()&&"rtl"==a.css("direction")?c.left=b:c.right=b,c}function r(){// responsible for caching the computation
return null===Wa&&(Wa=s()),Wa}function s(){// creates an offscreen test element, then removes it
var b=a("
").css({position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}).appendTo("body"),c=b.children(),d=c.offset().left>b.offset().left;// is the inner div shifted to accommodate a left scrollbar?
return b.remove(),d}
// Retrieves a jQuery element's computed CSS value as a floating-point number.
// If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero.
function t(a,b){return parseFloat(a.css(b))||0}
// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
function u(a){return 1==a.which&&!a.ctrlKey}function v(a){if(void 0!==a.pageX)return a.pageX;var b=a.originalEvent.touches;return b?b[0].pageX:void 0}function w(a){if(void 0!==a.pageY)return a.pageY;var b=a.originalEvent.touches;return b?b[0].pageY:void 0}function x(a){return/^touch/.test(a.type)}function y(a){a.addClass("fc-unselectable").on("selectstart",z)}
// Stops a mouse/touch event from doing it's native browser action
function z(a){a.preventDefault()}
// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
function A(a,b){var c={left:Math.max(a.left,b.left),right:Math.min(a.right,b.right),top:Math.max(a.top,b.top),bottom:Math.min(a.bottom,b.bottom)};return c.lefti&&j>g?(g>=i?(c=g.clone(),e=!0):(c=i.clone(),e=!1),j>=h?(d=h.clone(),f=!0):(d=j.clone(),f=!1),{start:c,end:d,isStart:e,isEnd:f}):void 0}
// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time.
// Moments will have their timezones normalized.
function J(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days"),ms:a.time()-c.time()})}
// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations.
function K(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days")})}
// Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding.
function L(a,c,d){// returnFloat=true
return b.duration(Math.round(a.diff(c,d,!0)),d)}
// Computes the unit name of the largest whole-unit period of time.
// For example, 48 hours will be "days" whereas 49 hours will be "hours".
// Accepts start/end, a range object, or an original duration object.
function M(a,b){var c,d,e;for(c=0;c=1&&fa(e)));c++);return d}
// Computes the number of units (like "hours") in the given range.
// Range can be a {start,end} object, separate start/end args, or a Duration.
// Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling
// of month-diffing logic (which tends to vary from version to version).
function N(a,c,d){return null!=d?d.diff(c,a,!0):b.isDuration(c)?c.as(a):c.end.diff(c.start,a,!0)}
// Intelligently divides a range (specified by a start/end params) by a duration
function O(a,b,c){var d;return R(c)?(b-a)/c:(d=c.asMonths(),Math.abs(d)>=1&&fa(d)?b.diff(a,"months",!0)/d:b.diff(a,"days",!0)/c.asDays())}
// Intelligently divides one duration by another
function P(a,b){var c,d;return R(a)||R(b)?a/b:(c=a.asMonths(),d=b.asMonths(),Math.abs(c)>=1&&fa(c)&&Math.abs(d)>=1&&fa(d)?c/d:a.asDays()/b.asDays())}
// Intelligently multiplies a duration by a number
function Q(a,c){var d;return R(a)?b.duration(a*c):(d=a.asMonths(),Math.abs(d)>=1&&fa(d)?b.duration({months:d*c}):b.duration({days:a.asDays()*c}))}
// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms)
function R(a){return Boolean(a.hours()||a.minutes()||a.seconds()||a.milliseconds())}function S(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}
// Returns a boolean about whether the given input is a time string, like "06:40:00" or "06:00"
function T(a){return/^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(a)}
// Merges an array of objects into a single object.
// The second argument allows for an array of property names who's object values will be merged together.
function U(a,b){var c,d,e,f,g,h,i={};if(b)for(c=0;c=0;f--)if(g=a[f][d],"object"==typeof g)e.unshift(g);else if(void 0!==g){i[d]=g;// if there were no objects, this value will be used
break}
// if the trailing values were objects, use the merged value
e.length&&(i[d]=U(e))}
// copy values into the destination, going from last to first
for(c=a.length-1;c>=0;c--){h=a[c];for(d in h)d in i||(// if already assigned by previous props or complex props, don't reassign
i[d]=h[d])}return i}
// Create an object that has the given prototype. Just like Object.create
function V(a){var b=function(){};return b.prototype=a,new b}function W(a,b){for(var c in a)Y(a,c)&&(b[c]=a[c])}
// Copies over certain methods with the same names as Object.prototype methods. Overcomes an IE<=8 bug:
// https://developer.mozilla.org/en-US/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
function X(a,b){var c,d,e=["constructor","toString","valueOf"];for(c=0;c/g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g," ")}function ba(a){return a.replace(/&.*?;/g,"")}
// Given a hash of CSS properties, returns a string of CSS.
// Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
function ca(b){var c=[];return a.each(b,function(a,b){null!=b&&c.push(a+":"+b)}),c.join(";")}function da(a){return a.charAt(0).toUpperCase()+a.slice(1)}function ea(a,b){// for .sort()
return a-b}function fa(a){return a%1===0}
// Returns a method bound to the given object context.
// Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with
// different contexts as identical when binding/unbinding events.
function ga(a,b){var c=a[b];return function(){return c.apply(a,arguments)}}
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714
function ha(a,b,c){var d,e,f,g,h,i=function(){var j=+new Date-g;b>j?d=setTimeout(i,b-j):(d=null,c||(h=a.apply(f,e),f=e=null))};return function(){f=this,e=arguments,g=+new Date;var j=c&&!d;return d||(d=setTimeout(i,b)),j&&(h=a.apply(f,e),f=e=null),h}}
// Builds an enhanced moment from args. When given an existing moment, it clones. When given a
// native Date, or called with no arguments (the current time), the resulting moment will be local.
// Anything else needs to be "parsed" (a string or an array), and will be affected by:
// parseAsUTC - if there is no zone information, should we parse the input in UTC?
// parseZone - if there is zone information, should we force the zone of the moment?
function ia(c,d,e){var f,g,h,i,j=c[0],k=1==c.length&&"string"==typeof j;// flag for extended functionality
// clone it
// "parsing" is required
// accept strings like '2014-05', but convert to the first of the month
// for when we pass it on to moment's constructor
// no time part?
// arrays have no timezone information, so assume ambiguous zone
// otherwise, probably a string with a format
// let's record the inputted zone somehow
return b.isMoment(j)?(i=b.apply(null,c),ka(j,i)):S(j)||void 0===j?i=b.apply(null,c):(f=!1,g=!1,k?bb.test(j)?(j+="-01",c=[j],f=!0,g=!0):(h=cb.exec(j))&&(f=!h[5],g=!0):a.isArray(j)&&(g=!0),i=d||f?b.utc.apply(b,c):b.apply(null,c),f?(i._ambigTime=!0,i._ambigZone=!0):e&&(g?i._ambigZone=!0:k&&(i.utcOffset?i.utcOffset(j):i.zone(j)))),i._fullCalendar=!0,i}
// Misc Internals
// -------------------------------------------------------------------------------------------------
// given an array of moment-like inputs, return a parallel array w/ moments similarly ambiguated.
// for example, of one moment has ambig time, but not others, all moments will have their time stripped.
// set `preserveTime` to `true` to keep times, but only normalize zone ambiguity.
// returns the original moments if no modifications are necessary.
function ja(a,c){var d,e,f=!1,g=!1,h=a.length,i=[];
// parse inputs into real moments and query their ambig flags
for(d=0;h>d;d++)e=a[d],b.isMoment(e)||(e=Ta.moment.parseZone(e)),f=f||e._ambigTime,g=g||e._ambigZone,i.push(e);
// strip each moment down to lowest common ambiguity
// use clones to avoid modifying the original moments
for(d=0;h>d;d++)e=i[d],c||!f||e._ambigTime?g&&!e._ambigZone&&(i[d]=e.clone().stripZone()):i[d]=e.clone().stripTime();return i}
// Transfers all the flags related to ambiguous time/zone from the `src` moment to the `dest` moment
// TODO: look into moment.momentProperties for this.
function ka(a,b){a._ambigTime?b._ambigTime=!0:b._ambigTime&&(b._ambigTime=!1),a._ambigZone?b._ambigZone=!0:b._ambigZone&&(b._ambigZone=!1)}
// Sets the year/month/date/etc values of the moment from the given array.
// Inefficient because it calls each individual setter.
function la(a,b){a.year(b[0]||0).month(b[1]||0).date(b[2]||0).hours(b[3]||0).minutes(b[4]||0).seconds(b[5]||0).milliseconds(b[6]||0)}
// Single Date Formatting
// -------------------------------------------------------------------------------------------------
// call this if you want Moment's original format method to be used
function ma(a,b){return eb.format.call(a,b)}
// Formats `date` with a Moment formatting string, but allow our non-zero areas and
// additional token.
function na(a,b){return oa(a,ta(b))}function oa(a,b){var c,d="";for(c=0;c "MMMM D YYYY"
// BTW, this is not important for `formatDate` because it is impossible to put custom tokens
// or non-zero areas in Moment's localized format strings.
return a=Ta.moment.parseZone(a),b=Ta.moment.parseZone(b),f=(a.localeData||a.lang).call(a),c=f.longDateFormat(c)||c,d=d||" - ",ra(a,b,ta(c),d,e)}// expose
function ra(a,b,c,d,e){var f,g,h,i,j=a.clone().stripZone(),k=b.clone().stripZone(),l="",m="",n="",o="",p="";
// Start at the leftmost side of the formatting string and continue until you hit a token
// that is not the same between dates.
for(g=0;gg&&(f=sa(a,b,j,k,c[h]),f!==!1);h--)m=f+m;
// The area in the middle is different for both of the dates.
// Collect them distinctly so we can jam them together later.
for(i=g;h>=i;i++)n+=pa(a,c[i]),o+=pa(b,c[i]);return(n||o)&&(p=e?o+d+n:n+d+o),l+p+m}
// TODO: week maybe?
// Given a formatting chunk, and given that both dates are similar in the regard the
// formatting chunk is concerned, format date1 against `chunk`. Otherwise, return `false`.
function sa(a,b,c,d,e){var f,g;return"string"==typeof e?e:(f=e.token)&&(g=gb[f.charAt(0)],g&&c.isSame(d,g))?ma(a,f):!1}function ta(a){return a in hb?hb[a]:hb[a]=ua(a)}
// Break the formatting string into an array of chunks
function ua(a){for(var b,c=[],d=/\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;b=d.exec(a);)b[1]?// a literal string inside [ ... ]
c.push(b[1]):b[2]?// non-zero formatting inside ( ... )
c.push({maybe:ua(b[2])}):b[3]?// a formatting token
c.push({token:b[3]}):b[5]&&// an unenclosed literal string
c.push(b[5]);return c}// export
// Class that all other classes will inherit from
function va(){}function wa(a,b){var c;
// ensure a constructor for the subclass, forwarding all arguments to the super-constructor if it doesn't exist
// build the base prototype for the subclass, which is an new object chained to the superclass's prototype
// copy each member variable/method onto the the subclass's prototype
// hack for IE8
// copy over all class variables/methods to the subclass, such as `extend` and `mixin`
return Y(b,"constructor")&&(c=b.constructor),"function"!=typeof c&&(c=b.constructor=function(){a.apply(this,arguments)}),c.prototype=V(a.prototype),W(b,c.prototype),X(b,c.prototype),W(a,c),c}function xa(a,b){W(b,a.prototype)}
// Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component.
// Two null values will be considered equal, as two "out of the component" states are the same.
function ya(a,b){return a||b?a&&b?a.component===b.component&&za(a,b)&&za(b,a):!1:!0}
// Returns true if all of subHit's non-standard properties are within superHit
function za(a,b){for(var c in a)if(!/^(component|left|right|top|bottom)$/.test(c)&&a[c]!==b[c])return!1;return!0}/* Utilities
----------------------------------------------------------------------------------------------------------------------*/
function Aa(a){// returns true if background OR inverse-background
var b=Ca(a);return"background"===b||"inverse-background"===b}// export
function Ba(a){return"inverse-background"===Ca(a)}function Ca(a){return _((a.source||{}).rendering,a.rendering)}function Da(a){var b,c,d={};for(b=0;b=a.leftCol)return!0;return!1}
// A cmp function for determining the leftmost event
function Ha(a,b){return a.leftCol-b.leftCol}
// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
function Ia(a){var b,c,d,e=[];for(b=0;bb.top&&a.top").prependTo(c),R=N.header=new Qa(N,O),S=R.render(),S&&c.prepend(S),i(O.defaultView),O.handleWindowResize&&(Y=ha(m,O.windowResizeDelay),a(window).resize(Y))}function g(){W&&W.removeElement(),R.removeElement(),T.remove(),c.removeClass("fc fc-touch fc-cursor fc-ltr fc-rtl fc-unthemed ui-widget"),Y&&a(window).unbind("resize",Y)}function h(){return c.is(":visible")}
// View Rendering
// -----------------------------------------------------------------------------------
// Renders a view because of a date change, view-type change, or for the first time.
// If not given a viewType, keep the current view but render different dates.
function i(b){ca++,
// if viewType is changing, remove the old view's rendering
W&&b&&W.type!==b&&(R.deactivateButton(W.type),H(),// prevent a scroll jump when view element is removed
W.removeElement(),W=N.view=null),
// if viewType changed, or the view was never created, create a fresh view
!W&&b&&(W=N.view=ba[b]||(ba[b]=N.instantiateView(b)),W.setElement(a("").appendTo(T)),R.activateButton(b)),W&&(Z=W.massageCurrentDate(Z),W.displaying&&Z.isWithin(W.intervalStart,W.intervalEnd)||h()&&(W.display(Z),I(),u(),v(),q())),I(),// undo any lone freezeContentHeight calls
ca--}function j(a){// isResize=true. will poll getSuggestedViewHeight() and isHeightAuto()
return h()?(a&&l(),ca++,W.updateSize(!0),ca--,!0):void 0}function k(){h()&&l()}function l(){// assumes elementVisible
X="number"==typeof O.contentHeight?O.contentHeight:"number"==typeof O.height?O.height-(S?S.outerHeight(!0):0):Math.round(T.width()/Math.max(O.aspectRatio,.5))}function m(a){!ca&&a.target===window&&W.start&&j(!0)&&W.trigger("windowResize",aa)}/* Event Fetching/Rendering
-----------------------------------------------------------------------------*/
// TODO: going forward, most of this stuff should be directly handled by the view
function n(){// can be called as an API method
p(),// so that events are cleared before user starts waiting for AJAX
r()}function o(){// destroys old events if previously rendered
h()&&(H(),W.displayEvents(da),I())}function p(){H(),W.clearEvents(),I()}function q(){!O.lazyFetching||$(W.start,W.end)?r():o()}function r(){_(W.start,W.end)}
// called when event data arrives
function s(a){da=a,o()}
// called when a single event's data has been changed
function t(){o()}/* Header Updating
-----------------------------------------------------------------------------*/
function u(){R.updateTitle(W.title)}function v(){var a=N.getNow();a.isWithin(W.intervalStart,W.intervalEnd)?R.disableButton("today"):R.enableButton("today")}/* Selection
-----------------------------------------------------------------------------*/
// this public method receives start/end dates in any format, with any timezone
function w(a,b){W.select(N.buildSelectSpan.apply(N,arguments))}function x(){// safe to be called before renderView
W&&W.unselect()}/* Date
-----------------------------------------------------------------------------*/
function y(){Z=W.computePrevDate(Z),i()}function z(){Z=W.computeNextDate(Z),i()}function A(){Z.add(-1,"years"),i()}function B(){Z.add(1,"years"),i()}function C(){Z=N.getNow(),i()}function D(a){Z=N.moment(a).stripZone(),i()}function E(a){Z.add(b.duration(a)),i()}
// Forces navigation to a view for the given date.
// `viewType` can be a specific view name or a generic one like "week" or "day".
function F(a,b){var c;b=b||"day",c=N.getViewSpec(b)||N.getUnitViewSpec(b),Z=a.clone(),i(c?c.type:null)}
// for external API
function G(){return N.applyTimezone(Z)}function H(){T.css({width:"100%",height:T.height(),overflow:"hidden"})}function I(){T.css({width:"",height:"",overflow:""})}/* Misc
-----------------------------------------------------------------------------*/
function J(){return N}function K(){return W}function L(a,b){return void 0===b?O[a]:void("height"!=a&&"contentHeight"!=a&&"aspectRatio"!=a||(O[a]=b,j(!0)))}function M(a,b){// overrides the Emitter's trigger method :(
var c=Array.prototype.slice.call(arguments,2);return b=b||aa,this.triggerWith(a,b,c),O[a]?O[a].apply(b,c):void 0}var N=this;N.initOptions(d||{});var O=this.options;
// Exports
// -----------------------------------------------------------------------------------
N.render=e,N.destroy=g,N.refetchEvents=n,N.reportEvents=s,N.reportEventChange=t,N.rerenderEvents=o,// `renderEvents` serves as a rerender. an API method
N.changeView=i,// `renderView` will switch to another view
N.select=w,N.unselect=x,N.prev=y,N.next=z,N.prevYear=A,N.nextYear=B,N.today=C,N.gotoDate=D,N.incrementDate=E,N.zoomTo=F,N.getDate=G,N.getCalendar=J,N.getView=K,N.option=L,N.trigger=M;
// Language-data Internals
// -----------------------------------------------------------------------------------
// Apply overrides to the current language's data
var P=V(// make a cheap copy
Pa(O.lang));if(O.monthNames&&(P._months=O.monthNames),O.monthNamesShort&&(P._monthsShort=O.monthNamesShort),O.dayNames&&(P._weekdays=O.dayNames),O.dayNamesShort&&(P._weekdaysShort=O.dayNamesShort),null!=O.firstDay){var Q=V(P._week);// _week: { dow: # }
Q.dow=O.firstDay,P._week=Q}
// assign a normalized value, to be used by our .week() moment extension
P._fullCalendar_weekCalc=function(a){return"function"==typeof a?a:"local"===a?a:"iso"===a||"ISO"===a?"ISO":void 0}(O.weekNumberCalculation),
// Calendar-specific Date Utilities
// -----------------------------------------------------------------------------------
N.defaultAllDayEventDuration=b.duration(O.defaultAllDayEventDuration),N.defaultTimedEventDuration=b.duration(O.defaultTimedEventDuration),
// Builds a moment using the settings of the current calendar: timezone and language.
// Accepts anything the vanilla moment() constructor accepts.
N.moment=function(){var a;
// Force the moment to be local, because FC.moment doesn't guarantee it.
// don't give ambiguously-timed moments a local zone
// moment 2.8 and above
// pre-moment-2.8
return"local"===O.timezone?(a=Ta.moment.apply(null,arguments),a.hasTime()&&a.local()):a="UTC"===O.timezone?Ta.moment.utc.apply(null,arguments):Ta.moment.parseZone.apply(null,arguments),"_locale"in a?a._locale=P:a._lang=P,a},
// Returns a boolean about whether or not the calendar knows how to calculate
// the timezone offset of arbitrary dates in the current timezone.
N.getIsAmbigTimezone=function(){return"local"!==O.timezone&&"UTC"!==O.timezone},
// Returns a copy of the given date in the current timezone. Has no effect on dates without times.
N.applyTimezone=function(a){if(!a.hasTime())return a.clone();var b,c=N.moment(a.toArray()),d=a.time()-c.time();
// Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396)
// is the time result different than expected?
// add milliseconds
// does it match perfectly now?
return d&&(b=c.clone().add(d),a.time()-b.time()===0&&(c=b)),c},
// Returns a moment for the current date, as defined by the client's computer or from the `now` option.
// Will return an moment with an ambiguous timezone.
N.getNow=function(){var a=O.now;return"function"==typeof a&&(a=a()),N.moment(a).stripZone()},
// Get an event's normalized end date. If not present, calculate it from the defaults.
N.getEventEnd=function(a){return a.end?a.end.clone():N.getDefaultEventEnd(a.allDay,a.start)},
// Given an event's allDay status and start date, return what its fallback end date should be.
// TODO: rename to computeDefaultEventEnd
N.getDefaultEventEnd=function(a,b){var c=b.clone();return a?c.stripTime().add(N.defaultAllDayEventDuration):c.add(N.defaultTimedEventDuration),N.getIsAmbigTimezone()&&c.stripZone(),c},
// Produces a human-readable string for the given duration.
// Side-effect: changes the locale of the given duration.
N.humanizeDuration=function(a){return(a.locale||a.lang).call(a,O.lang).humanize()},
// Imports
// -----------------------------------------------------------------------------------
Ra.call(N,O);var R,S,T,U,W,X,Y,Z,$=N.isFetchNeeded,_=N.fetchEvents,aa=c[0],ba={},ca=0,da=[];// unzoned
// Main Rendering
// -----------------------------------------------------------------------------------
// compute the initial ambig-timezone date
Z=null!=O.defaultDate?N.moment(O.defaultDate).stripZone():N.getNow(),N.getSuggestedViewHeight=function(){return void 0===X&&k(),X},N.isHeightAuto=function(){return"auto"===O.contentHeight||"auto"===O.height},N.freezeContentHeight=H,N.unfreezeContentHeight=I,N.initialize()}function Oa(b){a.each(zb,function(a,c){null==b[a]&&(b[a]=c(b))})}
// Returns moment's internal locale data. If doesn't exist, returns English.
// Works with moment-pre-2.8
function Pa(a){var c=b.localeData||b.langData;return c.call(b,a)||c.call(b,"en")}/* Top toolbar area with buttons and title
----------------------------------------------------------------------------------------------------------------------*/
// TODO: rename all header-related things to "toolbar"
function Qa(b,c){function d(){var b=c.header;return n=c.theme?"ui":"fc",b?o=a("").append(f("left")).append(f("right")).append(f("center")).append(''):void 0}function e(){o.remove(),o=a()}function f(d){var e=a(''),f=c.header[d];return f&&a.each(f.split(" "),function(d){var f,g=a(),h=!0;a.each(this.split(","),function(d,e){var f,i,j,k,l,m,o,q,r,s;// the element
"title"==e?(g=g.add(a("
"},/* Generic
------------------------------------------------------------------------------------------------------------------*/
// Generates the default HTML intro for any row. User classes should override
renderIntroHtml:function(){},
// TODO: a generic method for dealing with
, RTL, intro
// when increment internalApiVersion
// wrapTr (scheduler)
/* Utils
------------------------------------------------------------------------------------------------------------------*/
// Applies the generic "intro" and "outro" HTML to the given cells.
// Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.
bookendCells:function(a){var b=this.renderIntroHtml();b&&(this.isRTL?a.append(b):a.prepend(b))}},rb=Ta.DayGrid=pb.extend(qb,{numbersVisible:!1,// should render a row for day/week numbers? set by outside view. TODO: make internal
bottomCoordPadding:0,// hack for extending the hit area for the last row of the coordinate grid
rowEls:null,// set of fake row elements
cellEls:null,// set of whole-day elements comprising the row's background
helperEls:null,// set of cell skeleton elements for rendering the mock event "helper"
rowCoordCache:null,colCoordCache:null,
// Renders the rows and columns into the component's `this.el`, which should already be assigned.
// isRigid determins whether the individual rows should ignore the contents and be a constant height.
// Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.
renderDates:function(a){var b,c,d=this.view,e=this.rowCnt,f=this.colCnt,g="";for(b=0;e>b;b++)g+=this.renderDayRowHtml(b,a);
// trigger dayRender with each cell's element
for(this.el.html(g),this.rowEls=this.el.find(".fc-row"),this.cellEls=this.el.find(".fc-day"),this.rowCoordCache=new lb({els:this.rowEls,isVertical:!0}),this.colCoordCache=new lb({els:this.cellEls.slice(0,this.colCnt),// only the first row
isHorizontal:!0}),b=0;e>b;b++)for(c=0;f>c;c++)d.trigger("dayRender",null,this.getCellDate(b,c),this.getCellEl(b,c))},unrenderDates:function(){this.removeSegPopover()},renderBusinessHours:function(){var a=this.view.calendar.getBusinessHoursEvents(!0),b=this.eventsToSegs(a);this.renderFill("businessHours",b,"bgevent")},
// Generates the HTML for a single row, which is a div that wraps a table.
// `row` is the row number.
renderDayRowHtml:function(a,b){var c=this.view,d=["fc-row","fc-week",c.widgetContentClass];return b&&d.push("fc-rigid"),'
"},renderNumberIntroHtml:function(a){return this.renderIntroHtml()},renderNumberCellsHtml:function(a){var b,c,d=[];for(b=0;bs of the "number" row in the DayGrid's content skeleton.
// The number row will only exist if either day numbers or week numbers are turned on.
renderNumberCellHtml:function(a){var b;return this.view.dayNumbersVisible?(b=this.getDayClasses(a),b.unshift("fc-day-number"),'
'+a.date()+"
"):"
"},/* Options
------------------------------------------------------------------------------------------------------------------*/
// Computes a default event time formatting string if `timeFormat` is not explicitly defined
computeEventTimeFormat:function(){return this.view.opt("extraSmallTimeFormat")},
// Computes a default `displayEventEnd` value if one is not expliclty defined
computeDisplayEventEnd:function(){return 1==this.colCnt},/* Dates
------------------------------------------------------------------------------------------------------------------*/
rangeUpdated:function(){this.updateDayTable()},
// Slices up the given span (unzoned start/end with other misc data) into an array of segments
spanToSegs:function(a){var b,c,d=this.sliceRangeByRow(a);for(b=0;b
');g=c&&c.row===b?c.el.position().top:h.find(".fc-content-skeleton tbody").position().top,i.css("top",g).find("table").append(d[b].tbodyEl),h.append(i),e.push(i[0])}),this.helperEls=a(e)},
// Unrenders any visual indication of a mock helper event
unrenderHelper:function(){this.helperEls&&(this.helperEls.remove(),this.helperEls=null)},/* Fill System (highlight, background events, business hours)
------------------------------------------------------------------------------------------------------------------*/
fillSegTag:"td",// override the default tag name
// Renders a set of rectangles over the given segments of days.
// Only returns segments that successfully rendered.
renderFill:function(b,c,d){var e,f,g,h=[];// assignes `.el` to each seg. returns successfully rendered segs
for(c=this.renderFillSegEls(b,c),e=0;e
'),this.bookendCells(f),e}});/* Event-rendering methods for the DayGrid class
----------------------------------------------------------------------------------------------------------------------*/
rb.mixin({rowStructs:null,// an array of objects, each holding information about a row's foreground event-rendering
// Unrenders all events currently rendered on the grid
unrenderEvents:function(){this.removeSegPopover(),// removes the "more.." events popover
pb.prototype.unrenderEvents.apply(this,arguments)},
// Retrieves all rendered segment objects currently rendered on the grid
getEventSegs:function(){return pb.prototype.getEventSegs.call(this).concat(this.popoverSegs||[])},
// Renders the given background event segments onto the grid
renderBgSegs:function(b){
// don't render timed background events
var c=a.grep(b,function(a){return a.event.allDay});return pb.prototype.renderBgSegs.call(this,c)},
// Renders the given foreground event segments onto the grid
renderFgSegs:function(b){var c;
// render an `.el` on each seg
// returns a subset of the segs. segs that were actually rendered
// append to each row's content skeleton
return b=this.renderFgSegEls(b),c=this.rowStructs=this.renderSegRows(b),this.rowEls.each(function(b,d){a(d).find(".fc-content-skeleton > table").append(c[b].tbodyEl)}),b},
// Unrenders all currently rendered foreground event segments
unrenderFgSegs:function(){for(var a,b=this.rowStructs||[];a=b.pop();)a.tbodyEl.remove();this.rowStructs=null},
// Uses the given events array to generate elements that should be appended to each row's content skeleton.
// Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
// PRECONDITION: each segment shoud already have a rendered and assigned `.el`
renderSegRows:function(a){var b,c,d=[];// group into nested arrays
// iterate each row of segment groupings
for(b=this.groupSegRows(a),c=0;c'+aa(c)+"")),d=''+(aa(f.title||"")||" ")+"",'
"+(h?'':"")+(i?'':"")+""},
// Given a row # and an array of segments all in the same row, render a element, a skeleton that contains
// the segments. Returns object with a bunch of internal data about how the render was calculated.
// NOTE: modifies rowSegs
renderSegRow:function(b,c){
// populates empty cells from the current column (`col`) to `endCol`
function d(b){for(;b>g;)k=(r[e-1]||[])[g],k?k.attr("rowspan",parseInt(k.attr("rowspan")||1,10)+1):(k=a("
"),h.append(k)),q[e][g]=k,r[e][g]=k,g++}var e,f,g,h,i,j,k,l=this.colCnt,m=this.buildSegLevels(c),n=Math.max(1,m.length),o=a(""),p=[],q=[],r=[];for(e=0;n>e;e++){
// levelCnt might be 1 even though there are no actual levels. protect against this.
// this single empty row is useful for styling.
if(f=m[e],g=0,h=a("
"),p.push([]),q.push([]),r.push([]),f)for(i=0;i').append(j.el),j.leftCol!=j.rightCol?k.attr("colspan",j.rightCol-j.leftCol+1):// a single-column segment
r[e][g]=k;g<=j.rightCol;)q[e][g]=k,p[e][g]=j,g++;h.append(k)}d(l),// finish off the row
this.bookendCells(h),o.append(h)}return{// a "rowStruct"
row:b,// the row number
tbodyEl:o,cellMatrix:q,segMatrix:p,segLevels:m,segs:c}},
// Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
// NOTE: modifies segs
buildSegLevels:function(a){var b,c,d,e=[];for(
// Give preference to elements with certain criteria, so they have
// a chance to be closer to the top.
this.sortEventSegs(a),b=0;b at a time and stop when we find one out of bounds
for(d=0;d td > :first-child").each(c),e.position().top+f>h)return d;return!1},
// Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
// `row` is the row number.
// `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
limitRow:function(b,c){
// Iterates through empty level cells and places "more" links inside if need be
function d(d){// goes from current `col` to `endCol`
for(;d>w;)j=t.getCellSegs(b,w,c),j.length&&(m=f[c-1][w],s=t.renderMoreLink(b,w,j),r=a("").append(s),m.append(r),v.push(r[0])),w++}var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t=this,u=this.rowStructs[b],v=[],w=0;if(c&&c for each column the segment occupies. will be one for each colspan
for(m=f[c-1][i.leftCol],n=m.attr("rowspan")||1,o=[],p=0;p').attr("rowspan",n),j=l[p],s=this.renderMoreLink(b,i.leftCol+p,[i].concat(j)),r=a("").append(s),q.append(r),o.push(q[0]),v.push(q[0]);m.addClass("fc-limited").after(a(o)),// hide original
and inject replacements
g.push(m[0])}}d(this.colCnt),// finish off the level
u.moreEls=a(v),// for easy undoing later
u.limitedEls=a(g)}},
// Reveals all levels and removes all "more"-related elements for a grid's row.
// `row` is a row number.
unlimitRow:function(a){var b=this.rowStructs[a];b.moreEls&&(b.moreEls.remove(),b.moreEls=null),b.limitedEls&&(b.limitedEls.removeClass("fc-limited"),b.limitedEls=null)},
// Renders an element that represents hidden event element for a cell.
// Responsible for attaching click handler as well.
renderMoreLink:function(b,c,d){var e=this,f=this.view;return a('').text(this.getMoreLinkText(d.length)).on("click",function(g){var h=f.opt("eventLimitClick"),i=e.getCellDate(b,c),j=a(this),k=e.getCellEl(b,c),l=e.getCellSegs(b,c),m=e.resliceDaySegs(l,i),n=e.resliceDaySegs(d,i);"function"==typeof h&&(
// the returned value can be an atomic option
h=f.trigger("eventLimitClick",null,{date:i,dayEl:k,moreEl:j,segs:m,hiddenSegs:n},g)),"popover"===h?e.showSegPopover(b,c,j,m):"string"==typeof h&&// a view name
f.calendar.zoomTo(i,h)})},
// Reveals the popover that displays all events within a cell
showSegPopover:function(a,b,c,d){var e,f,g=this,h=this.view,i=c.parent();e=1==this.rowCnt?h.el:this.rowEls.eq(a),f={className:"fc-more-popover",content:this.renderSegPopoverContent(a,b,d),parentEl:this.el,top:e.offset().top,autoHide:!0,viewportConstrain:h.opt("popoverViewportConstrain"),hide:function(){g.segPopover.removeElement(),g.segPopover=null,g.popoverSegs=null}},this.isRTL?f.right=i.offset().left+i.outerWidth()+1:f.left=i.offset().left-1,this.segPopover=new kb(f),this.segPopover.show()},
// Builds the inner DOM contents of the segment popover
renderSegPopoverContent:function(b,c,d){var e,f=this.view,g=f.opt("theme"),h=this.getCellDate(b,c).format(f.opt("dayPopoverFormat")),i=a('
"},
// Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
renderSlatRowHtml:function(){
// Calculate the time for each slot
for(var a,c,d,e=this.view,f=this.isRTL,g="",h=b.duration(+this.minTime);h"+(c?""+aa(a.format(this.labelFormat))+"":"")+"
",g+='
"+(f?"":d)+'
'+(f?d:"")+"
",h.add(this.slotDuration);return g},/* Options
------------------------------------------------------------------------------------------------------------------*/
// Parses various options into properties of this object
processOptions:function(){var c,d=this.view,e=d.opt("slotDuration"),f=d.opt("snapDuration");e=b.duration(e),f=f?b.duration(f):e,this.slotDuration=e,this.snapDuration=f,this.snapsPerSlot=e/f,this.minResizeDuration=f,this.minTime=b.duration(d.opt("minTime")),this.maxTime=b.duration(d.opt("maxTime")),c=d.opt("slotLabelFormat"),a.isArray(c)&&(c=c[c.length-1]),this.labelFormat=c||d.opt("axisFormat")||d.opt("smallTimeFormat"),c=d.opt("slotLabelInterval"),this.labelInterval=c?b.duration(c):this.computeLabelInterval(e)},
// Computes an automatic value for slotLabelInterval
computeLabelInterval:function(a){var c,d,e;
// find the smallest stock label interval that results in more than one slots-per-label
for(c=Jb.length-1;c>=0;c--)if(d=b.duration(Jb[c]),e=P(d,a),fa(e)&&e>1)return d;return b.duration(a)},
// Computes a default event time formatting string if `timeFormat` is not explicitly defined
computeEventTimeFormat:function(){return this.view.opt("noMeridiemTimeFormat")},
// Computes a default `displayEventEnd` value if one is not expliclty defined
computeDisplayEventEnd:function(){return!0},/* Hit System
------------------------------------------------------------------------------------------------------------------*/
prepareHits:function(){this.colCoordCache.build(),this.slatCoordCache.build()},releaseHits:function(){this.colCoordCache.clear()},queryHit:function(a,b){var c=this.snapsPerSlot,d=this.colCoordCache,e=this.slatCoordCache,f=d.getHorizontalIndex(a),g=e.getVerticalIndex(b);if(null!=f&&null!=g){var h=e.getTopOffset(g),i=e.getHeight(g),j=(b-h)/i,k=Math.floor(j*c),l=g*c+k,m=h+k/c*i,n=h+(k+1)/c*i;return{col:f,snap:l,component:this,// needed unfortunately :(
left:d.getLeftOffset(f),right:d.getRightOffset(f),top:m,bottom:n}}},getHitSpan:function(a){var b,c=this.getCellDate(0,a.col),d=this.computeSnapTime(a.snap);return c.time(d),b=c.clone().add(this.snapDuration),{start:c,end:b}},getHitEl:function(a){return this.colEls.eq(a.col)},/* Dates
------------------------------------------------------------------------------------------------------------------*/
rangeUpdated:function(){this.updateDayTable()},
// Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day
computeSnapTime:function(a){return b.duration(this.minTime+this.snapDuration*a)},
// Slices up the given span (unzoned start/end with other misc data) into an array of segments
spanToSegs:function(a){var b,c=this.sliceRangeByTimes(a);for(b=0;b').css("top",e).appendTo(this.colContainerEls.eq(d[c].col))[0]);
// render an arrow over the axis
d.length>0&&// is the current time in view?
f.push(a('').css("top",e).appendTo(this.el.find(".fc-content-skeleton"))[0]),this.nowIndicatorEls=a(f)},unrenderNowIndicator:function(){this.nowIndicatorEls&&(this.nowIndicatorEls.remove(),this.nowIndicatorEls=null)},/* Selection
------------------------------------------------------------------------------------------------------------------*/
// Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
renderSelection:function(a){this.view.opt("selectHelper")?// this setting signals that a mock helper event should be rendered
// normally acceps an eventLocation, span has a start/end, which is good enough
this.renderEventLocationHelper(a):this.renderHighlight(a)},
// Unrenders any visual indication of a selection
unrenderSelection:function(){this.unrenderHelper(),this.unrenderHighlight()},/* Highlight
------------------------------------------------------------------------------------------------------------------*/
renderHighlight:function(a){this.renderHighlightSegs(this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderHighlightSegs()}});/* Methods for rendering SEGMENTS, pieces of content that live on the view
( this file is no longer just for events )
----------------------------------------------------------------------------------------------------------------------*/
sb.mixin({colContainerEls:null,// containers for each column
// inner-containers for each column where different types of segs live
fgContainerEls:null,bgContainerEls:null,helperContainerEls:null,highlightContainerEls:null,businessContainerEls:null,
// arrays of different types of displayed segments
fgSegs:null,bgSegs:null,helperSegs:null,highlightSegs:null,businessSegs:null,
// Renders the DOM that the view's content will live in
renderContentSkeleton:function(){var b,c,d="";for(b=0;b
';c=a('
'+d+"
"),this.colContainerEls=c.find(".fc-content-col"),this.helperContainerEls=c.find(".fc-helper-container"),this.fgContainerEls=c.find(".fc-event-container:not(.fc-helper-container)"),this.bgContainerEls=c.find(".fc-bgevent-container"),this.highlightContainerEls=c.find(".fc-highlight-container"),this.businessContainerEls=c.find(".fc-business-container"),this.bookendCells(c.find("tr")),this.el.append(c)},/* Foreground Events
------------------------------------------------------------------------------------------------------------------*/
renderFgSegs:function(a){return a=this.renderFgSegsIntoContainers(a,this.fgContainerEls),this.fgSegs=a,a},unrenderFgSegs:function(){this.unrenderNamedSegs("fgSegs")},/* Foreground Helper Events
------------------------------------------------------------------------------------------------------------------*/
renderHelperSegs:function(b,c){var d,e,f,g=[];
// Try to make the segment that is in the same row as sourceSeg look the same
for(b=this.renderFgSegsIntoContainers(b,this.helperContainerEls),d=0;d' :
''
) +
*/
return k.unshift("fc-time-grid-event","fc-v-event"),f.isMultiDayEvent(g)?(a.isStart||a.isEnd)&&(c=this.getEventTimeText(a),d=this.getEventTimeText(a,"LT"),e=this.getEventTimeText(a,null,!1)):(c=this.getEventTimeText(g),d=this.getEventTimeText(g,"LT"),e=this.getEventTimeText(g,null,!1)),'
'+(j?'':"")+""},/* Seg Position Utils
------------------------------------------------------------------------------------------------------------------*/
// Refreshes the CSS top/bottom coordinates for each segment element.
// Works when called after initial render, after a window resize/zoom for example.
updateSegVerticals:function(a){this.computeSegVerticals(a),this.assignSegVerticals(a)},
// For each segment in an array, computes and assigns its top and bottom properties
computeSegVerticals:function(a){var b,c;for(b=0;b1?"ll":"LL"},
// Utility for formatting a range. Accepts a range object, formatting string, and optional separator.
// Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.
// The timezones of the dates within `range` will be respected.
formatRange:function(a,b,c){var d=a.end;// all-day?
return d.hasTime()||(d=d.clone().subtract(1)),qa(a.start,d,b,c,this.opt("isRTL"))},/* Rendering
------------------------------------------------------------------------------------------------------------------*/
// Sets the container element that the view should render inside of.
// Does other DOM-related initializations.
setElement:function(a){this.el=a,this.bindGlobalHandlers()},
// Removes the view's container element from the DOM, clearing any content beforehand.
// Undoes any other DOM-related attachments.
removeElement:function(){this.clear(),// clears all content
// clean up the skeleton
this.isSkeletonRendered&&(this.unrenderSkeleton(),this.isSkeletonRendered=!1),this.unbindGlobalHandlers(),this.el.remove()},
// Does everything necessary to display the view centered around the given unzoned date.
// Does every type of rendering EXCEPT rendering events.
// Is asychronous and returns a promise.
display:function(b){var c=this,d=null;return this.displaying&&(d=this.queryScroll()),this.calendar.freezeContentHeight(),this.clear().then(function(){// clear the content first (async)
return c.displaying=a.when(c.displayView(b)).then(function(){c.forceScroll(c.computeInitialScroll(d)),c.calendar.unfreezeContentHeight(),c.triggerRender()})})},
// Does everything necessary to clear the content of the view.
// Clears dates and events. Does not clear the skeleton.
// Is asychronous and returns a promise.
clear:function(){var b=this,c=this.displaying;return c?c.then(function(){// wait for the display to finish
return b.displaying=null,b.clearEvents(),b.clearView()}):a.when()},
// Displays the view's non-event content, such as date-related content or anything required by events.
// Renders the view's non-content skeleton if necessary.
// Can be asynchronous and return a promise.
displayView:function(a){this.isSkeletonRendered||(this.renderSkeleton(),this.isSkeletonRendered=!0),a&&this.setDate(a),this.render&&this.render(),this.renderDates(),this.updateSize(),this.renderBusinessHours(),// might need coordinates, so should go after updateSize()
this.startNowIndicator()},
// Unrenders the view content that was rendered in displayView.
// Can be asynchronous and return a promise.
clearView:function(){this.unselect(),this.stopNowIndicator(),this.triggerUnrender(),this.unrenderBusinessHours(),this.unrenderDates(),this.destroy&&this.destroy()},
// Renders the basic structure of the view before any content is rendered
renderSkeleton:function(){},
// Unrenders the basic structure of the view
unrenderSkeleton:function(){},
// Renders the view's date-related content.
// Assumes setRange has already been called and the skeleton has already been rendered.
renderDates:function(){},
// Unrenders the view's date-related content
unrenderDates:function(){},
// Signals that the view's content has been rendered
triggerRender:function(){this.trigger("viewRender",this,this,this.el)},
// Signals that the view's content is about to be unrendered
triggerUnrender:function(){this.trigger("viewDestroy",this,this,this.el)},
// Binds DOM handlers to elements that reside outside the view container, such as the document
bindGlobalHandlers:function(){this.listenTo(a(document),"mousedown",this.handleDocumentMousedown),this.listenTo(a(document),"touchstart",this.handleDocumentTouchStart),this.listenTo(a(document),"touchend",this.handleDocumentTouchEnd)},
// Unbinds DOM handlers from elements that reside outside the view container
unbindGlobalHandlers:function(){this.stopListeningTo(a(document))},
// Initializes internal variables related to theming
initThemingProps:function(){var a=this.opt("theme")?"ui":"fc";this.widgetHeaderClass=a+"-widget-header",this.widgetContentClass=a+"-widget-content",this.highlightStateClass=a+"-state-highlight"},/* Business Hours
------------------------------------------------------------------------------------------------------------------*/
// Renders business-hours onto the view. Assumes updateSize has already been called.
renderBusinessHours:function(){},
// Unrenders previously-rendered business-hours
unrenderBusinessHours:function(){},/* Now Indicator
------------------------------------------------------------------------------------------------------------------*/
// Immediately render the current time indicator and begins re-rendering it at an interval,
// which is defined by this.getNowIndicatorUnit().
// TODO: somehow do this for the current whole day's background too
startNowIndicator:function(){var a,c,d,e=this;// ms wait value
this.opt("nowIndicator")&&(a=this.getNowIndicatorUnit(),a&&(c=ga(this,"updateNowIndicator"),this.initialNowDate=this.calendar.getNow(),this.initialNowQueriedMs=+new Date,this.renderNowIndicator(this.initialNowDate),this.isNowIndicatorRendered=!0,d=this.initialNowDate.clone().startOf(a).add(1,a)-this.initialNowDate,this.nowIndicatorTimeoutID=setTimeout(function(){e.nowIndicatorTimeoutID=null,c(),d=+b.duration(1,a),d=Math.max(100,d),e.nowIndicatorIntervalID=setInterval(c,d)},d)))},
// rerenders the now indicator, computing the new current time from the amount of time that has passed
// since the initial getNow call.
updateNowIndicator:function(){this.isNowIndicatorRendered&&(this.unrenderNowIndicator(),this.renderNowIndicator(this.initialNowDate.clone().add(new Date-this.initialNowQueriedMs)))},
// Immediately unrenders the view's current time indicator and stops any re-rendering timers.
// Won't cause side effects if indicator isn't rendered.
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)},
// Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator
// should be refreshed. If something falsy is returned, no time indicator is rendered at all.
getNowIndicatorUnit:function(){},
// Renders a current time indicator at the given datetime
renderNowIndicator:function(a){},
// Undoes the rendering actions from renderNowIndicator
unrenderNowIndicator:function(){},/* Dimensions
------------------------------------------------------------------------------------------------------------------*/
// Refreshes anything dependant upon sizing of the container element of the grid
updateSize:function(a){var b;a&&(b=this.queryScroll()),this.updateHeight(a),this.updateWidth(a),this.updateNowIndicator(),a&&this.setScroll(b)},
// Refreshes the horizontal dimensions of the calendar
updateWidth:function(a){},
// Refreshes the vertical dimensions of the calendar
updateHeight:function(a){var b=this.calendar;// we poll the calendar for height information
this.setHeight(b.getSuggestedViewHeight(),b.isHeightAuto())},
// Updates the vertical dimensions of the calendar to the specified height.
// if `isAuto` is set to true, height becomes merely a suggestion and the view should use its "natural" height.
setHeight:function(a,b){},/* Scroller
------------------------------------------------------------------------------------------------------------------*/
// Computes the initial pre-configured scroll state prior to allowing the user to change it.
// Given the scroll state from the previous rendering. If first time rendering, given null.
computeInitialScroll:function(a){return 0},
// Retrieves the view's current natural scroll state. Can return an arbitrary format.
queryScroll:function(){},
// Sets the view's scroll state. Will accept the same format computeInitialScroll and queryScroll produce.
setScroll:function(a){},
// Sets the scroll state, making sure to overcome any predefined scroll value the browser has in mind
forceScroll:function(a){var b=this;this.setScroll(a),setTimeout(function(){b.setScroll(a)},0)},/* Event Elements / Segments
------------------------------------------------------------------------------------------------------------------*/
// Does everything necessary to display the given events onto the current view
displayEvents:function(a){var b=this.queryScroll();this.clearEvents(),this.renderEvents(a),this.isEventsRendered=!0,this.setScroll(b),this.triggerEventRender()},
// Does everything necessary to clear the view's currently-rendered events
clearEvents:function(){var a;this.isEventsRendered&&(a=this.queryScroll(),this.triggerEventUnrender(),this.destroyEvents&&this.destroyEvents(),this.unrenderEvents(),this.setScroll(a),this.isEventsRendered=!1)},
// Renders the events onto the view.
renderEvents:function(a){},
// Removes event elements from the view.
unrenderEvents:function(){},
// Signals that all events have been rendered
triggerEventRender:function(){this.renderedEventSegEach(function(a){this.trigger("eventAfterRender",a.event,a.event,a.el)}),this.trigger("eventAfterAllRender")},
// Signals that all event elements are about to be removed
triggerEventUnrender:function(){this.renderedEventSegEach(function(a){this.trigger("eventDestroy",a.event,a.event,a.el)})},
// Given an event and the default element used for rendering, returns the element that should actually be used.
// Basically runs events and elements through the eventRender hook.
resolveEventEl:function(b,c){var d=this.trigger("eventRender",b,b,c);// means don't render at all
return d===!1?c=null:d&&d!==!0&&(c=a(d)),c},
// Hides all rendered event segments linked to the given event
showEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","")},a)},
// Shows all rendered event segments linked to the given event
hideEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","hidden")},a)},
// Iterates through event segments that have been rendered (have an el). Goes through all by default.
// If the optional `event` argument is specified, only iterates through segments linked to that event.
// The `this` value of the callback function will be the view.
renderedEventSegEach:function(a,b){var c,d=this.getEventSegs();for(c=0;cb;b++)(d[b]=-1!==a.inArray(b,c))||e++;if(!e)throw"invalid hiddenDays";this.isHiddenDayHash=d},
// Is the current day hidden?
// `day` is a day-of-week index (0-6), or a Moment
isHiddenDay:function(a){return b.isMoment(a)&&(a=a.day()),this.isHiddenDayHash[a]},
// Incrementing the current day until it is no longer a hidden day, returning a copy.
// If the initial value of `date` is not a hidden day, don't do anything.
// Pass `isExclusive` as `true` if you are dealing with an end date.
// `inc` defaults to `1` (increment one day forward each time)
skipHiddenDays:function(a,b,c){var d=a.clone();for(b=b||1;this.isHiddenDayHash[(d.day()+(c?b:0)+7)%7];)d.add(b,"days");return d},
// Returns the date range of the full days the given range visually appears to occupy.
// Returns a new range object.
computeDayRange:function(a){var b,c=a.start.clone().stripTime(),d=a.end,e=null;// the beginning of the day the range exclusively ends
// # of milliseconds into `endDay`
// If the end time is actually inclusively part of the next day and is equal to or
// beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
// Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
// If no end was specified, or if it is within `startDay` but not past nextDayThreshold,
// assign the default duration of one day.
return d&&(e=d.clone().stripTime(),b=+d.time(),b&&b>=this.nextDayThreshold&&e.add(1,"days")),(!d||c>=e)&&(e=c.clone().add(1,"days")),{start:c,end:e}},
// Does the given event visually appear to occupy more than one day?
isMultiDayEvent:function(a){var b=this.computeDayRange(a);// event is range-ish
return b.end.diff(b.start,"days")>1}}),ub=Ta.Scroller=va.extend({el:null,// the guaranteed outer element
scrollEl:null,// the element with the scrollbars
overflowX:null,overflowY:null,constructor:function(a){a=a||{},this.overflowX=a.overflowX||a.overflow||"auto",this.overflowY=a.overflowY||a.overflow||"auto"},render:function(){this.el=this.renderEl(),this.applyOverflow()},renderEl:function(){return this.scrollEl=a('')},
// sets to natural height, unlocks overflow
clear:function(){this.setHeight("auto"),this.applyOverflow()},destroy:function(){this.el.remove()},
// Overflow
// -----------------------------------------------------------------------------------------------------------------
applyOverflow:function(){this.scrollEl.css({"overflow-x":this.overflowX,"overflow-y":this.overflowY})},
// Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
// Useful for preserving scrollbar widths regardless of future resizes.
// Can pass in scrollbarWidths for optimization.
lockOverflow:function(a){var b=this.overflowX,c=this.overflowY;a=a||this.getScrollbarWidths(),"auto"===b&&(b=a.top||a.bottom||this.scrollEl[0].scrollWidth-1>this.scrollEl[0].clientWidth?"scroll":"hidden"),"auto"===c&&(c=a.left||a.right||this.scrollEl[0].scrollHeight-1>this.scrollEl[0].clientHeight?"scroll":"hidden"),this.scrollEl.css({"overflow-x":b,"overflow-y":c})},
// Getters / Setters
// -----------------------------------------------------------------------------------------------------------------
setHeight:function(a){this.scrollEl.height(a)},getScrollTop:function(){return this.scrollEl.scrollTop()},setScrollTop:function(a){this.scrollEl.scrollTop(a)},getClientWidth:function(){return this.scrollEl[0].clientWidth},getClientHeight:function(){return this.scrollEl[0].clientHeight},getScrollbarWidths:function(){return q(this.scrollEl)}}),vb=Ta.Calendar=va.extend({dirDefaults:null,// option defaults related to LTR or RTL
langDefaults:null,// option defaults related to current locale
overrides:null,// option overrides given to the fullCalendar constructor
options:null,// all defaults combined with overrides
viewSpecCache:null,// cache of view definitions
view:null,// current View object
header:null,loadingLevel:0,// number of simultaneous loading tasks
isTouch:!1,
// a lot of this class' OOP logic is scoped within this constructor function,
// but in the future, write individual methods on the prototype.
constructor:Na,
// Subclasses can override this for initialization logic after the constructor has been called
initialize:function(){},
// Initializes `this.options` and other important options-related objects
initOptions:function(a){var b,e,f,g;a=d(a),b=a.lang,e=wb[b],e||(b=vb.defaults.lang,e=wb[b]||{}),f=_(a.isRTL,e.isRTL,vb.defaults.isRTL),g=f?vb.rtlDefaults:{},this.dirDefaults=g,this.langDefaults=e,this.overrides=a,this.options=c([vb.defaults,g,e,a]),Oa(this.options),this.isTouch=null!=this.options.isTouch?this.options.isTouch:Ta.isTouch,this.viewSpecCache={}},
// Gets information about how to create a view. Will use a cache.
getViewSpec:function(a){var b=this.viewSpecCache;return b[a]||(b[a]=this.buildViewSpec(a))},
// Given a duration singular unit, like "week" or "day", finds a matching view spec.
// Preference is given to views that have corresponding buttons.
getUnitViewSpec:function(b){var c,d,e;if(-1!=a.inArray(b,Ya))for(c=this.header.getViewsWithButtons(),a.each(Ta.views,function(a){c.push(a)}),d=0;d "September 2014"
monthYearFormat:function(a){return a.showMonthAfterYear?"YYYY["+a.yearSuffix+"] MMMM":"MMMM YYYY["+a.yearSuffix+"]"}},yb={
// Produces format strings like "ddd M/D" -> "Fri 9/15"
dayOfMonthFormat:function(a,b){var c=a.longDateFormat("l");// for the format like "M/D/YYYY"
// strip the year off the edge, as well as other misc non-whitespace chars
return c=c.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g,""),b.isRTL?c+=" ddd":c="ddd "+c,c},
// Produces format strings like "h:mma" -> "6:00pm"
mediumTimeFormat:function(a){// can't be called `timeFormat` because collides with option
return a.longDateFormat("LT").replace(/\s*a$/i,"a")},
// Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm"
smallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"a")},
// Produces format strings like "h(:mm)t" -> "6p" / "6:30p"
extraSmallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"t")},
// Produces format strings like "ha" / "H" -> "6pm" / "18"
hourFormat:function(a){return a.longDateFormat("LT").replace(":mm","").replace(/(\Wmm)$/,"").replace(/\s*a$/i,"a")},
// Produces format strings like "h:mm" -> "6:30" (with no AM/PM)
noMeridiemTimeFormat:function(a){return a.longDateFormat("LT").replace(/\s*a$/i,"")}},zb={
// Produces format strings for results like "Mo 16"
smallDayDateFormat:function(a){return a.isRTL?"D dd":"dd D"},
// Produces format strings for results like "Wk 5"
weekFormat:function(a){return a.isRTL?"w[ "+a.weekNumberTitle+"]":"["+a.weekNumberTitle+" ]w"},
// Produces format strings for results like "Wk5"
smallWeekFormat:function(a){return a.isRTL?"w["+a.weekNumberTitle+"]":"["+a.weekNumberTitle+"]w"}};
// Initialize English by forcing computation of moment-derived options.
// Also, sets it as the default.
Ta.lang("en",vb.englishDefaults),Ta.sourceNormalizers=[],Ta.sourceFetchers=[];var Ab={dataType:"json",cache:!1},Bb=1;
// Returns a list of events that the given event should be compared against when being considered for a move to
// the specified span. Attached to the Calendar's prototype because EventManager is a mixin for a Calendar.
vb.prototype.getPeerEvents=function(a,b){var c,d,e=this.getEventCache(),f=[];for(c=0;c1,// TODO: make grid responsible
this.weekNumbersVisible=this.opt("weekNumbers"),this.dayGrid.numbersVisible=this.dayNumbersVisible||this.weekNumbersVisible,this.el.addClass("fc-basic-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-day-grid-container"),c=a('').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.dayGrid.setElement(c),this.dayGrid.renderDates(this.hasRigidRows())},
// render the day-of-week headers
renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.dayGrid.renderHeadHtml()),this.headRowEl=this.headContainerEl.find(".fc-row")},
// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
// always completely kill the dayGrid's rendering.
unrenderDates:function(){this.dayGrid.unrenderDates(),this.dayGrid.removeElement(),this.scroller.destroy()},renderBusinessHours:function(){this.dayGrid.renderBusinessHours()},
// Builds the HTML skeleton for the view.
// The day-grid component will render inside of a container defined by this HTML.
renderSkeletonHtml:function(){return'
'},
// Generates an HTML attribute string for setting the width of the week number column, if it is known
weekNumberStyleAttr:function(){return null!==this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},
// Determines whether each row should have a constant height
hasRigidRows:function(){var a=this.opt("eventLimit");return a&&"number"!=typeof a},/* Dimensions
------------------------------------------------------------------------------------------------------------------*/
// Refreshes the horizontal dimensions of the view
updateWidth:function(){this.weekNumbersVisible&&(
// Make sure all week number cells running down the side have the same width.
// Record the width for cells created later.
this.weekNumberWidth=k(this.el.find(".fc-week-number")))},
// Adjusts the vertical dimensions of the view to the specified values
setHeight:function(a,b){var c,d,g=this.opt("eventLimit");
// reset all heights to be natural
this.scroller.clear(),f(this.headRowEl),this.dayGrid.removeSegPopover(),// kill the "more" popover if displayed
// is the event limit a constant level number?
g&&"number"==typeof g&&this.dayGrid.limitRows(g),c=this.computeScrollerHeight(a),this.setGridHeight(c,b),g&&"number"!=typeof g&&this.dayGrid.limitRows(g),b||(this.scroller.setHeight(c),d=this.scroller.getScrollbarWidths(),(d.left||d.right)&&(e(this.headRowEl,d),c=this.computeScrollerHeight(a),this.scroller.setHeight(c)),this.scroller.lockOverflow(d))},
// given a desired total height of the view, returns what the height of the scroller should be
computeScrollerHeight:function(a){return a-l(this.el,this.scroller.el)},
// Sets the height of just the DayGrid component in this view
setGridHeight:function(a,b){b?j(this.dayGrid.rowEls):i(this.dayGrid.rowEls,a,!0)},/* Scroll
------------------------------------------------------------------------------------------------------------------*/
queryScroll:function(){return this.scroller.getScrollTop()},setScroll:function(a){this.scroller.setScrollTop(a)},/* Hit Areas
------------------------------------------------------------------------------------------------------------------*/
// forward all hit-related method calls to dayGrid
prepareHits:function(){this.dayGrid.prepareHits()},releaseHits:function(){this.dayGrid.releaseHits()},queryHit:function(a,b){return this.dayGrid.queryHit(a,b)},getHitSpan:function(a){return this.dayGrid.getHitSpan(a)},getHitEl:function(a){return this.dayGrid.getHitEl(a)},/* Events
------------------------------------------------------------------------------------------------------------------*/
// Renders the given events onto the view and populates the segments array
renderEvents:function(a){this.dayGrid.renderEvents(a),this.updateHeight()},
// Retrieves all segment objects that are rendered in the view
getEventSegs:function(){return this.dayGrid.getEventSegs()},
// Unrenders all event elements and clears internal segment data
unrenderEvents:function(){this.dayGrid.unrenderEvents()},/* Dragging (for both events and external elements)
------------------------------------------------------------------------------------------------------------------*/
// A returned value of `true` signals that a mock "helper" event has been rendered.
renderDrag:function(a,b){return this.dayGrid.renderDrag(a,b)},unrenderDrag:function(){this.dayGrid.unrenderDrag()},/* Selection
------------------------------------------------------------------------------------------------------------------*/
// Renders a visual indication of a selection
renderSelection:function(a){this.dayGrid.renderSelection(a)},
// Unrenders a visual indications of a selection
unrenderSelection:function(){this.dayGrid.unrenderSelection()}}),Db={
// Generates the HTML that will go before the day-of week header cells
renderHeadIntroHtml:function(){var a=this.view;// needed for matchCellWidths
return a.weekNumbersVisible?'
"+aa(a.opt("weekNumberTitle"))+"
":""},
// Generates the HTML that will go before content-skeleton cells that display the day/week numbers
renderNumberIntroHtml:function(a){var b=this.view;// needed for matchCellWidths
return b.weekNumbersVisible?'
"+this.getCellDate(a,0).format("w")+"
":""},
// Generates the HTML that goes before the day bg cells for each day-row
renderBgIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'
":""},
// Generates the HTML that goes before every other type of row generated by DayGrid.
// Affects helper-skeleton and highlight-skeleton rows.
renderIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'
":""}},Eb=Ta.MonthView=Cb.extend({
// Produces information about what range to display
computeRange:function(a){var b,c=Cb.prototype.computeRange.call(this,a);
// ensure 6 weeks
// could be partial weeks due to hiddenDays
return this.isFixedWeeks()&&(b=Math.ceil(c.end.diff(c.start,"weeks",!0)),c.end.add(6-b,"weeks")),c},
// Overrides the default BasicView behavior to have special multi-week auto-height logic
setGridHeight:function(a,b){b=b||"variable"===this.opt("weekMode"),b&&(a*=this.rowCnt/6),i(this.dayGrid.rowEls,a,!b)},isFixedWeeks:function(){var a=this.opt("weekMode");// LEGACY: weekMode is deprecated
// LEGACY: weekMode is deprecated
return a?"fixed"===a:this.opt("fixedWeekCount")}});Ua.basic={"class":Cb},Ua.basicDay={type:"basic",duration:{days:1}},Ua.basicWeek={type:"basic",duration:{weeks:1}},Ua.month={"class":Eb,duration:{months:1},// important for prev/next
defaults:{fixedWeekCount:!0}};/* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.
----------------------------------------------------------------------------------------------------------------------*/
// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
// Responsible for managing width/height.
var Fb=Ta.AgendaView=tb.extend({scroller:null,timeGridClass:sb,// class used to instantiate the timeGrid. subclasses can override
timeGrid:null,// the main time-grid subcomponent of this view
dayGridClass:rb,// class used to instantiate the dayGrid. subclasses can override
dayGrid:null,// the "all-day" subcomponent. if all-day is turned off, this will be null
axisWidth:null,// the width of the time axis running down the side
headContainerEl:null,// div that hold's the timeGrid's rendered date header
noScrollRowEls:null,// set of fake row elements that must compensate when scroller has scrollbars
// when the time-grid isn't tall enough to occupy the given height, we render an underneath
bottomRuleEl:null,initialize:function(){this.timeGrid=this.instantiateTimeGrid(),this.opt("allDaySlot")&&(// should we display the "all-day" area?
this.dayGrid=this.instantiateDayGrid()),this.scroller=new ub({overflowX:"hidden",overflowY:"auto"})},
// Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass
instantiateTimeGrid:function(){var a=this.timeGridClass.extend(Gb);return new a(this)},
// Instantiates the DayGrid object this view might need. Draws from this.dayGridClass
instantiateDayGrid:function(){var a=this.dayGridClass.extend(Hb);return new a(this)},/* Rendering
------------------------------------------------------------------------------------------------------------------*/
// Sets the display range and computes all necessary dates
setRange:function(a){tb.prototype.setRange.call(this,a),// call the super-method
this.timeGrid.setRange(a),this.dayGrid&&this.dayGrid.setRange(a)},
// Renders the view into `this.el`, which has already been assigned
renderDates:function(){this.el.addClass("fc-agenda-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-time-grid-container"),c=a('').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.timeGrid.setElement(c),this.timeGrid.renderDates(),
// the that sometimes displays under the time-grid
this.bottomRuleEl=a('').appendTo(this.timeGrid.el),// inject it into the time-grid
this.dayGrid&&(this.dayGrid.setElement(this.el.find(".fc-day-grid")),this.dayGrid.renderDates(),
// have the day-grid extend it's coordinate area over the dividing the two grids
this.dayGrid.bottomCoordPadding=this.dayGrid.el.next("hr").outerHeight()),this.noScrollRowEls=this.el.find(".fc-row:not(.fc-scroller *)")},
// render the day-of-week headers
renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.timeGrid.renderHeadHtml())},
// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
// always completely kill each grid's rendering.
unrenderDates:function(){this.timeGrid.unrenderDates(),this.timeGrid.removeElement(),this.dayGrid&&(this.dayGrid.unrenderDates(),this.dayGrid.removeElement()),this.scroller.destroy()},
// Builds the HTML skeleton for the view.
// The day-grid and time-grid components will render inside containers defined by this HTML.
renderSkeletonHtml:function(){return'
'+(this.dayGrid?'':"")+"
"},
// Generates an HTML attribute string for setting the width of the axis, if it is known
axisStyleAttr:function(){return null!==this.axisWidth?'style="width:'+this.axisWidth+'px"':""},/* Business Hours
------------------------------------------------------------------------------------------------------------------*/
renderBusinessHours:function(){this.timeGrid.renderBusinessHours(),this.dayGrid&&this.dayGrid.renderBusinessHours()},unrenderBusinessHours:function(){this.timeGrid.unrenderBusinessHours(),this.dayGrid&&this.dayGrid.unrenderBusinessHours()},/* Now Indicator
------------------------------------------------------------------------------------------------------------------*/
getNowIndicatorUnit:function(){return this.timeGrid.getNowIndicatorUnit()},renderNowIndicator:function(a){this.timeGrid.renderNowIndicator(a)},unrenderNowIndicator:function(){this.timeGrid.unrenderNowIndicator()},/* Dimensions
------------------------------------------------------------------------------------------------------------------*/
updateSize:function(a){this.timeGrid.updateSize(a),tb.prototype.updateSize.call(this,a)},
// Refreshes the horizontal dimensions of the view
updateWidth:function(){
// make all axis cells line up, and record the width so newly created axis cells will have it
this.axisWidth=k(this.el.find(".fc-axis"))},
// Adjusts the vertical dimensions of the view to the specified values
setHeight:function(a,b){var c,d,g;
// reset all dimensions back to the original state
this.bottomRuleEl.hide(),// .show() will be called later if this is necessary
this.scroller.clear(),// sets height to 'auto' and clears overflow
f(this.noScrollRowEls),
// limit number of events in the all-day area
this.dayGrid&&(this.dayGrid.removeSegPopover(),c=this.opt("eventLimit"),c&&"number"!=typeof c&&(c=Ib),c&&this.dayGrid.limitRows(c)),b||(d=this.computeScrollerHeight(a),this.scroller.setHeight(d),g=this.scroller.getScrollbarWidths(),(g.left||g.right)&&(e(this.noScrollRowEls,g),d=this.computeScrollerHeight(a),this.scroller.setHeight(d)),this.scroller.lockOverflow(g),this.timeGrid.getTotalSlatHeight()"+aa(a)+""):'
"},
// Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
renderBgIntroHtml:function(){var a=this.view;return'
"},
// Generates the HTML that goes before all other types of cells.
// Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
renderIntroHtml:function(){var a=this.view;return'
"}},Hb={
// Generates the HTML that goes before the all-day cells
renderBgIntroHtml:function(){var a=this.view;// needed for matchCellWidths
return'
"},
// Generates the HTML that goes before all other types of cells.
// Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
renderIntroHtml:function(){var a=this.view;return'