PageSourceSearch

https://corporateapartments.in/wp-content/plugins/ova-brw/assets/libs/fullcalendar/main.js

js corporateapartments.in collected 2026-10-06 22:00:36 UTC 675,073 bytes, 14,418 lines download raw bytes

vendor: 11,323 bytes, lines 1-57
1/*!
2FullCalendar v5.3.0
3Docs & License: https://fullcalendar.io/
4(c) 2020 Adam Shaw
5*/
6var FullCalendar = (function (exports) {
7    'use strict';
8
9    /*! *****************************************************************************
10    Copyright (c) Microsoft Corporation.
11
12    Permission to use, copy, modify, and/or distribute this software for any
13    purpose with or without fee is hereby granted.
14
15    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
18    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21    PERFORMANCE OF THIS SOFTWARE.
22    ***************************************************************************** */
23    /* global Reflect, Promise */
24
25    var extendStatics = function(d, b) {
26        extendStatics = Object.setPrototypeOf ||
27            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
28            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
29        return extendStatics(d, b);
30    };
31
32    function __extends(d, b) {
33        extendStatics(d, b);
34        function __() { this.constructor = d; }
35        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
36    }
37
38    var __assign = function() {
39        __assign = Object.assign || function __assign(t) {
40            for (var s, i = 1, n = arguments.length; i < n; i++) {
41                s = arguments[i];
42                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
43            }
44            return t;
45        };
46        return __assign.apply(this, arguments);
47    };
48
49    function __spreadArrays() {
50        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
51        for (var r = Array(s), k = 0, i = 0; i < il; i++)
52            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
53                r[k] = a[j];
54        return r;
55    }
56
57    var n,u,i,t,r,o,f,e={},c=[],s=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord/i;function a(n,l){for(var u in l)n[u]=l[u];return n}function v(n){var l=n.parentNode;l&&l.removeChild(n);}function h(n,l,u){var i,t=arguments,r={};for(i in l)"key"!==i&&"ref"!==i&&(r[i]=l[i]);if(arguments.length>3)for(u=[u],i=3;i<arguments.length;i++)u.push(t[i]);if(null!=u&&(r.children=u),"function"==typeof n&&null!=n.defaultProps)for(i in n.defaultProps)void 0===r[i]&&(r[i]=n.defaultProps[i]);return p(n,r,l&&l.key,l&&l.ref,null)}function p(l,u,i,t,r){var o={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,constructor:void 0,__v:r};return null==r&&(o.__v=o),n.vnode&&n.vnode(o),o}function y(){return {}}function d(n){return n.children}function m(n,l){this.props=n,this.context=l;}function w(n,l){if(null==l)return n.__?w(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?w(n):null}function k(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k(n)}}function g(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!i++||r!==n.debounceRendering)&&((r=n.debounceRendering)||t)(_);}function _(){for(var n;i=u.length;)n=u.sort(function(n,l){return n.__v.__b-l.__v.__b}),u=[],n.some(function(n){var l,u,i,t,r,o,f;n.__d&&(o=(r=(l=n).__v).__e,(f=l.__P)&&(u=[],(i=a({},r)).__v=i,t=A(f,r,i,l.__n,void 0!==f.ownerSVGElement,null,u,null==o?w(r):o),T(u,r),t!=o&&k(r)));});}function b(n,l,u,i,t,r,o,f,s){var a,h,p,y,d,m,k,g=u&&u.__k||c,_=g.length;if(f==e&&(f=null!=r?r[0]:_?w(u,0):null),a=0,l.__k=x(l.__k,function(u){if(null!=u){if(u.__=l,u.__b=l.__b+1,null===(p=g[a])||p&&u.key==p.key&&u.type===p.type)g[a]=void 0;else for(h=0;h<_;h++){if((p=g[h])&&u.key==p.key&&u.type===p.type){g[h]=void 0;break}p=null;}if(y=A(n,u,p=p||e,i,t,r,o,f,s),(h=u.ref)&&p.ref!=h&&(k||(k=[]),p.ref&&k.push(p.ref,null,u),k.push(h,u.__c||y,u)),null!=y){var c;if(null==m&&(m=y),void 0!==u.__d)c=u.__d,u.__d=void 0;else if(r==p||y!=f||null==y.parentNode){n:if(null==f||f.parentNode!==n)n.appendChild(y),c=null;else {for(d=f,h=0;(d=d.nextSibling)&&h<_;h+=2)if(d==y)break n;n.insertBefore(y,f),c=f;}"option"==l.type&&(n.value="");}f=void 0!==c?c:y.nextSibling,"function"==typeof l.type&&(l.__d=f);}else f&&p.__e==f&&f.parentNode!=n&&(f=w(p));}return a++,u}),l.__e=m,null!=r&&"function"!=typeof l.type)for(a=r.length;a--;)null!=r[a]&&v(r[a]);for(a=_;a--;)null!=g[a]&&D(g[a],g[a]);if(k)for(a=0;a<k.length;a++)j(k[a],k[++a],k[++a]);}function x(n,l,u){if(null==u&&(u=[]),null==n||"boolean"==typeof n)l&&u.push(l(null));else if(Array.isArray(n))for(var i=0;i<n.length;i++)x(n[i],l,u);else u.push(l?l("string"==typeof n||"number"==typeof n?p(null,n,null,null,n):null!=n.__e||null!=n.__c?p(n.type,n.props,n.key,null,n.__v):n):n);return u}function P(n,l,u,i,t){var r;for(r in u)"children"===r||"key"===r||r in l||N(n,r,null,u[r],i);for(r in l)t&&"function"!=typeof l[r]||"children"===r||"key"===r||"value"===r||"checked"===r||u[r]===l[r]||N(n,r,l[r],u[r],i);}function C(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]="number"==typeof u&&!1===s.test(l)?u+"px":null==u?"":u;}function N(n,l,u,i,t){var r,o,f,e,c;if(t?"className"===l&&(l="class"):"class"===l&&(l="className"),"style"===l)if(r=n.style,"string"==typeof u)r.cssText=u;else {if("string"==typeof i&&(r.cssText="",i=null),i)for(e in i)u&&e in u||C(r,e,"");if(u)for(c in u)i&&u[c]===i[c]||C(r,c,u[c]);}else "o"===l[0]&&"n"===l[1]?(o=l!==(l=l.replace(/Capture$/,"")),f=l.toLowerCase(),l=(f in n?f:l).slice(2),u?(i||n.addEventListener(l,z,o),(n.l||(n.l={}))[l]=u):n.removeEventListener(l,z,o)):"list"!==l&&"tagName"!==l&&"form"!==l&&"type"!==l&&"size"!==l&&!t&&l in n?n[l]=null==u?"":u:"function"!=typeof u&&"dangerouslySetInnerHTML"!==l&&(l!==(l=l.replace(/^xlink:?/,""))?null==u||!1===u?n.removeAttributeNS("http://www.w3.org/1999/xlink",l.toLowerCase()):n.setAttributeNS("http://www.w3.org/1999/xlink",l.toLowerCase(),u):null==u||!1===u&&!/^ar/.test(l)?n.removeAttribute(l):n.setAttribute(l,u));}function z(l){this.l[l.type](n.event?n.event(l):l);}function A(l,u,i,t,r,o,f,e,c){var s,v,h,p,y,w,k,g,_,x,P=u.type;if(void 0!==u.constructor)return null;(s=n.__b)&&s(u);try{n:if("function"==typeof P){if(g=u.props,_=(s=P.contextType)&&t[s.__c],x=s?_?_.props.value:s.__:t,i.__c?k=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new m(g,x),v.constructor=P,v.render=E),_&&_.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=a({},v.__s)),a(v.__s,P.getDerivedStateFromProps(g,v.__s))),p=v.props,y=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==p&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v&&!v.__){for(v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,v.__h.length&&f.push(v),s=0;s<u.__k.length;s++)u.__k[s]&&(u.__k[s].__=u);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(p,y,w);});}v.context=x,v.props=g,v.state=v.__s,(s=n.__r)&&s(u),v.__d=!1,v.__v=u,v.__P=l,s=v.render(v.props,v.state,v.context),u.__k=null!=s&&s.type==d&&null==s.key?s.props.children:Array.isArray(s)?s:[s],null!=v.getChildContext&&(t=a(a({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(w=v.getSnapshotBeforeUpdate(p,y)),b(l,u,i,t,r,o,f,e,c),v.base=u.__e,v.__h.length&&f.push(v),k&&(v.__E=v.__=null),v.__e=!1;}else null==o&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=$(i.__e,u,i,t,r,o,f,c);(s=n.diffed)&&s(u);}catch(l){u.__v=null,n.__e(l,u,i);}return u.__e}function T(l,u){n.__c&&n.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n.__e(l,u.__v);}});}function $(n,l,u,i,t,r,o,f){var s,a,v,h,p,y=u.props,d=l.props;if(t="svg"===l.type||t,null!=r)for(s=0;s<r.length;s++)if(null!=(a=r[s])&&((null===l.type?3===a.nodeType:a.localName===l.type)||n==a)){n=a,r[s]=null;break}if(null==n){if(null===l.type)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",l.type):document.createElement(l.type,d.is&&{is:d.is}),r=null,f=!1;}if(null===l.type)y!==d&&n.data!=d&&(n.data=d);else {if(null!=r&&(r=c.slice.call(n.childNodes)),v=(y=u.props||e).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!f){if(y===e)for(y={},p=0;p<n.attributes.length;p++)y[n.attributes[p].name]=n.attributes[p].value;(h||v)&&(h&&v&&h.__html==v.__html||(n.innerHTML=h&&h.__html||""));}P(n,d,y,t,f),h?l.__k=[]:(l.__k=l.props.children,b(n,l,u,i,"foreignObject"!==l.type&&t,r,o,e,f)),f||("value"in d&&void 0!==(s=d.value)&&s!==n.value&&N(n,"value",s,y.value,!1),"checked"in d&&void 0!==(s=d.checked)&&s!==n.checked&&N(n,"checked",s,y.checked,!1));}return n}function j(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function D(l,u,i){var t,r,o;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||j(t,null,u)),i||"function"==typeof l.type||(i=null!=(r=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(o=0;o<t.length;o++)t[o]&&D(t[o],u,i);null!=r&&v(r);}function E(n,l,u){return this.constructor(n,u)}function H(l,u,i){var t,r,f;n.__&&n.__(l,u),r=(t=i===o)?null:i&&i.__k||u.__k,l=h(d,null,[l]),f=[],A(u,(t?u:i||u).__k=l,r||e,e,void 0!==u.ownerSVGElement,i&&!t?[i]:r?null:c.slice.call(u.childNodes),f,i||e,t),T(f,l);}function M(n){var l={},u={__c:"__cC"+f++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var i,t=this;return this.getChildContext||(i=[],this.getChildContext=function(){return l[u.__c]=t,l},this.shouldComponentUpdate=function(n){t.props.value!==n.value&&i.some(function(l){l.context=n.value,g(l);});},this.sub=function(n){i.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){i.splice(i.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Consumer.contextType=u,u.Provider.__=u,u}n={__e:function(n,l){for(var u,i;l=l.__;)if((u=l.__c)&&!u.__)try{if(u.constructor&&null!=u.constructor.getDerivedStateFromError&&(i=!0,u.setState(u.constructor.getDerivedStateFromError(n))),null!=u.componentDidCatch&&(i=!0,u.componentDidCatch(n)),i)return g(u.__E=u)}catch(l){n=l;}throw n}},m.prototype.setState=function(n,l){var u;u=this.__s!==this.state?this.__s:this.__s=a({},this.state),"function"==typeof n&&(n=n(u,this.props)),n&&a(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),g(this));},m.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),g(this));},m.prototype.render=d,u=[],i=0,t="function"==typeof Promise?Promise.prototype.then.bind(Prom
57ise.resolve()):setTimeout,o=e,f=0;
58
59    (typeof globalThis !== 'undefined' ? globalThis : window).FullCalendarVDom = {
60        Component: m,
61        createElement: h,
62        render: H,
63        createRef: y,
64        Fragment: d,
65        createContext: createContext,
66        flushToDom: flushToDom
67    };
68    // HACKS...
69    // TODO: lock version
70    // TODO: link gh issues
71    function flushToDom() {
72        var oldDebounceRendering = n.debounceRendering; // orig
73        var callbackQ = [];
74        function execCallbackSync(callback) {
75            callbackQ.push(callback);
76        }
77        n.debounceRendering = execCallbackSync;
78        H(h(FakeComponent, {}), document.createElement('div'));
79        while (callbackQ.length) {
80            callbackQ.shift()();
81        }
82        n.debounceRendering = oldDebounceRendering;
83    }
84    var FakeComponent = /** @class */ (function (_super) {
85        __extends(FakeComponent, _super);
86        function FakeComponent() {
87            return _super !== null && _super.apply(this, arguments) || this;
88        }
89        FakeComponent.prototype.render = function () { return h('div', {}); };
90        FakeComponent.prototype.componentDidMount = function () { this.setState({}); };
91        return FakeComponent;
92    }(m));
93    function createContext(defaultValue) {
94        var ContextType = M(defaultValue);
95        var origProvider = ContextType.Provider;
96        ContextType.Provider = function () {
97            var _this = this;
98            var isNew = !this.getChildContext;
99            var children = origProvider.apply(this, arguments);
100            if (isNew) {
101                var subs_1 = [];
102                this.shouldComponentUpdate = function (_props) {
103                    if (_this.props.value !== _props.value) {
104                        subs_1.some(function (c) {
105                            c.context = _props.value;
106                            c.forceUpdate();
107                        });
108                    }
109                };
110                this.sub = function (c) {
111                    subs_1.push(c);
112                    var old = c.componentWillUnmount;
113                    c.componentWillUnmount = function () {
114                        subs_1.splice(subs_1.indexOf(c), 1);
115                        old && old.call(c);
116                    };
117                };
118            }
119            return children;
120        };
121        return ContextType;
122    }
123
124    // no public types yet. when there are, export from:
125    // import {} from './api-type-deps'
126    var EventSourceApi = /** @class */ (function () {
127        function EventSourceApi(context, internalEventSource // rename?
128        ) {
129            this.context = context;
130            this.internalEventSource = internalEventSource;
131        }
132        EventSourceApi.prototype.remove = function () {
133            this.context.dispatch({
134                type: 'REMOVE_EVENT_SOURCE',
135                sourceId: this.internalEventSource.sourceId
136            });
137        };
138        EventSourceApi.prototype.refetch = function () {
139            this.context.dispatch({
140                type: 'FETCH_EVENT_SOURCES',
141                sourceIds: [this.internalEventSource.sourceId]
142            });
143        };
144        Object.defineProperty(EventSourceApi.prototype, "id", {
145            get: function () {
146                return this.internalEventSource.publicId;
147            },
148            enumerable: false,
149            configurable: true
150        });
151        Object.defineProperty(EventSourceApi.prototype, "url", {
152            // only relevant to json-feed event sources
153            get: function () {
154                return this.internalEventSource.meta.url;
155            },
156            enumerable: false,
157            configurable: true
158        });
159        return EventSourceApi;
160    }());
161
162    function removeElement(el) {
163        if (el.parentNode) {
164            el.parentNode.removeChild(el);
165        }
166    }
167    // Querying
168    // ----------------------------------------------------------------------------------------------------------------
169    function elementClosest(el, selector) {
170        if (el.closest) {
171            return el.closest(selector);
172            // really bad fallback for IE
173            // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
174        }
175        else {
176            if (!document.documentElement.contains(el)) {
177                return null;
178            }
179            do {
180                if (elementMatches(el, selector)) {
181                    return el;
182                }
183                el = (el.parentElement || el.parentNode);
184            } while (el !== null && el.nodeType === 1);
185            return null;
186        }
187    }
188    function elementMatches(el, selector) {
189        var method = el.matches || el.matchesSelector || el.msMatchesSelector;
190        return method.call(el, selector);
191    }
192    // accepts multiple subject els
193    // returns a real array. good for methods like forEach
194    // TODO: accept the document
195    function findElements(container, selector) {
196        var containers = container instanceof HTMLElement ? [container] : container;
197        var allMatches = [];
198        for (var i = 0; i < containers.length; i++) {
199            var matches = containers[i].querySelectorAll(selector);
200            for (var j = 0; j < matches.length; j++) {
201                allMatches.push(matches[j]);
202            }
203        }
204        return allMatches;
205    }
206    // accepts multiple subject els
207    // only queries direct child elements // TODO: rename to findDirectChildren!
208    function findDirectChildren(parent, selector) {
209        var parents = parent instanceof HTMLElement ? [parent] : parent;
210        var allMatches = [];
211        for (var i = 0; i < parents.length; i++) {
212            var childNodes = parents[i].children; // only ever elements
213            for (var j = 0; j < childNodes.length; j++) {
214                var childNode = childNodes[j];
215                if (!selector || elementMatches(childNode, selector)) {
216                    allMatches.push(childNode);
217                }
218            }
219        }
220        return allMatches;
221    }
222    // Style
223    // ----------------------------------------------------------------------------------------------------------------
224    var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
225    function applyStyle(el, props) {
226        for (var propName in props) {
227            applyStyleProp(el, propName, props[propName]);
228        }
229    }
230    function applyStyleProp(el, name, val) {
231        if (val == null) {
232            el.style[name] = '';
233        }
234        else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
235            el.style[name] = val + 'px';
236        }
237        else {
238            el.style[name] = val;
239        }
240    }
241
242    // Stops a mouse/touch event from doing it's native browser action
243    function preventDefault(ev) {
244        ev.preventDefault();
245    }
246    // Event Delegation
247    // ----------------------------------------------------------------------------------------------------------------
248    function buildDelegationHandler(selector, handler) {
249        return function (ev) {
vendor: 15,049 bytes, lines 250-680
250            var matchedChild = elementClosest(ev.target, selector);
251            if (matchedChild) {
252                handler.call(matchedChild, ev, matchedChild);
253            }
254        };
255    }
256    function listenBySelector(container, eventType, selector, handler) {
257        var attachedHandler = buildDelegationHandler(selector, handler);
258        container.addEventListener(eventType, attachedHandler);
259        return function () {
260            container.removeEventListener(eventType, attachedHandler);
261        };
262    }
263    function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
264        var currentMatchedChild;
265        return listenBySelector(container, 'mouseover', selector, function (ev, matchedChild) {
266            if (matchedChild !== currentMatchedChild) {
267                currentMatchedChild = matchedChild;
268                onMouseEnter(ev, matchedChild);
269                var realOnMouseLeave_1 = function (ev) {
270                    currentMatchedChild = null;
271                    onMouseLeave(ev, matchedChild);
272                    matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
273                };
274                // listen to the next mouseleave, and then unattach
275                matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
276            }
277        });
278    }
279    // Animation
280    // ----------------------------------------------------------------------------------------------------------------
281    var transitionEventNames = [
282        'webkitTransitionEnd',
283        'otransitionend',
284        'oTransitionEnd',
285        'msTransitionEnd',
286        'transitionend'
287    ];
288    // triggered only when the next single subsequent transition finishes
289    function whenTransitionDone(el, callback) {
290        var realCallback = function (ev) {
291            callback(ev);
292            transitionEventNames.forEach(function (eventName) {
293                el.removeEventListener(eventName, realCallback);
294            });
295        };
296        transitionEventNames.forEach(function (eventName) {
297            el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
298        });
299    }
300
301    var guidNumber = 0;
302    function guid() {
303        return String(guidNumber++);
304    }
305    /* FullCalendar-specific DOM Utilities
306    ----------------------------------------------------------------------------------------------------------------------*/
307    // Make the mouse cursor express that an event is not allowed in the current area
308    function disableCursor() {
309        document.body.classList.add('fc-not-allowed');
310    }
311    // Returns the mouse cursor to its original look
312    function enableCursor() {
313        document.body.classList.remove('fc-not-allowed');
314    }
315    /* Selection
316    ----------------------------------------------------------------------------------------------------------------------*/
317    function preventSelection(el) {
318        el.classList.add('fc-unselectable');
319        el.addEventListener('selectstart', preventDefault);
320    }
321    function allowSelection(el) {
322        el.classList.remove('fc-unselectable');
323        el.removeEventListener('selectstart', preventDefault);
324    }
325    /* Context Menu
326    ----------------------------------------------------------------------------------------------------------------------*/
327    function preventContextMenu(el) {
328        el.addEventListener('contextmenu', preventDefault);
329    }
330    function allowContextMenu(el) {
331        el.removeEventListener('contextmenu', preventDefault);
332    }
333    function parseFieldSpecs(input) {
334        var specs = [];
335        var tokens = [];
336        var i;
337        var token;
338        if (typeof input === 'string') {
339            tokens = input.split(/\s*,\s*/);
340        }
341        else if (typeof input === 'function') {
342            tokens = [input];
343        }
344        else if (Array.isArray(input)) {
345            tokens = input;
346        }
347        for (i = 0; i < tokens.length; i++) {
348            token = tokens[i];
349            if (typeof token === 'string') {
350                specs.push(token.charAt(0) === '-' ?
351                    { field: token.substring(1), order: -1 } :
352                    { field: token, order: 1 });
353            }
354            else if (typeof token === 'function') {
355                specs.push({ func: token });
356            }
357        }
358        return specs;
359    }
360    function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
361        var i;
362        var cmp;
363        for (i = 0; i < fieldSpecs.length; i++) {
364            cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
365            if (cmp) {
366                return cmp;
367            }
368        }
369        return 0;
370    }
371    function compareByFieldSpec(obj0, obj1, fieldSpec) {
372        if (fieldSpec.func) {
373            return fieldSpec.func(obj0, obj1);
374        }
375        return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
376            * (fieldSpec.order || 1);
377    }
378    function flexibleCompare(a, b) {
379        if (!a && !b) {
380            return 0;
381        }
382        if (b == null) {
383            return -1;
384        }
385        if (a == null) {
386            return 1;
387        }
388        if (typeof a === 'string' || typeof b === 'string') {
389            return String(a).localeCompare(String(b));
390        }
391        return a - b;
392    }
393    /* String Utilities
394    ----------------------------------------------------------------------------------------------------------------------*/
395    function padStart(val, len) {
396        var s = String(val);
397        return '000'.substr(0, len - s.length) + s;
398    }
399    /* Number Utilities
400    ----------------------------------------------------------------------------------------------------------------------*/
401    function compareNumbers(a, b) {
402        return a - b;
403    }
404    function isInt(n) {
405        return n % 1 === 0;
406    }
407    /* FC-specific DOM dimension stuff
408    ----------------------------------------------------------------------------------------------------------------------*/
409    function computeSmallestCellWidth(cellEl) {
410        var allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame');
411        var contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion');
412        if (!allWidthEl) {
413            throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const
414        }
415        if (!contentWidthEl) {
416            throw new Error('needs fc-scrollgrid-shrink-cushion className');
417        }
418        return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border
419            contentWidthEl.getBoundingClientRect().width;
420    }
421
422    var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
423    // Adding
424    function addWeeks(m, n) {
425        var a = dateToUtcArray(m);
426        a[2] += n * 7;
427        return arrayToUtcDate(a);
428    }
429    function addDays(m, n) {
430        var a = dateToUtcArray(m);
431        a[2] += n;
432        return arrayToUtcDate(a);
433    }
434    function addMs(m, n) {
435        var a = dateToUtcArray(m);
436        a[6] += n;
437        return arrayToUtcDate(a);
438    }
439    // Diffing (all return floats)
440    // TODO: why not use ranges?
441    function diffWeeks(m0, m1) {
442        return diffDays(m0, m1) / 7;
443    }
444    function diffDays(m0, m1) {
445        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
446    }
447    function diffHours(m0, m1) {
448        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
449    }
450    function diffMinutes(m0, m1) {
451        return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
452    }
453    function diffSeconds(m0, m1) {
454        return (m1.valueOf() - m0.valueOf()) / 1000;
455    }
456    function diffDayAndTime(m0, m1) {
457        var m0day = startOfDay(m0);
458        var m1day = startOfDay(m1);
459        return {
460            years: 0,
461            months: 0,
462            days: Math.round(diffDays(m0day, m1day)),
463            milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf())
464        };
465    }
466    // Diffing Whole Units
467    function diffWholeWeeks(m0, m1) {
468        var d = diffWholeDays(m0, m1);
469        if (d !== null && d % 7 === 0) {
470            return d / 7;
471        }
472        return null;
473    }
474    function diffWholeDays(m0, m1) {
475        if (timeAsMs(m0) === timeAsMs(m1)) {
476            return Math.round(diffDays(m0, m1));
477        }
478        return null;
479    }
480    // Start-Of
481    function startOfDay(m) {
482        return arrayToUtcDate([
483            m.getUTCFullYear(),
484            m.getUTCMonth(),
485            m.getUTCDate()
486        ]);
487    }
488    function startOfHour(m) {
489        return arrayToUtcDate([
490            m.getUTCFullYear(),
491            m.getUTCMonth(),
492            m.getUTCDate(),
493            m.getUTCHours()
494        ]);
495    }
496    function startOfMinute(m) {
497        return arrayToUtcDate([
498            m.getUTCFullYear(),
499            m.getUTCMonth(),
500            m.getUTCDate(),
501            m.getUTCHours(),
502            m.getUTCMinutes()
503        ]);
504    }
505    function startOfSecond(m) {
506        return arrayToUtcDate([
507            m.getUTCFullYear(),
508            m.getUTCMonth(),
509            m.getUTCDate(),
510            m.getUTCHours(),
511            m.getUTCMinutes(),
512            m.getUTCSeconds()
513        ]);
514    }
515    // Week Computation
516    function weekOfYear(marker, dow, doy) {
517        var y = marker.getUTCFullYear();
518        var w = weekOfGivenYear(marker, y, dow, doy);
519        if (w < 1) {
520            return weekOfGivenYear(marker, y - 1, dow, doy);
521        }
522        var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
523        if (nextW >= 1) {
524            return Math.min(w, nextW);
525        }
526        return w;
527    }
528    function weekOfGivenYear(marker, year, dow, doy) {
529        var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
530        var dayStart = startOfDay(marker);
531        var days = Math.round(diffDays(firstWeekStart, dayStart));
532        return Math.floor(days / 7) + 1; // zero-indexed
533    }
534    // start-of-first-week - start-of-year
535    function firstWeekOffset(year, dow, doy) {
536        // first-week day -- which january is always in the first week (4 for iso, 1 for other)
537        var fwd = 7 + dow - doy;
538        // first-week day local weekday -- which local weekday is fwd
539        var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
540        return -fwdlw + fwd - 1;
541    }
542    // Array Conversion
543    function dateToLocalArray(date) {
544        return [
545            date.getFullYear(),
546            date.getMonth(),
547            date.getDate(),
548            date.getHours(),
549            date.getMinutes(),
550            date.getSeconds(),
551            date.getMilliseconds()
552        ];
553    }
554    function arrayToLocalDate(a) {
555        return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
556        a[3] || 0, a[4] || 0, a[5] || 0);
557    }
558    function dateToUtcArray(date) {
559        return [
560            date.getUTCFullYear(),
561            date.getUTCMonth(),
562            date.getUTCDate(),
563            date.getUTCHours(),
564            date.getUTCMinutes(),
565            date.getUTCSeconds(),
566            date.getUTCMilliseconds()
567        ];
568    }
569    function arrayToUtcDate(a) {
570        // according to web standards (and Safari), a month index is required.
571        // massage if only given a year.
572        if (a.length === 1) {
573            a = a.concat([0]);
574        }
575        return new Date(Date.UTC.apply(Date, a));
576    }
577    // Other Utils
578    function isValidDate(m) {
579        return !isNaN(m.valueOf());
580    }
581    function timeAsMs(m) {
582        return m.getUTCHours() * 1000 * 60 * 60 +
583            m.getUTCMinutes() * 1000 * 60 +
584            m.getUTCSeconds() * 1000 +
585            m.getUTCMilliseconds();
586    }
587
588    function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
589        return {
590            instanceId: guid(),
591            defId: defId,
592            range: range,
593            forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
594            forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo
595        };
596    }
597
598    var hasOwnProperty = Object.prototype.hasOwnProperty;
599    // Merges an array of objects into a single object.
600    // The second argument allows for an array of property names who's object values will be merged together.
601    function mergeProps(propObjs, complexPropsMap) {
602        var dest = {};
603        if (complexPropsMap) {
604            for (var name_1 in complexPropsMap) {
605                var complexObjs = [];
606                // collect the trailing object values, stopping when a non-object is discovered
607                for (var i = propObjs.length - 1; i >= 0; i--) {
608                    var val = propObjs[i][name_1];
609                    if (typeof val === 'object' && val) { // non-null object
610                        complexObjs.unshift(val);
611                    }
612                    else if (val !== undefined) {
613                        dest[name_1] = val; // if there were no objects, this value will be used
614                        break;
615                    }
616                }
617                // if the trailing values were objects, use the merged value
618                if (complexObjs.length) {
619                    dest[name_1] = mergeProps(complexObjs);
620                }
621            }
622        }
623        // copy values into the destination, going from last to first
624        for (var i = propObjs.length - 1; i >= 0; i--) {
625            var props = propObjs[i];
626            for (var name_2 in props) {
627                if (!(name_2 in dest)) { // if already assigned by previous props or complex props, don't reassign
628                    dest[name_2] = props[name_2];
629                }
630            }
631        }
632        return dest;
633    }
634    function filterHash(hash, func) {
635        var filtered = {};
636        for (var key in hash) {
637            if (func(hash[key], key)) {
638                filtered[key] = hash[key];
639            }
640        }
641        return filtered;
642    }
643    function mapHash(hash, func) {
644        var newHash = {};
645        for (var key in hash) {
646            newHash[key] = func(hash[key], key);
647        }
648        return newHash;
649    }
650    function arrayToHash(a) {
651        var hash = {};
652        for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
653            var item = a_1[_i];
654            hash[item] = true;
655        }
656        return hash;
657    }
658    function buildHashFromArray(a, func) {
659        var hash = {};
660        for (var i = 0; i < a.length; i++) {
661            var tuple = func(a[i], i);
662            hash[tuple[0]] = tuple[1];
663        }
664        return hash;
665    }
666    function hashValuesToArray(obj) {
667        var a = [];
668        for (var key in obj) {
669            a.push(obj[key]);
670        }
671        return a;
672    }
673    function isPropsEqual(obj0, obj1) {
674        if (obj0 === obj1) {
675            return true;
676        }
677        for (var key in obj0) {
678            if (hasOwnProperty.call(obj0, key)) {
679                if (!(key in obj1)) {
680                    return false;
681                }
682            }
683        }
684        for (var key in obj1) {
685            if (hasOwnProperty.call(obj1, key)) {
686                if (obj0[key] !== obj1[key]) {
687                    return false;
688                }
689            }
690        }
691        return true;
692    }
693    function getUnequalProps(obj0, obj1) {
694        var keys = [];
695        for (var key in obj0) {
696            if (hasOwnProperty.call(obj0, key)) {
697                if (!(key in obj1)) {
698                    keys.push(key);
699                }
700            }
701        }
702        for (var key in obj1) {
703            if (hasOwnProperty.call(obj1, key)) {
704                if (obj0[key] !== obj1[key]) {
705                    keys.push(key);
706                }
707            }
708        }
709        return keys;
710    }
711    function compareObjs(oldProps, newProps, equalityFuncs) {
712        if (equalityFuncs === void 0) { equalityFuncs = {}; }
713        if (oldProps === newProps) {
714            return true;
715        }
716        for (var key in newProps) {
717            if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ;
718            else {
719                return false;
720            }
721        }
722        // check for props that were omitted in the new
723        for (var key in oldProps) {
724            if (!(key in newProps)) {
725                return false;
726            }
727        }
728        return true;
729    }
730    /*
731    assumed "true" equality for handler names like "onReceiveSomething"
732    */
733    function isObjValsEqual(val0, val1, comparator) {
734        if (val0 === val1 || comparator === true) {
735            return true;
736        }
737        if (comparator) {
738            return comparator(val0, val1);
739        }
740        return false;
741    }
742    function collectFromHash(hash, startIndex, endIndex, step) {
743        if (startIndex === void 0) { startIndex = 0; }
744        if (step === void 0) { step = 1; }
745        var res = [];
746        if (endIndex == null) {
747            endIndex = Object.keys(hash).length;
748        }
749        for (var i = startIndex; i < endIndex; i += step) {
750            var val = hash[i];
751            if (val !== undefined) { // will disregard undefined for sparse arrays
752                res.push(val);
753            }
754        }
755        return res;
756    }
757
758    function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) {
759        for (var i = 0; i < recurringTypes.length; i++) {
760            var parsed = recurringTypes[i].parse(refined, dateEnv);
761            if (parsed) {
762                var allDay = refined.allDay;
763                if (allDay == null) {
764                    allDay = defaultAllDay;
765                    if (allDay == null) {
766                        allDay = parsed.allDayGuess;
767                        if (allDay == null) {
768                            allDay = false;
769                        }
770                    }
771                }
772                return {
773                    allDay: allDay,
774                    duration: parsed.duration,
775                    typeData: parsed.typeData,
776                    typeId: i
777                };
778            }
779        }
780        return null;
781    }
782    function expandRecurring(eventStore, framingRange, context) {
783        var dateEnv = context.dateEnv, pluginHooks = context.pluginHooks, options = context.options;
784        var defs = eventStore.defs, instances = eventStore.instances;
785        // remove existing recurring instances
786        // TODO: bad. always expand events as a second step
787        instances = filterHash(instances, function (instance) {
788            return !defs[instance.defId].recurringDef;
789        });
790        for (var defId in defs) {
791            var def = defs[defId];
792            if (def.recurringDef) {
793                var duration = def.recurringDef.duration;
794                if (!duration) {
795                    duration = def.allDay ?
796                        options.defaultAllDayEventDuration :
797                        options.defaultTimedEventDuration;
798                }
799                var starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes);
800                for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
801                    var start = starts_1[_i];
802                    var instance = createEventInstance(defId, {
803                        start: start,
804                        end: dateEnv.add(start, duration)
805                    });
806                    instances[instance.instanceId] = instance;
807                }
808            }
809        }
810        return { defs: defs, instances: instances };
811    }
812    /*
813    Event MUST have a recurringDef
814    */
815    function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
816        var typeDef = recurringTypes[eventDef.recurringDef.typeId];
817        var markers = typeDef.expand(eventDef.recurringDef.typeData, {
818            start: dateEnv.subtract(framingRange.start, duration),
819            end: framingRange.end
820        }, dateEnv);
821        // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
822        if (eventDef.allDay) {
823            markers = markers.map(startOfDay);
824        }
825        return markers;
826    }
827
828    var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
829    var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
830    // Parsing and Creation
831    function createDuration(input, unit) {
832        var _a;
833        if (typeof input === 'string') {
834            return parseString(input);
835        }
836        else if (typeof input === 'object' && input) { // non-null object
837            return parseObject(input);
838        }
839        else if (typeof input === 'number') {
840            return parseObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
841        }
842        else {
843            return null;
844        }
845    }
846    function parseString(s) {
847        var m = PARSE_RE.exec(s);
848        if (m) {
849            var sign = m[1] ? -1 : 1;
850            return {
851                years: 0,
852                months: 0,
853                days: sign * (m[2] ? parseInt(m[2], 10) : 0),
854                milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
855                    (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
856                    (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
857                    (m[6] ? parseInt(m[6], 10) : 0) // ms
858                )
859            };
860        }
861        return null;
862    }
863    function parseObject(obj) {
864        var duration = {
865            years: obj.years || obj.year || 0,
866            months: obj.months || obj.month || 0,
867            days: obj.days || obj.day || 0,
868            milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
869                (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
870                (obj.seconds || obj.second || 0) * 1000 + // seconds
871                (obj.milliseconds || obj.millisecond || obj.ms || 0) // ms
872        };
873        var weeks = obj.weeks || obj.week;
874        if (weeks) {
875            duration.days += weeks * 7;
876            duration.specifiedWeeks = true;
877        }
878        return duration;
879    }
880    // Equality
881    function durationsEqual(d0, d1) {
882        return d0.years === d1.years &&
883            d0.months === d1.months &&
884            d0.days === d1.days &&
885            d0.milliseconds === d1.milliseconds;
886    }
887    function asCleanDays(dur) {
888        if (!dur.years && !dur.months && !dur.milliseconds) {
889            return dur.days;
890        }
891        return 0;
892    }
893    // Simple Math
894    function addDurations(d0, d1) {
895        return {
896            years: d0.years + d1.years,
897            months: d0.months + d1.months,
898            days: d0.days + d1.days,
899            milliseconds: d0.milliseconds + d1.milliseconds
900        };
901    }
902    function subtractDurations(d1, d0) {
903        return {
904            years: d1.years - d0.years,
905            months: d1.months - d0.months,
906            days: d1.days - d0.days,
907            milliseconds: d1.milliseconds - d0.milliseconds
908        };
909    }
910    function multiplyDuration(d, n) {
911        return {
912            years: d.years * n,
913            months: d.months * n,
914            days: d.days * n,
915            milliseconds: d.milliseconds * n
916        };
917    }
918    // Conversions
919    // "Rough" because they are based on average-case Gregorian months/years
920    function asRoughYears(dur) {
921        return asRoughDays(dur) / 365;
922    }
923    function asRoughMonths(dur) {
924        return asRoughDays(dur) / 30;
925    }
926    function asRoughDays(dur) {
927        return asRoughMs(dur) / 864e5;
928    }
929    function asRoughMinutes(dur) {
930        return asRoughMs(dur) / (1000 * 60);
931    }
932    function asRoughSeconds(dur) {
933        return asRoughMs(dur) / 1000;
934    }
935    function asRoughMs(dur) {
936        return dur.years * (365 * 864e5) +
937            dur.months * (30 * 864e5) +
938            dur.days * 864e5 +
939            dur.milliseconds;
940    }
941    // Advanced Math
942    function wholeDivideDurations(numerator, denominator) {
943        var res = null;
944        for (var i = 0; i < INTERNAL_UNITS.length; i++) {
945            var unit = INTERNAL_UNITS[i];
946            if (denominator[unit]) {
947                var localRes = numerator[unit] / denominator[unit];
948                if (!isInt(localRes) || (res !== null && res !== localRes)) {
949                    return null;
950                }
951                res = localRes;
952            }
953            else if (numerator[unit]) {
954                // needs to divide by something but can't!
955                return null;
956            }
957        }
958        return res;
959    }
960    function greatestDurationDenominator(dur) {
961        var ms = dur.milliseconds;
962        if (ms) {
963            if (ms % 1000 !== 0) {
964                return { unit: 'millisecond', value: ms };
965            }
966            if (ms % (1000 * 60) !== 0) {
967                return { unit: 'second', value: ms / 1000 };
968            }
969            if (ms % (1000 * 60 * 60) !== 0) {
970                return { unit: 'minute', value: ms / (1000 * 60) };
971            }
972            if (ms) {
973                return { unit: 'hour', value: ms / (1000 * 60 * 60) };
974            }
975        }
976        if (dur.days) {
977            if (dur.specifiedWeeks && dur.days % 7 === 0) {
978                return { unit: 'week', value: dur.days / 7 };
979            }
980            return { unit: 'day', value: dur.days };
981        }
982        if (dur.months) {
983            return { unit: 'month', value: dur.months };
984        }
985        if (dur.years) {
986            return { unit: 'year', value: dur.years };
987        }
988        return { unit: 'millisecond', value: 0 };
989    }
990
991    // timeZoneOffset is in minutes
992    function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
993        if (stripZeroTime === void 0) { stripZeroTime = false; }
994        var s = marker.toISOString();
995        s = s.replace('.000', '');
996        if (stripZeroTime) {
997            s = s.replace('T00:00:00Z', '');
998        }
999        if (s.length > 10) { // time part wasn't stripped, can add timezone info
1000            if (timeZoneOffset == null) {
1001                s = s.replace('Z', '');
1002            }
1003            else if (timeZoneOffset !== 0) {
1004                s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
1005            }
1006            // otherwise, its UTC-0 and we want to keep the Z
1007        }
1008        return s;
1009    }
1010    // formats the date, but with no time part
1011    // TODO: somehow merge with buildIsoString and stripZeroTime
1012    // TODO: rename. omit "string"
1013    function formatDayString(marker) {
1014        return marker.toISOString().replace(/T.*$/, '');
1015    }
1016    // TODO: use Date::toISOString and use everything after the T?
1017    function formatIsoTimeString(marker) {
1018        return padStart(marker.getUTCHours(), 2) + ':' +
1019            padStart(marker.getUTCMinutes(), 2) + ':' +
1020            padStart(marker.getUTCSeconds(), 2);
1021    }
1022    function formatTimeZoneOffset(minutes, doIso) {
1023        if (doIso === void 0) { doIso = false; }
1024        var sign = minutes < 0 ? '-' : '+';
1025        var abs = Math.abs(minutes);
1026        var hours = Math.floor(abs / 60);
1027        var mins = Math.round(abs % 60);
1028        if (doIso) {
1029            return sign + padStart(hours, 2) + ':' + padStart(mins, 2);
1030        }
1031        else {
1032            return 'GMT' + sign + hours + (mins ? ':' + padStart(mins, 2) : '');
1033        }
1034    }
1035
1036    // TODO: new util arrayify?
1037    function removeExact(array, exactVal) {
1038        var removeCnt = 0;
1039        var i = 0;
1040        while (i < array.length) {
1041            if (array[i] === exactVal) {
1042                array.splice(i, 1);
1043                removeCnt++;
1044            }
1045            else {
1046                i++;
1047            }
1048        }
1049        return removeCnt;
1050    }
1051    function isArraysEqual(a0, a1, equalityFunc) {
1052        if (a0 === a1) {
1053            return true;
1054        }
1055        var len = a0.length;
1056        var i;
1057        if (len !== a1.length) { // not array? or not same length?
1058            return false;
1059        }
1060        for (i = 0; i < len; i++) {
1061            if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) {
1062                return false;
1063            }
1064        }
1065        return true;
1066    }
1067
1068    function memoize(workerFunc, resEquality, teardownFunc) {
1069        var currentArgs;
1070        var currentRes;
1071        return function () {
1072            var newArgs = [];
1073            for (var _i = 0; _i < arguments.length; _i++) {
1074                newArgs[_i] = arguments[_i];
1075            }
1076            if (!currentArgs) {
1077                currentRes = workerFunc.apply(this, newArgs);
1078            }
1079            else if (!isArraysEqual(currentArgs, newArgs)) {
1080                if (teardownFunc) {
1081                    teardownFunc(currentRes);
1082                }
1083                var res = workerFunc.apply(this, newArgs);
1084                if (!resEquality || !resEquality(res, currentRes)) {
1085                    currentRes = res;
1086                }
1087            }
1088            currentArgs = newArgs;
1089            return currentRes;
1090        };
1091    }
1092    function memoizeObjArg(workerFunc, resEquality, teardownFunc) {
1093        var currentArg;
1094        var currentRes;
1095        return function (newArg) {
1096            if (!currentArg) {
1097                currentRes = workerFunc.call(this, newArg);
1098            }
1099            else if (!isPropsEqual(currentArg, newArg)) {
1100                if (teardownFunc) {
1101                    teardownFunc(currentRes);
1102                }
1103                var res = workerFunc.call(this, newArg);
1104                if (!resEquality || !resEquality(res, currentRes)) {
1105                    currentRes = res;
1106                }
1107            }
1108            currentArg = newArg;
1109            return currentRes;
1110        };
1111    }
1112    function memoizeArraylike(// used at all?
1113    workerFunc, resEquality, teardownFunc) {
1114        var currentArgSets = [];
1115        var currentResults = [];
1116        return function (newArgSets) {
1117            var currentLen = currentArgSets.length;
1118            var newLen = newArgSets.length;
1119            var i = 0;
1120            for (; i < currentLen; i++) {
1121                if (!newArgSets[i]) { // one of the old sets no longer exists
1122                    if (teardownFunc) {
1123                        teardownFunc(currentResults[i]);
1124                    }
1125                }
1126                else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) {
1127                    if (teardownFunc) {
1128                        teardownFunc(currentResults[i]);
1129                    }
1130                    var res = workerFunc.apply(this, newArgSets[i]);
1131                    if (!resEquality || !resEquality(res, currentResults[i])) {
1132                        currentResults[i] = res;
1133                    }
1134                }
1135            }
1136            for (; i < newLen; i++) {
1137                currentResults[i] = workerFunc.apply(this, newArgSets[i]);
1138            }
1139            currentArgSets = newArgSets;
1140            currentResults.splice(newLen); // remove excess
1141            return currentResults;
1142        };
1143    }
1144    function memoizeHashlike(// used?
1145    workerFunc, resEquality, teardownFunc // TODO: change arg order
1146    ) {
1147        var currentArgHash = {};
1148        var currentResHash = {};
1149        return function (newArgHash) {
1150            var newResHash = {};
1151            for (var key in newArgHash) {
1152                if (!currentResHash[key]) {
1153                    newResHash[key] = workerFunc.apply(this, newArgHash[key]);
1154                }
1155                else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) {
1156                    if (teardownFunc) {
1157                        teardownFunc(currentResHash[key]);
1158                    }
1159                    var res = workerFunc.apply(this, newArgHash[key]);
1160                    newResHash[key] = (resEquality && resEquality(res, currentResHash[key]))
1161                        ? currentResHash[key]
1162                        : res;
1163                }
1164                else {
1165                    newResHash[key] = currentResHash[key];
1166                }
1167            }
1168            currentArgHash = newArgHash;
1169            currentResHash = newResHash;
1170            return newResHash;
1171        };
1172    }
1173
1174    var EXTENDED_SETTINGS_AND_SEVERITIES = {
1175        week: 3,
1176        separator: 0,
1177        omitZeroMinute: 0,
1178        meridiem: 0,
1179        omitCommas: 0
1180    };
1181    var STANDARD_DATE_PROP_SEVERITIES = {
1182        timeZoneName: 7,
1183        era: 6,
1184        year: 5,
1185        month: 4,
1186        day: 2,
1187        weekday: 2,
1188        hour: 1,
1189        minute: 1,
1190        second: 1
1191    };
1192    var MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
1192 // eats up leading spaces too
1193    var COMMA_RE = /,/g; // we need re for globalness
1194    var MULTI_SPACE_RE = /\s+/g;
1195    var LTR_RE = /\u200e/g; // control character
1196    var UTC_RE = /UTC|GMT/;
1197    var NativeFormatter = /** @class */ (function () {
1198        function NativeFormatter(formatSettings) {
1199            var standardDateProps = {};
1200            var extendedSettings = {};
1201            var severity = 0;
1202            for (var name_1 in formatSettings) {
1203                if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
1204                    extendedSettings[name_1] = formatSettings[name_1];
1205                    severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
1206                }
1207                else {
1208                    standardDateProps[name_1] = formatSettings[name_1];
1209                    if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity
1210                        severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
1211                    }
1212                }
1213            }
1214            this.standardDateProps = standardDateProps;
1215            this.extendedSettings = extendedSettings;
1216            this.severity = severity;
1217            this.buildFormattingFunc = memoize(buildFormattingFunc);
1218        }
1219        NativeFormatter.prototype.format = function (date, context) {
1220            return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
1221        };
1222        NativeFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1223            var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
1224            var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
1225            if (!diffSeverity) {
1226                return this.format(start, context);
1227            }
1228            var biggestUnitForPartial = diffSeverity;
1229            if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
1230                (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
1231                (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
1232                (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
1233                biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
1234            }
1235            var full0 = this.format(start, context);
1236            var full1 = this.format(end, context);
1237            if (full0 === full1) {
1238                return full0;
1239            }
1240            var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
1241            var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
1242            var partial0 = partialFormattingFunc(start);
1243            var partial1 = partialFormattingFunc(end);
1244            var insertion = findCommonInsertion(full0, partial0, full1, partial1);
1245            var separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || '';
1246            if (insertion) {
1247                return insertion.before + partial0 + separator + partial1 + insertion.after;
1248            }
1249            return full0 + separator + full1;
1250        };
1251        NativeFormatter.prototype.getLargestUnit = function () {
1252            switch (this.severity) {
1253                case 7:
1254                case 6:
1255                case 5:
1256                    return 'year';
1257                case 4:
1258                    return 'month';
1259                case 3:
1260                    return 'week';
1261                case 2:
1262                    return 'day';
1263                default:
1264                    return 'time'; // really?
1265            }
1266        };
1267        return NativeFormatter;
1268    }());
1269    function buildFormattingFunc(standardDateProps, extendedSettings, context) {
1270        var standardDatePropCnt = Object.keys(standardDateProps).length;
1271        if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
1272            return function (date) {
1273                return formatTimeZoneOffset(date.timeZoneOffset);
1274            };
1275        }
1276        if (standardDatePropCnt === 0 && extendedSettings.week) {
1277            return function (date) {
1278                return formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.locale, extendedSettings.week);
1279            };
1280        }
1281        return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
1282    }
1283    function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
1284        standardDateProps = __assign({}, standardDateProps); // copy
1285        extendedSettings = __assign({}, extendedSettings); // copy
1286        sanitizeSettings(standardDateProps, extendedSettings);
1287        standardDateProps.timeZone = 'UTC';
1287 // we leverage the only guaranteed timeZone for our UTC markers
1288        var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
1289        var zeroFormat; // needed?
1290        if (extendedSettings.omitZeroMinute) {
1291            var zeroProps = __assign({}, standardDateProps);
1292            delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
1293            zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
1294        }
1295        return function (date) {
1296            var marker = date.marker;
1297            var format;
1298            if (zeroFormat && !marker.getUTCMinutes()) {
1299                format = zeroFormat;
1300            }
1301            else {
1302                format = normalFormat;
1303            }
1304            var s = format.format(marker);
1305            return postProcess(s, date, standardDateProps, extendedSettings, context);
1306        };
1307    }
1308    function sanitizeSettings(standardDateProps, extendedSettings) {
1309        // deal with a browser inconsistency where formatting the timezone
1310        // requires that the hour/minute be present.
1311        if (standardDateProps.timeZoneName) {
1312            if (!standardDateProps.hour) {
1313                standardDateProps.hour = '2-digit';
1314            }
1315            if (!standardDateProps.minute) {
1316                standardDateProps.minute = '2-digit';
1317            }
1318        }
1319        // only support short timezone names
1320        if (standardDateProps.timeZoneName === 'long') {
1321            standardDateProps.timeZoneName = 'short';
1322        }
1323        // if requesting to display seconds, MUST display minutes
1324        if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
1325            delete extendedSettings.omitZeroMinute;
1326        }
1327    }
1328    function postProcess(s, date, standardDateProps, extendedSettings, context) {
1329        s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
1330        if (standardDateProps.timeZoneName === 'short') {
1331            s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
1332                'UTC' : // important to normalize for IE, which does "GMT"
1333                formatTimeZoneOffset(date.timeZoneOffset));
1334        }
1335        if (extendedSettings.omitCommas) {
1336            s = s.replace(COMMA_RE, '').trim();
1337        }
1338        if (extendedSettings.omitZeroMinute) {
1339            s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
1340        }
1341        // ^ do anything that might create adjacent spaces before this point,
1342        // because MERIDIEM_RE likes to eat up loading spaces
1343        if (extendedSettings.meridiem === false) {
1344            s = s.replace(MERIDIEM_RE, '').trim();
1345        }
1346        else if (extendedSettings.meridiem === 'narrow') { // a/p
1347            s = s.replace(MERIDIEM_RE, function (m0, m1) {
1348                return m1.toLocaleLowerCase();
1349            });
1350        }
1351        else if (extendedSettings.meridiem === 'short') { // am/pm
1352            s = s.replace(MERIDIEM_RE, function (m0, m1) {
1353                return m1.toLocaleLowerCase() + 'm';
1354            });
1355        }
1356        else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
1357            s = s.replace(MERIDIEM_RE, function (m0) {
1358                return m0.toLocaleLowerCase();
1359            });
1360        }
1361        s = s.replace(MULTI_SPACE_RE, ' ');
1362        s = s.trim();
1363        return s;
1364    }
1365    function injectTzoStr(s, tzoStr) {
1366        var replaced = false;
1367        s = s.replace(UTC_RE, function () {
1368            replaced = true;
1369            return tzoStr;
1370        });
1371        // IE11 doesn't include UTC/GMT in the original string, so append to end
1372        if (!replaced) {
1373            s += ' ' + tzoStr;
1374        }
1375        return s;
1376    }
1377    function formatWeekNumber(num, weekText, locale, display) {
1378        var parts = [];
1379        if (display === 'narrow') {
1380            parts.push(weekText);
1381        }
1382        else if (display === 'short') {
1383            parts.push(weekText, ' ');
1384        }
1385        // otherwise, considered 'numeric'
1386        parts.push(locale.simpleNumberFormat.format(num));
1387        if (locale.options.direction === 'rtl') { // TODO: use control characters instead?
1388            parts.reverse();
1389        }
1390        return parts.join('');
1391    }
1392    // Range Formatting Utils
1393    // 0 = exactly the same
1394    // 1 = different by time
1395    // and bigger
1396    function computeMarkerDiffSeverity(d0, d1, ca) {
1397        if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
1398            return 5;
1399        }
1400        if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
1401            return 4;
1402        }
1403        if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
1404            return 2;
1405        }
1406        if (timeAsMs(d0) !== timeAsMs(d1)) {
1407            return 1;
1408        }
1409        return 0;
1410    }
1411    function computePartialFormattingOptions(options, biggestUnit) {
1412        var partialOptions = {};
1413        for (var name_2 in options) {
1414            if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
1415                STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
1416                partialOptions[name_2] = options[name_2];
1417            }
1418        }
1419        return partialOptions;
1420    }
1421    function findCommonInsertion(full0, partial0, full1, partial1) {
1422        var i0 = 0;
1423        while (i0 < full0.length) {
1424            var found0 = full0.indexOf(partial0, i0);
1425            if (found0 === -1) {
1426                break;
1427            }
1428            var before0 = full0.substr(0, found0);
1429            i0 = found0 + partial0.length;
1430            var after0 = full0.substr(i0);
1431            var i1 = 0;
1432            while (i1 < full1.length) {
1433                var found1 = full1.indexOf(partial1, i1);
1434                if (found1 === -1) {
1435                    break;
1436                }
1437                var before1 = full1.substr(0, found1);
1438                i1 = found1 + partial1.length;
1439                var after1 = full1.substr(i1);
1440                if (before0 === before1 && after0 === after1) {
1441                    return {
1442                        before: before0,
1443                        after: after0
1444                    };
1445                }
1446            }
1447        }
1448        return null;
1449    }
1450
1451    function expandZonedMarker(dateInfo, calendarSystem) {
1452        var a = calendarSystem.markerToArray(dateInfo.marker);
1453        return {
1454            marker: dateInfo.marker,
1455            timeZoneOffset: dateInfo.timeZoneOffset,
1456            array: a,
1457            year: a[0],
1458            month: a[1],
1459            day: a[2],
1460            hour: a[3],
1461            minute: a[4],
1462            second: a[5],
1463            millisecond: a[6]
1464        };
1465    }
1466
1467    function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
1468        var startInfo = expandZonedMarker(start, context.calendarSystem);
1469        var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
1470        return {
1471            date: startInfo,
1472            start: startInfo,
1473            end: endInfo,
1474            timeZone: context.timeZone,
1475            localeCodes: context.locale.codes,
1476            defaultSeparator: betterDefaultSeparator || context.defaultSeparator
1477        };
1478    }
1479
1480    /*
1481    TODO: fix the terminology of "formatter" vs "formatting func"
1482    */
1483    /*
1484    At the time of instantiation, this object does not know which cmd-formatting system it will use.
1485    It receives this at the time of formatting, as a setting.
1486    */
1487    var CmdFormatter = /** @class */ (function () {
1488        function CmdFormatter(cmdStr) {
1489            this.cmdStr = cmdStr;
1490        }
1491        CmdFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
1492            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
1493        };
1494        CmdFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1495            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
1496        };
1497        return CmdFormatter;
1498    }());
1499
1500    var FuncFormatter = /** @class */ (function () {
1501        function FuncFormatter(func) {
1502            this.func = func;
1503        }
1504        FuncFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
1505            return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
1506        };
1507        FuncFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1508            return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
1509        };
1510        return FuncFormatter;
1511    }());
1512
1513    function createFormatter(input) {
1514        if (typeof input === 'object' && input) { // non-null object
1515            return new NativeFormatter(input);
1516        }
1517        else if (typeof input === 'string') {
1518            return new CmdFormatter(input);
1519        }
1520        else if (typeof input === 'function') {
1521            return new FuncFormatter(input);
1522        }
1523    }
1524
1525    // base options
1526    // ------------
1527    var BASE_OPTION_REFINERS = {
1528        navLinkDayClick: identity,
1529        navLinkWeekClick: identity,
1530        duration: createDuration,
1531        bootstrapFontAwesome: identity,
1532        buttonIcons: identity,
1533        customButtons: identity,
1534        defaultAllDayEventDuration: createDuration,
1535        defaultTimedEventDuration: createDuration,
1536        nextDayThreshold: createDuration,
1537        scrollTime: createDuration,
1538        slotMinTime: createDuration,
1539        slotMaxTime: createDuration,
1540        dayPopoverFormat: createFormatter,
1541        slotDuration: createDuration,
1542        snapDuration: createDuration,
1543        headerToolbar: identity,
1544        footerToolbar: identity,
1545        defaultRangeSeparator: String,
1546        titleRangeSeparator: String,
1547        forceEventDuration: Boolean,
1548        dayHeaders: Boolean,
1549        dayHeaderFormat: createFormatter,
1550        dayHeaderClassNames: identity,
1551        dayHeaderContent: identity,
1552        dayHeaderDidMount: identity,
1553        dayHeaderWillUnmount: identity,
1554        dayCellClassNames: identity,
1555        dayCellContent: identity,
1556        dayCellDidMount: identity,
1557        dayCellWillUnmount: identity,
1558        initialView: String,
1559        aspectRatio: Number,
1560        weekends: Boolean,
1561        weekNumberCalculation: identity,
1562        weekNumbers: Boolean,
1563        weekNumberClassNames: identity,
1564        weekNumberContent: identity,
1565        weekNumberDidMount: identity,
1566        weekNumberWillUnmount: identity,
1567        editable: Boolean,
1568        viewClassNames: identity,
1569        viewDidMount: identity,
1570        viewWillUnmount: identity,
1571        nowIndicator: Boolean,
1572        nowIndicatorClassNames: identity,
1573        nowIndicatorContent: identity,
1574        nowIndicatorDidMount: identity,
1575        nowIndicatorWillUnmount: identity,
1576        showNonCurrentDates: Boolean,
1577        lazyFetching: Boolean,
1578        startParam: String,
1579        endParam: String,
1580        timeZoneParam: String,
1581        timeZone: String,
1582        locales: identity,
1583        locale: identity,
1584        themeSystem: String,
1585        dragRevertDuration: Number,
1586        dragScroll: Boolean,
1587        allDayMaintainDuration: Boolean,
1588        unselectAuto: Boolean,
1589        dropAccept: identity,
1590        eventOrder: parseFieldSpecs,
1591        handleWindowResize: Boolean,
1592        windowResizeDelay: Number,
1593        longPressDelay: Number,
1594        eventDragMinDistance: Number,
1595        expandRows: Boolean,
1596        height: identity,
1597        contentHeight: identity,
1598        direction: String,
1599        weekNumberFormat: createFormatter,
1600        eventResizableFromStart: Boolean,
1601        displayEventTime: Boolean,
1602        displayEventEnd: Boolean,
1603        weekText: String,
1604        progressiveEventRendering: Boolean,
1605        businessHours: identity,
1606        initialDate: identity,
1607        now: identity,
1608        eventDataTransform: identity,
1609        stickyHeaderDates: identity,
1610        stickyFooterScrollbar: identity,
1611        viewHeight: identity,
1612        defaultAllDay: Boolean,
1613        eventSourceFailure: identity,
1614        eventSourceSuccess: identity,
1615        eventDisplay: String,
1616        eventStartEditable: Boolean,
1617        eventDurationEditable: Boolean,
1618        eventOverlap: identity,
1619        eventConstraint: identity,
1620        eventAllow: identity,
1621        eventBackgroundColor: String,
1622        eventBorderColor: String,
1623        eventTextColor: String,
1624        eventColor: String,
1625        eventClassNames: identity,
1626        eventContent: identity,
1627        eventDidMount: identity,
1628        eventWillUnmount: identity,
1629        selectConstraint: identity,
1630        selectOverlap: identity,
1631        selectAllow: identity,
1632        droppable: Boolean,
1633        unselectCancel: String,
1634        slotLabelFormat: identity,
1635        slotLaneClassNames: identity,
1636        slotLaneContent: identity,
1637        slotLaneDidMount: identity,
1638        slotLaneWillUnmount: identity,
1639        slotLabelClassNames: identity,
1640        slotLabelContent: identity,
1641        slotLabelDidMount: identity,
1642        slotLabelWillUnmount: identity,
1643        dayMaxEvents: identity,
1644        dayMaxEventRows: identity,
1645        dayMinWidth: Number,
1646        slotLabelInterval: createDuration,
1647        allDayText: String,
1648        allDayClassNames: identity,
1649        allDayContent: identity,
1650        allDayDidMount: identity,
1651        allDayWillUnmount: identity,
1652        slotMinWidth: Number,
1653        navLinks: Boolean,
1654        eventTimeFormat: createFormatter,
1655        rerenderDelay: Number,
1656        moreLinkText: identity,
1657        selectMinDistance: Number,
1658        selectable: Boolean,
1659        selectLongPressDelay: Number,
1660        eventLongPressDelay: Number,
1661        selectMirror: Boolean,
1662        eventMinHeight: Number,
1663        slotEventOverlap: Boolean,
1664        plugins: identity,
1665        firstDay: Number,
1666        dayCount: Number,
1667        dateAlignment: String,
1668        dateIncrement: createDuration,
1669        hiddenDays: identity,
1670        monthMode: Boolean,
1671        fixedWeekCount: Boolean,
1672        validRange: identity,
1673        visibleRange: identity,
1674        titleFormat: identity,
1675        // only used by list-view, but languages define the value, so we need it in base options
1676        noEventsText: String
1677    };
1678    // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results.
1679    // raw values.
1680    var BASE_OPTION_DEFAULTS = {
1681        eventDisplay: 'auto',
1682        defaultRangeSeparator: ' - ',
1683        titleRangeSeparator: ' \u2013 ',
1684        defaultTimedEventDuration: '01:00:00',
1685        defaultAllDayEventDuration: { day: 1 },
1686        forceEventDuration: false,
1687        nextDayThreshold: '00:00:00',
1688        dayHeaders: true,
1689        initialView: '',
1690        aspectRatio: 1.35,
1691        headerToolbar: {
1692            start: 'title',
1693            center: '',
1694            end: 'today prev,next'
1695        },
1696        weekends: true,
1697        weekNumbers: false,
1698        weekNumberCalculation: 'local',
1699        editable: false,
1700        nowIndicator: false,
1701        scrollTime: '06:00:00',
1702        slotMinTime: '00:00:00',
1703        slotMaxTime: '24:00:00',
1704        showNonCurrentDates: true,
1705        lazyFetching: true,
1706        startParam: 'start',
1707        endParam: 'end',
1708        timeZoneParam: 'timeZone',
1709        timeZone: 'local',
1710        locales: [],
1711        locale: '',
1712        themeSystem: 'standard',
1713        dragRevertDuration: 500,
1714        dragScroll: true,
1715        allDayMaintainDuration: false,
1716        unselectAuto: true,
1717        dropAccept: '*',
1718        eventOrder: 'start,-duration,allDay,title',
1719        dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
1720        handleWindowResize: true,
1721        windowResizeDelay: 100,
1722        longPressDelay: 1000,
1723        eventDragMinDistance: 5,
1724        expandRows: false,
1725        navLinks: false,
1726        selectable: false
1727    };
1728    // calendar listeners
1729    // ------------------
1730    var CALENDAR_LISTENER_REFINERS = {
1731        datesSet: identity,
1732        eventsSet: identity,
1733        eventAdd: identity,
1734        eventChange: identity,
1735        eventRemove: identity,
1736        windowResize: identity,
1737        eventClick: identity,
1738        eventMouseEnter: identity,
1739        eventMouseLeave: identity,
1740        select: identity,
1741        unselect: identity,
1742        loading: identity,
1743        // internal
1744        _unmount: identity,
1745        _beforeprint: identity,
1746        _afterprint: identity,
1747        _noEventDrop: identity,
1748        _noEventResize: identity,
1749        _resize: identity,
1750        _scrollRequest: identity
1751    };
1752    // calendar-specific options
1753    // -------------------------
1754    var CALENDAR_OPTION_REFINERS = {
1755        buttonText: identity,
1756        views: identity,
1757        plugins: identity,
1758        initialEvents: identity,
1759        events: identity,
1760        eventSources: identity
1761    };
1762    var COMPLEX_OPTION_COMPARATORS = {
1763        headerToolbar: isBoolComplexEqual,
1764        footerToolbar: isBoolComplexEqual,
1765        buttonText: isBoolComplexEqual,
1766        buttonIcons: isBoolComplexEqual
1767    };
1768    function isBoolComplexEqual(a, b) {
1769        if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects
1770            return isPropsEqual(a, b);
1771        }
1772        else {
1773            return a === b;
1774        }
1775    }
1776    // view-specific options
1777    // ---------------------
1778    var VIEW_OPTION_REFINERS = {
1779        type: String,
1780        component: identity,
1781        buttonText: String,
1782        buttonTextKey: String,
1783        dateProfileGeneratorClass: identity,
1784        usesMinMaxTime: Boolean,
1785        classNames: identity,
1786        content: identity,
1787        didMount: identity,
1788        willUnmount: identity
1789    };
1790    // util funcs
1791    // ----------------------------------------------------------------------------------------------------
1792    function mergeRawOptions(optionSets) {
1793        return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS);
1794    }
1795    function refineProps(input, refiners) {
1796        var refined = {};
1797        var extra = {};
1798        for (var propName in refiners) {
1799            if (propName in input) {
1800                refined[propName] = refiners[propName](input[propName]);
1801            }
1802        }
1803        for (var propName in input) {
1804            if (!(propName in refiners)) {
1805                extra[propName] = input[propName];
1806            }
1807        }
1808        return { refined: refined, extra: extra };
1809    }
1810    function identity(raw) {
1811        return raw;
1812    }
1813
1814    function parseEvents(rawEvents, eventSource, context, allowOpenRange) {
1815        var eventStore = createEmptyEventStore();
1816        var eventRefiners = buildEventRefiners(context);
1817        for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
1818            var rawEvent = rawEvents_1[_i];
1819            var tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners);
1820            if (tuple) {
1821                eventTupleToStore(tuple, eventStore);
1822            }
1823        }
1824        return eventStore;
1825    }
1826    function eventTupleToStore(tuple, eventStore) {
1827        if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
1828        eventStore.defs[tuple.def.defId] = tuple.def;
1829        if (tuple.instance) {
1830            eventStore.instances[tuple.instance.instanceId] = tuple.instance;
1831        }
1832        return eventStore;
1833    }
1834    // retrieves events that have the same groupId as the instance specified by `instanceId`
1835    // or they are the same as the instance.
1836    // why might instanceId not be in the store? an event from another calendar?
1837    function getRelevantEvents(eventStore, instanceId) {
1838        var instance = eventStore.instances[instanceId];
1839        if (instance) {
1840            var def_1 = eventStore.defs[instance.defId];
1841            // get events/instances with same group
1842            var newStore = filterEventStoreDefs(eventStore, function (lookDef) {
1843                return isEventDefsGrouped(def_1, lookDef);
1844            });
1845            // add the original
1846            // TODO: wish we could use eventTupleToStore or something like it
1847            newStore.defs[def_1.defId] = def_1;
1848            newStore.instances[instance.instanceId] = instance;
1849            return newStore;
1850        }
1851        return createEmptyEventStore();
1852    }
1853    function isEventDefsGrouped(def0, def1) {
1854        return Boolean(def0.groupId && def0.groupId === def1.groupId);
1855    }
1856    function createEmptyEventStore() {
1857        return { defs: {}, instances: {} };
1858    }
1859    function mergeEventStores(store0, store1) {
1860        return {
1861            defs: __assign(__assign({}, store0.defs), store1.defs),
1862            instances: __assign(__assign({}, store0.instances), store1.instances)
1863        };
1864    }
1865    function filterEventStoreDefs(eventStore, filterFunc) {
1866        var defs = filterHash(eventStore.defs, filterFunc);
1867        var instances = filterHash(eventStore.instances, function (instance) {
1868            return defs[instance.defId]; // still exists?
1869        });
1870        return { defs: defs, instances: instances };
1871    }
1872    function excludeSubEventStore(master, sub) {
1873        var defs = master.defs, instances = master.instances;
1874        var filteredDefs = {};
1875        var filteredInstances = {};
1876        for (var defId in defs) {
1877            if (!sub.defs[defId]) { // not explicitly excluded
1878                filteredDefs[defId] = defs[defId];
1879            }
1880        }
1881        for (var instanceId in instances) {
1882            if (!sub.instances[instanceId] && // not explicitly excluded
1883                filteredDefs[instances[instanceId].defId] // def wasn't filtered away
1884            ) {
1885                filteredInstances[instanceId] = instances[instanceId];
1886            }
1887        }
1888        return {
1889            defs: filteredDefs,
1890            instances: filteredInstances
1891        };
1892    }
1893
1894    function normalizeConstraint(input, context) {
1895        if (Array.isArray(input)) {
1896            return parseEvents(input, null, context, true); // allowOpenRange=true
1897        }
1898        else if (typeof input === 'object' && input) { // non-null object
1899            return parseEvents([input], null, context, true); // allowOpenRange=true
1900        }
1901        else if (input != null) {
1902            return String(input);
1903        }
1904        else {
1905            return null;
1906        }
1907    }
1908
1909    function parseClassNames(raw) {
1910        if (Array.isArray(raw)) {
1911            return raw;
1912        }
1913        else if (typeof raw === 'string') {
1914            return raw.split(/\s+/);
1915        }
1916        else {
1917            return [];
1918        }
1919    }
1920
1921    // TODO: better called "EventSettings" or "EventConfig"
1922    // TODO: move this file into structs
1923    // TODO: separate constraint/overlap/allow, because selection uses only that, not other props
1924    var EVENT_UI_REFINERS = {
1925        display: String,
1926        editable: Boolean,
1927        startEditable: Boolean,
1928        durationEditable: Boolean,
1929        constraint: identity,
1930        overlap: identity,
1931        allow: identity,
1932        className: parseClassNames,
1933        classNames: parseClassNames,
1934        color: String,
1935        backgroundColor: String,
1936        borderColor: String,
1937        textColor: String
1938    };
1939    function createEventUi(refined, context) {
1940        var constraint = normalizeConstraint(refined.constraint, context);
1941        return {
1942            display: refined.display || null,
1943            startEditable: refined.startEditable != null ? refined.startEditable : refined.editable,
1944            durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable,
1945            constraints: constraint != null ? [constraint] : [],
1946            overlap: refined.overlap != null ? refined.overlap : null,
1947            allows: refined.allow != null ? [refined.allow] : [],
1948            backgroundColor: refined.backgroundColor || refined.color || '',
1949            borderColor: refined.borderColor || refined.color || '',
1950            textColor: refined.textColor || '',
1951            classNames: (refined.className || []).concat(refined.classNames || []) // join singular and plural
1952        };
1953    }
1954    // TODO: prevent against problems with <2 args!
1955    function combineEventUis(uis) {
1956        return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
1957    }
1958    function combineTwoEventUis(item0, item1) {
1959        return {
1960            display: item1.display != null ? item1.display : item0.display,
1961            startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
1962            durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
1963            constraints: item0.constraints.concat(item1.constraints),
1964            overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
1965            allows: item0.allows.concat(item1.allows),
1966            backgroundColor: item1.backgroundColor || item0.backgroundColor,
1967            borderColor: item1.borderColor || item0.borderColor,
1968            textColor: item1.textColor || item0.textColor,
1969            classNames: item0.classNames.concat(item1.classNames)
1970        };
1971    }
1972    var EMPTY_EVENT_UI = {
1973        display: null,
1974        startEditable: null,
1975        durationEditable: null,
1976        constraints: [],
1977        overlap: null,
1978        allows: [],
1979        backgroundColor: '',
1980        borderColor: '',
1981        textColor: '',
1982        classNames: []
1983    };
1984
1985    var EVENT_NON_DATE_REFINERS = {
1986        id: String,
1987        groupId: String,
1988        title: String,
1989        url: String
1990    };
1991    var EVENT_DATE_REFINERS = {
1992        start: identity,
1993        end: identity,
1994        date: identity,
1995        allDay: Boolean
1996    };
1997    var EVENT_REFINERS = __assign(__assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity });
1998    function parseEvent(raw, eventSource, context, allowOpenRange, refiners) {
1999        if (refiners === void 0) { refiners = buildEventRefiners(context); }
2000        var _a = refineEventDef(raw, context, refiners), refined 
2000= _a.refined, extra = _a.extra;
2001        var defaultAllDay = computeIsDefaultAllDay(eventSource, context);
2002        var recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes);
2003        if (recurringRes) {
2004            var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context);
2005            def.recurringDef = {
2006                typeId: recurringRes.typeId,
2007                typeData: recurringRes.typeData,
2008                duration: recurringRes.duration
2009            };
2010            return { def: def, instance: null };
2011        }
2012        else {
2013            var singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange);
2014            if (singleRes) {
2015                var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context);
2016                var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
2017                return { def: def, instance: instance };
2018            }
2019        }
2020        return null;
2021    }
2022    function refineEventDef(raw, context, refiners) {
2023        if (refiners === void 0) { refiners = buildEventRefiners(context); }
2024        return refineProps(raw, refiners);
2025    }
2026    function buildEventRefiners(context) {
2027        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners);
2028    }
2029    /*
2030    Will NOT populate extendedProps with the leftover properties.
2031    Will NOT populate date-related props.
2032    */
2033    function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) {
2034        var def = {
2035            title: refined.title || '',
2036            groupId: refined.groupId || '',
2037            publicId: refined.id || '',
2038            url: refined.url || '',
2039            recurringDef: null,
2040            defId: guid(),
2041            sourceId: sourceId,
2042            allDay: allDay,
2043            hasEnd: hasEnd,
2044            ui: createEventUi(refined, context),
2045            extendedProps: __assign(__assign({}, (refined.extendedProps || {})), extra)
2046        };
2047        for (var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; _i < _a.length; _i++) {
2048            var memberAdder = _a[_i];
2049            __assign(def, memberAdder(refined));
2050        }
2051        // help out EventApi from having user modify props
2052        Object.freeze(def.ui.classNames);
2053        Object.freeze(def.extendedProps);
2054        return def;
2055    }
2056    function parseSingle(refined, defaultAllDay, context, allowOpenRange) {
2057        var allDay = refined.allDay;
2058        var startMeta;
2059        var startMarker = null;
2060        var hasEnd = false;
2061        var endMeta;
2062        var endMarker = null;
2063        var startInput = refined.start != null ? refined.start : refined.date;
2064        startMeta = context.dateEnv.createMarkerMeta(startInput);
2065        if (startMeta) {
2066            startMarker = startMeta.marker;
2067        }
2068        else if (!allowOpenRange) {
2069            return null;
2070        }
2071        if (refined.end != null) {
2072            endMeta = context.dateEnv.createMarkerMeta(refined.end);
2073        }
2074        if (allDay == null) {
2075            if (defaultAllDay != null) {
2076                allDay = defaultAllDay;
2077            }
2078            else {
2079                // fall back to the date props LAST
2080                allDay = (!startMeta || startMeta.isTimeUnspecified) &&
2081                    (!endMeta || endMeta.isTimeUnspecified);
2082            }
2083        }
2084        if (allDay && startMarker) {
2085            startMarker = startOfDay(startMarker);
2086        }
2087        if (endMeta) {
2088            endMarker = endMeta.marker;
2089            if (allDay) {
2090                endMarker = startOfDay(endMarker);
2091            }
2092            if (startMarker && endMarker <= startMarker) {
2093                endMarker = null;
2094            }
2095        }
2096        if (endMarker) {
2097            hasEnd = true;
2098        }
2099        else if (!allowOpenRange) {
2100            hasEnd = context.options.forceEventDuration || false;
2101            endMarker = context.dateEnv.add(startMarker, allDay ?
2102                context.options.defaultAllDayEventDuration :
2103                context.options.defaultTimedEventDuration);
2104        }
2105        return {
2106            allDay: allDay,
2107            hasEnd: hasEnd,
2108            range: { start: startMarker, end: endMarker },
2109            forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
2110            forcedEndTzo: endMeta ? endMeta.forcedTzo : null
2111        };
2112    }
2113    function computeIsDefaultAllDay(eventSource, context) {
2114        var res = null;
2115        if (eventSource) {
2116            res = eventSource.defaultAllDay;
2117        }
2118        if (res == null) {
2119            res = context.options.defaultAllDay;
2120        }
2121        return res;
2122    }
2123
2124    /* Date stuff that doesn't belong in datelib core
2125    ----------------------------------------------------------------------------------------------------------------------*/
2126    // given a timed range, computes an all-day range that has the same exact duration,
2127    // but whose start time is aligned with the start of the day.
2128    function computeAlignedDayRange(timedRange) {
2129        var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
2130        var start = startOfDay(timedRange.start);
2131        var end = addDays(start, dayCnt);
2132        return { start: start, end: end };
2133    }
2134    // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
2135    // TODO: give nextDayThreshold a default arg
2136    function computeVisibleDayRange(timedRange, nextDayThreshold) {
2137        if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
2138        var startDay = null;
2139        var endDay = null;
2140        if (timedRange.end) {
2141            endDay = startOfDay(timedRange.end);
2142            var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
2143            // If the end time is actually inclusively part of the next day and is equal to or
vendor: 15,865 bytes, lines 2144-2533
2144            // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
2145            // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
2146            if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
2147                endDay = addDays(endDay, 1);
2148            }
2149        }
2150        if (timedRange.start) {
2151            startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
2152            // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
2153            if (endDay && endDay <= startDay) {
2154                endDay = addDays(startDay, 1);
2155            }
2156        }
2157        return { start: startDay, end: endDay };
2158    }
2159    // spans from one day into another?
2160    function isMultiDayRange(range) {
2161        var visibleRange = computeVisibleDayRange(range);
2162        return diffDays(visibleRange.start, visibleRange.end) > 1;
2163    }
2164    function diffDates(date0, date1, dateEnv, largeUnit) {
2165        if (largeUnit === 'year') {
2166            return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
2167        }
2168        else if (largeUnit === 'month') {
2169            return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
2170        }
2171        else {
2172            return diffDayAndTime(date0, date1); // returns a duration
2173        }
2174    }
2175
2176    function parseRange(input, dateEnv) {
2177        var start = null;
2178        var end = null;
2179        if (input.start) {
2180            start = dateEnv.createMarker(input.start);
2181        }
2182        if (input.end) {
2183            end = dateEnv.createMarker(input.end);
2184        }
2185        if (!start && !end) {
2186            return null;
2187        }
2188        if (start && end && end < start) {
2189            return null;
2190        }
2191        return { start: start, end: end };
2192    }
2193    // SIDE-EFFECT: will mutate ranges.
2194    // Will return a new array result.
2195    function invertRanges(ranges, constraintRange) {
2196        var invertedRanges = [];
2197        var start = constraintRange.start; // the end of the previous range. the start of the new range
2198        var i;
2199        var dateRange;
2200        // ranges need to be in order. required for our date-walking algorithm
2201        ranges.sort(compareRanges);
2202        for (i = 0; i < ranges.length; i++) {
2203            dateRange = ranges[i];
2204            // add the span of time before the event (if there is any)
2205            if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
2206                invertedRanges.push({ start: start, end: dateRange.start });
2207            }
2208            if (dateRange.end > start) {
2209                start = dateRange.end;
2210            }
2211        }
2212        // add the span of time after the last event (if there is any)
2213        if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
2214            invertedRanges.push({ start: start, end: constraintRange.end });
2215        }
2216        return invertedRanges;
2217    }
2218    function compareRanges(range0, range1) {
2219        return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
2220    }
2221    function intersectRanges(range0, range1) {
2222        var start = range0.start;
2223        var end = range0.end;
2224        var newRange = null;
2225        if (range1.start !== null) {
2226            if (start === null) {
2227                start = range1.start;
2228            }
2229            else {
2230                start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
2231            }
2232        }
2233        if (range1.end != null) {
2234            if (end === null) {
2235                end = range1.end;
2236            }
2237            else {
2238                end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
2239            }
2240        }
2241        if (start === null || end === null || start < end) {
2242            newRange = { start: start, end: end };
2243        }
2244        return newRange;
2245    }
2246    function rangesEqual(range0, range1) {
2247        return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
2248            (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
2249    }
2250    function rangesIntersect(range0, range1) {
2251        return (range0.end === null || range1.start === null || range0.end > range1.start) &&
2252            (range0.start === null || range1.end === null || range0.start < range1.end);
2253    }
2254    function rangeContainsRange(outerRange, innerRange) {
2255        return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
2256            (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
2257    }
2258    function rangeContainsMarker(range, date) {
2259        return (range.start === null || date >= range.start) &&
2260            (range.end === null || date < range.end);
2261    }
2262    // If the given date is not within the given range, move it inside.
2263    // (If it's past the end, make it one millisecond before the end).
2264    function constrainMarkerToRange(date, range) {
2265        if (range.start != null && date < range.start) {
2266            return range.start;
2267        }
2268        if (range.end != null && date >= range.end) {
2269            return new Date(range.end.valueOf() - 1);
2270        }
2271        return date;
2272    }
2273
2274    /*
2275    Specifying nextDayThreshold signals that all-day ranges should be sliced.
2276    */
2277    function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
2278        var inverseBgByGroupId = {};
2279        var inverseBgByDefId = {};
2280        var defByGroupId = {};
2281        var bgRanges = [];
2282        var fgRanges = [];
2283        var eventUis = compileEventUis(eventStore.defs, eventUiBases);
2284        for (var defId in eventStore.defs) {
2285            var def = eventStore.defs[defId];
2286            var ui = eventUis[def.defId];
2287            if (ui.display === 'inverse-background') {
2288                if (def.groupId) {
2289                    inverseBgByGroupId[def.groupId] = [];
2290                    if (!defByGroupId[def.groupId]) {
2291                        defByGroupId[def.groupId] = def;
2292                    }
2293                }
2294                else {
2295                    inverseBgByDefId[defId] = [];
2296                }
2297            }
2298        }
2299        for (var instanceId in eventStore.instances) {
2300            var instance = eventStore.instances[instanceId];
2301            var def = eventStore.defs[instance.defId];
2302            var ui = eventUis[def.defId];
2303            var origRange = instance.range;
2304            var normalRange = (!def.allDay && nextDayThreshold) ?
2305                computeVisibleDayRange(origRange, nextDayThreshold) :
2306                origRange;
2307            var slicedRange = intersectRanges(normalRange, framingRange);
2308            if (slicedRange) {
2309                if (ui.display === 'inverse-background') {
2310                    if (def.groupId) {
2311                        inverseBgByGroupId[def.groupId].push(slicedRange);
2312                    }
2313                    else {
2314                        inverseBgByDefId[instance.defId].push(slicedRange);
2315                    }
2316                }
2317                else if (ui.display !== 'none') {
2318                    (ui.display === 'background' ? bgRanges : fgRanges).push({
2319                        def: def,
2320                        ui: ui,
2321                        instance: instance,
2322                        range: slicedRange,
2323                        isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
2324                        isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf()
2325                    });
2326                }
2327            }
2328        }
2329        for (var groupId in inverseBgByGroupId) { // BY GROUP
2330            var ranges = inverseBgByGroupId[groupId];
2331            var invertedRanges = invertRanges(ranges, framingRange);
2332            for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
2333                var invertedRange = invertedRanges_1[_i];
2334                var def = defByGroupId[groupId];
2335                var ui = eventUis[def.defId];
2336                bgRanges.push({
2337                    def: def,
2338                    ui: ui,
2339                    instance: null,
2340                    range: invertedRange,
2341                    isStart: false,
2342                    isEnd: false
2343                });
2344            }
2345        }
2346        for (var defId in inverseBgByDefId) {
2347            var ranges = inverseBgByDefId[defId];
2348            var invertedRanges = invertRanges(ranges, framingRange);
2349            for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
2350                var invertedRange = invertedRanges_2[_a];
2351                bgRanges.push({
2352                    def: eventStore.defs[defId],
2353                    ui: eventUis[defId],
2354                    instance: null,
2355                    range: invertedRange,
2356                    isStart: false,
2357                    isEnd: false
2358                });
2359            }
2360        }
2361        return { bg: bgRanges, fg: fgRanges };
2362    }
2363    function hasBgRendering(def) {
2364        return def.ui.display === 'background' || def.ui.display === 'inverse-background';
2365    }
2366    function setElSeg(el, seg) {
2367        el.fcSeg = seg;
2368    }
2369    function getElSeg(el) {
2370        return el.fcSeg ||
2371            el.parentNode.fcSeg || // for the harness
2372            null;
2373    }
2374    // event ui computation
2375    function compileEventUis(eventDefs, eventUiBases) {
2376        return mapHash(eventDefs, function (eventDef) {
2377            return compileEventUi(eventDef, eventUiBases);
2378        });
2379    }
2380    function compileEventUi(eventDef, eventUiBases) {
2381        var uis = [];
2382        if (eventUiBases['']) {
2383            uis.push(eventUiBases['']);
2384        }
2385        if (eventUiBases[eventDef.defId]) {
2386            uis.push(eventUiBases[eventDef.defId]);
2387        }
2388        uis.push(eventDef.ui);
2389        return combineEventUis(uis);
2390    }
2391    function sortEventSegs(segs, eventOrderSpecs) {
2392        var objs = segs.map(buildSegCompareObj);
2393        objs.sort(function (obj0, obj1) {
2394            return compareByFieldSpecs(obj0, obj1, eventOrderSpecs);
2395        });
2396        return objs.map(function (c) {
2397            return c._seg;
2398        });
2399    }
2400    // returns a object with all primitive props that can be compared
2401    function buildSegCompareObj(seg) {
2402        var eventRange = seg.eventRange;
2403        var eventDef = eventRange.def;
2404        var range = eventRange.instance ? eventRange.instance.range : eventRange.range;
2405        var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
2406        var end = range.end ? range.end.valueOf() : 0; // "
2407        return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start: start,
2408            end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg // for later retrieval
2409         });
2410    }
2411    function computeSegDraggable(seg, context) {
2412        var pluginHooks = context.pluginHooks;
2413        var transformers = pluginHooks.isDraggableTransformers;
2414        var _a = seg.eventRange, def = _a.def, ui = _a.ui;
2415        var val = ui.startEditable;
2416        for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
2417            var transformer = transformers_1[_i];
2418            val = transformer(val, def, ui, context);
2419        }
2420        return val;
2421    }
2422    function computeSegStartResizable(seg, context) {
2423        return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart;
2424    }
2425    function computeSegEndResizable(seg, context) {
2426        return seg.isEnd && seg.eventRange.ui.durationEditable;
2427    }
2428    function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true
2429    defaultDisplayEventEnd, // defaults to true
2430    startOverride, endOverride) {
2431        var dateEnv = context.dateEnv, options = context.options;
2432        var displayEventTime = options.displayEventTime, displayEventEnd = options.displayEventEnd;
2433        var eventDef = seg.eventRange.def;
2434        var eventInstance = seg.eventRange.instance;
2435        if (displayEventTime == null) {
2436            displayEventTime = defaultDisplayEventTime !== false;
2437        }
2438        if (displayEventEnd == null) {
2439            displayEventEnd = defaultDisplayEventEnd !== false;
2440        }
2441        if (displayEventTime && !eventDef.allDay && (seg.isStart || seg.isEnd)) {
2442            var segStart = startOverride || (seg.isStart ? eventInstance.range.start : (seg.start || seg.eventRange.range.start));
2443            var segEnd = endOverride || (seg.isEnd ? eventInstance.range.end : (seg.end || seg.eventRange.range.end));
2444            if (displayEventEnd && eventDef.hasEnd) {
2445                return dateEnv.formatRange(segStart, segEnd, timeFormat, {
2446                    forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo,
2447                    forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo
2448                });
2449            }
2450            else {
2451                return dateEnv.format(segStart, timeFormat, {
2452                    forcedTzo: startOverride ? null : eventInstance.forcedStartTzo // nooooo, same
2453                });
2454            }
2455        }
2456        return '';
2457    }
2458    function getSegMeta(seg, todayRange, nowDate) {
2459        var segRange = seg.eventRange.range;
2460        return {
2461            isPast: segRange.end < (nowDate || todayRange.start),
2462            isFuture: segRange.start >= (nowDate || todayRange.end),
2463            isToday: todayRange && rangeContainsMarker(todayRange, segRange.start)
2464        };
2465    }
2466    function getEventClassNames(props) {
2467        var classNames = ['fc-event'];
2468        if (props.isMirror) {
2469            classNames.push('fc-event-mirror');
2470        }
2471        if (props.isDraggable) {
2472            classNames.push('fc-event-draggable');
2473        }
2474        if (props.isStartResizable || props.isEndResizable) {
2475            classNames.push('fc-event-resizable');
2476        }
2477        if (props.isDragging) {
2478            classNames.push('fc-event-dragging');
2479        }
2480        if (props.isResizing) {
2481            classNames.push('fc-event-resizing');
2482        }
2483        if (props.isSelected) {
2484            classNames.push('fc-event-selected');
2485        }
2486        if (props.isStart) {
2487            classNames.push('fc-event-start');
2488        }
2489        if (props.isEnd) {
2490            classNames.push('fc-event-end');
2491        }
2492        if (props.isPast) {
2493            classNames.push('fc-event-past');
2494        }
2495        if (props.isToday) {
2496            classNames.push('fc-event-today');
2497        }
2498        if (props.isFuture) {
2499            classNames.push('fc-event-future');
2500        }
2501        return classNames;
2502    }
2503    function buildEventRangeKey(eventRange) {
2504        return eventRange.instance
2505            ? eventRange.instance.instanceId
2506            : eventRange.def.defId + ':' + eventRange.range.start.toISOString();
2507        // inverse-background events don't have specific instances. TODO: better solution
2508    }
2509
2510    var STANDARD_PROPS = {
2511        start: identity,
2512        end: identity,
2513        allDay: Boolean
2514    };
2515    function parseDateSpan(raw, dateEnv, defaultDuration) {
2516        var span = parseOpenDateSpan(raw, dateEnv);
2517        var range = span.range;
2518        if (!range.start) {
2519            return null;
2520        }
2521        if (!range.end) {
2522            if (defaultDuration == null) {
2523                return null;
2524            }
2525            else {
2526                range.end = dateEnv.add(range.start, defaultDuration);
2527            }
2528        }
2529        return span;
2530    }
2531    /*
2532    TODO: somehow combine with parseRange?
2533    Will return null if the start/end props were present but parsed invali
2533dly.
2534    */
2535    function parseOpenDateSpan(raw, dateEnv) {
2536        var _a = refineProps(raw, STANDARD_PROPS), standardProps = _a.refined, extra = _a.extra;
2537        var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
2538        var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
2539        var allDay = standardProps.allDay;
2540        if (allDay == null) {
2541            allDay = (startMeta && startMeta.isTimeUnspecified) &&
2542                (!endMeta || endMeta.isTimeUnspecified);
2543        }
2544        return __assign({ range: {
2545                start: startMeta ? startMeta.marker : null,
2546                end: endMeta ? endMeta.marker : null,
2547            }, allDay: allDay }, extra);
2548    }
2549    function isDateSpansEqual(span0, span1) {
2550        return rangesEqual(span0.range, span1.range) &&
2551            span0.allDay === span1.allDay &&
2552            isSpanPropsEqual(span0, span1);
2553    }
2554    // the NON-DATE-RELATED props
2555    function isSpanPropsEqual(span0, span1) {
2556        for (var propName in span1) {
2557            if (propName !== 'range' && propName !== 'allDay') {
2558                if (span0[propName] !== span1[propName]) {
2559                    return false;
2560                }
2561            }
2562        }
2563        // are there any props that span0 has that span1 DOESN'T have?
2564        // both have range/allDay, so no need to special-case.
2565        for (var propName in span0) {
2566            if (!(propName in span1)) {
2567                return false;
2568            }
2569        }
2570        return true;
2571    }
2572    function buildDateSpanApi(span, dateEnv) {
2573        return __assign(__assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay });
2574    }
2575    function buildRangeApiWithTimeZone(range, dateEnv, omitTime) {
2576        return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone });
2577    }
2578    function buildRangeApi(range, dateEnv, omitTime) {
2579        return {
2580            start: dateEnv.toDate(range.start),
2581            end: dateEnv.toDate(range.end),
2582            startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }),
2583            endStr: dateEnv.formatIso(range.end, { omitTime: omitTime })
2584        };
2585    }
2586    function fabricateEventRange(dateSpan, eventUiBases, context) {
2587        var res = refineEventDef({ editable: false }, context);
2588        var def = parseEventDef(res.refined, res.extra, '', // sourceId
2589        dateSpan.allDay, true, // hasEnd
2590        context);
2591        return {
2592            def: def,
2593            ui: compileEventUi(def, eventUiBases),
2594            instance: createEventInstance(def.defId, dateSpan.range),
2595            range: dateSpan.range,
2596            isStart: true,
2597            isEnd: true
2598        };
2599    }
2600
2601    function triggerDateSelect(selection, pev, context) {
2602        context.emitter.trigger('select', __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view }));
2603    }
2604    function triggerDateUnselect(pev, context) {
2605        context.emitter.trigger('unselect', {
2606            jsEvent: pev ? pev.origEvent : null,
2607            view: context.viewApi || context.calendarApi.view
2608        });
2609    }
2610    function buildDateSpanApiWithContext(dateSpan, context) {
2611        var props = {};
2612        for (var _i = 0, _a = context.pluginHooks.dateSpanTransforms; _i < _a.length; _i++) {
2613            var transform = _a[_i];
2614            __assign(props, transform(dateSpan, context));
2615        }
2616        __assign(props, buildDateSpanApi(dateSpan, context.dateEnv));
2617        return props;
2618    }
2619    // Given an event's allDay status and start date, return what its fallback end date should be.
2620    // TODO: rename to computeDefaultEventEnd
2621    function getDefaultEventEnd(allDay, marker, context) {
2622        var dateEnv = context.dateEnv, options = context.options;
2623        var end = marker;
2624        if (allDay) {
2625            end = startOfDay(end);
2626            end = dateEnv.add(end, options.defaultAllDayEventDuration);
2627        }
2628        else {
2629            end = dateEnv.add(end, options.defaultTimedEventDuration);
2630        }
2631        return end;
2632    }
2633
2634    // applies the mutation to ALL defs/instances within the event store
2635    function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) {
2636        var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
2637        var dest = createEmptyEventStore();
2638        for (var defId in eventStore.defs) {
2639            var def = eventStore.defs[defId];
2640            dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context);
2641        }
2642        for (var instanceId in eventStore.instances) {
2643            var instance = eventStore.instances[instanceId];
2644            var def = dest.defs[instance.defId]; // important to grab the newly modified def
2645            dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context);
2646        }
2647        return dest;
2648    }
2649    function applyMutationToEventDef(eventDef, eventConfig, mutation, context) {
2650        var standardProps = mutation.standardProps || {};
2651        // if hasEnd has not been specified, guess a good value based on deltas.
2652        // if duration will change, there's no way the default duration will persist,
2653        // and thus, we need to mark the event as having a real end
2654        if (standardProps.hasEnd == null &&
2655            eventConfig.durationEditable &&
2656            (mutation.startDelta || mutation.endDelta)) {
2657            standardProps.hasEnd = true; // TODO: is this mutation okay?
2658        }
2659        var copy = __assign(__assign(__assign({}, eventDef), standardProps), { ui: __assign(__assign({}, eventDef.ui), standardProps.ui) });
2660        if (mutation.extendedProps) {
2661            copy.extendedProps = __assign(__assign({}, copy.extendedProps), mutation.extendedProps);
2662        }
2663        for (var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; _i < _a.length; _i++) {
2664            var applier = _a[_i];
2665            applier(copy, mutation, context);
2666        }
2667        if (!copy.hasEnd && context.options.forceEventDuration) {
2668            copy.hasEnd = true;
2669        }
2670        return copy;
2671    }
2672    function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
2673    eventConfig, mutation, context) {
2674        var dateEnv = context.dateEnv;
2675        var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
2676        var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
2677        var copy = __assign({}, eventInstance);
2678        if (forceAllDay) {
2679            copy.range = computeAlignedDayRange(copy.range);
2680        }
2681        if (mutation.datesDelta && eventConfig.startEditable) {
2682            copy.range = {
2683                start: dateEnv.add(copy.range.start, mutation.datesDelta),
2684                end: dateEnv.add(copy.range.end, mutation.datesDelta)
2685            };
2686        }
2687        if (mutation.startDelta && eventConfig.durationEditable) {
2688            copy.range = {
2689                start: dateEnv.add(copy.range.start, mutation.startDelta),
2690                end: copy.range.end
2691            };
2692        }
2693        if (mutation.endDelta && eventConfig.durationEditable) {
2694            copy.range = {
2695                start: copy.range.start,
2696                end: dateEnv.add(copy.range.end, mutation.endDelta)
2697            };
2698        }
2699        if (clearEnd) {
2700            copy.range = {
2701                start: copy.range.start,
2702                end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context)
2703            };
2704        }
2705        // in case event was all-day but the supplied deltas were not
2706        // better util for this?
2707        if (eventDef.allDay) {
2708            copy.range = {
2709                start: startOfDay(copy.range.start),
2710                end: startOfDay(copy.range.end)
2711            };
2712        }
2713        // handle invalid durations
2714        if (copy.range.end < copy.range.start) {
2715            copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context);
2716        }
2717        return copy;
2718    }
2719
2720    // no public types yet. when there are, export from:
2721    // import {} from './api-type-deps'
2722    var ViewApi = /** @class */ (function () {
2723        function ViewApi(type, getCurrentData, dateEnv) {
2724            this.type = type;
2725            this.getCurrentData = getCurrentData;
2726            this.dateEnv = dateEnv;
2727        }
2728        Object.defineProperty(ViewApi.prototype, "calendar", {
2729            get: function () {
2730                return this.getCurrentData().calendarApi;
2731            },
2732            enumerable: false,
2733            configurable: true
2734        });
2735        Object.defineProperty(ViewApi.prototype, "title", {
2736            get: function () {
2737                return this.getCurrentData().viewTitle;
2738            },
2739            enumerable: false,
2740            configurable: true
2741        });
2742        Object.defineProperty(ViewApi.prototype, "activeStart", {
2743            get: function () {
2744                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);
2745            },
2746            enumerable: false,
2747            configurable: true
2748        });
2749        Object.defineProperty(ViewApi.prototype, "activeEnd", {
2750            get: function () {
2751                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);
2752            },
2753            enumerable: false,
2754            configurable: true
2755        });
2756        Object.defineProperty(ViewApi.prototype, "currentStart", {
2757            get: function () {
2758                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);
2759            },
2760            enumerable: false,
2761            configurable: true
2762        });
2763        Object.defineProperty(ViewApi.prototype, "currentEnd", {
2764            get: function () {
2765                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);
2766            },
2767            enumerable: false,
2768            configurable: true
2769        });
2770        ViewApi.prototype.getOption = function (name) {
2771            return this.getCurrentData().options[name]; // are the view-specific options
2772        };
2773        return ViewApi;
2774    }());
2775
2776    var EVENT_SOURCE_REFINERS = {
2777        id: String,
2778        defaultAllDay: Boolean,
2779        url: String,
2780        events: identity,
2781        eventDataTransform: identity,
2782        // for any network-related sources
2783        success: identity,
2784        failure: identity,
2785    };
2786    function parseEventSource(raw, context, refiners) {
2787        if (refiners === void 0) { refiners = buildEventSourceRefiners(context); }
2788        var rawObj;
2789        if (typeof raw === 'string') {
2790            rawObj = { url: raw };
2791        }
2792        else if (typeof raw === 'function' || Array.isArray(raw)) {
2793            rawObj = { events: raw };
2794        }
2795        else if (typeof raw === 'object' && raw) { // not null
2796            rawObj = raw;
2797        }
2798        if (rawObj) {
2799            var _a = refineProps(rawObj, refiners), refined = _a.refined, extra = _a.extra;
2800            var metaRes = buildEventSourceMeta(refined, context);
2801            if (metaRes) {
2802                return {
2803                    _raw: raw,
2804                    isFetching: false,
2805                    latestFetchId: '',
2806                    fetchRange: null,
2807                    defaultAllDay: refined.defaultAllDay,
2808                    eventDataTransform: refined.eventDataTransform,
2809                    success: refined.success,
2810                    failure: refined.failure,
2811                    publicId: refined.id || '',
2812                    sourceId: guid(),
2813                    sourceDefId: metaRes.sourceDefId,
2814                    meta: metaRes.meta,
2815                    ui: createEventUi(refined, context),
2816                    extendedProps: extra
2817                };
2818            }
2819        }
2820        return null;
2821    }
2822    function buildEventSourceRefiners(context) {
2823        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS), context.pluginHooks.eventSourceRefiners);
2824    }
2825    function buildEventSourceMeta(raw, context) {
2826        var defs = context.pluginHooks.eventSourceDefs;
2827        for (var i = defs.length - 1; i >= 0; i--) { // later-added plugins take precedence
2828            var def = defs[i];
2829            var meta = def.parseMeta(raw);
2830            if (meta) {
2831                return { sourceDefId: i, meta: meta };
2832            }
2833        }
2834        return null;
2835    }
2836
2837    function reduceCurrentDate(currentDate, action) {
2838        switch (action.type) {
2839            case 'CHANGE_DATE':
2840                return action.dateMarker;
2841            default:
2842                return currentDate;
2843        }
2844    }
2845    function getInitialDate(options, dateEnv) {
2846        var initialDateInput = options.initialDate;
2847        // compute the initial ambig-timezone date
2848        if (initialDateInput != null) {
2849            return dateEnv.createMarker(initialDateInput);
2850        }
2851        else {
2852            return getNow(options.now, dateEnv); // getNow already returns unzoned
2853        }
2854    }
2855    function getNow(nowInput, dateEnv) {
2856        if (typeof nowInput === 'function') {
2857            nowInput = nowInput();
2858        }
2859        if (nowInput == null) {
2860            return dateEnv.createNowMarker();
2861        }
2862        return dateEnv.createMarker(nowInput);
2863    }
2864
2865    var CalendarApi = /** @class */ (function () {
2866        function CalendarApi() {
2867        }
2868        CalendarApi.prototype.getCurrentData = function () {
2869            return this.currentDataManager.getCurrentData();
2870        };
2871        CalendarApi.prototype.dispatch = function (action) {
2872            return this.currentDataManager.dispatch(action);
2873        };
2874        Object.defineProperty(CalendarApi.prototype, "view", {
2875            get: function () { return this.getCurrentData().viewApi; } // for public API
2876            ,
2877            enumerable: false,
2878            configurable: true
2879        });
2880        CalendarApi.prototype.batchRendering = function (callback) {
2881            callback();
2882        };
2883        CalendarApi.prototype.updateSize = function () {
2884            this.trigger('_resize', true);
2885        };
2886        // Options
2887        // -----------------------------------------------------------------------------------------------------------------
2888        CalendarApi.prototype.setOption = function (name, val) {
2889            this.dispatch({
2890                type: 'SET_OPTION',
2891                optionName: name,
2892                rawOptionValue: val
2893            });
2894        };
2895        CalendarApi.prototype.getOption = function (name) {
2896            return this.currentDataManager.currentCalendarOptionsInput[name];
2897        };
2898        CalendarApi.prototype.getAvailableLocaleCodes = function () {
2899            return Object.keys(this.getCurrentData().availableRawLocales);
2900        };
2901        // Trigger
2902        // -----------------------------------------------------------------------------------------------------------------
2903        CalendarApi.prototype.on = function (handlerName, handler) {
2904            var currentDataManager = this.currentDataManager;
2905            if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) {
2906                currentDataManager.emitter.on(handlerName, handler);
2907            }
2908            else {
2909                console.warn("Unknown listener name '" + handlerName + "'");
2910            }
2911        };
2912        CalendarApi.prototype.off = function (handlerName, handler) {
2913            this.currentDataManager.emitter.off(handlerName, handler);
2914        };
2915        // not meant for public use
2916        CalendarApi.prototype.trigger = function (handlerName) {
2917            var _a;
2918            var args = [];
2919            for (var _i = 1; _i < arguments.length; _i++) {
2920                args[_i - 1] = arguments[_i];
2921            }
2922            (_a = this.currentDataManager.emitter).trigger.apply(_a, __spreadArrays([handlerName], args));
2923        };
2924        // View
2925        // -----------------------------------------------------------------------------------------------------------------
2926        CalendarApi.prototype.changeView = function (viewType, dateOrRange) {
2927            var _this = this;
2928            this.batchRendering(function () {
2929                _this.unselect();
2930                if (dateOrRange) {
2931                    if (dateOrRange.start && dateOrRange.end) { // a range
2932                        _this.dispatch({
2933                            type: 'CHANGE_VIEW_TYPE',
2934                            viewType: viewType,
2935                        });
2936                        _this.dispatch({
2937                            type: 'SET_OPTION',
2938                            optionName: 'visibleRange',
2939                            rawOptionValue: dateOrRange
2940                        });
2941                    }
2942                    else {
2943                        var dateEnv = _this.getCurrentData().dateEnv;
2944                        _this.dispatch({
2945                            type: 'CHANGE_VIEW_TYPE',
2946                            viewType: viewType,
2947                            dateMarker: dateEnv.createMarker(dateOrRange)
2948                        });
2949                    }
2950                }
2951                else {
2952                    _this.dispatch({
2953                        type: 'CHANGE_VIEW_TYPE',
2954                        viewType: viewType
2955                    });
2956                }
2957            });
2958        };
2959        // Forces navigation to a view for the given date.
2960        // `viewType` can be a specific view name or a generic one like "week" or "day".
2961        // needs to change
2962        CalendarApi.prototype.zoomTo = function (dateMarker, viewType) {
2963            var state = this.getCurrentData();
2964            var spec;
2965            viewType = viewType || 'day'; // day is default zoom
2966            spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType);
2967            this.unselect();
2968            if (spec) {
2969                this.dispatch({
2970                    type: 'CHANGE_VIEW_TYPE',
2971                    viewType: spec.type,
2972                    dateMarker: dateMarker
2973                });
2974            }
2975            else {
2976                this.dispatch({
2977                    type: 'CHANGE_DATE',
2978                    dateMarker: dateMarker
2979                });
2980            }
2981        };
2982        // Given a duration singular unit, like "week" or "day", finds a matching view spec.
2983        // Preference is given to views that have corresponding buttons.
2984        CalendarApi.prototype.getUnitViewSpec = function (unit) {
2985            var _a = this.getCurrentData(), viewSpecs = _a.viewSpecs, toolbarConfig = _a.toolbarConfig;
2986            var viewTypes = [].concat(toolbarConfig.viewsWithButtons);
2987            var i;
2988            var spec;
2989            for (var viewType in viewSpecs) {
2990                viewTypes.push(viewType);
2991            }
2992            for (i = 0; i < viewTypes.length; i++) {
2993                spec = viewSpecs[viewTypes[i]];
2994                if (spec) {
2995                    if (spec.singleUnit === unit) {
2996                        return spec;
2997                    }
2998                }
2999            }
3000        };
3001        // Current Date
3002        // -----------------------------------------------------------------------------------------------------------------
3003        CalendarApi.prototype.prev = function () {
3004            this.unselect();
3005            this.dispatch({ type: 'PREV' });
3006        };
3007        CalendarApi.prototype.next = function () {
3008            this.unselect();
3009            this.dispatch({ type: 'NEXT' });
3010        };
3011        CalendarApi.prototype.prevYear = function () {
3012            var state = this.getCurrentData();
3013            this.unselect();
3014            this.dispatch({
3015                type: 'CHANGE_DATE',
3016                dateMarker: state.dateEnv.addYears(state.currentDate, -1)
3017            });
3018        };
3019        CalendarApi.prototype.nextYear = function () {
3020            var state = this.getCurrentData();
3021            this.unselect();
3022            this.dispatch({
3023                type: 'CHANGE_DATE',
3024                dateMarker: state.dateEnv.addYears(state.currentDate, 1)
3025            });
3026        };
3027        CalendarApi.prototype.today = function () {
3028            var state = this.getCurrentData();
3029            this.unselect();
3030            this.dispatch({
3031                type: 'CHANGE_DATE',
3032                dateMarker: getNow(state.calendarOptions.now, state.dateEnv)
3033            });
3034        };
3035        CalendarApi.prototype.gotoDate = function (zonedDateInput) {
3036            var state = this.getCurrentData();
3037            this.unselect();
3038            this.dispatch({
3039                type: 'CHANGE_DATE',
3040                dateMarker: state.dateEnv.createMarker(zonedDateInput)
3041            });
3042        };
3043        CalendarApi.prototype.incrementDate = function (deltaInput) {
3044            var state = this.getCurrentData();
3045            var delta = createDuration(deltaInput);
3046            if (delta) { // else, warn about invalid input?
3047                this.unselect();
3048                this.dispatch({
3049                    type: 'CHANGE_DATE',
3050                    dateMarker: state.dateEnv.add(state.currentDate, delta)
3051                });
3052            }
3053        };
3054        // for external API
3055        CalendarApi.prototype.getDate = function () {
3056            var state = this.getCurrentData();
3057            return state.dateEnv.toDate(state.currentDate);
3058        };
3059        // Date Formatting Utils
3060        // -----------------------------------------------------------------------------------------------------------------
3061        CalendarApi.prototype.formatDate = function (d, formatter) {
3062            var dateEnv = this.getCurrentData().dateEnv;
3063            return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
3064        };
3065        // `settings` is for formatter AND isEndExclusive
3066        CalendarApi.prototype.formatRange = function (d0, d1, settings) {
3067            var dateEnv = this.getCurrentData().dateEnv;
3068            return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings);
3069        };
3070        CalendarApi.prototype.formatIso = function (d, omitTime) {
3071            var dateEnv = this.getCurrentData().dateEnv;
3072            return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
3073        };
3074        // Date Selection / Event Selection / DayClick
3075        // -----------------------------------------------------------------------------------------------------------------
3076        // this public method receives start/end dates in any format, with any timezone
3077        // NOTE: args were changed from v3
3078        CalendarApi.prototype.select = function (dateOrObj, endDate) {
3079            var selectionInput;
3080            if (endDate == null) {
3081                if (dateOrObj.start != null) {
3082                    selectionInput = dateOrObj;
3083                }
3084                else {
3085                    selectionInput = {
3086                        start: dateOrObj,
3087                        end: null
3088                    };
3089                }
3090            }
3091            else {
3092                selectionInput = {
3093                    start: dateOrObj,
3094                    end: endDate
3095                };
3096            }
3097            var state = this.getCurrentData();
3098            var selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 }) // TODO: cache this?
3099            );
3100            if (selection) { // throw parse error otherwise?
3101                this.dispatch({ type: 'SELECT_DATES', selection: selection });
3102                triggerDateSelect(selection, null, state);
3103            }
3104        };
3105        // public method
3106        CalendarApi.prototype.unselect = function (pev) {
3107            var state = this.getCurrentData();
3108            if (state.dateSelection) {
3109                this.dispatch({ type: 'UNSELECT_DATES' });
3110                triggerDateUnselect(pev, state);
3111            }
3112        };
3113        // Public Events API
3114        // -----------------------------------------------------------------------------------------------------------------
3115        CalendarApi.prototype.addEvent = function (eventInput, sourceIn
3115put) {
3116            if (eventInput instanceof EventApi) {
3117                var def = eventInput._def;
3118                var instance = eventInput._instance;
3119                var currentData = this.getCurrentData();
3120                // not already present? don't want to add an old snapshot
3121                if (!currentData.eventStore.defs[def.defId]) {
3122                    this.dispatch({
3123                        type: 'ADD_EVENTS',
3124                        eventStore: eventTupleToStore({ def: def, instance: instance }) // TODO: better util for two args?
3125                    });
3126                    this.triggerEventAdd(eventInput);
3127                }
3128                return eventInput;
3129            }
3130            var state = this.getCurrentData();
3131            var eventSource;
3132            if (sourceInput instanceof EventSourceApi) {
3133                eventSource = sourceInput.internalEventSource;
3134            }
3135            else if (typeof sourceInput === 'boolean') {
3136                if (sourceInput) { // true. part of the first event source
3137                    eventSource = hashValuesToArray(state.eventSources)[0];
3138                }
3139            }
3140            else if (sourceInput != null) { // an ID. accepts a number too
3141                var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
3142                if (!sourceApi) {
3143                    console.warn('Could not find an event source with ID "' + sourceInput + '"'); // TODO: test
3144                    return null;
3145                }
3146                else {
3147                    eventSource = sourceApi.internalEventSource;
3148                }
3149            }
3150            var tuple = parseEvent(eventInput, eventSource, state, false);
3151            if (tuple) {
3152                var newEventApi = new EventApi(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
3153                this.dispatch({
3154                    type: 'ADD_EVENTS',
3155                    eventStore: eventTupleToStore(tuple)
3156                });
3157                this.triggerEventAdd(newEventApi);
3158                return newEventApi;
3159            }
3160            return null;
3161        };
3162        CalendarApi.prototype.triggerEventAdd = function (eventApi) {
3163            var _this = this;
3164            var emitter = this.getCurrentData().emitter;
3165            emitter.trigger('eventAdd', {
3166                event: eventApi,
3167                relatedEvents: [],
3168                revert: function () {
3169                    _this.dispatch({
3170                        type: 'REMOVE_EVENTS',
3171                        eventStore: eventApiToStore(eventApi)
3172                    });
3173                }
3174            });
3175        };
3176        // TODO: optimize
3177        CalendarApi.prototype.getEventById = function (id) {
3178            var state = this.getCurrentData();
3179            var _a = state.eventStore, defs = _a.defs, instances = _a.instances;
3180            id = String(id);
3181            for (var defId in defs) {
3182                var def = defs[defId];
3183                if (def.publicId === id) {
3184                    if (def.recurringDef) {
3185                        return new EventApi(state, def, null);
3186                    }
3187                    else {
3188                        for (var instanceId in instances) {
3189                            var instance = instances[instanceId];
3190                            if (instance.defId === def.defId) {
3191                                return new EventApi(state, def, instance);
3192                            }
3193                        }
3194                    }
3195                }
3196            }
3197            return null;
3198        };
3199        CalendarApi.prototype.getEvents = function () {
3200            var currentData = this.getCurrentData();
3201            return buildEventApis(currentData.eventStore, currentData);
3202        };
3203        CalendarApi.prototype.removeAllEvents = function () {
3204            this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
3205        };
3206        // Public Event Sources API
3207        // -----------------------------------------------------------------------------------------------------------------
3208        CalendarApi.prototype.getEventSources = function () {
3209            var state = this.getCurrentData();
3210            var sourceHash = state.eventSources;
3211            var sourceApis = [];
3212            for (var internalId in sourceHash) {
3213                sourceApis.push(new EventSourceApi(state, sourceHash[internalId]));
3214            }
3215            return sourceApis;
3216        };
3217        CalendarApi.prototype.getEventSourceById = function (id) {
3218            var state = this.getCurrentData();
3219            var sourceHash = state.eventSources;
3220            id = String(id);
3221            for (var sourceId in sourceHash) {
3222                if (sourceHash[sourceId].publicId === id) {
3223                    return new EventSourceApi(state, sourceHash[sourceId]);
3224                }
3225            }
3226            return null;
3227        };
3228        CalendarApi.prototype.addEventSource = function (sourceInput) {
3229            var state = this.getCurrentData();
3230            if (sourceInput instanceof EventSourceApi) {
3231                // not already present? don't want to add an old snapshot
3232                if (!state.eventSources[sourceInput.internalEventSource.sourceId]) {
3233                    this.dispatch({
3234                        type: 'ADD_EVENT_SOURCES',
3235                        sources: [sourceInput.internalEventSource]
3236                    });
3237                }
3238                return sourceInput;
3239            }
3240            var eventSource = parseEventSource(sourceInput, state);
3241            if (eventSource) { // TODO: error otherwise?
3242                this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
3243                return new EventSourceApi(state, eventSource);
3244            }
3245            return null;
3246        };
3247        CalendarApi.prototype.removeAllEventSources = function () {
3248            this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
3249        };
3250        CalendarApi.prototype.refetchEvents = function () {
3251            this.dispatch({ type: 'FETCH_EVENT_SOURCES' });
3252        };
3253        // Scroll
3254        // -----------------------------------------------------------------------------------------------------------------
3255        CalendarApi.prototype.scrollToTime = function (timeInput) {
3256            var time = createDuration(timeInput);
3257            if (time) {
3258                this.trigger('_scrollRequest', { time: time });
3259            }
3260        };
3261        return CalendarApi;
3262    }());
3263
3264    var EventApi = /** @class */ (function () {
3265        // instance will be null if expressing a recurring event that has no current instances,
3266        // OR if trying to validate an incoming external event that has no dates assigned
3267        function EventApi(context, def, instance) {
3268            this._context = context;
3269            this._def = def;
3270            this._instance = instance || null;
3271        }
3272        /*
3273        TODO: make event struct more responsible for this
3274        */
3275        EventApi.prototype.setProp = function (name, val) {
3276            var _a, _b;
3277            if (name in EVENT_DATE_REFINERS) {
3278                console.warn("Could not set date-related prop 'name'. Use one of the date-related methods instead.");
3279            }
3280            else if (name in EVENT_NON_DATE_REFINERS) {
3281                val = EVENT_NON_DATE_REFINERS[name](val);
3282                this.mutate({
3283                    standardProps: (_a = {}, _a[name] = val, _a)
3284                });
3285            }
3286            else if (name in EVENT_UI_REFINERS) {
3287                var ui = EVENT_UI_REFINERS[name](val);
3288                if (name === 'color') {
3289                    ui = { backgroundColor: val, borderColor: val };
3290                }
3291                else if (name === 'editable') {
3292                    ui = { startEditable: val, durationEditable: val };
3293                }
3294                else {
3295                    ui = (_b = {}, _b[name] = val, _b);
3296                }
3297                this.mutate({
3298                    standardProps: { ui: ui }
3299                });
3300            }
3301            else {
3302                console.warn("Could not set prop '" + name + "'. Use setExtendedProp instead.");
3303            }
3304        };
3305        EventApi.prototype.setExtendedProp = function (name, val) {
3306            var _a;
3307            this.mutate({
3308                extendedProps: (_a = {}, _a[name] = val, _a)
3309            });
3310        };
3311        EventApi.prototype.setStart = function (startInput, options) {
3312            if (options === void 0) { options = {}; }
3313            var dateEnv = this._context.dateEnv;
3314            var start = dateEnv.createMarker(startInput);
3315            if (start && this._instance) { // TODO: warning if parsed bad
3316                var instanceRange = this._instance.range;
3317                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
3318                if (options.maintainDuration) {
3319                    this.mutate({ datesDelta: startDelta });
3320                }
3321                else {
3322                    this.mutate({ startDelta: startDelta });
3323                }
3324            }
3325        };
3326        EventApi.prototype.setEnd = function (endInput, options) {
3327            if (options === void 0) { options = {}; }
3328            var dateEnv = this._context.dateEnv;
3329            var end;
3330            if (endInput != null) {
3331                end = dateEnv.createMarker(endInput);
3332                if (!end) {
3333                    return; // TODO: warning if parsed bad
3334                }
3335            }
3336            if (this._instance) {
3337                if (end) {
3338                    var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
3339                    this.mutate({ endDelta: endDelta });
3340                }
3341                else {
3342                    this.mutate({ standardProps: { hasEnd: false } });
3343                }
3344            }
3345        };
3346        EventApi.prototype.setDates = function (startInput, endInput, options) {
3347            if (options === void 0) { options = {}; }
3348            var dateEnv = this._context.dateEnv;
3349            var standardProps = { allDay: options.allDay };
3350            var start = dateEnv.createMarker(startInput);
3351            var end;
3352            if (!start) {
3353                return; // TODO: warning if parsed bad
3354            }
3355            if (endInput != null) {
3356                end = dateEnv.createMarker(endInput);
3357                if (!end) { // TODO: warning if parsed bad
3358                    return;
3359                }
3360            }
3361            if (this._instance) {
3362                var instanceRange = this._instance.range;
3363                // when computing the diff for an event being converted to all-day,
3364                // compute diff off of the all-day values the way event-mutation does.
3365                if (options.allDay === true) {
3366                    instanceRange = computeAlignedDayRange(instanceRange);
3367                }
3368                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
3369                if (end) {
3370                    var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
3371                    if (durationsEqual(startDelta, endDelta)) {
3372                        this.mutate({ datesDelta: startDelta, standardProps: standardProps });
3373                    }
3374                    else {
3375                        this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
3376                    }
3377                }
3378                else { // means "clear the end"
3379                    standardProps.hasEnd = false;
3380                    this.mutate({ datesDelta: startDelta, standardProps: standardProps });
3381                }
3382            }
3383        };
3384        EventApi.prototype.moveStart = function (deltaInput) {
3385            var delta = createDuration(deltaInput);
3386            if (delta) { // TODO: warning if parsed bad
3387                this.mutate({ startDelta: delta });
3388            }
3389        };
3390        EventApi.prototype.moveEnd = function (deltaInput) {
3391            var delta = createDuration(deltaInput);
3392            if (delta) { // TODO: warning if parsed bad
3393                this.mutate({ endDelta: delta });
3394            }
3395        };
3396        EventApi.prototype.moveDates = function (deltaInput) {
3397            var delta = createDuration(deltaInput);
3398            if (delta) { // TODO: warning if parsed bad
3399                this.mutate({ datesDelta: delta });
3400            }
3401        };
3402        EventApi.prototype.setAllDay = function (allDay, options) {
3403            if (options === void 0) { options = {}; }
3404            var standardProps = { allDay: allDay };
3405            var maintainDuration = options.maintainDuration;
3406            if (maintainDuration == null) {
3407                maintainDuration = this._context.options.allDayMaintainDuration;
3408            }
3409            if (this._def.allDay !== allDay) {
3410                standardProps.hasEnd = maintainDuration;
3411            }
3412            this.mutate({ standardProps: standardProps });
3413        };
3414        EventApi.prototype.formatRange = function (formatInput) {
3415            var dateEnv = this._context.dateEnv;
3416            var instance = this._instance;
3417            var formatter = createFormatter(formatInput);
3418            if (this._def.hasEnd) {
3419                return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
3420                    forcedStartTzo: instance.forcedStartTzo,
3421                    forcedEndTzo: instance.forcedEndTzo
3422                });
3423            }
3424            else {
3425                return dateEnv.format(instance.range.start, formatter, {
3426                    forcedTzo: instance.forcedStartTzo
3427                });
3428            }
3429        };
3430        EventApi.prototype.mutate = function (mutation) {
3431            var instance = this._instance;
3432            if (instance) {
3433                var def = this._def;
3434                var context_1 = this._context;
3435                var eventStore = context_1.getCurrentData().eventStore;
3436                var relevantEvents_1 = getRelevantEvents(eventStore, instance.instanceId);
3437                var eventConfigBase = {
3438                    '': {
3439                        display: '',
3440                        startEditable: true,
3441                        durationEditable: true,
3442                        constraints: [],
3443                        overlap: null,
3444                        allows: [],
3445                        backgroundColor: '',
3446                        borderColor: '',
3447                        textColor: '',
3448                        classNames: []
3449                    }
3450                };
3451                relevantEvents_1 = applyMutationToEventStore(relevantEvents_1, eventConfigBase, mutation, context_1);
3452                var oldEvent = new EventApi(context_1, def, instance); // snapshot
3453                this._def = relevantEvents_1.defs[def.defId];
3454                this._instance = relevantEvents_1.instances[instance.instanceId];
3455                context_1.dispatch({
3456                    type: 'MERGE_EVENTS',
3457                    eventStore: relevantEvents_1
3458                });
3459                context_1.emitter.trigger('eventChange', {
3460                    oldEvent: oldEvent,
3461                    event: this,
3462                    relatedEvents: buildEventApis(relevantEvents_1, context_1, instance),
3463                    revert: function () {
3464                        context_1.dispatch({
3465                            type: 'REMOVE_EVENTS',
3466                            eventStore: relevantEvents_1
3467                        });
3468                    }
3469                });
3470            }
3471        };
3472        EventApi.prototype.remove = function () {
3473            var context = this._context;
3474            var asStore = eventApiToStore(this);
3475            context.dispatch({
3476                type: 'REMOVE_EVENTS',
3477                eventStore: asStore
3478            });
3479            context.emitter.trigger('eventRemove', {
3480                event: this,
3481                relatedEvents: [],
3482                revert: function () {
3483                    context.dispatch({
3484                        type: 'MERGE_EVENTS',
3485                        eventStore: asStore
3486                    });
3487                }
3488            });
3489        };
3490        Object.defineProperty(EventApi.prototype, "source", {
3491            get: function () {
3492                var sourceId = this._def.sourceId;
3493                if (sourceId) {
3494                    return new EventSourceApi(this._context, this._context.getCurrentData().eventSources[sourceId]);
3495                }
3496                return null;
3497            },
3498            enumerable: false,
3499            configurable: true
3500        });
3501        Object.defineProperty(EventApi.prototype, "start", {
3502            get: function () {
3503                return this._instance ?
3504                    this._context.dateEnv.toDate(this._instance.range.start) :
3505                    null;
3506            },
3507            enumerable: false,
3508            configurable: true
3509        });
3510        Object.defineProperty(EventApi.prototype, "end", {
3511            get: function () {
3512                return (this._instance && this._def.hasEnd) ?
3513                    this._context.dateEnv.toDate(this._instance.range.end) :
3514                    null;
3515            },
3516            enumerable: false,
3517            configurable: true
3518        });
3519        Object.defineProperty(EventApi.prototype, "startStr", {
3520            get: function () {
3521                var instance = this._instance;
3522                if (instance) {
3523                    return this._context.dateEnv.formatIso(instance.range.start, {
3524                        omitTime: this._def.allDay,
3525                        forcedTzo: instance.forcedStartTzo
3526                    });
3527                }
3528                return '';
3529            },
3530            enumerable: false,
3531            configurable: true
3532        });
3533        Object.defineProperty(EventApi.prototype, "endStr", {
3534            get: function () {
3535                var instance = this._instance;
3536                if (instance && this._def.hasEnd) {
3537                    return this._context.dateEnv.formatIso(instance.range.end, {
3538                        omitTime: this._def.allDay,
3539                        forcedTzo: instance.forcedEndTzo
3540                    });
3541                }
3542                return '';
3543            },
3544            enumerable: false,
3545            configurable: true
3546        });
3547        Object.defineProperty(EventApi.prototype, "id", {
3548            // computable props that all access the def
3549            // TODO: find a TypeScript-compatible way to do this at scale
3550            get: function () { return this._def.publicId; },
3551            enumerable: false,
3552            configurable: true
3553        });
3554        Object.defineProperty(EventApi.prototype, "groupId", {
3555            get: function () { return this._def.groupId; },
3556            enumerable: false,
3557            configurable: true
3558        });
3559        Object.defineProperty(EventApi.prototype, "allDay", {
3560            get: function () { return this._def.allDay; },
3561            enumerable: false,
3562            configurable: true
3563        });
3564        Object.defineProperty(EventApi.prototype, "title", {
3565            get: function () { return this._def.title; },
3566            enumerable: false,
3567            configurable: true
3568        });
3569        Object.defineProperty(EventApi.prototype, "url", {
3570            get: function () { return this._def.url; },
3571            enumerable: false,
3572            configurable: true
3573        });
3574        Object.defineProperty(EventApi.prototype, "display", {
3575            get: function () { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier
3576            ,
3577            enumerable: false,
3578            configurable: true
3579        });
3580        Object.defineProperty(EventApi.prototype, "startEditable", {
3581            get: function () { return this._def.ui.startEditable; },
3582            enumerable: false,
3583            configurable: true
3584        });
3585        Object.defineProperty(EventApi.prototype, "durationEditable", {
3586            get: function () { return this._def.ui.durationEditable; },
3587            enumerable: false,
3588            configurable: true
3589        });
3590        Object.defineProperty(EventApi.prototype, "constraint", {
3591            get: function () { return this._def.ui.constraints[0] || null; },
3592            enumerable: false,
3593            configurable: true
3594        });
3595        Object.defineProperty(EventApi.prototype, "overlap", {
3596            get: function () { return this._def.ui.overlap; },
3597            enumerable: false,
3598            configurable: true
3599        });
3600        Object.defineProperty(EventApi.prototype, "allow", {
3601            get: function () { return this._def.ui.allows[0] || null; },
3602            enumerable: false,
3603            configurable: true
3604        });
3605        Object.defineProperty(EventApi.prototype, "backgroundColor", {
3606            get: function () { return this._def.ui.backgroundColor; },
3607            enumerable: false,
3608            configurable: true
3609        });
3610        Object.defineProperty(EventApi.prototype, "borderColor", {
3611            get: function () { return this._def.ui.borderColor; },
3612            enumerable: false,
3613            configurable: true
3614        });
3615        Object.defineProperty(EventApi.prototype, "textColor", {
3616            get: function () { return this._def.ui.textColor; },
3617            enumerable: false,
3618            configurable: true
3619        });
3620        Object.defineProperty(EventApi.prototype, "classNames", {
3621            // NOTE: user can't modify these because Object.freeze was called in event-def parsing
3622            get: function () { return this._def.ui.classNames; },
3623            enumerable: false,
3624            configurable: true
3625        });
3626        Object.defineProperty(EventApi.prototype, "extendedProps", {
3627            get: function () { return this._def.extendedProps; },
3628            enumerable: false,
3629            configurable: true
3630        });
3631        EventApi.prototype.toPlainObject = function (settings) {
3632            if (settings === void 0) { settings = {}; }
3633            var def = this._def;
3634            var ui = def.ui;
3635            var _a = this, startStr = _a.startStr, endStr = _a.endStr;
3636            var res = {};
3637            if (def.title) {
3638                res.title = def.title;
3639            }
3640            if (startStr) {
3641                res.start = startStr;
3642            }
3643            if (endStr) {
3644                res.end = endStr;
3645            }
3646            if (def.publicId) {
3647                res.id = def.publicId;
3648            }
3649            if (def.groupId) {
3650                res.groupId = def.groupId;
3651            }
3652            if (def.url) {
3653                res.url = def.url;
3654            }
3655            if (ui.display && ui.display !== 'auto') {
3656                res.display = ui.display;
3657            }
3658            // TODO: what about recurring-event properties???
3659            // TODO: include startEditable/durationEditable/constraint/overlap/allow
3660            if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) {
3661                res.color = ui.backgroundColor;
3662            }
3663            else {
3664                if (ui.backgroundColor) {
3665                    res.backgroundColor = ui.backgroundColor;
3666                }
3667                if (ui.borderColor) {
3668                    res.borderColor = ui.borderColor;
3669                }
3670            }
3671            if (ui.textColor) {
3672                res.textColor = ui.textColor;
3673            }
3674            if (ui.classNames.length) {
3675                res.classNames = ui.classNames;
3676            }
3677            if (Object.keys(def.extendedProps).length) {
3678                if (settings.collapseExtendedProps) {
3679                    __assign(res, def.extendedProps);
3680                }
3681                else {
3682                    res.extendedProps = def.extendedProps;
3683                }
3684            }
3685            return res;
3686        };
3687        EventApi.prototype.toJSON = function () {
3688            return this.toPlainObject();
3689        };
3690        return EventApi;
3691    }());
3692    function eventApiToStore(eventApi) {
3693        var _a, _b;
3694        var def = eventApi._def;
3695        var instance = eventApi._instance;
3696        return {
3697            defs: (_a = {}, _a[def.defId] = def, _a),
3698            instances: instance
3699                ? (_b = {}, _b[instance.instanceId] = instance, _b) : {}
3700        };
3701    }
3702    function buildEventApis(eventStore, context, excludeInstance) {
3703        var defs = eventStore.defs, instances = eventStore.instances;
3704        var eventApis = [];
3705        var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : '';
3706        for (var id in instances) {
3707            var instance = instances[id];
3708            var def = defs[instance.defId];
3709            if (instance.instanceId !== excludeInstanceId) {
3710                eventApis.push(new EventApi(context, def, instance));
3711            }
3712        }
3713        return eventApis;
3714    }
3715
3716    var calendarSystemClassMap = {};
3717    function registerCalendarSystem(name, theClass) {
3718        calendarSystemClassMap[name] = theClass;
3719    }
3720    function createCalendarSystem(name) {
3721        return new calendarSystemClassMap[name]();
3722    }
3723    var GregorianCalendarSystem = /** @class */ (function () {
3724        function GregorianCalendarSystem() {
3725        }
3726        GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
3727            return d.getUTCFullYear();
3728        };
3729        GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
3730            return d.getUTCMonth();
3731        };
3732        GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
3733            return d.getUTCDate();
3734        };
3735        GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
3736            return arrayToUtcDate(arr);
3737        };
3738        GregorianCalendarSystem.prototype.markerToArray = function (marker) {
3739            return dateToUtcArray(marker);
3740        };
3741        return GregorianCalendarSystem;
3742    }());
3743    registerCalendarSystem('gregory', GregorianCalendarSystem);
3744
3745    var ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
3746    function parse(str) {
3747        var m = ISO_RE.exec(str);
3748        if (m) {
3749            var marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number('0.' + m[12]) * 1000 : 0));
3750            if (isValidDate(marker)) {
3751                var timeZoneOffset = null;
3752                if (m[13]) {
3753                    timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
3754                        Number(m[18] || 0));
3755                }
3756                return {
3757                    marker: marker,
3758                    isTimeUnspecified: !m[6],
3759                    timeZoneOffset: timeZoneOffset
3760                };
3761            }
3762        }
3763        return null;
3764    }
3765
3766    var DateEnv = /** @class */ (function () {
3767        function DateEnv(settings) {
3768            var timeZone = this.timeZone = settings.timeZone;
3769            var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
3770            if (settings.namedTimeZoneImpl && isNamedTimeZone) {
3771                this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
3772            }
3773            this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
3774            this.calendarSystem = createCalendarSystem(settings.calendarSystem);
3775            this.locale = settings.locale;
3776            this.weekDow = settings.locale.week.dow;
3777            this.weekDoy = settings.locale.week.doy;
3778            if (settings.weekNumberCalculation === 'ISO') {
3779                this.weekDow = 1;
3780                this.weekDoy = 4;
3781            }
3782            if (typeof settings.firstDay === 'number') {
3783                this.weekDow = settings.firstDay;
3784            }
3785            if (typeof settings.weekNumberCalculation === 'function') {
3786                this.weekNumberFunc = settings.weekNumberCalculation;
3787            }
3788            this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText;
3789            this.cmdFormatter = settings.cmdFormatter;
3790            this.defaultSeparator = settings.defaultSeparator;
3791        }
3792        // Creating / Parsing
3793        DateEnv.prototype.createMarker = function (input) {
3794            var meta = this.createMarkerMeta(input);
3795            if (meta === null) {
3796                return null;
3797            }
3798            return meta.marker;
3799        };
3800        DateEnv.prototype.createNowMarker = function () {
3801            if (this.canComputeOffset) {
3802                return this.timestampToMarker(new Date().valueOf());
3803            }
3804            else {
3805                // if we can't compute the current date val for a timezone,
3806                // better to give the current local date vals than UTC
3807                return arrayToUtcDate(dateToLocalArray(new Date()));
3808            }
3809        };
3810        DateEnv.prototype.createMarkerMeta = function (input) {
3811            if (typeof input === 'string') {
3812                return this.parse(input);
3813            }
3814            var marker = null;
3815            if (typeof input === 'number') {
3816                marker = this.timestampToMarker(input);
3817            }
3818            else if (input instanceof Date) {
3819                input = input.valueOf();
3820                if (!isNaN(input)) {
3821                    marker = this.timestampToMarker(input);
3822                }
3823            }
3824            else if (Array.isArray(input)) {
3825                marker = arrayToUtcDate(input);
3826            }
3827            if (marker === null || !isValidDate(marker)) {
3828                return null;
3829            }
3830            return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
3831        };
3832        DateEnv.prototype.parse = function (s) {
3833            var parts = parse(s);
3834            if (parts === null) {
3835                return null;
3836            }
3837            var marker = parts.marker;
3838            var forcedTzo = null;
3839            if (parts.timeZoneOffset !== null) {
3840                if (this.canComputeOffset) {
3841                    marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
3842                }
3843                else {
3844                    forcedTzo = parts.timeZoneOffset;
3845                }
3846            }
3847            return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
3848        };
3849        // Accessors
3850        DateEnv.prototype.getYear = function (marker) {
3851            return this.calendarSystem.getMarkerYear(marker);
3852        };
3853        DateEnv.prototype.getMonth = function (marker) {
3854            return this.calendarSystem.getMarkerMonth(marker);
3855        };
3856        // Adding / Subtracting
3857        DateEnv.prototype.add = function (marker, dur) {
3858            var a = this.calendarSystem.markerToArray(marker);
3859            a[0] += dur.years;
3860            a[1] += dur.months;
3861            a[2] += dur.days;
3862            a[6] += dur.milliseconds;
3863            return this.calendarSystem.arrayToMarker(a);
3864        };
3865        DateEnv.prototype.subtract = function (marker, dur) {
3866            var a = this.calendarSystem.markerToArray(marker);
3867            a[0] -= dur.years;
3868            a[1] -= dur.months;
3869            a[2] -= dur.days;
3870            a[6] -= dur.milliseconds;
3871            return this.calendarSystem.arrayToMarker(a);
3872        };
3873        DateEnv.prototype.addYears = function (marker, n) {
3874            var a = this.calendarSystem.markerToArray(marker);
3875            a[0] += n;
3876            return this.calendarSystem.arrayToMarker(a);
3877        };
3878        DateEnv.prototype.addMonths = function (marker, n) {
3879            var a = this.calendarSystem.markerToArray(marker);
3880            a[1] += n;
3881            return this.calendarSystem.arrayToMarker(a);
3882        };
3883        // Diffing Whole Units
3884        DateEnv.prototype.diffWholeYears = function (m0, m1) {
3885            var calendarSystem = this.calendarSystem;
3886            if (timeAsMs(m0) === timeAsMs(m1) &&
3887                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
3888                calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
3889                return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
3890            }
3891            return null;
3892        };
3893        DateEnv.prototype.diffWholeMonths = function (m0, m1) {
3894            var calendarSystem = this.calendarSystem;
3895            if (timeAsMs(m0) === timeAsMs(m1) &&
3896                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
3897                return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
3898                    (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
3899            }
3900            return null;
3901        };
3902        // Range / Duration
3903        DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
3904            var n = this.diffWholeYears(m0, m1);
3905            if (n !== null) {
3906                return { unit: 'year', value: n };
3907            }
3908            n = this.diffWholeMonths(m0, m1);
3909            if (n !== null) {
3910                return { unit: 'month', value: n };
3911            }
3912            n = diffWholeWeeks(m0, m1);
3913            if (n !== null) {
3914                return { unit: 'week', value: n };
3915            }
3916            n = diffWholeDays(m0, m1);
3917            if (n !== null) {
3918                return { unit: 'day', value: n };
3919            }
3920            n = diffHours(m0, m1);
3921            if (isInt(n)) {
3922                return { unit: 'hour', value: n };
3923            }
3924            n = diffMinutes(m0, m1);
3925            if (isInt(n)) {
3926                return { unit: 'minute', value: n };
3927            }
3928            n = diffSeconds(m0, m1);
3929            if (isInt(n)) {
3930                return { unit: 'second', value: n };
3931            }
3932            return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
3933        };
3934        DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
3935            // TODO: can use greatestWholeUnit
3936            var diff;
3937            if (d.years) {
3938                diff = this.diffWholeYears(m0, m1);
3939                if (diff !== null) {
3940                    return diff / asRoughYears(d);
3941                }
3942            }
3943            if (d.months) {
3944                diff = this.diffWholeMonths(m0, m1);
3945                if (diff !== null) {
3946                    return diff / asRoughMonths(d);
3947                }
3948            }
3949            if (d.days) {
3950                diff = diffWholeDays(m0, m1);
3951                if (diff !== null) {
3952                    return diff / asRoughDays(d);
3953                }
3954            }
3955            return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
3956        };
3957        // Start-Of
3958        // these DON'T return zoned-dates. only UTC start-of dates
3959        DateEnv.prototype.startOf = function (m, unit) {
3960            if (unit === 'year') {
3961                return this.startOfYear(m);
3962            }
3963            else if (unit === 'month') {
3964                return this.startOfMonth(m);
3965            }
3966            else if (unit === 'week') {
3967                return this.startOfWeek(m);
3968            }
3969            else if (unit === 'day') {
3970                return startOfDay(m);
3971            }
3972            else if (unit === 'hour') {
3973                return startOfHour(m);
3974            }
3975            else if (unit === 'minute') {
3976                return startOfMinute(m);
3977            }
3978            else if (unit === 'second') {
3979                return startOfSecond(m);
3980            }
3981        };
3982        DateEnv.prototype.startOfYear = function (m) {
3983            return this.calendarSystem.arrayToMarker([
3984                this.calendarSystem.getMarkerYear(m)
3985            ]);
3986        };
3987        DateEnv.prototype.startOfMonth = function (m) {
3988            return this.calendarSystem.arrayToMarker([
3989                this.calendarSystem.getMarkerYear(m),
3990                this.calendarSystem.getMarkerMonth(m)
3991            ]);
3992        };
3993        DateEnv.prototype.startOfWeek = function (m) {
3994            return this.calendarSystem.arrayToMarker([
3995                this.calendarSystem.getMarkerYear(m),
3996                this.calendarSystem.getMarkerMonth(m),
3997                m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7)
3998            ]);
3999        };
4000        // Week Number
4001        DateEnv.prototype.computeWeekNumber = function (marker) {
4002            if (this.weekNumberFunc) {
4003                return this.weekNumberFunc(this.toDate(marker));
4004            }
4005            else {
4006                return weekOfYear(marker, this.weekDow, this.weekDoy);
4007            }
4008        };
4009        // TODO: choke on timeZoneName: long
4010        DateEnv.prototype.format = function (marker, formatter, dateOptions) {
4011            if (dateOptions === void 0) { dateOptions = {}; }
4012            return formatter.format({
4013                marker: marker,
4014                timeZoneOffset: dateOptions.forcedTzo != null ?
4015                    dateOptions.forcedTzo :
4016                    this.offsetForMarker(marker)
4017            }, this);
4018        };
4019        DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
4020            if (dateOptions === void 0) { dateOptions = {}; }
4021            if (dateOptions.isEndExclusive) {
4022                end = addMs(end, -1);
4023            }
4024            return formatter.formatRange({
4025                marker: start,
4026                timeZoneOffset: dateOptions.forcedStartTzo != null ?
4027                    dateOptions.forcedStartTzo :
4028                    this.offsetForMarker(start)
4029            }, {
4030                marker: end,
4031                timeZoneOffset: dateOptions.forcedEndTzo != null ?
4032                    dateOptions.forcedEndTzo :
4033                    this.offsetForMarker(end)
4034            }, this, dateOptions.defaultSeparator);
4035        };
4036        /*
4037        DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
4038        might as well use buildIsoString or some other util directly
4039        */
4040        DateEnv.prototype.formatIso = function (marker, extraOptions) {
4041            if (extraOptions === void 0) { extraOptions = {}; }
4042            var timeZoneOffset = null;
4043            if (!extraOptions.omitTimeZoneOffset) {
4044                if (extraOptions.forcedTzo != null) {
4045                    timeZoneOffset = extraOptions.forcedTzo;
4046                }
4047                else {
4048                    timeZoneOffset = this.offsetForMarker(marker);
4049                }
4050            }
4051            return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
4052        };
4053        // TimeZone
4054        DateEnv.prototype.timestampToMarker = function (ms) {
4055            if (this.timeZone === 'local') {
4056                return arrayToUtcDate(dateToLocalArray(new Date(ms)));
4057            }
4058            else if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
4059                return new Date(ms);
4060            }
4061            else {
4062                return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
4063            }
4064        };
4065        DateEnv.prototype.offsetForMarker = function (m) {
4066            if (this.timeZone === 'local') {
4067                return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
4068            }
4069            else if (this.timeZone === 'UTC') {
4070                return 0;
4071            }
4072            else if (this.namedTimeZoneImpl) {
4073                return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
4074            }
4075            return null;
4076        };
4077        // Conversion
4078        DateEnv.prototype.toDate = function (m, forcedTzo) {
4079            if (this.timeZone === 'local') {
4080                return arrayToLocalDate(dateToUtcArray(m));
4081            }
4082            else if (this.timeZone === 'UTC') {
4083                return new Date(m.valueOf()); // make sure it's a copy
4084            }
4085            else if (!this.namedTimeZoneImpl) {
4086                return new Date(m.valueOf() - (forcedTzo || 0));
4087            }
4088            else {
4089                return new Date(m.valueOf() -
4090                    this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms
4091                );
4092            }
4093        };
4094        return DateEnv;
4095    }());
4096
4097    var globalLocales = [];
4098
4099    var RAW_EN_LOCALE = {
4100        code: 'en',
4101        week: {
4102            dow: 0,
4103            doy: 4 // 4 days need to be within the year to be considered the first week
4104        },
4105        direction: 'ltr',
4106        buttonText: {
4107            prev: 'prev',
4108            next: 'next',
4109            prevYear: 'prev year',
4110            nextYear: 'next year',
4111            year: 'year',
4112            today: 'today',
4113            month: 'month',
4114            week: 'week',
4115            day: 'day',
4116            list: 'list'
4117        },
4118        weekText: 'W',
4119        allDayText: 'all-day',
4120        moreLinkText: 'more',
4121        noEventsText: 'No events to display'
4122    };
4123    function organizeRawLocales(explicitRawLocales) {
4124        var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
4125        var allRawLocales = globalLocales.concat(explicitRawLocales);
4126        var rawLocaleMap = {
4127            en: RAW_EN_LOCALE // necessary?
4128        };
4129        for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
4130            var rawLocale = allRawLocales_1[_i];
4131            rawLocaleMap[rawLocale.code] = rawLocale;
4132        }
4133        return {
4134            map: rawLocaleMap,
4135            defaultCode: defaultCode
4136        };
4137    }
4138    function buildLocale(inputSingular, available) {
4139        if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
4140            return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
4141        }
4142        else {
4143            return queryLocale(inputSingular, available);
4144        }
4145    }
4146    function queryLocale(codeArg, available) {
4147        var codes = [].concat(codeArg || []); // will convert to array
4148        var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
4149        return parseLocale(codeArg, codes, raw);
4150    }
4151    function queryRawLocale(codes, available) {
4152        for (var i = 0; i < codes.length; i++) {
4153            var parts = codes[i].toLocaleLowerCase().split('-');
4154            for (var j = parts.length; j > 0; j--) {
4155                var simpleId = parts.slice(0, j).join('-');
4156                if (available[simpleId]) {
4157                    return available[simpleId];
4158                }
4159            }
4160        }
4161        return null;
4162    }
4163    function parseLocale(codeArg, codes, raw) {
4164        var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
4165        delete merged.code; // don't want this part of the options
4166        var week = merged.week;
4167        delete merged.week;
4168        return {
4169            codeArg: codeArg,
4170            codes: codes,
4171            week: week,
4172            simpleNumberFormat: new Intl.NumberFormat(codeArg),
4173            options: merged
4174        };
4175    }
4176
4177    function formatDate(dateInput, options) {
4178        if (options === void 0) { options = {}; }
4179        var dateEnv = buildDateEnv(options);
4180        var formatter = createFormatter(options);
4181        var dateMeta = dateEnv.createMarkerMeta(dateInput);
4182        if (!dateMeta) { // TODO: warning?
4183            return '';
4184        }
4185        return dateEnv.format(dateMeta.marker, formatter, {
4186            forcedTzo: dateMeta.forcedTzo
4187        });
4188    }
4189    function formatRange(startInput, endInput, options // mixture of env and formatter settings
4190    ) {
4191        var dateEnv = buildDateEnv(typeof options === 'object' && options ? options : {}); // pass in if non-null object
4192        var formatter = createFormatter(options);
4193        var startMeta = dateEnv.createMarkerMeta(startInput);
4194        var endMeta = dateEnv.createMarkerMeta(endInput);
4195        if (!startMeta || !endMeta) { // TODO: warning?
4196            return '';
4197        }
4198        return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
4199            forcedStartTzo: startMeta.forcedTzo,
4200            forcedEndTzo: endMeta.forcedTzo,
4201            isEndExclusive: options.isEndExclusive,
4202            defaultS
4202eparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator
4203        });
4204    }
4205    // TODO: more DRY and optimized
4206    function buildDateEnv(settings) {
4207        var locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
4208        return new DateEnv(__assign(__assign({ timeZone: BASE_OPTION_DEFAULTS.timeZone, calendarSystem: 'gregory' }, settings), { locale: locale }));
4209    }
4210
4211    var DEF_DEFAULTS = {
4212        startTime: '09:00',
4213        endTime: '17:00',
4214        daysOfWeek: [1, 2, 3, 4, 5],
4215        display: 'inverse-background',
4216        classNames: 'fc-non-business',
4217        groupId: '_businessHours' // so multiple defs get grouped
4218    };
4219    /*
4220    TODO: pass around as EventDefHash!!!
4221    */
4222    function parseBusinessHours(input, context) {
4223        return parseEvents(refineInputs(input), null, context);
4224    }
4225    function refineInputs(input) {
4226        var rawDefs;
4227        if (input === true) {
4228            rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
4229        }
4230        else if (Array.isArray(input)) {
4231            // if specifying an array, every sub-definition NEEDS a day-of-week
4232            rawDefs = input.filter(function (rawDef) {
4233                return rawDef.daysOfWeek;
4234            });
4235        }
4236        else if (typeof input === 'object' && input) { // non-null object
4237            rawDefs = [input];
4238        }
4239        else { // is probably false
4240            rawDefs = [];
4241        }
4242        rawDefs = rawDefs.map(function (rawDef) {
4243            return __assign(__assign({}, DEF_DEFAULTS), rawDef);
4244        });
4245        return rawDefs;
4246    }
4247
4248    function pointInsideRect(point, rect) {
4249        return point.left >= rect.left &&
4250            point.left < rect.right &&
4251            point.top >= rect.top &&
4252            point.top < rect.bottom;
4253    }
4254    // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
4255    function intersectRects(rect1, rect2) {
4256        var res = {
4257            left: Math.max(rect1.left, rect2.left),
4258            right: Math.min(rect1.right, rect2.right),
4259            top: Math.max(rect1.top, rect2.top),
4260            bottom: Math.min(rect1.bottom, rect2.bottom)
4261        };
4262        if (res.left < res.right && res.top < res.bottom) {
4263            return res;
4264        }
4265        return false;
4266    }
4267    function translateRect(rect, deltaX, deltaY) {
4268        return {
4269            left: rect.left + deltaX,
4270            right: rect.right + deltaX,
4271            top: rect.top + deltaY,
4272            bottom: rect.bottom + deltaY
4273        };
4274    }
4275    // Returns a new point that will have been moved to reside within the given rectangle
4276    function constrainPoint(point, rect) {
4277        return {
4278            left: Math.min(Math.max(point.left, rect.left), rect.right),
4279            top: Math.min(Math.max(point.top, rect.top), rect.bottom)
4280        };
4281    }
4282    // Returns a point that is the center of the given rectangle
4283    function getRectCenter(rect) {
4284        return {
4285            left: (rect.left + rect.right) / 2,
4286            top: (rect.top + rect.bottom) / 2
4287        };
4288    }
4289    // Subtracts point2's coordinates from point1's coordinates, returning a delta
4290    function diffPoints(point1, point2) {
4291        return {
4292            left: point1.left - point2.left,
4293            top: point1.top - point2.top
4294        };
4295    }
4296
4297    var canVGrowWithinCell;
4298    function getCanVGrowWithinCell() {
4299        if (canVGrowWithinCell == null) {
4300            canVGrowWithinCell = computeCanVGrowWithinCell();
4301        }
4302        return canVGrowWithinCell;
4303    }
4304    function computeCanVGrowWithinCell() {
4305        // for SSR, because this function is call immediately at top-level
4306        // TODO: just make this logic execute top-level, immediately, instead of doing lazily
4307        if (typeof document === 'undefined') {
4308            return true;
4309        }
4310        var el = document.createElement('div');
4311        el.style.position = 'absolute';
4312        el.style.top = '0px';
4313        el.style.left = '0px';
4314        el.innerHTML = '<table><tr><td><div></div></td></tr></table>';
4315        el.querySelector('table').style.height = '100px';
4316        el.querySelector('div').style.height = '100%';
4317        document.body.appendChild(el);
4318        var div = el.querySelector('div');
4319        var possible = div.offsetHeight > 0;
4320        document.body.removeChild(el);
4321        return possible;
4322    }
4323
4324    var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
4325    var Splitter = /** @class */ (function () {
4326        function Splitter() {
4327            this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
4328            this.splitDateSelection = memoize(this._splitDateSpan);
4329            this.splitEventStore = memoize(this._splitEventStore);
4330            this.splitIndividualUi = memoize(this._splitIndividualUi);
4331            this.splitEventDrag = memoize(this._splitInteraction);
4332            this.splitEventResize = memoize(this._splitInteraction);
4333            this.eventUiBuilders = {}; // TODO: typescript protection
4334        }
4335        Splitter.prototype.splitProps = function (props) {
4336            var _this = this;
4337            var keyInfos = this.getKeyInfo(props);
4338            var defKeys = this.getKeysForEventDefs(props.eventStore);
4339            var dateSelections = this.splitDateSelection(props.dateSelection);
4340            var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
4341            var eventStores = this.splitEventStore(props.eventStore, defKeys);
4342            var eventDrags = this.splitEventDrag(props.eventDrag);
4343            var eventResizes = this.splitEventResize(props.eventResize);
4344            var splitProps = {};
4345            this.eventUiBuilders = mapHash(keyInfos, function (info, key) {
4346                return _this.eventUiBuilders[key] || memoize(buildEventUiForKey);
4347            });
4348            for (var key in keyInfos) {
4349                var keyInfo = keyInfos[key];
4350                var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
4351                var buildEventUi = this.eventUiBuilders[key];
4352                splitProps[key] = {
4353                    businessHours: keyInfo.businessHours || props.businessHours,
4354                    dateSelection: dateSelections[key] || null,
4355                    eventStore: eventStore,
4356                    eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
4357                    eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
4358                    eventDrag: eventDrags[key] || null,
4359                    eventResize: eventResizes[key] || null
4360                };
4361            }
4362            return splitProps;
4363        };
4364        Splitter.prototype._splitDateSpan = function (dateSpan) {
4365            var dateSpans = {};
4366            if (dateSpan) {
4367                var keys = this.getKeysForDateSpan(dateSpan);
4368                for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
4369                    var key = keys_1[_i];
4370                    dateSpans[key] = dateSpan;
4371                }
4372            }
4373            return dateSpans;
4374        };
4375        Splitter.prototype._getKeysForEventDefs = function (eventStore) {
4376            var _this = this;
4377            return mapHash(eventStore.defs, function (eventDef) {
4378                return _this.getKeysForEventDef(eventDef);
4379            });
4380        };
4381        Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
4382            var defs = eventStore.defs, instances = eventStore.instances;
4383            var splitStores = {};
4384            for (var defId in defs) {
4385                for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
4386                    var key = _a[_i];
4387                    if (!splitStores[key]) {
4388                        splitStores[key] = createEmptyEventStore();
4389                    }
4390                    splitStores[key].defs[defId] = defs[defId];
4391                }
4392            }
4393            for (var instanceId in instances) {
4394                var instance = instances[instanceId];
4395                for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
4396                    var key = _c[_b];
4397                    if (splitStores[key]) { // must have already been created
4398                        splitStores[key].instances[instanceId] = instance;
4399                    }
4400                }
4401            }
4402            return splitStores;
4403        };
4404        Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
4405            var splitHashes = {};
4406            for (var defId in eventUiBases) {
4407                if (defId) { // not the '' key
4408                    for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
4409                        var key = _a[_i];
4410                        if (!splitHashes[key]) {
4411                            splitHashes[key] = {};
4412                        }
4413                        splitHashes[key][defId] = eventUiBases[defId];
4414                    }
4415                }
4416            }
4417            return splitHashes;
4418        };
4419        Splitter.prototype._splitInteraction = function (interaction) {
4420            var splitStates = {};
4421            if (interaction) {
4422                var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeys
4422ForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar
4423                );
4424                // can't rely on defKeys because event data is mutated
4425                var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
4426                var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
4427                var populate = function (key) {
4428                    if (!splitStates[key]) {
4429                        splitStates[key] = {
4430                            affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
4431                            mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
4432                            isEvent: interaction.isEvent
4433                        };
4434                    }
4435                };
4436                for (var key in affectedStores_1) {
4437                    populate(key);
4438                }
4439                for (var key in mutatedStores_1) {
4440                    populate(key);
4441                }
4442            }
4443            return splitStates;
4444        };
4445        return Splitter;
4446    }());
4447    function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
4448        var baseParts = [];
4449        if (allUi) {
4450            baseParts.push(allUi);
4451        }
4452        if (eventUiForKey) {
4453            baseParts.push(eventUiForKey);
4454        }
4455        var stuff = {
4456            '': combineEventUis(baseParts)
4457        };
4458        if (individualUi) {
4459            __assign(stuff, individualUi);
4460        }
4461        return stuff;
4462    }
4463
4464    function getDateMeta(date, todayRange, nowDate, dateProfile) {
4465        return {
4466            dow: date.getUTCDay(),
4467            isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)),
4468            isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),
4469            isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),
4470            isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false),
4471            isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false)
4472        };
4473    }
4474    function getDayClassNames(meta, theme) {
4475        var classNames = [
4476            'fc-day',
4477            'fc-day-' + DAY_IDS[meta.dow]
4478        ];
4479        if (meta.isDisabled) {
4480            classNames.push('fc-day-disabled');
4481        }
4482        else {
4483            if (meta.isToday) {
4484                classNames.push('fc-day-today');
4485                classNames.push(theme.getClass('today'));
4486            }
4487            if (meta.isPast) {
4488                classNames.push('fc-day-past');
4489            }
4490            if (meta.isFuture) {
4491                classNames.push('fc-day-future');
4492            }
4493            if (meta.isOther) {
4494                classNames.push('fc-day-other');
4495            }
4496        }
4497        return classNames;
4498    }
4499    function getSlotClassNames(meta, theme) {
4500        var classNames = [
4501            'fc-slot',
4502            'fc-slot-' + DAY_IDS[meta.dow]
4503        ];
4504        if (meta.isDisabled) {
4505            classNames.push('fc-slot-disabled');
4506        }
4507        else {
4508            if (meta.isToday) {
4509                classNames.push('fc-slot-today');
4510                classNames.push(theme.getClass('today'));
4511            }
4512            if (meta.isPast) {
4513                classNames.push('fc-slot-past');
4514            }
4515            if (meta.isFuture) {
4516                classNames.push('fc-slot-future');
4517            }
4518        }
4519        return classNames;
4520    }
4521
4522    function buildNavLinkData(date, type) {
4523        if (type === void 0) { type = 'day'; }
4524        return JSON.stringify({
4525            date: formatDayString(date),
4526            type: type
4527        });
4528    }
4529
4530    var _isRtlScrollbarOnLeft = null;
4531    function getIsRtlScrollbarOnLeft() {
4532        if (_isRtlScrollbarOnLeft === null) {
4533            _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
4534        }
4535        return _isRtlScrollbarOnLeft;
4536    }
4537    function computeIsRtlScrollbarOnLeft() {
4538        var outerEl = document.createElement('div');
4539        applyStyle(outerEl, {
4540            position: 'absolute',
4541            top: -1000,
4542            left: 0,
4543            border: 0,
4544            padding: 0,
4545            overflow: 'scroll',
4546            direction: 'rtl'
4547        });
4548        outerEl.innerHTML = '<div></div>';
4549        document.body.appendChild(outerEl);
4550        var innerEl = outerEl.firstChild;
4551        var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
4552        removeElement(outerEl);
4553        return res;
4554    }
4555
4556    var _scrollbarWidths;
4557    function getScrollbarWidths() {
4558        if (!_scrollbarWidths) {
4559            _scrollbarWidths = computeScrollbarWidths();
4560        }
4561        return _scrollbarWidths;
4562    }
4563    function computeScrollbarWidths() {
4564        var el = document.createElement('div');
4565        el.style.overflow = 'scroll';
4566        document.body.appendChild(el);
4567        var res = computeScrollbarWidthsForEl(el);
4568        document.body.removeChild(el);
4569        return res;
4570    }
4571    // WARNING: will include border
4572    function computeScrollbarWidthsForEl(el) {
4573        return {
4574            x: el.offsetHeight - el.clientHeight,
4575            y: el.offsetWidth - el.clientWidth
4576        };
4577    }
4578
4579    function computeEdges(el, getPadding) {
4580        if (getPadding === void 0) { getPadding = false; }
4581        var computedStyle = window.getComputedStyle(el);
4582        var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
4583        var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
4584        var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
4585        var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
4586        var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border!
4587        var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;
4588        var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;
4589        var res = {
4590            borderLeft: borderLeft,
4591            borderRight: borderRight,
4592            borderTop: borderTop,
4593            borderBottom: borderBottom,
4594            scrollbarBottom: scrollbarBottom,
4595            scrollbarLeft: 0,
4596            scrollbarRight: 0
4597        };
4598        if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
4599            res.scrollbarLeft = scrollbarLeftRight;
4600        }
4601        else {
4602            res.scrollbarRight = scrollbarLeftRight;
4603        }
4604        if (getPadding) {
4605            res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
4606            res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
4607            res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
4608            res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
4609        }
4610        return res;
4611    }
4612    function computeInnerRect(el, goWithinPadding, doFromWindowViewport) {
4613        if (goWithinPadding === void 0) { goWithinPadding = false; }
4614        var outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);
4615        var edges = computeEdges(el, goWithinPadding);
4616        var res = {
4617            left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
4618            right: outerRect.right - edges.borderRight - edges.scrollbarRight,
4619            top: outerRect.top + edges.borderTop,
4620            bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom
4621        };
4622        if (goWithinPadding) {
4623            res.left += edges.paddingLeft;
4624            res.right -= edges.paddingRight;
4625            res.top += edges.paddingTop;
4626            res.bottom -= edges.paddingBottom;
4627        }
4628        return res;
4629    }
4630    function computeRect(el) {
4631        var rect = el.getBoundingClientRect();
4632        return {
4633            left: rect.left + window.pageXOffset,
4634            top: rect.top + window.pageYOffset,
4635            right: rect.right + window.pageXOffset,
4636            bottom: rect.bottom + window.pageYOffset
4637        };
4638    }
4639    function computeHeightAndMargins(el) {
4640        return el.getBoundingClientRect().height + computeVMargins(el);
4641    }
4642    function computeVMargins(el) {
4643        var computed = window.getComputedStyle(el);
4644        return parseInt(computed.marginTop, 10) +
4645            parseInt(computed.marginBottom, 10);
4646    }
4647    // does not return window
4648    function getClippingParents(el) {
4649        var parents = [];
4650        while (el instanceof HTMLElement) { // will stop when gets to document or null
4651            var computedStyle = window.getComputedStyle(el);
4652            if (computedStyle.position === 'fixed') {
4653                break;
4654            }
4655            if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
4656                parents.push(el);
4657            }
4658            el = el.parentNode;
4659        }
4660        return parents;
4661    }
4662
4663    // given a function that resolves a result asynchronously.
4664    // the function can either call passed-in success and failure callbacks,
4665    // or it can return a promise.
4666    // if you need to pass additional params to func, bind them first.
4667    function unpromisify(func, success, failure) {
4668        // guard against success/failure callbacks being called more than once
4669        // and guard against a promise AND callback being used together.
4670        var isResolved = false;
4671        var wrappedSuccess = function () {
4672            if (!isResolved) {
4673                isResolved = true;
4674                success.apply(this, arguments);
4675            }
4676        };
4677        var wrappedFailure = function () {
4678            if (!isResolved) {
4679                isResolved = true;
4680                if (failure) {
4681                    failure.apply(this, arguments);
4682                }
4683            }
4684        };
4685        var res = func(wrappedSuccess, wrappedFailure);
4686        if (res && typeof res.then === 'function') {
4687            res.then(wrappedSuccess, wrappedFailure);
4688        }
4689    }
4690
4691    var Emitter = /** @class */ (function () {
4692        function Emitter() {
4693            this.handlers = {};
4694            this.thisContext = null;
4695        }
4696        Emitter.prototype.setThisContext = function (thisContext) {
4697            this.thisContext = thisContext;
4698        };
4699        Emitter.prototype.setOptions = function (options) {
4700            this.options = options;
4701        };
4702        Emitter.prototype.on = function (type, handler) {
4703            addToHash(this.handlers, type, handler);
4704        };
4705        Emitter.prototype.off = function (type, handler) {
4706            removeFromHash(this.handlers, type, handler);
4707        };
4708        Emitter.prototype.trigger = function (type) {
4709            var args = [];
4710            for (var _i = 1; _i < arguments.length; _i++) {
4711                args[_i - 1] = arguments[_i];
4712            }
4713            var attachedHandlers = this.handlers[type] || [];
4714            var optionHandler = this.options && this.options[type];
4715            var handlers = [].concat(optionHandler || [], attachedHandlers);
4716            for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) {
4717                var handler = handlers_1[_a];
4718                handler.apply(this.thisContext, args);
4719            }
4720        };
4721        Emitter.prototype.hasHandlers = function (type) {
4722            return (this.handlers[type] && this.handlers[type].length) ||
4723                (this.options && this.options[type]);
4724        };
4725        return Emitter;
4726    }());
4727    function addToHash(hash, type, handler) {
4728        (hash[type] || (hash[type] = []))
4729            .push(handler);
4730    }
4731    function removeFromHash(hash, type, handler) {
4732        if (handler) {
4733            if (hash[type]) {
4734                hash[type] = hash[type].filter(function (func) {
4735                    return func !== handler;
4736                });
4737            }
4738        }
4739        else {
4740            delete hash[type]; // remove all handler funcs for this type
4741        }
4742    }
4743
4744    /*
4745    Records offset information for a set of elements, relative to an origin element.
4746    Can record the left/right OR the top/bottom OR both.
4747    Provides methods for querying the cache by position.
4748    */
4749    var PositionCache = /** @class */ (function () {
4750        function PositionCache(originEl, els, isHorizontal, isVertical) {
4751            this.els = els;
4752            var originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left
4753            if (isHorizontal) {
4754                this.buildElHorizontals(originClientRect.left);
4755            }
4756            if (isVertical) {
4757                this.buildElVerticals(originClientRect.top);
4758            }
4759        }
4760        // Populates the left/right internal coordinate arrays
4761        PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
4762            var lefts = [];
4763            var rights = [];
4764            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
4765                var el = _a[_i];
4766                var rect = el.getBoundingClientRect();
4767                lefts.push(rect.left - originClientLeft);
4768                rights.push(rect.right - originClientLeft);
4769            }
4770            this.lefts = lefts;
4771            this.rights = rights;
4772        };
4773        // Populates the top/bottom internal coordinate arrays
4774        PositionCache.prototype.buildElVerticals = function (originClientTop) {
4775            var tops = [];
4776            var bottoms = [];
4777            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
4778                var el = _a[_i];
4779                var rect = el.getBoundingClientRect();
4780                tops.push(rect.top - originClientTop);
4781                bottoms.push(rect.bottom - originClientTop);
4782            }
4783            this.tops = tops;
4784            this.bottoms = bottoms;
4785        };
4786        // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
4787        // If no intersection is made, returns undefined.
4788        PositionCache.prototype.leftToIndex = function (leftPosition) {
4789            var lefts = this.lefts;
4790            var rights = this.rights;
4791            var len = lefts.length;
4792            var i;
4793            for (i = 0; i < len; i++) {
4794                if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
4795                    return i;
4796                }
4797            }
4798        };
4799        // Given a top offset (from document top), returns the index of the el that it vertically intersects.
4800        // If no intersection is made, returns undefined.
4801        PositionCache.prototype.topToIndex = function (topPosition) {
4802            var tops = this.tops;
4803            var bottoms = this.bottoms;
4804            var len = tops.length;
4805            var i;
4806            for (i = 0; i < len; i++) {
4807                if (topPosition >= tops[i] && topPosition < bottoms[i]) {
4808                    return i;
4809                }
4810            }
4811        };
4812        // Gets the width of the element at the given index
4813        PositionCache.prototype.getWidth = function (leftIndex) {
4814            return this.rights[leftIndex] - this.lefts[leftIndex];
4815        };
4816        // Gets the height of the element at the given index
4817        PositionCache.prototype.getHeight = function (topIndex) {
4818            return this.bottoms[topIndex] - this.tops[topIndex];
4819        };
4820        return PositionCache;
4821    }());
4822
4823    /*
4824    An object for getting/setting scroll-related information for an element.
4825    Internally, this is done very differently for window versus DOM element,
4826    so this object serves as a common interface.
4827    */
4828    var ScrollController = /** @class */ (function () {
4829        function ScrollController() {
4830        }
4831        ScrollController.prototype.getMaxScrollTop = function () {
4832            return this.getScrollHeight() - this.getClientHeight();
4833        };
4834        ScrollController.prototype.getMaxScrollLeft = function () {
4835            return this.getScrollWidth() - this.getClientWidth();
4836        };
4837        ScrollController.prototype.canScrollVertically = function () {
4838            return this.getMaxScrollTop() > 0;
4839        };
4840        ScrollController.prototype.canScrollHorizontally = function () {
4841            return this.getMaxScrollLeft() > 0;
4842        };
4843        ScrollController.prototype.canScrollUp = function () {
4844            return this.getScrollTop() > 0;
4845        };
4846        ScrollController.prototype.canScrollDown = function () {
4847            return this.getScrollTop() < this.getMaxScrollTop();
4848        };
4849        ScrollController.prototype.canScrollLeft = function () {
4850            return this.getScrollLeft() > 0;
4851        };
4852        ScrollController.prototype.canScrollRight = function () {
4853            return this.getScrollLeft() < this.getMaxScrollLeft();
4854        };
4855        return ScrollController;
4856    }());
4857    var ElementScrollController = /** @class */ (function (_super) {
4858        __extends(ElementScrollController, _super);
4859        function ElementScrollController(el) {
4860            var _this = _super.call(this) || this;
4861            _this.el = el;
4862            return _this;
4863        }
4864        ElementScrollController.prototype.getScrollTop = function () {
4865            return this.el.scrollTop;
4866        };
4867        ElementScrollController.prototype.getScrollLeft = function () {
4868            return this.el.scrollLeft;
4869        };
4870        ElementScrollController.prototype.setScrollTop = function (top) {
4871            this.el.scrollTop = top;
4872        };
4873        ElementScrollController.prototype.setScrollLeft = function (left) {
4874            this.el.scrollLeft = left;
4875        };
4876        ElementScrollController.prototype.getScrollWidth = function () {
4877            return this.el.scrollWidth;
4878        };
4879        ElementScrollController.prototype.getScrollHeight = function () {
4880            return this.el.scrollHeight;
4881        };
4882        ElementScrollController.prototype.getClientHeight = function () {
4883            return this.el.clientHeight;
4884        };
4885        ElementScrollController.prototype.getClientWidth = function () {
4886            return this.el.clientWidth;
4887        };
4888        return ElementScrollController;
4889    }(ScrollController));
4890    var WindowScrollController = /** @class */ (function (_super) {
4891        __extends(WindowScrollController, _super);
4892        function WindowScrollController() {
4893            return _super !== null && _super.apply(this, arguments) || this;
4894        }
4895        WindowScrollController.prototype.getScrollTop = function () {
4896            return window.pageYOffset;
4897        };
4898        WindowScrollController.prototype.getScrollLeft = function () {
4899            return window.pageXOffset;
4900        };
4901        WindowScrollController.prototype.setScrollTop = function (n) {
4902            window.scroll(window.pageXOffset, n);
4903        };
4904        WindowScrollController.prototype.setScrollLeft = function (n) {
4905            window.scroll(n, window.pageYOffset);
4906        };
4907        WindowScrollController.prototype.getScrollWidth = function () {
4908            return document.documentElement.scrollWidth;
4909        };
4910        WindowScrollController.prototype.getScrollHeight = function () {
4911            return document.documentElement.scrollHeight;
4912        };
4913        WindowScrollController.prototype.getClientHeight = function () {
4914            return document.documentElement.clientHeight;
4915        };
4916        WindowScrollController.prototype.getClientWidth = function () {
4917            return document.documentElement.clientWidth;
4918        };
4919        return WindowScrollController;
4920    }(ScrollController));
4921
4922    var Theme = /** @class */ (function () {
4923        function Theme(calendarOptions) {
4924            if (this.iconOverrideOption) {
4925                this.setIconOverride(calendarOptions[this.iconOverrideOption]);
4926            }
4927        }
4928        Theme.prototype.setIconOverride = function (iconOverrideHash) {
4929            var iconClassesCopy;
4930            var buttonName;
4931            if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
4932                iconClassesCopy = __assign({}, this.iconClasses);
4933                for (buttonName in iconOverrideHash) {
4934                    iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
4935                }
4936                this.iconClasses = iconClassesCopy;
4937            }
4938            else if (iconOverrideHash === false) {
4939                this.iconClasses = {};
4940            }
4941        };
4942        Theme.prototype.applyIconOverridePrefix = function (className) {
4943            var prefix = this.iconOverridePrefix;
4944            if (prefix && className.indexOf(prefix) !== 0) { // if not already present
4945                className = prefix + className;
4946            }
4947            return className;
4948        };
4949        Theme.prototype.getClass = function (key) {
4950            return this.classes[key] || '';
4951        };
4952        Theme.prototype.getIconClass = function (buttonName, isRtl) {
4953            var className;
4954            if (isRtl && this.rtlIconClasses) {
4955                className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName];
4956            }
4957            else {
4958                className = this.iconClasses[buttonName];
4959            }
4960            if (className) {
4961                return this.baseIconClass + ' ' + className;
4962            }
4963            return '';
4964        };
4965        Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
4966            var className;
4967            if (this.iconOverrideCustomButtonOption) {
4968                className = customButtonProps[this.iconOverrideCustomButtonOption];
4969                if (className) {
4970                    return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
4971                }
4972            }
4973            return '';
4974        };
4975        return Theme;
4976    }());
4977    Theme.prototype.classes = {};
4978    Theme.prototype.iconClasses = {};
4979    Theme.prototype.baseIconClass = '';
4980    Theme.prototype.iconOverridePrefix = '';
4981
4982    /// <reference types="@fullcalendar/core-vdom" />
4983    if (typeof FullCalendarVDom === 'undefined') {
4984        throw new Error('Please import the top-level fullcalendar lib before attempting to import a plugin.');
4985    }
4986    var Component = FullCalendarVDom.Component;
4987    var createElement = FullCalendarVDom.createElement;
4988    var render = FullCalendarVDom.render;
4989    var createRef = FullCalendarVDom.createRef;
4990    var Fragment = FullCalendarVDom.Fragment;
4991    var createContext$1 = FullCalendarVDom.createContext;
4992    var flushToDom$1 = FullCalendarVDom.flushToDom;
4993
4994    var ScrollResponder = /** @class */ (function () {
4995        function ScrollResponder(execFunc, emitter, scrollTime) {
4996            var _this = this;
4997            this.execFunc = execFunc;
4998            this.emitter = emitter;
4999            this.scrollTime = scrollTime;
5000            this.handleScrollRequest = function (request) {
5001                _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request);
5002                _this.drain();
5003            };
5004            emitter.on('_scrollRequest', this.handleScrollRequest);
5005            this.fireInitialScroll();
5006        }
5007        ScrollResponder.prototype.detach = function () {
5008            this.emitter.off('_scrollRequest', this.handleScrollRequest);
5009        };
5010        ScrollResponder.prototype.update = function (isDatesNew) {
5011            if (isDatesNew) {
5012                this.fireInitialScroll(); // will drain
5013            }
5014            else {
5015                this.drain();
5016            }
5017        };
5018        ScrollResponder.prototype.fireInitialScroll = function () {
5019            this.handleScrollRequest({
5020                time: this.scrollTime
5021            });
5022        };
5023        ScrollResponder.prototype.drain = function () {
5024            if (this.queuedRequest && this.execFunc(this.queuedRequest)) {
5025                this.queuedRequest = null;
5026            }
5027        };
5028        return ScrollResponder;
5029    }());
5030
5031    var ViewContextType = createContext$1({}); // for Components
5032    function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
5033        return {
5034            dateEnv: dateEnv,
5035            options: viewOptions,
5036            pluginHooks: pluginHooks,
5037            emitter: emitter,
5038            dispatch: dispatch,
5039            getCurrentData: getCurrentData,
5040            calendarApi: calendarApi,
5041            viewSpec: viewSpec,
5042            viewApi: viewApi,
5043            dateProfileGenerator: dateProfileGenerator,
5044            theme: theme,
5045            isRtl: viewOptions.direction === 'rtl',
5046            addResizeHandler: function (handler) {
5047                emitter.on('_resize', handler);
5048            },
5049            removeResizeHandler: function (handler) {
5050                emitter.off('_resize', handler);
5051            },
5052            createScrollResponder: function (execFunc) {
5053                return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime));
5054            },
5055            registerInteractiveComponent: registerInteractiveComponent,
5056            unregisterInteractiveComponent: unregisterInteractiveComponent
5057        };
5058    }
5059
5060    var PureComponent = /** @class */ (function (_super) {
5061        __extends(PureComponent, _super);
5062        function PureComponent() {
5063            return _super !== null && _super.apply(this, arguments) || this;
5064        }
5065        PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
5066            if (this.debug) {
5067                console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state));
5068            }
5069            return !compareObjs(this.props, nextProps, this.propEquality) ||
5070                !compareObjs(this.state, nextState, this.stateEquality);
5071        };
5072        PureComponent.addPropsEquality = addPropsEquality;
5073        PureComponent.addStateEquality = addStateEquality;
5074        PureComponent.contextType = ViewContextType;
5075        return PureComponent;
5076    }(Component));
5077    PureComponent.prototype.propEquality = {};
5078    PureComponent.prototype.stateEquality = {};
5079    var BaseComponent = /** @class */ (function (_super) {
5080        __extends(BaseComponent, _super);
5081        function BaseComponent() {
5082            return _super !== null && _super.apply(this, arguments) || this;
5083        }
5084        BaseComponent.contextType = ViewContextType;
5085        return BaseComponent;
5086    }(PureComponent));
5087    function addPropsEquality(propEquality) {
5088        var hash = Object.create(this.prototype.propEquality);
5089        __assign(hash, propEquality);
5090        this.prototype.propEquality = hash;
5091    }
5092    function addStateEquality(stateEquality) {
5093        var hash = Object.create(this.prototype.stateEquality);
5094        __assign(hash, stateEquality);
5095        this.prototype.stateEquality = hash;
5096    }
5097    // use other one
5098    function setRef(ref, current) {
5099        if (typeof ref === 'function') {
5100            ref(current);
5101        }
5102        else if (ref) {
5103            // see https://github.com/facebook/react/issues/13029
5104            ref.current = current;
5105        }
5106    }
5107
5108    function reduceEventStore(eventStore, action, eventSources, dateProfile, context) {
5109        switch (action.type) {
5110            case 'RECEIVE_EVENTS': // raw
5111                return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context);
5112            case 'ADD_EVENTS': // already parsed, but not expanded
5113                return addEvent(eventStore, action.eventStore, // new ones
5114                dateProfile ? dateProfile.activeRange : null, context);
5115            case 'MERGE_EVENTS': // already parsed and expanded
5116                return mergeEventStores(eventStore, action.eventStore);
5117            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
5118            case 'NEXT':
5119            case 'CHANGE_DATE':
5120            case 'CHANGE_VIEW_TYPE':
5121                if (dateProfile) {
5122                    return expandRecurring(eventStore, dateProfile.activeRange, context);
5123                }
5124                else {
5125                    return eventStore;
5126                }
5127            case 'REMOVE_EVENTS':
5128                return excludeSubEventStore(eventStore, action.eventStore);
5129            case 'REMOVE_EVENT_SOURCE':
5130                return excludeEventsBySourceId(eventStore, action.sourceId);
5131            case 'REMOVE_ALL_EVENT_SOURCES':
5132                return filterEventStoreDefs(eventStore, function (eventDef) {
5133                    return !eventDef.sourceId; // only keep events with no source id
5134                });
5135            case 'REMOVE_ALL_EVENTS':
5136                return createEmptyEventStore();
5137            default:
5138                return eventStore;
5139        }
5140    }
5141    function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) {
5142        if (eventSource && // not already removed
5143            fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
5144        ) {
5145            var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context);
5146            if (fetchRange) {
5147                subset = expandRecurring(subset, fetchRange, context);
5148            }
5149            return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
5150        }
5151        return eventStore;
5152    }
5153    function transformRawEvents(rawEvents, eventSource, context) {
5154        var calEachTransform = context.options.eventDataTransform;
5155        var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
5156        if (sourceEachTransform) {
5157            rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
5158        }
5159        if (calEachTransform) {
5160            rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
5161        }
5162        return rawEvents;
5163    }
5164    function transformEachRawEvent(rawEvents, func) {
5165        var refinedEvents;
5166        if (!func) {
5167            refinedEvents = rawEvents;
5168        }
5169        else {
5170            refinedEvents = [];
5171            for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
5172                var rawEvent = rawEvents_1[_i];
5173                var refinedEvent = func(rawEvent);
5174                if (refinedEvent) {
5175                    refinedEvents.push(refinedEvent);
5176                }
5177                else if (refinedEvent == null) {
5178                    refinedEvents.push(rawEvent);
5179                } // if a different falsy value, do nothing
5180            }
5181        }
5182        return refinedEvents;
5183    }
5184    function addEvent(eventStore, subset, expandRange, context) {
5185        if (expandRange) {
5186            subset = expandRecurring(subset, expandRange, context);
5187        }
5188        return mergeEventStores(eventStore, subset);
5189    }
5190    function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) {
5191        var defs = eventStore.defs;
5192        var instances = mapHash(eventStore.instances, function (instance) {
5193            var def = defs[instance.defId];
5194            if (def.allDay || def.recurringDef) {
5195                return instance; // isn't dependent on timezone
5196            }
5197            else {
5198                return __assign(__assign({}, instance), { range: {
5199                        start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
5200                        end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo))
5201                    }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
5202            }
5203        });
5204        return { defs: defs, instances: instances };
5205    }
5206    function excludeEventsBySourceId(eventStore, sourceId) {
5207        return filterEventStoreDefs(eventStore, function (eventDef) {
5208            return eventDef.sourceId !== sourceId;
5209        });
5210    }
5211    // QUESTION: why not just return instances? do a general object-property-exclusion util
5212    function excludeInstances(eventStore, removals) {
5213        return {
5214            defs: eventStore.defs,
5215            instances: filterHash(eventStore.instances, function (instance) {
5216                return !removals[instance.instanceId];
5217            })
5218        };
5219    }
5220
5221    // high-level segmenting-aware tester functions
5222    // ------------------------------------------------------------------------------------------------------------------------
5223    function isInteractionValid(interaction, context) {
5224        return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions
5225    }
5226    function isDateSelectionValid(dateSelection, context) {
5227        return isNewPropsValid({ dateSelection: dateSelection }, context);
5228    }
5229    function isNewPropsValid(newProps, context) {
5230        var calendarState = context.getCurrentData();
5231        var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
5232        return (context.pluginHooks.isPropsValid || isPropsValid)(props, context);
5233    }
5234    function isPropsValid(state, context, dateSpanMeta, filterConfig) {
5235        if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
5236        if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) {
5237            return false;
5238        }
5239        if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) {
5240            return false;
5241        }
5242        return true;
5243    }
5244    // Moving Event Validation
5245    // ------------------------------------------------------------------------------------------------------------------------
5246    function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) {
5247        var currentState = context.getCurrentData();
5248        var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
5249        var subjectEventStore = interaction.mutatedEvents;
5250        var subjectDefs = subjectEventStore.defs;
5251        var subjectInstances = subjectEventStore.instances;
5252        var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
5253            state.eventUiBases :
5254            { '': currentState.selectionConfig } // if not a real event, validate as a selection
5255        );
5256        if (filterConfig) {
5257            subjectConfigs = mapHash(subjectConfigs, filterConfig);
5258        }
5259        var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); // exclude the subject events. TODO: exclude defs too?
5260        var otherDefs = otherEventStore.defs;
5261        var otherInstances = otherEventStore.instances;
5262        var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
5263        for (var subjectInstanceId in subjectInstances) {
5264            var subjectInstance = subjectInstances[subjectInstanceId];
5265            var subjectRange = subjectInstance.range;
5266            var subjectConfig = subjectConfigs[subjectInstance.defId];
5267            var subjectDef = subjectDefs[subjectInstance.defId];
5268            // constraint
5269            if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) {
5270                return false;
5271            }
5272            // overlap
5273            var eventOverlap = context.options.eventOverlap;
5274            var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null;
5275            for (var otherInstanceId in otherInstances) {
5276                var otherInstance = otherInstances[otherInstanceId];
5277                // intersect! evaluate
5278                if (rangesIntersect(subjectRange, otherInstance.range)) {
5279                    var otherOverlap = otherConfigs[otherInstance.defId].overlap;
5280                    // consider the other event's overlap. only do this if the subject event is a "real" event
5281                    if (otherOverlap === false && interaction.isEvent) {
5282                        return false;
5283                    }
5284                    if (subjectConfig.overlap === false) {
5285                        return false;
5286                    }
5287                    if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event
5288                    new EventApi(context, subjectDef, subjectInstance) // moving event
5289                    )) {
5290                        return false;
5291                    }
5292                }
5293            }
5294            // allow (a function)
5295            var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state
5296            for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
5297                var subjectAllow = _a[_i];
5298                var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay });
5299                var origDef = calendarEventStore.defs[subjectDef.defId];
5300                var origInstance = calendarEventStore.instances[subjectInstanceId];
5301                var eventApi = void 0;
5302                if (origDef) { // was previously in the calendar
5303                    eventApi = new EventApi(context, origDef, origInstance);
5304                }
5305                else { // was an external event
5306                    eventApi = new EventApi(context, subjectDef); // no instance, because had no dates
5307                }
5308                if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) {
5309                    return false;
5310                }
5311            }
5312        }
5313        return true;
5314    }
5315    // Date Selection Validation
5316    // ------------------------------------------------------------------------------------------------------------------------
5317    function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) {
5318        var relevantEventStore = state.eventStore;
5319        var relevantDefs = relevantEventStore.defs;
5320        var relevantInstances = relevantEventStore.instances;
5321        var selection = state.dateSelection;
5322        var selectionRange = selection.range;
5323        var selectionConfig = context.getCurrentData().selectionConfig;
5324        if (filterConfig) {
5325            selectionConfig = filterConfig(selectionConfig);
5326        }
5327        // constraint
5328        if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) {
5329            return false;
5330        }
5331        // overlap
5332        var selectOverlap = context.options.selectOverlap;
5333        var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null;
5334        for (var relevantInstanceId in relevantInstances) {
5335            var relevantInstance = relevantInstances[relevantInstanceId];
5336            // intersect! evaluate
5337            if (rangesIntersect(selectionRange, relevantInstance.range)) {
5338                if (selectionConfig.overlap === false) {
5339                    return false;
5340                }
5341                if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) {
5342                    return false;
5343                }
5344            }
5345        }
5346        // allow (a function)
5347        for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
5348            var selectionAllow = _a[_i];
5349            var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection);
5350            if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) {
5351                return false;
5352            }
5353        }
5354        return true;
5355    }
5356    // Constraint Utils
5357    // ------------------------------------------------------------------------------------------------------------------------
5358    function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) {
5359        for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
5360            var constraint = constraints_1[_i];
5361            if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) {
5362                return false;
5363            }
5364        }
5365        return true;
5366    }
5367    function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
5368    otherEventStore, // for if constraint is an even group ID
5369    businessHoursUnexpanded, // for if constraint is 'businessHours'
5370    context // for expanding businesshours
5371    ) {
5372        if (constraint === 'businessHours') {
5373            return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context));
5374        }
5375        else if (typeof constraint === 'string') { // an group ID
5376            return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) {
5377                return eventDef.groupId === constraint;
5378            }));
5379        }
5380        else if (typeof constraint === 'object' && constraint) { // non-null object
5381            return eventStoreToRanges(expandRecurring(constraint, subjectRange, context));
5382        }
5383        return []; // if it's false
5384    }
5385    // TODO: move to event-store file?
5386    function eventStoreToRanges(eventStore) {
5387        var instances = eventStore.instances;
5388        var ranges = [];
5389        for (var instanceId in instances) {
5390            ranges.push(instances[instanceId].range);
5391        }
5392        return ranges;
5393    }
5394    // TODO: move to geom file?
5395    function anyRangesContainRange(outerRanges, innerRange) {
5396        for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
5397            var outerRange = outerRanges_1[_i];
5398            if (rangeContainsRange(outerRange, innerRange)) {
5399                return true;
5400            }
5401        }
5402        return false;
5403    }
5404
5405    /*
5406    an INTERACTABLE date component
5407
5408    PURPOSES:
5409    - hook up to fg, fill, and mirror renderers
5410    - interface for dragging and hits
5411    */
5412    var DateComponent = /** @class */ (function (_super) {
5413        __extends(DateComponent, _super);
5414        function DateComponent() {
5415            var _this = _super !== null && _super.apply(this, arguments) || this;
5416            _this.uid = guid();
5417            return _this;
5418        }
5419        // Hit System
5420        // -----------------------------------------------------------------------------------------------------------------
5421        DateComponent.prototype.prepareHits = function () {
5422        };
5423        DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
5424            return null; // this should be abstract
5425        };
5426        // Validation
5427        // -----------------------------------------------------------------------------------------------------------------
5428        DateComponent.prototype.isInteractionValid = function (interaction) {
5429            var dateProfile = this.props.dateProfile; // HACK
5430            var instances = interaction.mutatedEvents.instances;
5431            if (dateProfile) { // HACK for MorePopover
5432                for (var instanceId in instances) {
5433                    if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
5434                        return false;
5435                    }
5436                }
5437            }
5438            return isInteractionValid(interaction, this.context);
5439        };
5440        DateComponent.prototype.isDateSelectionValid = function (selection) {
5441            var dateProfile = this.props.dateProfile; // HACK
5442            if (dateProfile && // HACK for MorePopover
5443                !rangeContainsRange(dateProfile.validRange, selection.range)) {
5444                return false;
5445            }
5446            return isDateSelectionValid(selection, this.context);
5447        };
5448        // Pointer Interaction Utils
5449        // -----------------------------------------------------------------------------------------------------------------
5450        DateComponent.prototype.isValidSegDownEl = function (el) {
5451            return !this.props.eventDrag && // HACK
5452                !this.props.eventResize && // HACK
5453                !elementClosest(el, '.fc-event-mirror') &&
5454                (this.isPopover() || !this.isInPopover(el));
5455            // ^above line ensures we don't detect a seg interaction within a nested component.
5456            // it's a HACK because it only supports a popover as the nested component.
5457        };
5458        DateComponent.prototype.isValidDateDownEl = function (el) {
5459            return !elementClosest(el, '.fc-event:not(.fc-bg-event)') &&
5460                !elementClosest(el, '.fc-daygrid-more-link') && // a "more.." link
5461                !elementClosest(el, 'a[data-navlink]') && // a clickable nav link
5462                !this.isInPopover(el);
5463        };
5464        DateComponent.prototype.isPopover = function () {
5465            return false;
5466        };
5467        DateComponent.prototype.isInPopover = function (el) {
5468            return Boolean(elementClosest(el, '.fc-popover'));
5469        };
5470        return DateComponent;
5471    }(BaseComponent));
5472
5473    // TODO: easier way to add new hooks? need to update a million things
5474    function createPlugin(input) {
5475        return {
5476            id: guid(),
5477            deps: input.deps || [],
5478            reducers: input.reducers || [],
5479            contextInit: [].concat(input.contextInit || []),
5480            eventRefiners: input.eventRefiners || {},
5481            eventDefMemberAdders: input.eventDefMemberAdders || [],
5482            eventSourceRefiners: input.eventSourceRefiners || {},
5483            isDraggableTransformers: input.isDraggableTransformers || [],
5484            eventDragMutationMassagers: input.eventDragMutationMassagers || [],
5485            eventDefMutationAppliers: input.eventDefMutationAppliers || [],
5486            dateSelectionTransformers: input.dateSelectionTransformers || [],
5487            datePointTransforms: input.datePointTransforms || [],
5488            dateSpanTransforms: input.dateSpanTransforms || [],
5489            views: input.views || {},
5490            viewPropsTransformers: input.viewPropsTransformers || [],
5491            isPropsValid: input.isPropsValid || null,
5492            externalDefTransforms: input.externalDefTransforms || [],
5493            eventResizeJoinTransforms: input.eventResizeJoinTransforms || [],
5494            viewContainerAppends: input.viewContainerAppends || [],
5495            eventDropTransformers: input.eventDropTransformers || [],
5496            componentInteractions: input.componentInteractions || [],
5497            calendarInteractions: input.calendarInteractions || [],
5498            themeClasses: input.themeClasses || {},
5499            eventSourceDefs: input.eventSourceDefs || [],
5500            cmdFormatter: input.cmdFormatter,
5501            recurringTypes: input.recurringTypes || [],
5502            namedTimeZonedImpl: input.namedTimeZonedImpl,
5503            initialView: input.initialView || '',
5504            elementDraggingImpl: input.elementDraggingImpl,
5505            optionChangeHandlers: input.optionChangeHandlers || {},
5506            scrollGridImpl: input.scrollGridImpl || null,
5507            contentTypeHandlers: input.contentTypeHandlers || {},
5508            listenerRefiners: input.listenerRefiners || {},
5509            optionRefiners: input.optionRefiners || {},
5510            propSetHandlers: input.propSetHandlers || {}
5511        };
5512    }
5513    function buildPluginHooks(pluginDefs, globalDefs) {
5514        var isAdded = {};
5515        var hooks = {
5516            reducers: [],
5517            contextInit: [],
5518            eventRefiners: {},
5519            eventDefMemberAdders: [],
5520            eventSourceRefiners: {},
5521            isDraggableTransformers: [],
5522            eventDragMutationMassagers: [],
5523            eventDefMutationAppliers: [],
5524            dateSelectionTransformers: [],
5525            datePointTransforms: [],
5526            dateSpanTransforms: [],
5527            views: {},
5528            viewPropsTransformers: [],
5529            isPropsValid: null,
5530            externalDefTransforms: [],
5531            eventResizeJoinTransforms: [],
5532            viewContainerAppends: [],
5533            eventDropTransformers: [],
5534            componentInteractions: [],
5535            calendarInteractions: [],
5536            themeClasses: {},
5537            eventSourceDefs: [],
5538            cmdFormatter: null,
5539            recurringTypes: [],
5540            namedTimeZonedImpl: null,
5541            initialView: '',
5542            elementDraggingImpl: null,
5543            optionChangeHandlers: {},
5544            scrollGridImpl: null,
5545            contentTypeHandlers: {},
5546            listenerRefiners: {},
5547            optionRefiners: {},
5548            propSetHandlers: {}
5549        };
5550        function addDefs(defs) {
5551            for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) {
5552                var def = defs_1[_i];
5553                if (!isAdded[def.id]) {
5554                    isAdded[def.id] = true;
5555                    addDefs(def.deps);
5556                    hooks = combineHooks(hooks, def);
5557                }
5558            }
5559        }
5560        if (pluginDefs) {
5561            addDefs(pluginDefs);
5562        }
5563        addDefs(globalDefs);
5564        return hooks;
5565    }
5566    function buildBuildPluginHooks() {
5567        var currentOverrideDefs = [];
5568        var currentGlobalDefs = [];
5569        var currentHooks;
5570        return function (overrideDefs, globalDefs) {
5571            if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) {
5572                currentHooks = buildPluginHooks(overrideDefs, globalDefs);
5573            }
5574            currentOverrideDefs = overrideDefs;
5575            currentGlobalDefs = globalDefs;
5576            return currentHooks;
5577        };
5578    }
5579    function combineHooks(hooks0, hooks1) {
5580        return {
5581            reducers: hooks0.reducers.concat(hooks1.reducers),
5582            contextInit: hooks0.contextInit.concat(hooks1.contextInit),
5583            eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners),
5584            eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),
5585            eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),
5586            isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
5587            eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
5588            eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
5589            dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
5590            datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
5591            dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
5592            views: __assign(__assign({}, hooks0.views), hooks1.views),
5593            viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
5594            isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
5595            externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
5596            eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms),
5597            viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),
5598            eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
5599            calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
5600            componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
5601            themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses),
5602            eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
5603            cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
5604            recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
5605            namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
5606            initialView: hooks0.initialView || hooks1.initialView,
5607            elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
5608            optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),
5609            scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,
5610            contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers),
5611            listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),
5612            optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners),
5613            propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers)
5614        };
5615    }
5616
5617    var StandardTheme = /** @class */ (function (_super) {
5618        __extends(StandardTheme, _super);
5619        function StandardTheme() {
5620            return _super !== null && _super.apply(this, arguments) || this;
5621        }
5622        return StandardTheme;
5623    }(Theme));
5624    StandardTheme.prototype.classes = {
5625        root: 'fc-theme-standard',
5626        tableCellShaded: 'fc-cell-shaded',
5627        buttonGroup: 'fc-button-group',
5628        button: 'fc-button fc-button-primary',
5629        buttonActive: 'fc-button-active'
5630    };
5631    StandardTheme.prototype.baseIconClass = 'fc-icon';
5632    StandardTheme.prototype.iconClasses = {
5633        close: 'fc-icon-x',
5634        prev: 'fc-icon-chevron-left',
5635        next: 'fc-icon-chevron-right',
5636        prevYear: 'fc-icon-chevrons-left',
5637        nextYear: 'fc-icon-chevrons-right'
5638    };
5639    StandardTheme.prototype.rtlIconClasses = {
5640        prev: 'fc-icon-chevron-right',
5641        next: 'fc-icon-chevron-left',
5642        prevYear: 'fc-icon-chevrons-right',
5643        nextYear: 'fc-icon-chevrons-left'
5644    };
5645    StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly
5646    StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
5647    StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
5648
5649    function compileViewDefs(defaultConfigs, overrideConfigs) {
5650        var hash = {};
5651        var viewType;
5652        for (viewType in defaultConfigs) {
5653            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5654        }
5655        for (viewType in overrideConfigs) {
5656            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5657        }
5658        return hash;
5659    }
5660    function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5661        if (hash[viewType]) {
5662            return hash[viewType];
5663        }
5664        var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5665        if (viewDef) {
5666            hash[viewType] = viewDef;
5667        }
5668        return viewDef;
5669    }
5670    function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5671        var defaultConfig = defaultConfigs[viewType];
5672        var overrideConfig = overrideConfigs[viewType];
5673        var queryProp = function (name) {
5674            return (defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
5675                ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null);
5676        };
5677        var theComponent = queryProp('component');
5678        var superType = queryProp('superType');
5679        var superDef = null;
5680        if (superType) {
5681            if (superType === viewType) {
5682                throw new Error('Can\'t have a custom view type that references itself');
5683            }
5684            superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
5685        }
5686        if (!theComponent && superDef) {
5687            theComponent = superDef.component;
5688        }
5689        if (!theComponent) {
5690            return null; // don't throw a warning, might be settings for a single-unit view
5691        }
5692        return {
5693            type: viewType,
5694            component: theComponent,
5695            defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),
5696            overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {}))
5697        };
5698    }
5699
5700    // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any???
5701    var RenderHook = /** @class */ (function (_super) {
5702        __extends(RenderHook, _super);
5703        function RenderHook() {
5704            var _this = _super !== null && _super.apply(this, arguments) || this;
5705            _this.rootElRef = createRef();
5706            _this.handleRootEl = function (el) {
5707                setRef(_this.rootElRef, el);
5708                if (_this.props.elRef) {
5709                    setRef(_this.props.elRef, el);
5710                }
5711            };
5712            return _this;
5713        }
5714        RenderHook.prototype.render = function () {
5715            var _this = this;
5716            var props = this.props;
5717            var hookProps = props.hookProps;
5718            return (createElement(MountHook, { hookProps: hookProps, didMount: props.didMount, willUnmount: props.willUnmount, elRef: this.handleRootEl }, function (rootElRef) { return (createElement(ContentHook, { hookProps: hookProps, content: props.content, defaultContent: props.defaultContent, backupElRef: _this.rootElRef }, function (innerElRef, innerContent) { return props.children(rootElRef, normalizeClassNames(props.classNames, hookProps), innerElRef, innerContent); })); }));
5719        };
5720        return RenderHook;
5721    }(BaseComponent));
5722    // for forcing rerender of components that use the ContentHook
5723    var CustomContentRenderContext = createContext$1(0);
5724    function ContentHook(props) {
5725        return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); }));
5726    }
5727    var ContentHookInner = /** @class */ (function (_super) {
5728        __extends(ContentHookInner, _super);
5729        function ContentHookInner() {
5730            var _this = _super !== null && _super.apply(this, arguments) || this;
5731            _this.innerElRef = createRef();
5732            return _this;
5733        }
5734        ContentHookInner.prototype.render = function () {
5735            return this.props.children(this.innerElRef, this.renderInnerContent());
5736        };
5737        ContentHookInner.prototype.componentDidMount = function () {
5738            this.updateCustomContent();
5739        };
5740        ContentHookInner.prototype.componentDidUpdate = function () {
5741            this.updateCustomContent();
5742        };
5743        ContentHookInner.prototype.renderInnerContent = function () {
5744            var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers;
5745            var _a = this, props = _a.props, customContentInfo = _a.customContentInfo;
5746            var rawVal = props.content;
5747            var innerContent = normalizeContent(rawVal, props.hookProps);
5748            var innerContentVDom = null;
5749            if (innerContent === undefined) { // use the default
5750                innerContent = normalizeContent(props.defaultContent, props.hookProps);
5751            }
5752            if (innerContent !== undefined) { // we allow custom content handlers to return nothing
5753                if (customContentInfo) {
5754                    customContentInfo.contentVal = innerContent[customContentInfo.contentKey];
5755                }
5756                else if (typeof innerContent === 'object') {
5757                    // look for a prop that would indicate a custom content handler is needed
5758                    for (var contentKey in contentTypeHandlers) {
5759                        if (innerContent[contentKey] !== undefined) {
5760                            customContentInfo = this.customContentInfo = {
5761                                contentKey: contentKey,
5762                                contentVal: innerContent[contentKey],
5763                                handler: contentTypeHandlers[contentKey]()
5764                            };
5765                            break;
5766                        }
5767                    }
5768                }
5769                if (customContentInfo) {
5770                    innerContentVDom = []; // signal that something was specified
5771                }
5772                else {
5773                    innerContentVDom = innerContent; // assume a [p]react vdom node. use it
5774                }
5775            }
5776            return innerContentVDom;
5777        };
5778        ContentHookInner.prototype.updateCustomContent = function () {
5779            if (this.customContentInfo) {
5780                this.customContentInfo.handler(this.innerElRef.current || this.props.backupElRef.current, // the element to render into
5781                this.customContentInfo.contentVal);
5782            }
5783        };
5784        return ContentHookInner;
5785    }(BaseComponent));
5786    var MountHook = /** @class */ (function (_super) {
5787        __extends(MountHook, _super);
5788        function MountHook() {
5789            var _this = _super !== null && _super.apply(this, arguments) || this;
5790            _this.handleRootEl = function (rootEl) {
5791                _this.rootEl = rootEl;
5792                if (_this.props.elRef) {
5793                    setRef(_this.props.elRef, rootEl);
5794                }
5795            };
5796            return _this;
5797        }
5798        MountHook.prototype.render = function () {
5799            return this.props.children(this.handleRootEl);
5800        };
5801        MountHook.prototype.componentDidMount = function () {
5802            var callback = this.props.didMount;
5803            callback && callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
5804        };
5805        MountHook.prototype.componentWillUnmount = function () {
5806            var callback = this.props.willUnmount;
5807            callback && callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
5808        };
5809        return MountHook;
5810    }(BaseComponent));
5811    function buildClassNameNormalizer() {
5812        var currentGenerator;
5813        var currentHookProps;
5814        var currentClassNames = [];
5815        return function (generator, hookProps) {
5816            if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) {
5817                currentGenerator = generator;
5818                currentHookProps = hookProps;
5819                currentClassNames = normalizeClassNames(generator, hookProps);
5820            }
5821            return currentClassNames;
5822        };
5823    }
5824    function normalizeClassNames(classNames, hookProps) {
5825        if (typeof classNames === 'function') {
5826            classNames = classNames(hookProps);
5827        }
5828        return parseClassNames(classNames);
5829    }
5830    function normalizeContent(input, hookProps) {
5831        if (typeof input === 'function') {
5832            return input(hookProps, createElement); // give the function the vdom-creation func
5833        }
5834        else {
5835            return input;
5836        }
5837    }
5838
5839    var ViewRoot = /** @class */ (function (_super) {
5840        __extends(ViewRoot, _super);
5841        function ViewRoot() {
5842            var _this = _super !== null && _super.apply(this, arguments) || this;
5843            _this.normalizeClassNames = buildClassNameNormalizer();
5844            return _this;
5845        }
5846        ViewRoot.prototype.render = function () {
5847            var _a = this, props = _a.props, context = _a.context;
5848            var options = context.options;
5849            var hookProps = { view: context.viewApi };
5850            var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps);
5851            return (createElement(MountHook, { hookProps: hookProps, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, ["fc-" + props.viewSpec.type + "-view", 'fc-view'].concat(customClassNames)); }));
5852        };
5853        return ViewRoot;
5854    }(BaseComponent));
5855
5856    function parseViewConfigs(inputs) {
5857        return mapHash(inputs, parseViewConfig);
5858    }
5859    function parseViewConfig(input) {
5860        var rawOptions = typeof input === 'function' ?
5861            { component: input } :
5862            input;
5863        var component = rawOptions.component;
5864        if (rawOptions.content) {
5865            component = createViewHookComponent(rawOptions);
5866            // TODO: remove content/classNames/didMount/etc from options?
5867        }
5868        return {
5869            superType: rawOptions.type,
5870            component: component,
5871            rawOptions: rawOptions // includes type and component too :(
5872        };
5873    }
5874    function createViewHookComponent(options) {
5875        return function (viewProps) {
5876            return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, viewClassNames) {
5877                var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold });
5878                return (createElement(RenderHook, { hookProps: hookProps, classNames: options.classNames, content: options.content, didMount: options.didMount, willUnmount: options.willUnmount, elRef: rootElRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("div", { className: viewClassNames.c
5878oncat(customClassNames).join(' '), ref: rootElRef }, innerContent)); }));
5879            })); }));
5880        };
5881    }
5882
5883    function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
5884        var defaultConfigs = parseViewConfigs(defaultInputs);
5885        var overrideConfigs = parseViewConfigs(optionOverrides.views);
5886        var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
5887        return mapHash(viewDefs, function (viewDef) {
5888            return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults);
5889        });
5890    }
5891    function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
5892        var durationInput = viewDef.overrides.duration ||
5893            viewDef.defaults.duration ||
5894            dynamicOptionOverrides.duration ||
5895            optionOverrides.duration;
5896        var duration = null;
5897        var durationUnit = '';
5898        var singleUnit = '';
5899        var singleUnitOverrides = {};
5900        if (durationInput) {
5901            duration = createDurationCached(durationInput);
5902            if (duration) { // valid?
5903                var denom = greatestDurationDenominator(duration);
5904                durationUnit = denom.unit;
5905                if (denom.value === 1) {
5906                    singleUnit = durationUnit;
5907                    singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};
5908                }
5909            }
5910        }
5911        var queryButtonText = function (optionsSubset) {
5912            var buttonTextMap = optionsSubset.buttonText || {};
5913            var buttonTextKey = viewDef.defaults.buttonTextKey;
5914            if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
5915                return buttonTextMap[buttonTextKey];
5916            }
5917            if (buttonTextMap[viewDef.type] != null) {
5918                return buttonTextMap[viewDef.type];
5919            }
5920            if (buttonTextMap[singleUnit] != null) {
5921                return buttonTextMap[singleUnit];
5922            }
5923        };
5924        return {
5925            type: viewDef.type,
5926            component: viewDef.component,
5927            duration: duration,
5928            durationUnit: durationUnit,
5929            singleUnit: singleUnit,
5930            optionDefaults: viewDef.defaults,
5931            optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides),
5932            buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||
5933                queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence
5934                viewDef.overrides.buttonText,
5935            buttonTextDefault: queryButtonText(localeDefaults) ||
5936                viewDef.defaults.buttonText ||
5937                queryButtonText(BASE_OPTION_DEFAULTS) ||
5938                viewDef.type // fall back to given view name
5939        };
5940    }
5941    // hack to get memoization working
5942    var durationInputMap = {};
5943    function createDurationCached(durationInput) {
5944        var json = JSON.stringify(durationInput);
5945        var res = durationInputMap[json];
5946        if (res === undefined) {
5947            res = createDuration(durationInput);
5948            durationInputMap[json] = res;
5949        }
5950        return res;
5951    }
5952
5953    var DateProfileGenerator = /** @class */ (function () {
5954        function DateProfileGenerator(props) {
5955            this.props = props;
5956            this.nowDate = getNow(props.nowInput, props.dateEnv);
5957            this.initHiddenDays();
5958        }
5959        /* Date Range Computation
5960        ------------------------------------------------------------------------------------------------------------------*/
5961        // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5962        DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) {
5963            var dateEnv = this.props.dateEnv;
5964            var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5965            currentDateProfile.dateIncrement);
5966            return this.build(prevDate, -1, forceToValid);
5967        };
5968        // Builds a structure with info about what the dates/ranges will be for the "next" view.
5969        DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) {
5970            var dateEnv = this.props.dateEnv;
5971            var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5972            currentDateProfile.dateIncrement);
5973            return this.build(nextDate, 1, forceToValid);
5974        };
5975        // Builds a structure holding dates/ranges for rendering around the given date.
5976        // Optional direction param indicates whether the date is being incremented/decremented
5977        // from its previous value. decremented = -1, incremented = 1 (default).
5978        DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
5979            if (forceToValid === void 0) { forceToValid = true; }
5980            var props = this.props;
5981            var validRange;
5982            var currentInfo;
5983            var isRangeAllDay;
5984            var renderRange;
5985            var activeRange;
5986            var isValid;
5987            validRange = this.buildValidRange();
5988            validRange = this.trimHiddenDays(validRange);
5989            if (forceToValid) {
5990                currentDate = constrainMarkerToRange(currentDate, validRange);
5991            }
5992            currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
5993            isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5994            renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
5995            renderRange = this.trimHiddenDays(renderRange);
5996            activeRange = renderRange;
5997            if (!props.showNonCurrentDates) {
5998                activeRange = intersectRanges(activeRange, currentInfo.range);
5999            }
6000            activeRange = this.adjustActiveRange(activeRange);
6001            activeRange = intersectRanges(activeRange, validRange); // might return null
6002            // it's invalid if the originally requested date is not contained,
6003            // or if the range is completely outside of the valid range.
6004            isValid = rangesIntersect(currentInfo.range, validRange);
6005            return {
6006                // constraint for where prev/next operations can go and where events can be dragged/resized to.
6007                // an object with optional start and end properties.
6008                validRange: validRange,
6009                // range the view is formally responsible for.
6010                // for example, a month view might have 1st-31st, excluding padded dates
6011                currentRange: currentInfo.range,
6012                // name of largest unit being displayed, like "month" or "week"
6013                currentRangeUnit: currentInfo.unit,
6014                isRangeAllDay: isRangeAllDay,
6015                // dates that display events and accept drag-n-drop
6016                // will be `null` if no dates accept events
6017                activeRange: activeRange,
6018                // date range with a rendered skeleton
6019                // includes not-active days that need some sort of DOM
6020                renderRange: renderRange,
6021                // Duration object that denotes the first visible time of any given day
6022                slotMinTime: props.slotMinTime,
6023                // Duration object that denotes the exclusive visible end time of any given day
6024                slotMaxTime: props.slotMaxTime,
6025                isValid: isValid,
6026                // how far the current date will move for a prev/next operation
6027                dateIncrement: this.buildDateIncrement(currentInfo.duration)
6028                // pass a fallback (might be null) ^
6029            };
6030        };
6031        // Builds an object with optional start/end properties.
6032        // Indicates the minimum/maximum dates to display.
6033        // not responsible for trimming hidden days.
6034        DateProfileGenerator.prototype.buildValidRange = function () {
6035            var input = this.props.validRangeInput;
6036            var simpleInput = typeof input === 'function'
6037                ? input.call(this.props.calendarApi, this.nowDate)
6038                : input;
6039            return this.refineRange(simpleInput) ||
6040                { start: null, end: null }; // completely open-ended
6041        };
6042        // Builds a structure with info about the "current" range, the range that is
6043        // highlighted as being the current month for example.
6044        // See build() for a description of `direction`.
6045        // Guaranteed to have `range` and `unit` properties. `duration` is optional.
6046        DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
6047            var props = this.props;
6048            var duration = null;
6049            var unit = null;
6050            var range = null;
6051            var dayCount;
6052            if (props.duration) {
6053                duration = props.duration;
6054                unit = props.durationUnit;
6055                range = this.buildRangeFromDuration(date, direction, duration, unit);
6056            }
6057            else if ((dayCount = this.props.dayCount)) {
6058                unit = 'day';
6059                range = this.buildRangeFromDayCount(date, direction, dayCount);
6060            }
6061            else if ((range = this.buildCustomVisibleRange(date))) {
6062                unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit;
6063            }
6064            else {
6065                duration = this.getFallbackDuration();
6066                unit = greatestDurationDenominator(duration).unit;
6067                range = this.buildRangeFromDuration(date, direction, duration, unit);
6068            }
6069            return { duration: duration, unit: unit, range: range };
6070        };
6071        DateProfileGenerator.prototype.getFallbackDuration = function () {
6072            return createDuration({ day: 1 });
6073        };
6074        // Returns a new activeRange to have time values (un-ambiguate)
6075        // slotMinTime or slotMaxTime causes the range to expand.
6076        DateProfileGenerator.prototype.adjustActiveRange = function (range) {
6077            var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime;
6078            var start = range.start;
6079            var end = range.end;
6080            if (usesMinMaxTime) {
6081                // expand active range if slotMinTime is negative (why not when positive?)
6082                if (asRoughDays(slotMinTime) < 0) {
6083                    start = startOfDay(start); // necessary?
6084                    start = dateEnv.add(start, slotMinTime);
6085                }
6086                // expand active range if slotMaxTime is beyond one day (why not when negative?)
6087                if (asRoughDays(slotMaxTime) > 1) {
6088                    end = startOfDay(end); // necessary?
6089                    end = addDays(end, -1);
6090                    end = dateEnv.add(end, slotMaxTime);
6091                }
6092            }
6093            return { start: start, end: end };
6094        };
6095        // Builds the "current" range when it is specified as an explicit duration.
6096        // `unit` is the already-computed greatestDurationDenominator unit of duration.
6097        DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
6098            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
6099            var start;
6100            var end;
6101            var res;
6102            // compute what the alignment should be
6103            if (!dateAlignment) {
6104                var dateIncrement = this.props.dateIncrement;
6105                if (dateIncrement) {
6106                    // use the smaller of the two units
6107                    if (asRoughMs(dateIncrement) < asRoughMs(duration)) {
6108                        dateAlignment = greatestDurationDenominator(dateIncrement).unit;
6109                    }
6110                    else {
6111                        dateAlignment = unit;
6112                    }
6113                }
6114                else {
6115                    dateAlignment = unit;
6116                }
6117            }
6118            // if the view displays a single day or smaller
6119            if (asRoughDays(duration) <= 1) {
6120                if (this.isHiddenDay(start)) {
6121                    start = this.skipHiddenDays(start, direction);
6122                    start = startOfDay(start);
6123                }
6124            }
6125            function computeRes() {
6126                start = dateEnv.startOf(date, dateAlignment);
6127                end = dateEnv.add(start, duration);
6128                res = { start: start, end: end };
6129            }
6130            computeRes();
6131            // if range is completely enveloped by hidden days, go past the hidden days
6132            if (!this.trimHiddenDays(res)) {
6133                date = this.skipHiddenDays(date, direction);
6134                computeRes();
6135            }
6136            return res;
6137        };
6138        // Builds the "current" range when a dayCount is specified.
6139        DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
6140            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
6141            var runningCount = 0;
6142            var start = date;
6143            var end;
6144            if (dateAlignment) {
6145                start = dateEnv.startOf(start, dateAlignment);
6146            }
6147            start = startOfDay(start);
6148            start = this.skipHiddenDays(start, direction);
6149            end = start;
6150            do {
6151                end = addDays(end, 1);
6152                if (!this.isHiddenDay(end)) {
6153                    runningCount++;
6154                }
6155            } while (runningCount < dayCount);
6156            return { start: start, end: end };
6157        };
6158        // Builds a normalized range object for the "visible" range,
6159        // which is a way to define the currentRange and activeRange at the same time.
6160        DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
6161            var props = this.props;
6162            var input = props.visibleRangeInput;
6163            var simpleInput = typeof input === 'function'
6164                ? input.call(props.calendarApi, props.dateEnv.toDate(date))
6165                : input;
6166            var range = this.refineRange(simpleInput);
6167            if (range && (range.start == null || range.end == null)) {
6168                return null;
6169            }
6170            return range;
6171        };
6172        // Computes the range that will represent the element/cells for *rendering*,
6173        // but which may have voided days/times.
6174        // not responsible for trimming hidden days.
6175        DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
6176            return currentRange;
6177        };
6178        // Compute the duration value that should be added/substracted to the current date
6179        // when a prev/next operation happens.
6180        DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
6181            var dateIncrement = this.props.dateIncrement;
6182            var customAlignment;
6183            if (dateIncrement) {
6184                return dateIncrement;
6185            }
6186            else if ((customAlignment = this.props.dateAlignment)) {
6187                return createDuration(1, customAlignment);
6188            }
6189            else if (fallback) {
6190                return fallback;
6191            }
6192            else {
6193                return createDuration({ days: 1 });
6194            }
6195        };
6196        DateProfileGenerator.prototype.refineRange = function (rangeInput) {
6197            if (rangeInput) {
6198                var range = parseRange(rangeInput, this.props.dateEnv);
6199                if (range) {
6200                    range = computeVisibleDayRange(range);
6201                }
6202                return range;
6203            }
6204            return null;
6205        };
6206        /* Hidden Days
6207        ------------------------------------------------------------------------------------------------------------------*/
6208        // Initializes internal variables related to calculating hidden days-of-week
6209        DateProfileGenerator.prototype.initHiddenDays = function () {
6210            var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
6211            var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
6212            var dayCnt = 0;
6213            var i;
6214            if (this.props.weekends === false) {
6215                hiddenDays.push(0, 6); // 0=sunday, 6=saturday
6216            }
6217            for (i = 0; i < 7; i++) {
6218                if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
6219                    dayCnt++;
6220                }
6221            }
6222            if (!dayCnt) {
6223                throw new Error('invalid hiddenDays'); // all days were hidden? bad.
6224            }
6225            this.isHiddenDayHash = isHiddenDayHash;
6226        };
6227        // Remove days from the beginning and end of the range that are computed as hidden.
6228        // If the whole range is trimmed off, returns null
6229        DateProfileGenerator.prototype.trimHiddenDays = function (range) {
6230            var start = range.start;
6231            var end = range.end;
6232            if (start) {
6233                start = this.skipHiddenDays(start);
6234            }
6235            if (end) {
6236                end = this.skipHiddenDays(end, -1, true);
6237            }
6238            if (start == null || end == null || start < end) {
6239                return { start: start, end: end };
6240            }
6241            return null;
6242        };
6243        // Is the current day hidden?
6244        // `day` is a day-of-week index (0-6), or a Date (used for UTC)
6245        DateProfileGenerator.prototype.isHiddenDay = function (day) {
6246            if (day instanceof Date) {
6247                day = day.getUTCDay();
6248            }
6249            return this.isHiddenDayHash[day];
6250        };
6251        // Incrementing the current day until it is no longer a hidden day, returning a copy.
6252        // DOES NOT CONSIDER validRange!
6253        // If the initial value of `date` is not a hidden day, don't do anything.
6254        // Pass `isExclusive` as `true` if you are dealing with an end date.
6255        // `inc` defaults to `1` (increment one day forward each time)
6256        DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
6257            if (inc === void 0) { inc = 1; }
6258            if (isExclusive === void 0) { isExclusive = false; }
6259            while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
6260                date = addDays(date, inc);
6261            }
6262            return date;
6263        };
6264        return DateProfileGenerator;
6265    }());
6266
6267    function reduceViewType(viewType, action) {
6268        switch (action.type) {
6269            case 'CHANGE_VIEW_TYPE':
6270                return viewType = action.viewType;
6271        }
6272        return viewType;
6273    }
6274
6275    function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {
6276        var _a;
6277        switch (action.type) {
6278            case 'SET_OPTION':
6279                return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a));
6280            default:
6281                return dynamicOptionOverrides;
6282        }
6283    }
6284
6285    function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {
6286        var dp;
6287        switch (action.type) {
6288            case 'CHANGE_VIEW_TYPE':
6289                return dateProfileGenerator.build(action.dateMarker || currentDate);
6290            case 'CHANGE_DATE':
6291                if (!currentDateProfile.activeRange ||
6292                    !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker) // don't move if date already in view
6293                ) {
6294                    return dateProfileGenerator.build(action.dateMarker);
6295                }
6296                break;
6297            case 'PREV':
6298                dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);
6299                if (dp.isValid) {
6300                    return dp;
6301                }
6302                break;
6303            case 'NEXT':
6304                dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);
6305                if (dp.isValid) {
6306                    return dp;
6307                }
6308                break;
6309        }
6310        return currentDateProfile;
6311    }
6312
6313    function initEventSources(calendarOptions, dateProfile, context) {
6314        var activeRange = dateProfile ? dateProfile.activeRange : null;
6315        return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);
6316    }
6317    function reduceEventSources(eventSources, action, dateProfile, context) {
6318        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
6319        switch (action.type) {
6320            case 'ADD_EVENT_SOURCES': // already parsed
6321                return addSources(eventSources, action.sources, activeRange, context);
6322            case 'REMOVE_EVENT_SOURCE':
6323                return removeSource(eventSources, action.sourceId);
6324            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
6325            case 'NEXT':
6326            case 'CHANGE_DATE':
6327            case 'CHANGE_VIEW_TYPE':
6328                if (dateProfile) {
6329                    return fetchDirtySources(eventSources, activeRange, context);
6330                }
6331                else {
6332                    return eventSources;
6333                }
6334            case 'FETCH_EVENT_SOURCES':
6335                return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?
6336                    arrayToHash(action.sourceIds) :
6337                    excludeStaticSources(eventSources, context), activeRange, context);
6338            case 'RECEIVE_EVENTS':
6339            case 'RECEIVE_EVENT_ERROR':
6340                return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
6341            case 'REMOVE_ALL_EVENT_SOURCES':
6342                return {};
6343            default:
6344                return eventSources;
6345        }
6346    }
6347    function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {
6348        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
6349        return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, context);
6350    }
6351    function computeEventSourceLoadingLevel(eventSources) {
6352        var cnt = 0;
6353        for (var sourceId in eventSources) {
6354            if (eventSources[sourceId].isFetching) {
6355                cnt++;
6356            }
6357        }
6358        return cnt;
6359    }
6360    function addSources(eventSourceHash, sources, fetchRange, context) {
6361        var hash = {};
6362        for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
6363            var source = sources_1[_i];
6364            hash[source.sourceId] = source;
6365        }
6366        if (fetchRange) {
6367            hash = fetchDirtySources(hash, fetchRange, context);
6368        }
6369        return __assign(__assign({}, eventSourceHash), hash);
6370    }
6371    function removeSource(eventSourceHash, sourceId) {
6372        return filterHash(eventSourceHash, function (eventSource) {
6373            return eventSource.sourceId !== sourceId;
6374        });
6375    }
6376    function fetchDirtySources(sourceHash, fetchRange, context) {
6377        return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) {
6378            return isSourceDirty(eventSource, fetchRange, context);
6379        }), fetchRange, context);
6380    }
6381    function isSourceDirty(eventSource, fetchRange, context) {
6382        if (!doesSourceNeedRange(eventSource, context)) {
6383            return !eventSource.latestFetchId;
6384        }
6385        else {
6386            return !context.options.lazyFetching ||
6387                !eventSource.fetchRange ||
6388                eventSource.isFetching || // always cancel outdated in-progress fetches
6389                fetchRange.start < eventSource.fetchRange.start ||
6390                fetchRange.end > eventSource.fetchRange.end;
6391        }
6392    }
6393    function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, context) {
6394        var nextSources = {};
6395        for (var sourceId in prevSources) {
6396            var source = prevSources[sourceId];
6397            if (sourceIdHash[sourceId]) {
6398                nextSources[sourceId] = fetchSource(source, fetchRange, context);
6399            }
6400            else {
6401                nextSources[sourceId] = source;
6402            }
6403        }
6404        return nextSources;
6405    }
6406    function fetchSource(eventSource, fetchRange, context) {
6407        var options = context.options, calendarApi = context.calendarApi;
6408        var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];
6409        var fetchId = guid();
6410        sourceDef.fetch({
6411            eventSource: eventSource,
6412            range: fetchRange,
6413            context: context
6414        }, function (res) {
6415            var rawEvents = res.rawEvents;
6416            if (options.eventSourceSuccess) {
6417                rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents;
6418            }
6419            if (eventSource.success) {
6420                rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents;
6421            }
6422            context.dispatch({
6423                type: 'RECEIVE_EVENTS',
6424                sourceId: eventSource.sourceId,
6425                fetchId: fetchId,
6426                fetchRange: fetchRange,
6427                rawEvents: rawEvents
6428            });
6429        }, function (error) {
6430            console.warn(error.message, error);
6431            if (options.eventSourceFailure) {
6432                options.eventSourceFailure.call(calendarApi, error);
6433            }
6434            if (eventSource.failure) {
6435                eventSource.failure(error);
6436            }
6437            context.dispatch({
6438                type: 'RECEIVE_EVENT_ERROR',
6439                sourceId: eventSource.sourceId,
6440                fetchId: fetchId,
6441                fetchRange: fetchRange,
6442                error: error
6443            });
6444        });
6445        return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });
6446    }
6447    function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
6448        var _a;
6449        var eventSource = sourceHash[sourceId];
6450        if (eventSource && // not already removed
6451            fetchId === eventSource.latestFetchId) {
6452            return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange // also serves as a marker that at least one fetch has completed
6453             }), _a));
6454        }
6455        return sourceHash;
6456    }
6457    function excludeStaticSources(eventSources, context) {
6458        return filterHash(eventSources, function (eventSource) {
6459            return doesSourceNeedRange(eventSource, context);
6460        });
6461    }
6462    function parseInitialSources(rawOptions, context) {
6463        var refiners = buildEventSourceRefiners(context);
6464        var rawSources = [].concat(rawOptions.eventSources || []);
6465        var sources = []; // parsed
6466        if (rawOptions.initialEvents) {
6467            rawSources.unshift(rawOptions.initialEvents);
6468        }
6469        if (rawOptions.events) {
6470            rawSources.unshift(rawOptions.events);
6471        }
6472        for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
6473            var rawSource = rawSources_1[_i];
6474            var source = parseEventSource(rawSource, context, refiners);
6475            if (source) {
6476                sources.push(source);
6477            }
6478        }
6479        return sources;
6480    }
6481    function doesSourceNeedRange(eventSource, context) {
6482        var defs = context.pluginHooks.eventSourceDefs;
6483        return !defs[eventSource.sourceDefId].ignoreRange;
6484    }
6485
6486    function reduceDateSelection(currentSelection, action) {
6487        switch (action.type) {
6488            case 'UNSELECT_DATES':
6489                return null;
6490            case 'SELECT_DATES':
6491                return action.selection;
6492            default:
6493                return currentSelection;
6494        }
6495    }
6496
6497    function reduceSelectedEvent(currentInstanceId, action) {
6498        switch (action.type) {
6499            case 'UNSELECT_EVENT':
6500                return '';
6501            case 'SELECT_EVENT':
6502                return action.eventInstanceId;
6503            default:
6504                return currentInstanceId;
6505        }
6506    }
6507
6508    function reduceEventDrag(currentDrag, action) {
6509        var newDrag;
6510        switch (action.type) {
6511            case 'UNSET_EVENT_DRAG':
6512                return null;
6513            case 'SET_EVENT_DRAG':
6514                newDrag = action.state;
6515                return {
6516                    affectedEvents: newDrag.affectedEvents,
6517                    mutatedEvents: newDrag.mutatedEvents,
6518                    isEvent: newDrag.isEvent
6519                };
6520            default:
6521                return currentDrag;
6522        }
6523    }
6524
6525    function reduceEventResize(currentResize, action) {
6526        var newResize;
6527        switch (action.type) {
6528            case 'UNSET_EVENT_RESIZE':
6529                return null;
6530            case 'SET_EVENT_RESIZE':
6531                newResize = action.state;
6532                return {
6533                    affectedEvents: newResize.affectedEvents,
6534                    mutatedEvents: newResize.mutatedEvents,
6535                    isEvent: newResize.isEvent
6536                };
6537            default:
6538                return currentResize;
6539        }
6540    }
6541
6542    function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
6543        var viewsWithButtons = [];
6544        var headerToolbar = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null;
6545        var footerToolbar = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null;
6546        return { headerToolbar: headerToolbar, footerToolbar: footerToolbar, viewsWithButtons: viewsWithButtons };
6547    }
6548    function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons // dump side effects
6549    ) {
6550        return mapHash(sectionStrHash, function (sectionStr) { return parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons); });
6551    }
6552    /*
6553    BAD: querying icons and text here. should be done at render time
6554    */
6555    function parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons // dump side effects
6556    ) {
6557        var isRtl = calendarOptions.direction === 'rtl';
6558        var calendarCustomButtons = calendarOptions.customButtons || {};
6559        var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};
6560        var calendarButtonText = calendarOptions.buttonText || {};
6561        var sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];
6562        return sectionSubstrs.map(function (buttonGroupStr) {
6563            return buttonGroupStr.split(',').map(function (buttonName) {
6564                if (buttonName === 'title') {
6565                    return { buttonName: buttonName };
6566                }
6567                else {
6568                    var customButtonProps_1;
6569                    var viewSpec = void 0;
6570                    var buttonClick = void 0;
6571                    var buttonIcon = void 0; // only one of these will be set
6572                    var buttonText = void 0; // "
6573                    if ((customButtonProps_1 = calendarCustomButtons[buttonName])) {
6574                        buttonClick = function (ev) {
6575                            if (customButtonProps_1.click) {
6576                                customButtonProps_1.click.call(ev.target, ev, ev.target);
6577                            }
6578                        };
6579                        (buttonIcon = theme.getCustomButtonIconClass(customButtonProps_1)) ||
6580                            (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6581                            (buttonText = customButtonProps_1.text);
6582                    }
6583                    else if ((viewSpec = viewSpecs[buttonName])) {
6584                        viewsWithButtons.push(buttonName);
6585                        buttonClick = function () {
6586                            calendarApi.changeView(buttonName);
6587                        };
6588                        (buttonText = viewSpec.buttonTextOverride) ||
6589                            (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6590                            (buttonText = viewSpec.buttonTextDefault);
6591                    }
6592                    else if (calendarApi[buttonName]) { // a calendarApi method
6593                        buttonClick = function () {
6594                            calendarApi[buttonName]();
6595                        };
6596                        (buttonText = calendarButtonTextOverrides[buttonName]) ||
6597                            (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6598                            (buttonText = calendarButtonText[buttonName]);
6599                        //            ^ everything else is considered default
6600                    }
6601                    return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText };
6602                }
6603            });
6604        });
6605    }
6606
6607    var eventSourceDef = {
6608        ignoreRange: true,
6609        parseMeta: function (refined) {
6610            if (Array.isArray(refined.events)) {
6611                return refined.events;
6612            }
6613            return null;
6614        },
6615        fetch: function (arg, success) {
6616            success({
6617                rawEvents: arg.eventSource.meta
6618            });
6619        }
6620    };
6621    var arrayEventSourcePlugin = createPlugin({
6622        eventSourceDefs: [eventSourceDef]
6623    });
6624
6625    var eventSourceDef$1 = {
6626        parseMeta: function (refined) {
6627            if (typeof refined.events === 'function') {
6628                return refined.events;
6629            }
6630            return null;
6631        },
6632        fetch: function (arg, success, failure) {
6633            var dateEnv = arg.context.dateEnv;
6634            var func = arg.eventSource.meta;
6635            unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) {
6636                success({ rawEvents: rawEvents }); // needs an object response
6637            }, failure // send errorObj directly to failure callback
6638            );
6639        }
6640    };
6641    var funcEventSourcePlugin = createPlugin({
6642        eventSourceDefs: [eventSourceDef$1]
6643    });
6644
6645    function requestJson(method, url, params, successCallback, failureCallback) {
6646        method = method.toUpperCase();
6647        var body = null;
6648        if (method === 'GET') {
6649            url = injectQueryStringParams(url, params);
6650        }
6651        else {
6652            body = encodeParams(params);
6653        }
6654        var xhr = new XMLHttpRequest();
6655        xhr.open(method, url, true);
6656        if (method !== 'GET') {
6657            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
6658        }
6659        xhr.onload = function () {
6660            if (xhr.status >= 200 && xhr.status < 400) {
6661                var parsed = false;
6662                var res = void 0;
6663                try {
6664                    res = JSON.parse(xhr.responseText);
6665                    parsed = true;
6666                }
6667                catch (err) {
6668                    // will handle parsed=false
6669                }
6670                if (parsed) {
6671                    successCallback(res, xhr);
6672                }
6673                else {
6674                    failureCallback('Failure parsing JSON', xhr);
6675                }
6676            }
6677            else {
6678                failureCallback('Request failed', xhr);
6679            }
6680        };
6681        xhr.onerror = function () {
6682            failureCallback('Request failed', xhr);
6683        };
6684        xhr.send(body);
6685    }
6686    function injectQueryStringParams(url, params) {
6687        return url +
6688            (url.indexOf('?') === -1 ? '?' : '&') +
6689            encodeParams(params);
6690    }
6691    function encodeParams(params) {
6692        var parts = [];
6693        for (var key in params) {
6694            parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
6695        }
6696        return parts.join('&');
6697    }
6698
6699    var JSON_FEED_EVENT_SOURCE_REFINERS = {
6700        method: String,
6701        extraParams: identity,
6702        startParam: String,
6703        endParam: String,
6704        timeZoneParam: String
6705    };
6706
6707    var eventSourceDef$2 = {
6708        parseMeta: function (refined) {
6709            if (refined.url) {
6710                return {
6711                    url: refined.url,
6712                    method: (refined.method || 'GET').toUpperCase(),
6713                    extraParams: refined.extraParams,
6714                    startParam: refined.startParam,
6715                    endParam: refined.endParam,
6716                    timeZoneParam: refined.timeZoneParam
6717                };
6718            }
6719            return null;
6720        },
6721        fetch: function (arg, success, failure) {
6722            var meta = arg.eventSource.meta;
6723            var requestParams = buildRequestParams(meta, arg.range, arg.context);
6724            requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
6725                success({ rawEvents: rawEvents, xhr: xhr });
6726            }, function (errorMessage, xhr) {
6727                failure({ message: errorMessage, xhr: xhr });
6728            });
6729        }
6730    };
6731    var jsonFeedEventSourcePlugin = createPlugin({
6732        eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,
6733        eventSourceDefs: [eventSourceDef$2]
6734    });
6735    function buildRequestParams(meta, range, context) {
6736        var dateEnv = context.dateEnv, options = context.options;
6737        var startParam;
6738        var endParam;
6739        var timeZoneParam;
6740        var customRequestParams;
6741        var params = {};
6742        startParam = meta.startParam;
6743        if (startParam == null) {
6744            startParam = options.startParam;
6745        }
6746        endParam = meta.endParam;
6747        if (endParam == null) {
6748            endParam = options.endParam;
6749        }
6750        timeZoneParam = meta.timeZoneParam;
6751        if (timeZoneParam == null) {
6752            timeZoneParam = options.timeZoneParam;
6753        }
6754        // retrieve any outbound GET/POST data from the options
6755        if (typeof meta.extraParams === 'function') {
6756            // supplied as a function that returns a key/value object
6757            customRequestParams = meta.extraParams();
6758        }
6759        else {
6760            // probably supplied as a straight key/value object
6761            customRequestParams = meta.extraParams || {};
6762        }
6763        __assign(params, customRequestParams);
6764        params[startParam] = dateEnv.formatIso(range.start);
6765        params[endParam] = dateEnv.formatIso(range.end);
6766        if (dateEnv.timeZone !== 'local') {
6767            params[timeZoneParam] = dateEnv.timeZone;
6768        }
6769        return params;
6770    }
6771
6772    var SIMPLE_RECURRING_REFINERS = {
6773        daysOfWeek: identity,
6774        startTime: createDuration,
6775        endTime: createDuration,
6776        duration: createDuration,
6777        startRecur: identity,
6778        endRecur: identity
6779    };
6780
6781    var recurring = {
6782        parse: function (refined, dateEnv) {
6783            if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {
6784                var recurringData = {
6785                    daysOfWeek: refined.daysOfWeek || null,
6786                    startTime: refined.startTime || null,
6787                    endTime: refined.endTime || null,
6788                    startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,
6789                    endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null
6790                };
6791                var duration = void 0;
6792                if (refined.duration) {
6793                    duration = refined.duration;
6794                }
6795                if (!duration && refined.startTime && refined.endTime) {
6796                    duration = subtractDurations(refined.endTime, refined.startTime);
6797                }
6798                return {
6799                    allDayGuess: Boolean(!refined.startTime && !refined.endTime),
6800                    duration: duration,
6801                    typeData: recurringData // doesn't need endTime anymore but oh well
6802                };
6803            }
6804            return null;
6805        },
6806        expand: function (typeData, framingRange, dateEnv) {
6807            var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
6808            if (clippedFramingRange) {
6809                return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
6810            }
6811            else {
6812                return [];
6813            }
6814        }
6815    };
6816    var simpleRecurringEventsPlugin = createPlugin({
6817        recurringTypes: [recurring],
6818        eventRefiners: SIMPLE_RECURRING_REFINERS
6819    });
6820    function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
6821        var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
6822        var dayMarker = startOfDay(framingRange.start);
6823        var endMarker = framingRange.end;
6824        var instanceStarts = [];
6825        while (dayMarker < endMarker) {
6826            var instanceStart 
6827            // if everyday, or this particular day-of-week
6828            = void 0;
6829            // if everyday, or this particular day-of-week
6830            if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
6831                if (startTime) {
6832                    instanceStart = dateEnv.add(dayMarker, startTime);
6833                }
6834                else {
6835                    instanceStart = dayMarker;
6836                }
6837                instanceStarts.push(instanceStart);
6838            }
6839            dayMarker = addDays(dayMarker, 1);
6840        }
6841        return instanceStarts;
6842    }
6843
6844    var changeHandlerPlugin = createPlugin({
6845        optionChangeHandlers: {
6846            events: function (events, context) {
6847                handleEventSources([events], context);
6848            },
6849            eventSources: handleEventSources
6850        }
6851    });
6852    /*
6853    BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out
6854    */
6855    function handleEventSources(inputs, context) {
6856        var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources);
6857        var newInputs = [];
6858        for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
6859            var input = inputs_1[_i];
6860            var inputFound = false;
6861            for (var i = 0; i < unfoundSources.length; i++) {
6862                if (unfoundSources[i]._raw === input) {
6863                    unfoundSources.splice(i, 1); // delete
6864                    inputFound = true;
6865                    break;
6866                }
6867            }
6868            if (!inputFound) {
6869                newInputs.push(input);
6870            }
6871        }
6872        for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
6873            var unfoundSource = unfoundSources_1[_a];
6874            context.dispatch({
6875                type: 'REMOVE_EVENT_SOURCE',
6876                sourceId: unfoundSource.sourceId
6877            });
6878        }
6879        for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
6880            var newInput = newInputs_1[_b];
6881            context.calendarApi.addEventSource(newInput);
6882        }
6883    }
6884
6885    function handleDateProfile(dateProfile, context) {
6886        context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));
6887    }
6888
6889    function handleEventStore(eventStore, context) {
6890        var emitter = context.emitter;
6891        if (emitter.hasHandlers('eventsSet')) {
6892            emitter.trigger('eventsSet', buildEventApis(eventStore, context));
6893        }
6894    }
6895
6896    /*
6897    this array is exposed on the root namespace so that UMD plugins can add to it.
6898    see the rollup-bundles script.
6899    */
6900    var globalPlugins = [
6901        arrayEventSourcePlugin,
6902        funcEventSourcePlugin,
6903        jsonFeedEventSourcePlugin,
6904        simpleRecurringEventsPlugin,
6905        changeHandlerPlugin,
6906        createPlugin({
6907            contentTypeHandlers: {
6908                html: function () { return injectHtml; },
6909                domNodes: function () { return injectDomNodes; }
6910            },
6911            propSetHandlers: {
6912                dateProfile: handleDateProfile,
6913                eventStore: handleEventStore
6914            }
6915        })
6916    ];
6917    function injectHtml(el, html) {
6918        el.innerHTML = html;
6919    }
6920    function injectDomNodes(el, domNodes) {
6921        var oldNodes = Array.prototype.slice.call(el.childNodes); // TODO: use array util
6922        var newNodes = Array.prototype.slice.call(domNodes); // TODO: use array util
6923        if (!isArraysEqual(oldNodes, newNodes)) {
6924            for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) {
6925                var newNode = newNodes_1[_i];
6926                el.appendChild(newNode);
6927            }
6928            oldNodes.forEach(removeElement);
6929        }
6930    }
6931
6932    var DelayedRunner = /** @class */ (function () {
6933        function DelayedRunner(drainedOption) {
6934            this.drainedOption = drainedOption;
6935            this.isRunning = false;
6936            this.isDirty = false;
6937            this.pauseDepths = {};
6938            this.timeoutId = 0;
6939        }
6940        DelayedRunner.prototype.request = function (delay) {
6941            this.isDirty = true;
6942            if (!this.isPaused()) {
6943                this.clearTimeout();
6944                if (delay == null) {
6945                    this.tryDrain();
6946                }
6947                else {
6948                    this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce
6949                    this.tryDrain.bind(this), delay);
6950                }
6951            }
6952        };
6953        DelayedRunner.prototype.pause = function (scope) {
6954            if (scope === void 0) { scope = ''; }
6955            var pauseDepths = this.pauseDepths;
6956            pauseDepths[scope] = (pauseDepths[scope] || 0) + 1;
6957            this.clearTimeout();
6958        };
6959        DelayedRunner.prototype.resume = function (scope, force) {
6960            if (scope === void 0) { scope = ''; }
6961            var pauseDepths = this.pauseDepths;
6962            if (scope in pauseDepths) {
6963                if (force) {
6964                    delete pauseDepths[scope];
6965                }
6966                else {
6967                    var depth = --pauseDepths[scope];
6968                    if (depth <= 0) {
6969                        delete pauseDepths[scope];
6970                    }
6971                }
6972                this.tryDrain();
6973            }
6974        };
6975        DelayedRunner.prototype.isPaused = function () {
6976            return Object.keys(this.pauseDepths).length;
6977        };
6978        DelayedRunner.prototype.tryDrain = function () {
6979            if (!this.isRunning && !this.isPaused()) {
6980                this.isRunning = true;
6981                while (this.isDirty) {
6982                    this.isDirty = false;
6983                    this.drained(); // might set isDirty to true again
6984                }
6985                this.isRunning = false;
6986            }
6987        };
6988        DelayedRunner.prototype.clear = function () {
6989            this.clearTimeout();
6990            this.isDirty = false;
6991            this.pauseDepths = {};
6992        };
6993        DelayedRunner.prototype.clearTimeout = function () {
6994            if (this.timeoutId) {
6995                clearTimeout(this.timeoutId);
6996                this.timeoutId = 0;
6997            }
6998        };
6999        DelayedRunner.prototype.drained = function () {
7000            if (this.drainedOption) {
7001                this.drainedOption();
7002            }
7003        };
7004        return DelayedRunner;
7005    }());
7006    var TaskRunner = /** @class */ (function () {
7007        function TaskRunner(runTaskOption, drainedOption) {
7008            this.runTaskOption = runTaskOption;
7009            this.drainedOption = drainedOption;
7010            this.queue = [];
7011            this.delayedRunner = new DelayedRunner(this.drain.bind(this));
7012        }
7013        TaskRunner.prototype.request = function (task, delay) {
7014            this.queue.push(task);
7015            this.delayedRunner.request(delay);
7016        };
7017        TaskRunner.prototype.pause = function (scope) {
7018            this.delayedRunner.pause(scope);
7019        };
7020        TaskRunner.prototype.resume = function (scope, force) {
7021            this.delayedRunner.resume(scope, force);
7022        };
7023        TaskRunner.prototype.drain = function () {
7024            var queue = this.queue;
7025            while (queue.length) {
7026                var completedTasks = [];
7027                var task = void 0;
7028                while ((task = queue.shift())) {
7029                    this.runTask(task);
7030                    completedTasks.push(task);
7031                }
7032                this.drained(completedTasks);
7033            } // keep going, in case new tasks were added in the drained handler
7034        };
7035        TaskRunner.prototype.runTask = function (task) {
7036            if (this.runTaskOption) {
7037                this.runTaskOption(task);
7038            }
7039        };
7040        TaskRunner.prototype.drained = function (completedTasks) {
7041            if (this.drainedOption) {
7042                this.drainedOption(completedTasks);
7043            }
7044        };
7045        return TaskRunner;
7046    }());
7047
7048    // Computes what the title at the top of the calendarApi should be for this view
7049    function buildTitle(dateProfile, viewOptions, dateEnv) {
7050        var range;
7051        // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
7052        if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
7053            range = dateProfile.currentRange;
7054        }
7055        else { // for day units or smaller, use the actual day range
7056            range = dateProfile.activeRange;
7057        }
7058        return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {
7059            isEndExclusive: dateProfile.isRangeAllDay,
7060            defaultSeparator: viewOptions.titleRangeSeparator
7061        });
7062    }
7063    // Generates the format string that should be used to generate the title for the current date range.
7064    // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
7065    function buildTitleFormat(dateProfile) {
7066        var currentRangeUnit = dateProfile.currentRangeUnit;
7067        if (currentRangeUnit === 'year') {
7068            return { year: 'numeric' };
7069        }
7070        else if (currentRangeUnit === 'month') {
7071            return { year: 'numeric', month: 'long' }; // like "September 2014"
7072        }
7073        else {
7074            var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
7075            if (days !== null && days > 1) {
7076                // multi-day range. shorter, like "Sep 9 - 10 2014"
7077                return { year: 'numeric', month: 'short', day: 'numeric' };
7078            }
7079            else {
7080                // one day. longer, like "September 9 2014"
7081                return { year: 'numeric', month: 'long', day: 'numeric' };
7082            }
7083        }
7084    }
7085
7086    // in future refactor, do the redux-style function(state=initial) for initial-state
7087    // also, whatever is happening in constructor, have it happen in action queue too
7088    var CalendarDataManager = /** @class */ (function () {
7089        function CalendarDataManager(props) {
7090            var _this = this;
7091            this.computeOptionsData = memoize(this._computeOptionsData);
7092            this.computeCurrentViewData = memoize(this._computeCurrentViewData);
7093            this.organizeRawLocales = memoize(organizeRawLocales);
7094            this.buildLocale = memoize(buildLocale);
7095            this.buildPluginHooks = buildBuildPluginHooks();
7096            this.buildDateEnv = memoize(buildDateEnv$1);
7097            this.buildTheme = memoize(buildTheme);
7098            this.parseToolbars = memoize(parseToolbars);
7099            this.buildViewSpecs = memoize(buildViewSpecs);
7100            this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator);
7101            this.buildViewApi = memoize(buildViewApi);
7102            this.buildViewUiProps = memoizeObjArg(buildViewUiProps);
7103            this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual);
7104            this.buildEventUiBases = memoize(buildEventUiBases);
7105            this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours);
7106            this.buildTitle = memoize(buildTitle);
7107            this.emitter = new Emitter();
7108            this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));
7109            this.currentCalendarOptionsInput = {};
7110            this.currentCalendarOptionsRefined = {};
7111            this.currentViewOptionsInput = {};
7112            this.currentViewOptionsRefined = {};
7113            this.currentCalendarOptionsRefiners = {};
7114            this.getCurrentData = function () {
7115                return _this.data;
7116            };
7117            this.dispatch = function (action) {
7118                _this.actionRunner.request(action); // protects against recursive calls to _handleAction
7119            };
7120            this.props = props;
7121            this.actionRunner.pause();
7122            var dynamicOptionOverrides = {};
7123            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
7124            var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;
7125            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
7126            // wire things up
7127            // TODO: not DRY
7128            props.calendarApi.currentDataManager = this;
7129            this.emitter.setThisContext(props.calendarApi);
7130            this.emitter.setOptions(currentViewData.options);
7131            var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv);
7132            var dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
7133            if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) {
7134                currentDate = dateProfile.currentRange.start;
7135            }
7136            var calendarContext = {
7137                dateEnv: optionsData.dateEnv,
7138                options: optionsData.calendarOptions,
7139                pluginHooks: optionsData.pluginHooks,
7140                calendarApi: props.calendarApi,
7141                dispatch: this.dispatch,
7142                emitter: this.emitter,
7143                getCurrentData: this.getCurrentData
7144            };
7145            // needs to be after setThisContext
7146            for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) {
7147                var callback = _a[_i];
7148                callback(calendarContext);
7149            }
7150            // NOT DRY
7151            var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);
7152            var initialState = {
7153                dynamicOptionOverrides: dynamicOptionOverrides,
7154                currentViewType: currentViewType,
7155                currentDate: currentDate,
7156                dateProfile: dateProfile,
7157                businessHours: this.parseContextBusinessHours(calendarContext),
7158                eventSources: eventSources,
7159                eventUiBases: {},
7160                loadingLevel: computeEventSourceLoadingLevel(eventSources),
7161                eventStore: createEmptyEventStore(),
7162                renderableEventStore: createEmptyEventStore(),
7163                dateSelection: null,
7164                eventSelection: '',
7165                eventDrag: null,
7166                eventResize: null,
7167                selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig
7168            };
7169            var contextAndState = __assign(__assign({}, calendarContext), initialState);
7170            for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) {
7171                var reducer = _c[_b];
7172                __assign(initialState, reducer(null, null, contextAndState));
7173            }
7174            if (initialState.loadingLevel) {
7175                this.emitter.trigger('loading', true); // NOT DRY
7176            }
7177            this.state = initialState;
7178            this.updateData();
7179            this.actionRunner.resume();
7180        }
7181        CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) {
7182            var props = this.props;
7183            props.optionOverrides = append
7184                ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides;
7185            this.actionRunner.request({
7186                type: 'NOTHING'
7187            });
7188        };
7189        CalendarDataManager.prototype._handleAction = function (action) {
7190            var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter;
7191            var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);
7192            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
7193            var currentViewType = reduceViewType(state.currentViewType, action);
7194            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
7195            // wire things up
7196            // TODO: not DRY
7197            props.calendarApi.currentDataManager = this;
7198            emitter.setThisContext(props.calendarApi);
7199            emitter.setOptions(currentViewData.options);
7200            var calendarContext = {
7201                dateEnv: optionsData.dateEnv,
7202                options: optionsData.calendarOptions,
7203                pluginHooks: optionsData.pluginHooks,
7204                calendarApi: props.calendarApi,
7205                dispatch: this.dispatch,
7206                emitter: emitter,
7207                getCurrentData: this.getCurrentData
7208            };
7209            var currentDate = state.currentDate;
7210            var dateProfile = state.dateProfile;
7211            if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack
7212                dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
7213            }
7214            currentDate = reduceCurrentDate(currentDate, action);
7215            dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);
7216            if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
7217                currentDate = dateProfile.currentRange.start;
7218            }
7219            var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);
7220            var eventSourceLoadingLevel = computeEventSourceLoadingLevel(eventSources);
7221            var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext);
7222            var renderableEventStore = (eventSourceLoadingLevel && !currentViewData.options.progressiveEventRendering) ?
7223                (state.renderableEventStore || eventStore) : // try from previous state
7224                eventStore;
7225            var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj
7226            var eventUiBySource = this.buildEventUiBySource(eventSources);
7227            var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
7228            var prevLoadingLevel = state.loadingLevel || 0;
7229            var loadingLevel = eventSourceLoadingLevel;
7230            var newState = {
7231                dynamicOptionOverrides: dynamicOptionOverrides,
7232                currentViewType: currentViewType,
7233                currentDate: currentDate,
7234                dateProfile: dateProfile,
7235                eventSources: eventSources,
7236                eventStore: eventStore,
7237                renderableEventStore: renderableEventStore,
7238                selectionConfig: selectionConfig,
7239                eventUiBases: eventUiBases,
7240                loadingLevel: loadingLevel,
7241                businessHours: this.parseContextBusinessHours(calendarContext),
7242                dateSelection: reduceDateSelection(state.dateSelection, action),
7243                eventSelection: reduceSelectedEvent(state.eventSelection, action),
7244                eventDrag: reduceEventDrag(state.eventDrag, action),
7245                eventResize: reduceEventResize(state.eventResize, action)
7246            };
7247            var contextAndState = __assign(__assign({}, calendarContext), newState);
7248            for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) {
7249                var reducer = _c[_i];
7250                __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value
7251            }
7252            // TODO: use propSetHandlers in plugin system
7253            if (!prevLoadingLevel && loadingLevel) {
7254                emitter.trigger('loading', true);
7255            }
7256            else if (prevLoadingLevel && !loadingLevel) {
7257                emitter.trigger('loading', false);
7258            }
7259            this.state = newState;
7260            if (props.onAction) {
7261                props.onAction(action);
7262            }
7263        };
7264        CalendarDataManager.prototype.updateData = function () {
7265            var _a = this, props = _a.props, state = _a.state;
7266            var oldData = this.data;
7267            var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);
7268            var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);
7269            var data = this.data = __assign(__assign(__assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);
7270            var changeHandlers = optionsData.pluginHooks.optionChangeHandlers;
7271            var oldCalendarOptions = oldData && oldData.calendarOptions;
7272            var newCalendarOptions = optionsData.calendarOptions;
7273            if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {
7274                if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {
7275                    // hack
7276                    state.eventSources = data.eventSources = reduceEventSourcesNe
7276wTimeZone(data.eventSources, state.dateProfile, data);
7277                    state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv);
7278                }
7279                for (var optionName in changeHandlers) {
7280                    if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {
7281                        changeHandlers[optionName](newCalendarOptions[optionName], data);
7282                    }
7283                }
7284            }
7285            if (props.onData) {
7286                props.onData(data);
7287            }
7288        };
7289        CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) {
7290            // TODO: blacklist options that are handled by optionChangeHandlers
7291            var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra;
7292            warnUnknownOptions(extra);
7293            var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);
7294            var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults);
7295            var theme = this.buildTheme(refinedOptions, pluginHooks);
7296            var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi);
7297            return {
7298                calendarOptions: refinedOptions,
7299                pluginHooks: pluginHooks,
7300                dateEnv: dateEnv,
7301                viewSpecs: viewSpecs,
7302                theme: theme,
7303                toolbarConfig: toolbarConfig,
7304                localeDefaults: localeDefaults,
7305                availableRawLocales: availableLocaleData.map
7306            };
7307        };
7308        // always called from behind a memoizer
7309        CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) {
7310            var _a = mergeRawOptions([
7311                BASE_OPTION_DEFAULTS,
7312                optionOverrides,
7313                dynamicOptionOverrides
7314            ]), locales = _a.locales, locale = _a.locale;
7315            var availableLocaleData = this.organizeRawLocales(locales);
7316            var availableRawLocales = availableLocaleData.map;
7317            var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;
7318            var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);
7319            var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7320            var extra = {};
7321            var raw = mergeRawOptions([
7322                BASE_OPTION_DEFAULTS,
7323                localeDefaults,
7324                optionOverrides,
7325                dynamicOptionOverrides
7326            ]);
7327            var refined = {};
7328            var currentRaw = this.currentCalendarOptionsInput;
7329            var currentRefined = this.currentCalendarOptionsRefined;
7330            var anyChanges = false;
7331            for (var optionName in raw) {
7332                if (optionName !== 'plugins') { // because plugins is special-cased
7333                    if (raw[optionName] === currentRaw[optionName] ||
7334                        (COMPLEX_OPTION_COMPARATORS[optionName] && (optionName in currentRaw) && COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) {
7335                        refined[optionName] = currentRefined[optionName];
7336                    }
7337                    else if (refiners[optionName]) {
7338                        refined[optionName] = refiners[optionName](raw[optionName]);
7339                        anyChanges = true;
7340                    }
7341                    else {
7342                        extra[optionName] = currentRaw[optionName];
7343                    }
7344                }
7345            }
7346            if (anyChanges) {
7347                this.currentCalendarOptionsInput = raw;
7348                this.currentCalendarOptionsRefined = refined;
7349            }
7350            return {
7351                rawOptions: this.currentCalendarOptionsInput,
7352                refinedOptions: this.currentCalendarOptionsRefined,
7353                pluginHooks: pluginHooks,
7354                availableLocaleData: availableLocaleData,
7355                localeDefaults: localeDefaults,
7356                extra: extra
7357            };
7358        };
7359        CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) {
7360            var viewSpec = optionsData.viewSpecs[viewType];
7361            if (!viewSpec) {
7362                throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins");
7363            }
7364            var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra;
7365            warnUnknownOptions(extra);
7366            var dateProfileGenerator = this.buildDateProfileGenerator({
7367                dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,
7368                duration: viewSpec.duration,
7369                durationUnit: viewSpec.durationUnit,
7370                usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,
7371                dateEnv: optionsData.dateEnv,
7372                calendarApi: this.props.calendarApi,
7373                slotMinTime: refinedOptions.slotMinTime,
7374                slotMaxTime: refinedOptions.slotMaxTime,
7375                showNonCurrentDates: refinedOptions.showNonCurrentDates,
7376                dayCount: refinedOptions.dayCount,
7377                dateAlignment: refinedOptions.dateAlignment,
7378                dateIncrement: refinedOptions.dateIncrement,
7379                hiddenDays: refinedOptions.hiddenDays,
7380                weekends: refinedOptions.weekends,
7381                nowInput: refinedOptions.now,
7382                validRangeInput: refinedOptions.validRange,
7383                visibleRangeInput: refinedOptions.visibleRange,
7384                monthMode: refinedOptions.monthMode,
7385                fixedWeekCount: refinedOptions.fixedWeekCount
7386            });
7387            var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);
7388            return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi };
7389        };
7390        CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {
7391            var raw = mergeRawOptions([
7392                BASE_OPTION_DEFAULTS,
7393                viewSpec.optionDefaults,
7394                localeDefaults,
7395                optionOverrides,
7396                viewSpec.optionOverrides,
7397                dynamicOptionOverrides
7398            ]);
7399            var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7400            var refined = {};
7401            var currentRaw = this.currentViewOptionsInput;
7402            var currentRefined = this.currentViewOptionsRefined;
7403            var anyChanges = false;
7404            var extra = {};
7405            for (var optionName in raw) {
7406                if (raw[optionName] === currentRaw[optionName]) {
7407                    refined[optionName] = currentRefined[optionName];
7408                }
7409                else {
7410                    if (raw[optionName] === this.currentCalendarOptionsInput[optionName]) {
7411                        if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop
7412                            refined[optionName] = this.currentCalendarOptionsRefined[optionName];
7413                        }
7414                    }
7415                    else if (refiners[optionName]) {
7416                        refined[optionName] = refiners[optionName](raw[optionName]);
7417                    }
7418                    else {
7419                        extra[optionName] = raw[optionName];
7420                    }
7421                    anyChanges = true;
7422                }
7423            }
7424            if (anyChanges) {
7425                this.currentViewOptionsInput = raw;
7426                this.currentViewOptionsRefined = refined;
7427            }
7428            return {
7429                rawOptions: this.currentViewOptionsInput,
7430                refinedOptions: this.currentViewOptionsRefined,
7431                extra: extra
7432            };
7433        };
7434        return CalendarDataManager;
7435    }());
7436    function buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {
7437        var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);
7438        return new DateEnv({
7439            calendarSystem: 'gregory',
7440            timeZone: timeZone,
7441            namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,
7442            locale: locale,
7443            weekNumberCalculation: weekNumberCalculation,
7444            firstDay: firstDay,
7445            weekText: weekText,
7446            cmdFormatter: pluginHooks.cmdFormatter,
7447            defaultSeparator: defaultSeparator
7448        });
7449    }
7450    function buildTheme(options, pluginHooks) {
7451        var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;
7452        return new ThemeClass(options);
7453    }
7454    function buildDateProfileGenerator(props) {
7455        var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator;
7456        return new DateProfileGeneratorClass(props);
7457    }
7458    function buildViewApi(type, getCurrentData, dateEnv) {
7459        return new ViewApi(type, getCurrentData, dateEnv);
7460    }
7461    function buildEventUiBySource(eventSources) {
7462        return mapHash(eventSources, function (eventSource) {
7463            return eventSource.ui;
7464        });
7465    }
7466    function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
7467        var eventUiBases = { '': eventUiSingleBase };
7468        for (var defId in eventDefs) {
7469            var def = eventDefs[defId];
7470            if (def.sourceId && eventUiBySource[def.sourceId]) {
7471                eventUiBases[defId] = eventUiBySource[def.sourceId];
7472            }
7473        }
7474        return eventUiBases;
7475    }
7476    function buildViewUiProps(calendarContext) {
7477        var options = calendarContext.options;
7478        return {
7479            eventUiSingleBase: createEventUi({
7480                display: options.eventDisplay,
7481                editable: options.editable,
7482                startEditable: options.eventStartEditable,
7483                durationEditable: options.eventDurationEditable,
7484                constraint: options.eventConstraint,
7485                overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,
7486                allow: options.eventAllow,
7487                backgroundColor: options.eventBackgroundColor,
7488                borderColor: options.eventBorderColor,
7489                textColor: options.eventTextColor,
7490                color: options.eventColor
7491                // classNames: options.eventClassNames // render hook will handle this
7492            }, calendarContext),
7493            selectionConfig: createEventUi({
7494                constraint: options.selectConstraint,
7495                overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,
7496                allow: options.selectAllow
7497            }, calendarContext)
7498        };
7499    }
7500    function parseContextBusinessHours(calendarContext) {
7501        return parseBusinessHours(calendarContext.options.businessHours, calendarContext);
7502    }
7503    function warnUnknownOptions(options, viewName) {
7504        for (var optionName in options) {
7505            console.warn("Unknown option '" + optionName + "'" +
7506                (viewName ? " for view '" + viewName + "'" : ''));
7507        }
7508    }
7509
7510    // TODO: move this to react plugin?
7511    var CalendarDataProvider = /** @class */ (function (_super) {
7512        __extends(CalendarDataProvider, _super);
7513        function CalendarDataProvider(props) {
7514            var _this = _super.call(this, props) || this;
7515            _this.handleData = function (data) {
7516                if (!_this.dataManager) { // still within initial run, before assignment in constructor
7517                    // eslint-disable-next-line react/no-direct-mutation-state
7518                    _this.state = data; // can't use setState yet
7519                }
7520                else {
7521                    _this.setState(data);
7522                }
7523            };
7524            _this.dataManager = new CalendarDataManager({
7525                optionOverrides: props.optionOverrides,
7526                calendarApi: props.calendarApi,
7527                onData: _this.handleData
7528            });
7529            return _this;
7530        }
7531        CalendarDataProvider.prototype.render = function () {
7532            return this.props.children(this.state);
7533        };
7534        CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) {
7535            var newOptionOverrides = this.props.optionOverrides;
7536            if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData
7537                this.dataManager.resetOptions(newOptionOverrides);
7538            }
7539        };
7540        return CalendarDataProvider;
7541    }(Component));
7542
7543    // HELPERS
7544    /*
7545    if nextDayThreshold is specified, slicing is done in an all-day fashion.
7546    you can get nextDayThreshold from context.nextDayThreshold
7547    */
7548    function sliceEvents(props, allDay) {
7549        return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;
7550    }
7551
7552    var NamedTimeZoneImpl = /** @class */ (function () {
7553        function NamedTimeZoneImpl(timeZoneName) {
7554            this.timeZoneName = timeZoneName;
7555        }
7556        return NamedTimeZoneImpl;
7557    }());
7558
7559    var Interaction = /** @class */ (function () {
7560        function Interaction(settings) {
7561            this.component = settings.component;
7562        }
7563        Interaction.prototype.destroy = function () {
7564        };
7565        return Interaction;
7566    }());
7567    function parseInteractionSettings(component, input) {
7568        return {
7569            component: component,
7570            el: input.el,
7571            useEventCenter: input.useEventCenter != null ? input.useEventCenter : true
7572        };
7573    }
7574    function interactionSettingsToStore(settings) {
7575        var _a;
7576        return _a = {},
7577            _a[settings.component.uid] = settings,
7578            _a;
7579    }
7580    // global state
7581    var interactionSettingsStore = {};
7582
7583    /*
7584    An abstraction for a dragging interaction originating on an event.
7585    Does higher-level things than PointerDragger, such as possibly:
7586    - a "mirror" that moves with the pointer
7587    - a minimum number of pixels or other criteria for a true drag to begin
7588
7589    subclasses must emit:
7590    - pointerdown
7591    - dragstart
7592    - dragmove
7593    - pointerup
7594    - dragend
7595    */
7596    var ElementDragging = /** @class */ (function () {
7597        function ElementDragging(el, selector) {
7598            this.emitter = new Emitter();
7599        }
7600        ElementDragging.prototype.destroy = function () {
7601        };
7602        ElementDragging.prototype.setMirrorIsVisible = function (bool) {
7603            // optional if subclass doesn't want to support a mirror
7604        };
7605        ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
7606            // optional if subclass doesn't want to support a mirror
7607        };
7608        ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
7609            // optional
7610        };
7611        return ElementDragging;
7612    }());
7613
7614    // TODO: get rid of this in favor of options system,
7615    // tho it's really easy to access this globally rather than pass thru options.
7616    var config = {};
7617
7618    /*
7619    Information about what will happen when an external element is dragged-and-dropped
7620    onto a calendar. Contains information for creating an event.
7621    */
7622    var DRAG_META_REFINERS = {
7623        startTime: createDuration,
7624        duration: createDuration,
7625        create: Boolean,
7626        sourceId: String
7627    };
7628    function parseDragMeta(raw) {
7629        var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra;
7630        return {
7631            startTime: refined.startTime || null,
7632            duration: refined.duration || null,
7633            create: refined.create != null ? refined.create : true,
7634            sourceId: refined.sourceId,
7635            leftoverProps: extra
7636        };
7637    }
7638
7639    var Toolbar = /** @class */ (function (_super) {
7640        __extends(Toolbar, _super);
7641        function Toolbar() {
7642            return _super !== null && _super.apply(this, arguments) || this;
7643        }
7644        Toolbar.prototype.render = function () {
7645            var _a = this.props, model = _a.model, extraClassName = _a.extraClassName;
7646            var forceLtr = false;
7647            var startContent, endContent;
7648            var centerContent = model.center;
7649            if (model.left) {
7650                forceLtr = true;
7651                startContent = model.left;
7652            }
7653            else {
7654                startContent = model.start;
7655            }
7656            if (model.right) {
7657                forceLtr = true;
7658                endContent = model.right;
7659            }
7660            else {
7661                endContent = model.end;
7662            }
7663            var classNames = [
7664                extraClassName || '',
7665                'fc-toolbar',
7666                forceLtr ? 'fc-toolbar-ltr' : ''
7667            ];
7668            return (createElement("div", { className: classNames.join(' ') },
7669                this.renderSection('start', startContent || []),
7670                this.renderSection('center', centerContent || []),
7671                this.renderSection('end', endContent || [])));
7672        };
7673        Toolbar.prototype.renderSection = function (key, widgetGroups) {
7674            var props = this.props;
7675            return (createElement(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled }));
7676        };
7677        return Toolbar;
7678    }(BaseComponent));
7679    var ToolbarSection = /** @class */ (function (_super) {
7680        __extends(ToolbarSection, _super);
7681        function ToolbarSection() {
7682            return _super !== null && _super.apply(this, arguments) || this;
7683        }
7684        ToolbarSection.prototype.render = function () {
7685            var _this = this;
7686            var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); });
7687            return createElement.apply(void 0, __spreadArrays(['div', { className: 'fc-toolbar-chunk' }], children));
7688        };
7689        ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) {
7690            var props = this.props;
7691            var theme = this.context.theme;
7692            var children = [];
7693            var isOnlyButtons = true;
7694            for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) {
7695                var widget = widgetGroup_1[_i];
7696                var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon;
7697                if (buttonName === 'title') {
7698                    isOnlyButtons = false;
7699                    children.push(createElement("h2", { className: 'fc-toolbar-title' }, props.title));
7700                }
7701                else {
7702                    var ariaAttrs = buttonIcon ? { 'aria-label': buttonName } : {};
7703                    var buttonClasses = ['fc-' + buttonName + '-button', theme.getClass('button')];
7704                    if (buttonName === props.activeButton) {
7705                        buttonClasses.push(theme.getClass('buttonActive'));
7706                    }
7707                    var isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||
7708                        (!props.isPrevEnabled && buttonName === 'prev') ||
7709                        (!props.isNextEnabled && buttonName === 'next');
7710                    children.push(createElement("button", __assign({ disabled: isDisabled, className: buttonClasses.join(' '), onClick: buttonClick, type: 'button' }, ariaAttrs), buttonText || (buttonIcon ? createElement("span", { className: buttonIcon }) : '')));
7711                }
7712            }
7713            if (children.length > 1) {
7714                var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || '';
7715                return createElement.apply(void 0, __spreadArrays(['div', { className: groupClassName }], children));
7716            }
7717            else {
7718                return children[0];
7719            }
7720        };
7721        return ToolbarSection;
7722    }(BaseComponent));
7723
7724    // TODO: do function component?
7725    var ViewContainer = /** @class */ (function (_super) {
7726        __extends(ViewContainer, _super);
7727        function ViewContainer() {
7728            var _this = _super !== null && _super.apply(this, arguments) || this;
7729            _this.state = {
7730                availableWidth: null
7731            };
7732            _this.handleEl = function (el) {
7733                _this.el = el;
7734                setRef(_this.props.elRef, el);
7735                _this.updateAvailableWidth();
7736            };
7737            _this.handleResize = function () {
7738                _this.updateAvailableWidth();
7739            };
7740            return _this;
7741        }
7742        ViewContainer.prototype.render = function () {
7743            var _a = this, props = _a.props, state = _a.state;
7744            var aspectRatio = props.aspectRatio;
7745            var classNames = [
7746                'fc-view-harness',
7747                (aspectRatio || props.liquid || props.height)
7748                    ? 'fc-view-harness-active' // harness controls the height
7749                    : 'fc-view-harness-passive' // let the view do the height
7750            ];
7751            var height = '';
7752            var paddingBottom = '';
7753            if (aspectRatio) {
7754                if (state.availableWidth !== null) {
7755                    height = state.availableWidth / aspectRatio;
7756                }
7757                else {
7758                    // while waiting to know availableWidth, we can't set height to *zero*
7759                    // because will cause lots of unnecessary scrollbars within scrollgrid.
7760                    // BETTER: don't start rendering ANYTHING yet until we know container width
7761                    // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)
7762                    paddingBottom = (1 / aspectRatio) * 100 + '%';
7763                }
7764            }
7765            else {
7766                height = props.height || '';
7767            }
7768            return (createElement("div", { ref: this.handleEl, onClick: props.onClick, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children));
7769        };
7770        ViewContainer.prototype.componentDidMount = function () {
7771            this.context.addResizeHandler(this.handleResize);
7772        };
7773        ViewContainer.prototype.componentWillUnmount = function () {
7774            this.context.removeResizeHandler(this.handleResize);
7775        };
7776        ViewContainer.prototype.updateAvailableWidth = function () {
7777            if (this.el && // needed. but why?
7778                this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth
7779            ) {
7780                this.setState({ availableWidth: this.el.offsetWidth });
7781            }
7782        };
7783        return ViewContainer;
7784    }(BaseComponent));
7785
7786    /*
7787    Detects when the user clicks on an event within a DateComponent
7788    */
7789    var EventClicking = /** @class */ (function (_super) {
7790        __extends(EventClicking, _super);
7791        function EventClicking(settings) {
7792            var _this = _super.call(this, settings) || this;
7793            _this.handleSegClick = function (ev, segEl) {
7794                var component = _this.component;
7795                var context = component.context;
7796                var seg = getElSeg(segEl);
7797                if (seg && // might be the <div> surrounding the more link
7798                    component.isValidSegDownEl(ev.target)) {
7799                    // our way to simulate a link click for elements that can't be <a> tags
7800                    // grab before trigger fired in case trigger trashes DOM thru rerendering
7801                    var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url');
7802                    var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
7803                    context.emitter.trigger('eventClick', {
7804                        el: segEl,
7805                        event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance),
7806                        jsEvent: ev,
7807                        view: context.viewApi
7808                    });
7809                    if (url && !ev.defaultPrevented) {
7810                        window.location.href = url;
7811                    }
7812                }
7813            };
7814            _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events
7815            _this.handleSegClick);
7816            return _this;
7817        }
7818        return EventClicking;
7819    }(Interaction));
7820
7821    /*
7822    Triggers events and adds/removes core classNames when the user's pointer
7823    enters/leaves event-elements of a component.
7824    */
7825    var EventHovering = /** @class */ (function (_super) {
7826        __extends(EventHovering, _super);
7827        function EventHovering(settings) {
7828            var _this = _super.call(this, settings) || this;
7829            // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
7830            _this.handleEventElRemove = function (el) {
7831                if (el === _this.currentSegEl) {
7832                    _this.handleSegLeave(null, _this.currentSegEl);
7833                }
7834            };
7835            _this.handleSegEnter = function (ev, segEl) {
7836                if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
7837                    _this.currentSegEl = segEl;
7838                    _this.triggerEvent('eventMouseEnter', ev, segEl);
7839                }
7840            };
7841            _this.handleSegLeave = function (ev, segEl) {
7842                if (_this.currentSegEl) {
7843                    _this.currentSegEl = null;
7844                    _this.triggerEvent('eventMouseLeave', ev, segEl);
7845                }
7846            };
7847            _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events
7848            _this.handleSegEnter, _this.handleSegLeave);
7849            return _this;
7850        }
7851        EventHovering.prototype.destroy = function () {
7852            this.removeHoverListeners();
7853        };
7854        EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
7855            var component = this.component;
7856            var context = component.context;
7857            var seg = getElSeg(segEl);
7858            if (!ev || component.isValidSegDownEl(ev.target)) {
7859                context.emitter.trigger(publicEvName, {
7860                    el: segEl,
7861                    event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance),
7862                    jsEvent: ev,
7863                    view: context.viewApi
7864                });
7865            }
7866        };
7867        return EventHovering;
7868    }(Interaction));
7869
7870    var CalendarContent = /** @class */ (function (_super) {
7871        __extends(CalendarContent, _super);
7872        function CalendarContent() {
7873            var _this = _super !== null && _super.apply(this, arguments) || this;
7874            _this.buildViewContext = memoize(buildViewContext);
7875            _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
7876            _this.buildToolbarProps = memoize(buildToolbarProps);
7877            _this.handleNavLinkClick = buildDelegationHandler('a[data-navlink]', _this._handleNavLinkClick.bind(_this));
7878            _this.headerRef = createRef();
7879            _this.footerRef = createRef();
7880            _this.interactionsStore = {};
7881            // Component Registration
7882            // -----------------------------------------------------------------------------------------------------------------
7883            _this.registerInteractiveComponent = function (component, settingsInput) {
7884                var settings = parseInteractionSettings(component, settingsInput);
7885                var DEFAULT_INTERACTIONS = [
7886                    EventClicking,
7887                    EventHovering
7888                ];
7889                var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions);
7890                var interactions = interactionClasses.map(function (interactionClass) {
7891                    return new interactionClass(settings);
7892                });
7893                _this.interactionsStore[component.uid] = interactions;
7894                interactionSettingsStore[component.uid] = settings;
7895            };
7896            _this.unregisterInteractiveComponent = function (component) {
7897                for (var _i = 0, _a = _this.interactionsStore[component.uid]; _i < _a.length; _i++) {
7898                    var listener = _a[_i];
7899                    listener.destroy();
7900                }
7901                delete _this.interactionsStore[component.uid];
7902                delete interactionSettingsStore[component.uid];
7903            };
7904            // Resizing
7905            // -----------------------------------------------------------------------------------------------------------------
7906            _this.resizeRunner = new DelayedRunner(function () {
7907                _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ?
7908                _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi });
7909            });
7910            _this.handleWindowResize = function (ev) {
7911                var options = _this.props.options;
7912                if (options.handleWindowResize &&
7913                    ev.target === window // avoid jqui events
7914                ) {
7915                    _this.resizeRunner.request(options.windowResizeDelay);
7916                }
7917            };
7918            return _this;
7919        }
7920        /*
7921        renders INSIDE of an outer div
7922        */
7923        CalendarContent.prototype.render = function () {
7924            var props = this.props;
7925            var toolbarConfig = props.toolbarConfig, options = props.options;
7926            var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer????
7927            props.viewTitle);
7928            var viewVGrow = false;
7929            var viewHeight = '';
7930            var viewAspectRatio;
7931            if (props.isHeightAuto || props.forPrint) {
7932                viewHeight = '';
7933            }
7934            else if (options.height != null) {
7935                viewVGrow = true;
7936            }
7937            else if (options.contentHeight != null) {
7938                viewHeight = options.contentHeight;
7939            }
7940            else {
7941                viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall
7942            }
7943            var viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);
7944            return (createElement(ViewContextType.Provider, { value: viewContext },
7945                toolbarConfig.headerToolbar &&
7946                    createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: 'fc-header-toolbar', model: toolbarConfig.headerToolbar }, toolbarProps)),
7947                createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, onClick: this.handleNavLinkClick },
7948                    this.renderView(props),
7949                    this.buildAppendContent()),
7950                toolbarConfig.footerToolbar &&
7951                    createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: 'fc-footer-toolbar', model: toolbarConfig.footerToolbar }, toolbarProps))));
7952        };
7953        CalendarContent.prototype.componentDidMount = function () {
7954            var props = this.props;
7955            this.calendarInteractions = props.pluginHooks.calendarInteractions
7956                .map(function (calendarInteractionClass) {
7957                return new calendarInteractionClass(props);
7958            });
7959            window.addEventListener('resize', this.handleWindowResize);
7960            var propSetHandlers = props.pluginHooks.propSetHandlers;
7961            for (var propName in propSetHandlers) {
7962                propSetHandlers[propName](props[propName], props);
7963            }
7964        };
7965        CalendarContent.prototype.componentDidUpdate = function (prevProps) {
7966            var props = this.props;
7967            var propSetHandlers = props.pluginHooks.propSetHandlers;
7968            for (var propName in propSetHandlers) {
7969                if (props[propName] !== prevProps[propName]) {
7970                    propSetHandlers[propName](props[propName], props);
7971                }
7972            }
7973        };
7974        CalendarContent.prototype.componentWillUnmount = function () {
7975            window.removeEventListener('resize', this.handleWindowResize);
7976            this.resizeRunner.clear();
7977            for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
7978                var interaction = _a[_i];
7979                interaction.destroy();
7980            }
7981            this.props.emitter.trigger('_unmount');
7982        };
7983        CalendarContent.prototype._handleNavLinkClick = function (ev, anchorEl) {
7984            var _a = this.props, dateEnv = _a.dateEnv, options = _a.options, calendarApi = _a.calendarApi;
7985            var navLinkOptions = anchorEl.getAttribute('data-navlink');
7986            navLinkOptions = navLinkOptions ? JSON.parse(navLinkOptions) : {};
7987            var dateMarker = dateEnv.createMarker(navLinkOptions.date);
7988            var viewType = navLinkOptions.type;
7989            var customAction = viewType === 'day' ? options.navLinkDayClick :
7990                viewType === 'week' ? options.navLinkWeekClick : null;
7991            if (typeof customAction === 'function') {
7992                customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev);
7993            }
7994            else {
7995                if (typeof customAction === 'string') {
7996                    viewType = customAction;
7997                }
7998                calendarApi.zoomTo(dateMarker, viewType);
7999            }
8000        };
8001        CalendarContent.prototype.buildAppendContent = function () {
8002            var props = this.props;
8003            var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); });
8004            return createElement.apply(void 0, __spreadArrays([Fragment, {}], children));
8005        };
8006        CalendarContent.prototype.renderView = function (props) {
8007            var pluginHooks = props.pluginHooks;
8008            var viewSpec = props.viewSpec;
8009            var viewProps = {
8010                dateProfile: props.dateProfile,
8011                businessHours: props.businessHours,
8012                eventStore: props.renderableEventStore,
8013                eventUiBases: props.eventUiBases,
8014                dateSelection: props.dateSelection,
8015                eventSelection: props.eventSelection,
8016                eventDrag: props.eventDrag,
8017                eventResize: props.eventResize,
8018                isHeightAuto: props.isHeightAuto,
8019                forPrint: props.forPrint
8020            };
8021            var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);
8022            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
8023                var transformer = transformers_1[_i];
8024                __assign(viewProps, transformer.transform(viewProps, props));
8025            }
8026            var ViewComponent = viewSpec.component;
8027            return (createElement(ViewComponent, __assign({}, viewProps)));
8028        };
8029        return CalendarContent;
8030    }(PureComponent));
8031    function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {
8032        // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid
8033        var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason
8034        var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);
8035        var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);
8036        return {
8037            title: title,
8038            activeButton: viewSpec.type,
8039            isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
8040            isPrevEnabled: prevInfo.isValid,
8041            isNextEnabled: nextInfo.isValid
8042        };
8043    }
8044    // Plugin
8045    // -----------------------------------------------------------------------------------------------------------------
8046    function buildViewPropTransformers(theClasses) {
8047        return theClasses.map(function (theClass) {
8048            return new theClass();
8049        });
8050    }
8051
8052    var CalendarRoot = /** @class */ (function (_super) {
8053        __extends(CalendarRoot, _super);
8054        function CalendarRoot() {
8055            var _this = _super !== null && _super.apply(this, arguments) || this;
8056            _this.state = {
8057                forPrint: false
8058            };
8059            _this.handleBeforePrint = function () {
8060                _this.setState({ forPrint: true });
8061            };
8062            _this.handleAfterPrint = function () {
8063                _this.setState({ forPrint: false });
8064            };
8065            return _this;
8066        }
8067        CalendarRoot.prototype.render = function () {
8068            var props = this.props;
8069            var options = props.options;
8070            var forPrint = this.state.forPrint;
8071            var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto';
8072            var height = (!isHeightAuto && options.height != null) ? options.height : '';
8073            var classNames = [
8074                'fc',
8075                forPrint ? 'fc-media-print' : 'fc-media-screen',
8076                'fc-direction-' + options.direction,
8077                props.theme.getClass('root')
8078            ];
8079            if (!getCanVGrowWithinCell()) {
8080                classNames.push('fc-liquid-hack');
8081            }
8082            return props.children(classNames, height, isHeightAuto, forPrint);
8083        };
8084        CalendarRoot.prototype.componentDidMount = function () {
8085            var emitter = this.props.emitter;
8086            emitter.on('_beforeprint', this.handleBeforePrint);
8087            emitter.on('_afterprint', this.handleAfterPrint);
8088        };
8089        CalendarRoot.prototype.componentWillUnmount = function () {
8090            var emitter = this.props.emitter;
8091            emitter.off('_beforeprint', this.handleBeforePrint);
8092            emitter.off('_afterprint', this.handleAfterPrint);
8093        };
8094        return CalendarRoot;
8095    }(BaseComponent));
8096
8097    // Computes a default column header formatting string if `colFormat` is not explicitly defined
8098    function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
8099        // if more than one week row, or if there are a lot of columns with not much space,
8100        // put just the day numbers will be in each cell
8101        if (!datesRepDistinctDays || dayCnt > 10) {
8102            return createFormatter({ weekday: 'short' }); // "Sat"
8103        }
8104        else if (dayCnt > 1) {
8105            return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12"
8106        }
8107        else {
8108            return createFormatter({ weekday: 'long' }); // "Saturday"
8109        }
8110    }
8111
8112    var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no
8113    var TableDateCell = /** @class */ (function (_super) {
8114        __extends(TableDateCell, _super);
8115        function TableDateCell() {
8116            return _super !== null && _super.apply(this, arguments) || this;
8117        }
8118        TableDateCell.prototype.render = function () {
8119            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi;
8120            var props = this.props;
8121            var date = props.date, dateProfile = props.dateProfile;
8122            var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile);
8123            var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme));
8124            var text = dateEnv.format(date, props.dayHeaderFormat);
8125            // if colCnt is 1, we are already in a day-view and don't need a navlink
8126            var navLinkAttrs = (options.navLinks && !dayMeta.isDisabled && props.colCnt > 1)
8127                ? { 'data-navlink': buildNavLinkData(date), tabIndex: 0 }
8128                : {};
8129            var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta);
8130            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": !dayMeta.isDisabled ? formatDayString(date) : undefined, colSpan: props.colSpan }, props.extraDataAttrs),
8131                createElement("div", { className: 'fc-scrollgrid-sync-inner' }, !dayMeta.isDisabled &&
8132                    createElement("a", __assign({ ref: innerElRef, className: [
8133                            'fc-col-header-cell-cushion',
8134                            props.isSticky ? 'fc-sticky' : ''
8135                        ].join(' ') }, navLinkAttrs), innerContent)))); }));
8136        };
8137        return TableDateCell;
8138    }(BaseComponent));
8139    var TableDowCell = /** @class */ (function (_super) {
8140        __extends(TableDowCell, _super);
8141        function TableDowCell() {
8142            return _super !== null && _super.apply(this, arguments) || this;
8143        }
8144        TableDowCell.prototype.render = function () {
8145            var props = this.props;
8146            var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options;
8147            var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT
8148            var dateMeta = {
8149                dow: props.dow,
8150                isDisabled: false,
8151                isFuture: false,
8152                isPast: false,
8153                isToday: false,
8154                isOther: false
8155            };
8156            var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []);
8157            var text = dateEnv.format(date, props.dayHeaderFormat);
8158            var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public?
8159                date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text });
8160            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, className: classNames.concat(customClassNames).join(' '), colSpan: props.colSpan }, props.extraDataAttrs),
8161                createElement("div", { className: 'fc-scrollgrid-sync-inner' },
8162                    createElement("a", { className: [
8163                            'fc-col-header-cell-cushion',
8164                            props.isSticky ? 'fc-sticky' : ''
8165                        ].join(' '), ref: innerElRef }, innerContent)))); }));
8166        };
8167        return TableDowCell;
8168    }(BaseComponent));
8169    function renderInner(hookProps) {
8170        return hookProps.text;
8171    }
8172
8173    var NowTimer = /** @class */ (function (_super) {
8174        __extends(NowTimer, _super);
8175        function NowTimer(props, context) {
8176            var _this = _super.call(this, props, context) || this;
8177            _this.initialNowDate = getNow(context.options.now, context.dateEnv);
8178            _this.initialNowQueriedMs = new Date().valueOf();
8179            _this.state = _this.computeTiming().currentState;
8180            return _this;
8181        }
8182        NowTimer.prototype.render = function () {
8183            var _a = this, props = _a.props, state = _a.state;
8184            return props.children(state.nowDate, state.todayRange);
8185        };
8186        NowTimer.prototype.componentDidMount = function () {
8187            this.setTimeout();
8188        };
8189        NowTimer.prototype.componentDidUpdate = function (prevProps) {
8190            if (prevProps.unit !== this.props.unit) {
8191                this.clearTimeout();
8192                this.setTimeout();
8193            }
8194        };
8195        NowTimer.prototype.componentWillUnmount = function () {
8196            this.clearTimeout();
8197        };
8198        NowTimer.prototype.computeTiming = function () {
8199            var _a = this, props = _a.props, context = _a.context;
8200            var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs);
8201            var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);
8202            var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));
8203            var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
8204            return {
8205                currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },
8206                nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) },
8207                waitMs: waitMs
8208            };
8209        };
8210        NowTimer.prototype.setTimeout = function () {
8211            var _this = this;
8212            var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs;
8213            this.timeoutId = setTimeout(function () {
8214                _this.setState(nextState, function () {
8215                    _this.setTimeout();
8216                });
8217            }, waitMs);
8218        };
8219        NowTimer.prototype.clearTimeout = function () {
8220            if (this.timeoutId) {
8221                clearTimeout(this.timeoutId);
8222            }
8223        };
8224        NowTimer.contextType = ViewContextType;
8225        return NowTimer;
8226    }(Component));
8227    function buildDayRange(date) {
8228        var start = startOfDay(date);
8229        var end = addDays(start, 1);
8230        return { start: start, end: end };
8231    }
8232
8233    var DayHeader = /** @class */ (function (_super) {
8234        __extends(DayHeader, _super);
8235        function DayHeader() {
8236            var _this = _super !== null && _super.apply(this, arguments) || this;
8237            _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter);
8238            return _this;
8239        }
8240        DayHeader.prototype.render = function () {
8241            var context = this.context;
8242            var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro;
8243            var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length);
8244            return (createElement(NowTimer, { unit: 'day' }, function (nowDate, todayRange) { return (createElement("tr", null,
8245                renderIntro && renderIntro(),
8246                dates.map(function (date) { return (datesRepDistinctDays ?
8247                    createElement(TableDateCell, { key: date.toISOString(), date: date, dateProfile: dateProfile, todayRange: todayRange, colCnt: dates.length, dayHeaderFormat: dayHeaderFormat }) :
8248                    createElement(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat: dayHeaderFormat })); }))); }));
8249        };
8250        return DayHeader;
8251    }(BaseComponent));
8252    function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
8253        return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
8254    }
8255
8256    var DaySeriesModel = /** @class */ (function () {
8257        function DaySeriesModel(range, dateProfileGenerator) {
8258            var date = range.start;
8259            var end = range.end;
8260            var indices = [];
8261            var dates = [];
8262            var dayIndex = -1;
8263            while (date < end) { // loop each day from start to end
8264                if (dateProfileGenerator.isHiddenDay(date)) {
8265                    indices.push(dayIndex + 0.5); // mark that it's between indices
8266                }
8267                else {
8268                    dayIndex++;
8269                    indices.push(dayIndex);
8270                    dates.push(date);
8271                }
8272                date = addDays(date, 1);
8273            }
8274            this.dates = dates;
8275            this.indices = indices;
8276            this.cnt = dates.length;
8277        }
8278        DaySeriesModel.prototype.sliceRange = function (range) {
8279            var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
8280            var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
8281            var clippedFirstIndex = Math.max(0, firstIndex);
8282            var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
8283            // deal with in-between indices
8284            clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
8285            clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
8286            if (clippedFirstIndex <= clippedLastIndex) {
8287                return {
8288                    firstIndex: clippedFirstIndex,
8289                    lastIndex: clippedLastIndex,
8290                    isStart: firstIndex === clippedFirstIndex,
8291                    isEnd: lastIndex === clippedLastIndex
8292                };
8293            }
8294            else {
8295                return null;
8296            }
8297        };
8298        // Given a date, returns its chronolocial cell-index from the first cell of the grid.
8299        // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
8300        // If before the first offset, returns a negative number.
8301        // If after the last offset, returns an offset past the last cell offset.
8302        // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
8303        DaySeriesModel.prototype.getDateDayIndex = function (date) {
8304            var indices = this.indices;
8305            var dayOffset = Math.floor(diffDays(this.dates[0], date));
8306            if (dayOffset < 0) {
8307                return indices[0] - 1;
8308            }
8309            else if (dayOffset >= indices.length) {
8310                return indices[indices.length - 1] + 1;
8311            }
8312            else {
8313                return indices[dayOffset];
8314            }
8315        };
8316        return DaySeriesModel;
8317    }());
8318
8319    var DayTableModel = /** @class */ (function () {
8320        function DayTableModel(daySeries, breakOnWeeks) {
8321            var dates = daySeries.dates;
8322            var daysPerRow;
8323            var firstDay;
8324            var rowCnt;
8325            if (breakOnWeeks) {
8326                // count columns until the day-of-week repeats
8327                firstDay = dates[0].getUTCDay();
8328                for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) {
8329                    if (dates[daysPerRow].getUTCDay() === firstDay) {
8330                        break;
8331                    }
8332                }
8333                rowCnt = Math.ceil(dates.length / daysPerRow);
8334            }
8335            else {
8336                rowCnt = 1;
8337                daysPerRow = dates.length;
8338            }
8339            this.rowCnt = rowCnt;
8340            this.colCnt = daysPerRow;
8341            this.daySeries = daySeries;
8342            this.cells = this.buildCells();
8343            this.headerDates = this.buildHeaderDates();
8344        }
8345        DayTableModel.prototype.buildCells = function () {
8346            var rows = [];
8347            for (var row = 0; row < this.rowCnt; row++) {
8348                var cells = [];
8349                for (var col = 0; col < this.colCnt; col++) {
8350                    cells.push(this.buildCell(row, col));
8351                }
8352                rows.push(cells);
8353            }
8354            return rows;
8355        };
8356        DayTableModel.prototype.buildCell = function (row, col) {
8357            var date = this.daySeries.dates[row * this.colCnt + col];
8358            return {
8359                key: date.toISOString(),
8360                date: date
8361            };
8362        };
8363        DayTableModel.prototype.buildHeaderDates = function () {
8364            var dates = [];
8365            for (var col = 0; col < this.colCnt; col++) {
8366                dates.push(this.cells[0][col].date);
8367            }
8368            return dates;
8369        };
8370        DayTableModel.prototype.sliceRange = function (range) {
8371            var colCnt = this.colCnt;
8372            var seriesSeg = this.daySeries.sliceRange(range);
8373            var segs = [];
8374            if (seriesSeg) {
8375                var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
8376                var index = firstIndex;
8377                while (index <= lastIndex) {
8378                    var row = Math.floor(index / colCnt);
8379                    var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
8380                    segs.push({
8381                        row: row,
8382                        firstCol: index % colCnt,
8383                        lastCol: (nextIndex - 1) % colCnt,
8384                        isStart: seriesSeg.isStart && index === firstIndex,
8385                        isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex
8386                    });
8387                    index = nextIndex;
8388                }
8389            }
8390            return segs;
8391        };
8392        return DayTableModel;
8393    }());
8394
8395    var Slicer = /** @class */ (function () {
8396        function Slicer() {
8397            this.sliceBusinessHours = memoize(this._sliceBusinessHours);
8398            this.sliceDateSelection = memoize(this._sliceDateSpan);
8399            this.sliceEventStore = memoize(this._sliceEventStore);
8400            this.sliceEventDrag = memoize(this._sliceInteraction);
8401            this.sliceEventResize = memoize(this._sliceInteraction);
8402            this.forceDayIfListItem = false; // hack
8403        }
8404        Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) {
8405            var extraArgs = [];
8406            for (var _i = 4; _i < arguments.length; _i++) {
8407                extraArgs[_i - 4] = arguments[_i];
8408            }
8409            var eventUiBases = props.eventUiBases;
8410            var eventSegs = this.sliceEventStore.apply(this, __spreadArrays([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs));
8411            return {
8412                dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArrays([props.dateSelection, eventUiBases, context], extraArgs)),
8413                businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArrays([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)),
8414                fgEventSegs: eventSegs.fg,
8415                bgEventSegs: eventSegs.bg,
8416                eventDrag: this.sliceEventDrag.apply(this, __spreadArrays([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
8417                eventResize: this.sliceEventResize.apply(this, __spreadArrays([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
8418                eventSelection: props.eventSelection
8419            }; // TODO: give interactionSegs?
8420        };
8421        Slicer.prototype.sliceNowDate = function (// does not memoize
8422        date, context) {
8423            var extraArgs = [];
8424            for (var _i = 2; _i < arguments.length; _i++) {
8425                extraArgs[_i - 2] = arguments[_i];
8426            }
8427            return this._sliceDateSpan.apply(this, __spreadArrays([{ range: { start: date, end: addMs(date, 1) }, allDay: false },
8428                {},
8429                context], extraArgs));
8430        };
8431        Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) {
8432            var extraArgs = [];
8433            for (var _i = 4; _i < arguments.length; _i++) {
8434                extraArgs[_i - 4] = arguments[_i];
8435            }
8436            if (!businessHours) {
8437                return [];
8438            }
8439            return this._sliceEventStore.apply(this, __spreadArrays([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context),
8440                {},
8441                dateProfile,
8442                nextDayThreshold], extraArgs)).bg;
8443        };
8444        Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) {
8445            var extraArgs = [];
8446            for (var _i = 4; _i < arguments.length; _i++) {
8447                extraArgs[_i - 4] = arguments[_i];
8448            }
8449            if (eventStore) {
8450                var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8451                return {
8452                    bg: this.sliceEventRanges(rangeRes.bg, extraArgs),
8453                    fg: this.sliceEventRanges(rangeRes.fg, extraArgs)
8454                };
8455            }
8456            else {
8457                return { bg: [], fg: [] };
8458            }
8459        };
8460        Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) {
8461            var extraArgs = [];
8462            for (var _i = 4; _i < arguments.length; _i++) {
8463                extraArgs[_i - 4] = arguments[_i];
8464            }
8465            if (!interaction) {
8466                return null;
8467            }
8468            var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8469            return {
8470                segs: this.sliceEventRanges(rangeRes.fg, extraArgs),
8471                affectedInstances: interaction.affectedEvents.instances,
8472                isEvent: interaction.isEvent
8473            };
8474        };
8475        Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) {
8476            var extraArgs = [];
8477            for (var _i = 3; _i < arguments.length; _i++) {
8478                extraArgs[_i - 3] = arguments[_i];
8479            }
8480            if (!dateSpan) {
8481                return [];
8482            }
8483            var eventRange = fabricateEventRange(dateSpan, eventUiBases, context);
8484            var segs = this.sliceRange.apply(this, __spreadArrays([dateSpan.range], extraArgs));
8485            for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
8486                var seg = segs_1[_a];
8487                seg.eventRange = eventRange;
8488            }
8489            return segs;
8490        };
8491        /*
8492        "complete" seg means it has component and eventRange
8493        */
8494        Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) {
8495            var segs = [];
8496            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
8497                var eventRange = eventRanges_1[_i];
8498                segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs));
8499            }
8500            return segs;
8501        };
8502        /*
8503        "complete" seg means it has component and eventRange
8504        */
8505        Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) {
8506            var dateRange = eventRange.range;
8507            // hack to make multi-day events that are being force-displayed as list-items to take up only one day
8508            if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') {
8509                dateRange = {
8510                    start: dateRange.start,
8511                    end: addDays(dateRange.start, 1)
8512                };
8513            }
8514            var segs = this.sliceRange.apply(this, __spreadArrays([dateRange], extraArgs));
8515            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
8516                var seg = segs_2[_i];
8517                seg.eventRange = eventRange;
8518                seg.isStart = eventRange.isStart && seg.isStart;
8519                seg.isEnd = eventRange.isEnd && seg.isEnd;
8520            }
8521            return segs;
8522        };
8523        return Slicer;
8524    }());
8525    /*
8526    for incorporating slotMinTime/slotMaxTime if appropriate
8527    TODO: should be part of DateProfile!
8528    TimelineDateProfile already does this btw
8529    */
8530    function computeActiveRange(dateProfile, isComponentAllDay) {
8531        var range = dateProfile.activeRange;
8532        if (isComponentAllDay) {
8533            return range;
8534        }
8535        return {
8536            start: addMs(range.start, dateProfile.slotMinTime.milliseconds),
8537            end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5) // 864e5 = ms in a day
8538        };
8539    }
8540
8541    var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/;
8542    var Scroller = /** @class */ (function (_super) {
8543        __extends(Scroller, _super);
8544        function Scroller() {
8545            var _this = _super !== null && _super.apply(this, arguments) || this;
8546            _this.handleEl = function (el) {
8547                _this.el = el;
8548                setRef(_this.props.elRef, el);
8549            };
8550            return _this;
8551        }
8552        Scroller.prototype.render = function () {
8553            var props = this.props;
8554            var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute;
8555            var isAbsolute = liquid && liquidIsAbsolute;
8556            var className = ['fc-scroller'];
8557            if (liquid) {
8558                if (liquidIsAbsolute) {
8559                    className.push('fc-scroller-liquid-absolute');
8560                }
8561                else {
8562                    className.push('fc-scroller-liquid');
8563                }
8564            }
8565            return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: {
8566                    overflowX: props.overflowX,
8567                    overflowY: props.overflowY,
8568                    left: (isAbsolute && -(props.overcomeLeft || 0)) || '',
8569                    right: (isAbsolute && -(props.overcomeRight || 0
8569)) || '',
8570                    bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '',
8571                    marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '',
8572                    marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '',
8573                    marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '',
8574                    maxHeight: props.maxHeight || ''
8575                } }, props.children));
8576        };
8577        Scroller.prototype.needsXScrolling = function () {
8578            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
8579                return false;
8580            }
8581            // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers.
8582            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
8583            // inner-child margins and absolute positioning
8584            var el = this.el;
8585            var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth();
8586            var children = el.children;
8587            for (var i = 0; i < children.length; i++) {
8588                var childEl = children[i];
8589                if (childEl.getBoundingClientRect().width > realClientWidth) {
8590                    return true;
8591                }
8592            }
8593            return false;
8594        };
8595        Scroller.prototype.needsYScrolling = function () {
8596            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
8597                return false;
8598            }
8599            // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers.
8600            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
8601            // inner-child margins and absolute positioning
8602            var el = this.el;
8603            var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth();
8604            var children = el.children;
8605            for (var i = 0; i < children.length; i++) {
8606                var childEl = children[i];
8607                if (childEl.getBoundingClientRect().height > realClientHeight) {
8608                    return true;
8609                }
8610            }
8611            return false;
8612        };
8613        Scroller.prototype.getXScrollbarWidth = function () {
8614            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
8615                return 0;
8616            }
8617            else {
8618                return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important?
8619            }
8620        };
8621        Scroller.prototype.getYScrollbarWidth = function () {
8622            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
8623                return 0;
8624            }
8625            else {
8626                return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important?
8627            }
8628        };
8629        return Scroller;
8630    }(BaseComponent));
8631
8632    /*
8633    TODO: somehow infer OtherArgs from masterCallback?
8634    TODO: infer RefType from masterCallback if provided
8635    */
8636    var RefMap = /** @class */ (function () {
8637        function RefMap(masterCallback) {
8638            var _this = this;
8639            this.masterCallback = masterCallback;
8640            this.currentMap = {};
8641            this.depths = {};
8642            this.callbackMap = {};
8643            this.handleValue = function (val, key) {
8644                var _a = _this, depths = _a.depths, currentMap = _a.currentMap;
8645                var removed = false;
8646                var added = false;
8647                if (val !== null) {
8648                    removed = (key in currentMap); // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore
8649                    currentMap[key] = val;
8650                    depths[key] = (depths[key] || 0) + 1;
8651                    added = true;
8652                }
8653                else if (--depths[key] === 0) {
8654                    delete currentMap[key];
8655                    delete _this.callbackMap[key];
8656                    removed = true;
8657                }
8658                if (_this.masterCallback) {
8659                    if (removed) {
8660                        _this.masterCallback(null, String(key));
8661                    }
8662                    if (added) {
8663                        _this.masterCallback(val, String(key));
8664                    }
8665                }
8666            };
8667        }
8668        RefMap.prototype.createRef = function (key) {
8669            var _this = this;
8670            var refCallback = this.callbackMap[key];
8671            if (!refCallback) {
8672                refCallback = this.callbackMap[key] = function (val) {
8673                    _this.handleValue(val, String(key));
8674                };
8675            }
8676            return refCallback;
8677        };
8678        // TODO: check callers that don't care about order. should use getAll instead
8679        // NOTE: this method has become less valuable now that we are encouraged to map order by some other index
8680        // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect"
8681        RefMap.prototype.collect = function (startIndex, endIndex, step) {
8682            return collectFromHash(this.currentMap, startIndex, endIndex, step);
8683        };
8684        RefMap.prototype.getAll = function () {
8685            return hashValuesToArray(this.currentMap);
8686        };
8687        return RefMap;
8688    }());
8689
8690    function computeShrinkWidth(chunkEls) {
8691        var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink');
8692        var largestWidth = 0;
8693        for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) {
8694            var shrinkCell = shrinkCells_1[_i];
8695            largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell));
8696        }
8697        return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits
8698    }
8699    function getSectionHasLiquidHeight(props, sectionConfig) {
8700        return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well)
8701    }
8702    function getAllowYScrolling(props, sectionConfig) {
8703        return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars
8704            getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars
8705    }
8706    // TODO: ONLY use `arg`. force out internal function to use same API
8707    function renderChunkContent(sectionConfig, chunkConfig, arg) {
8708        var expandRows = arg.expandRows;
8709        var content = typeof chunkConfig.content === 'function' ?
8710            chunkConfig.content(arg) :
8711            createElement('table', {
8712                className: [
8713                    chunkConfig.tableClassName,
8714                    sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : ''
8715                ].join(' '),
8716                style: {
8717                    minWidth: arg.tableMinWidth,
8718                    width: arg.clientWidth,
8719                    height: expandRows ? arg.clientHeight : '' // css `height` on a <table> serves as a min-height
8720                }
8721            }, arg.tableColGroupNode, createElement('tbody', {}, typeof chunkConfig.rowContent === 'function' ? chunkConfig.rowContent(arg) : chunkConfig.rowContent));
8722        return content;
8723    }
8724    function isColPropsEqual(cols0, cols1) {
8725        return isArraysEqual(cols0, cols1, isPropsEqual);
8726    }
8727    function renderMicroColGroup(cols, shrinkWidth) {
8728        var colNodes = [];
8729        /*
8730        for ColProps with spans, it would have been great to make a single <col span="">
8731        HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans.
8732        SOLUTION: making individual <col> elements makes Chrome behave.
8733        */
8734        for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) {
8735            var colProps = cols_1[_i];
8736            var span = colProps.span || 1;
8737            for (var i = 0; i < span; i++) {
8738                colNodes.push(createElement("col", { style: {
8739                        width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''),
8740                        minWidth: colProps.minWidth || ''
8741                    } }));
8742            }
8743        }
8744        return createElement.apply(void 0, __spreadArrays(['colgroup', {}], colNodes));
8745    }
8746    function sanitizeShrinkWidth(shrinkWidth) {
8747        /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth
8748        4 accounts for 2 2-pixel borders. TODO: better solution? */
8749        return shrinkWidth == null ? 4 : shrinkWidth;
8750    }
8751    function hasShrinkWidth(cols) {
8752        for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) {
8753            var col = cols_2[_i];
8754            if (col.width === 'shrink') {
8755                return true;
8756            }
8757        }
8758        return false;
8759    }
8760    function getScrollGridClassNames(liquid, context) {
8761        var classNames = [
8762            'fc-scrollgrid',
8763            context.theme.getClass('table')
8764        ];
8765        if (liquid) {
8766            classNames.push('fc-scrollgrid-liquid');
8767        }
8768        return classNames;
8769    }
8770    function getSectionClassNames(sectionConfig, wholeTableVGrow) {
8771        var classNames = [
8772            'fc-scrollgrid-section',
8773            'fc-scrollgrid-section-' + sectionConfig.type,
8774            sectionConfig.className // used?
8775        ];
8776        if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) {
8777            classNames.push('fc-scrollgrid-section-liquid');
8778        }
8779        if (sectionConfig.isSticky) {
8780            classNames.push('fc-scrollgrid-section-sticky');
8781        }
8782        return classNames;
8783    }
8784    function renderScrollShim(arg) {
8785        return (createElement("div", { className: 'fc-scrollgrid-sticky-shim', style: {
8786                width: arg.clientWidth,
8787                minWidth: arg.tableMinWidth
8788            } }));
8789    }
8790    function getStickyHeaderDates(options) {
8791        var stickyHeaderDates = options.stickyHeaderDates;
8792        if (stickyHeaderDates == null || stickyHeaderDates === 'auto') {
8793            stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto';
8794        }
8795        return stickyHeaderDates;
8796    }
8797    function getStickyFooterScrollbar(options) {
8798        var stickyFooterScrollbar = options.stickyFooterScrollbar;
8799        if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') {
8800            stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto';
8801        }
8802        return stickyFooterScrollbar;
8803    }
8804
8805    var SimpleScrollGrid = /** @class */ (function (_super) {
8806        __extends(SimpleScrollGrid, _super);
8807        function SimpleScrollGrid() {
8808            var _this = _super !== null && _super.apply(this, arguments) || this;
8809            _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time
8810            _this.renderMicroColGroup = memoize(renderMicroColGroup); // yucky to memoize VNodes, but much more efficient for consumers
8811            _this.scrollerRefs = new RefMap();
8812            _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this));
8813            _this.state = {
8814                shrinkWidth: null,
8815                forceYScrollbars: false,
8816                scrollerClientWidths: {},
8817                scrollerClientHeights: {}
8818            };
8819            // TODO: can do a really simple print-view. dont need to join rows
8820            _this.handleSizing = function () {
8821                _this.setState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims()));
8822            };
8823            return _this;
8824        }
8825        SimpleScrollGrid.prototype.render = function () {
8826            var _a = this, props = _a.props, state = _a.state, context = _a.context;
8827            var sectionConfigs = props.sections || [];
8828            var cols = this.processCols(props.cols);
8829            var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth);
8830            var classNames = getScrollGridClassNames(props.liquid, context);
8831            // TODO: make DRY
8832            var configCnt = sectionConfigs.length;
8833            var configI = 0;
8834            var currentConfig;
8835            var headSectionNodes = [];
8836            var bodySectionNodes = [];
8837            var footSectionNodes = [];
8838            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {
8839                headSectionNodes.push(this.renderSection(currentConfig, configI, microColGroupNode));
8840                configI++;
8841            }
8842            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') {
8843                bodySectionNodes.push(this.renderSection(currentConfig, configI, microColGroupNode));
8844                configI++;
8845            }
8846            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') {
8847                footSectionNodes.push(this.renderSection(currentConfig, configI, microColGroupNode));
8848                configI++;
8849            }
8850            // firefox bug: when setting height on table and there is a thead or tfoot,
8851            // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524)
8852            // use getCanVGrowWithinCell as a way to detect table-stupid firefox.
8853            // if so, use a simpler dom structure, jam everything into a lone tbody.
8854            var isBuggy = !getCanVGrowWithinCell();
8855            return createElement('table', {
8856                className: classNames.join(' '),
8857                style: { height: props.height }
8858            }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArrays(['thead', {}
8858], headSectionNodes)), Boolean(!isBuggy && bodySectionNodes.length) && createElement.apply(void 0, __spreadArrays(['tbody', {}], bodySectionNodes)), Boolean(!isBuggy && footSectionNodes.length) && createElement.apply(void 0, __spreadArrays(['tfoot', {}], footSectionNodes)), isBuggy && createElement.apply(void 0, __spreadArrays(['tbody', {}], headSectionNodes, bodySectionNodes, footSectionNodes)));
8859        };
8860        SimpleScrollGrid.prototype.renderSection = function (sectionConfig, sectionI, microColGroupNode) {
8861            if ('outerContent' in sectionConfig) {
8862                return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent));
8863            }
8864            return (createElement("tr", { key: sectionConfig.key, className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, sectionI, microColGroupNode, sectionConfig.chunk)));
8865        };
8866        SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, sectionI, microColGroupNode, chunkConfig) {
8867            if ('outerContent' in chunkConfig) {
8868                return chunkConfig.outerContent;
8869            }
8870            var props = this.props;
8871            var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights;
8872            var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config?
8873            var isLiquid = getSectionHasLiquidHeight(props, sectionConfig);
8874            // for `!props.liquid` - is WHOLE scrollgrid natural height?
8875            // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars
8876            var overflowY = !props.liquid ? 'visible' :
8877                forceYScrollbars ? 'scroll' :
8878                    !needsYScrolling ? 'hidden' :
8879                        'auto';
8880            var content = renderChunkContent(sectionConfig, chunkConfig, {
8881                tableColGroupNode: microColGroupNode,
8882                tableMinWidth: '',
8883                clientWidth: scrollerClientWidths[sectionI] !== undefined ? scrollerClientWidths[sectionI] : null,
8884                clientHeight: scrollerClientHeights[sectionI] !== undefined ? scrollerClientHeights[sectionI] : null,
8885                expandRows: sectionConfig.expandRows,
8886                syncRowHeights: false,
8887                rowSyncHeights: [],
8888                reportRowHeightChange: function () { }
8889            });
8890            return (createElement("td", { ref: chunkConfig.elRef },
8891                createElement("div", { className: 'fc-scroller-harness' + (isLiquid ? ' fc-scroller-harness-liquid' : '') },
8892                    createElement(Scroller, { ref: this.scrollerRefs.createRef(sectionI), elRef: this.scrollerElRefs.createRef(sectionI), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */, maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute: true /* because its within a harness */ }, content))));
8893        };
8894        SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) {
8895            var sectionI = parseInt(key, 10);
8896            var chunkConfig = this.props.sections[sectionI].chunk;
8897            setRef(chunkConfig.scrollerElRef, scrollerEl);
8898        };
8899        SimpleScrollGrid.prototype.componentDidMount = function () {
8900            this.handleSizing();
8901            this.context.addResizeHandler(this.handleSizing);
8902        };
8903        SimpleScrollGrid.prototype.componentDidUpdate = function () {
8904            // TODO: need better solution when state contains non-sizing things
8905            this.handleSizing();
8906        };
8907        SimpleScrollGrid.prototype.componentWillUnmount = function () {
8908            this.context.removeResizeHandler(this.handleSizing);
8909        };
8910        SimpleScrollGrid.prototype.computeShrinkWidth = function () {
8911            return hasShrinkWidth(this.props.cols)
8912                ? computeShrinkWidth(this.scrollerElRefs.getAll())
8913                : 0;
8914        };
8915        SimpleScrollGrid.prototype.computeScrollerDims = function () {
8916            var scrollbarWidth = getScrollbarWidths();
8917            var sectionCnt = this.props.sections.length;
8918            var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs;
8919            var forceYScrollbars = false;
8920            var scrollerClientWidths = {};
8921            var scrollerClientHeights = {};
8922            for (var sectionI = 0; sectionI < sectionCnt; sectionI++) { // along edge
8923                var scroller = scrollerRefs.currentMap[sectionI];
8924                if (scroller && scroller.needsYScrolling()) {
8925                    forceYScrollbars = true;
8926                    break;
8927                }
8928            }
8929            for (var sectionI = 0; sectionI < sectionCnt; sectionI++) { // along edge
8930                var scrollerEl = scrollerElRefs.currentMap[sectionI];
8931                if (scrollerEl) {
8932                    var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders
8933                    scrollerClientWidths[sectionI] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars
8934                        ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future
8935                        : 0));
8936                    scrollerClientHeights[sectionI] = Math.floor(harnessEl.getBoundingClientRect().height // never has horizontal scrollbars
8937                    );
8938                }
8939            }
8940            return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights };
8941        };
8942        return SimpleScrollGrid;
8943    }(BaseComponent));
8944    SimpleScrollGrid.addStateEquality({
8945        scrollerClientWidths: isPropsEqual,
8946        scrollerClientHeights: isPropsEqual
8947    });
8948
8949    var EventRoot = /** @class */ (function (_super) {
8950        __extends(EventRoot, _super);
8951        function EventRoot() {
8952            var _this = _super !== null && _super.apply(this, arguments) || this;
8953            _this.elRef = createRef();
8954            return _this;
8955        }
8956        EventRoot.prototype.render = function () {
8957            var _a = this, props = _a.props, context = _a.context;
8958            var options = context.options;
8959            var seg = props.seg;
8960            var eventRange = seg.eventRange;
8961            var ui = eventRange.ui;
8962            var hookProps = {
8963                event: new EventApi(context, eventRange.def, eventRange.instance),
8964                view: context.viewApi,
8965                timeText: props.timeText,
8966                textColor: ui.textColor,
8967                backgroundColor: ui.backgroundColor,
8968                borderColor: ui.borderColor,
8969                isDraggable: !props.disableDragging && computeSegDraggable(seg, context),
8970                isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context),
8971                isEndResizable: !props.disableResizing && computeSegEndResizable(seg),
8972                isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),
8973                isStart: Boolean(seg.isStart),
8974                isEnd: Boolean(seg.isEnd),
8975                isPast: Boolean(props.isPast),
8976                isFuture: Boolean(props.isFuture),
8977                isToday: Boolean(props.isToday),
8978                isSelected: Boolean(props.isSelected),
8979                isDragging: Boolean(props.isDragging),
8980                isResizing: Boolean(props.isResizing)
8981            };
8982            var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames);
8983            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.eventClassNames, content: options.eventContent, defaultContent: props.defaultContent, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount, elRef: this.elRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, standardClassNames.concat(customClassNames), innerElRef, innerContent, hookProps); }));
8984        };
8985        EventRoot.prototype.componentDidMount = function () {
8986            setElSeg(this.elRef.current, this.props.seg);
8987        };
8988        /*
8989        need to re-assign seg to the element if seg changes, even if the element is the same
8990        */
8991        EventRoot.prototype.componentDidUpdate = function (prevProps) {
8992            var seg = this.props.seg;
8993            if (seg !== prevProps.seg) {
8994                setElSeg(this.elRef.current, seg);
8995            }
8996        };
8997        return EventRoot;
8998    }(BaseComponent));
8999
9000    // should not be a purecomponent
9001    var StandardEvent = /** @class */ (function (_super) {
9002        __extends(StandardEvent, _super);
9003        function StandardEvent() {
9004            return _super !== null && _super.apply(this, arguments) || this;
9005        }
9006        StandardEvent.prototype.render = function () {
9007            var _a = this, props = _a.props, context = _a.context;
9008            var seg = props.seg;
9009            var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat;
9010            var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd);
9011            return (createElement(EventRoot, { seg: seg, timeText: timeText, disableDragging: props.disableDragging, disableResizing: props.disableResizing, defaultContent: props.defaultContent || renderInnerContent, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("a", __assign({ className: props.extraClassNames.c
9011oncat(classNames).join(' '), style: {
9012                    borderColor: hookProps.borderColor,
9013                    backgroundColor: hookProps.backgroundColor
9014                }, ref: rootElRef }, getSegAnchorAttrs(seg)),
9015                createElement("div", { className: 'fc-event-main', ref: innerElRef, style: { color: hookProps.textColor } }, innerContent),
9016                hookProps.isStartResizable &&
9017                    createElement("div", { className: 'fc-event-resizer fc-event-resizer-start' }),
9018                hookProps.isEndResizable &&
9019                    createElement("div", { className: 'fc-event-resizer fc-event-resizer-end' }))); }));
9020        };
9021        return StandardEvent;
9022    }(BaseComponent));
9023    function renderInnerContent(innerProps) {
9024        return (createElement("div", { className: 'fc-event-main-frame' },
9025            innerProps.timeText &&
9026                createElement("div", { className: 'fc-event-time' }, innerProps.timeText),
9027            createElement("div", { className: 'fc-event-title-container' },
9028                createElement("div", { className: 'fc-event-title fc-sticky' }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))));
9029    }
9030    function getSegAnchorAttrs(seg) {
9031        var url = seg.eventRange.def.url;
9032        return url ? { href: url } : {};
9033    }
9034
9035    var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
9036        var options = context.options;
9037        var hookProps = {
9038            isAxis: props.isAxis,
9039            date: context.dateEnv.toDate(props.date),
9040            view: context.viewApi
9041        };
9042        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children));
9043    })); };
9044
9045    var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' });
9046    var DayCellRoot = /** @class */ (function (_super) {
9047        __extends(DayCellRoot, _super);
9048        function DayCellRoot() {
9049            var _this = _super !== null && _super.apply(this, arguments) || this;
9050            _this.refineHookProps = memoizeObjArg(refineHookProps);
9051            _this.normalizeClassNames = buildClassNameNormalizer();
9052            return _this;
9053        }
9054        DayCellRoot.prototype.render = function () {
9055            var _a = this, props = _a.props, context = _a.context;
9056            var options = context.options;
9057            var hookProps = this.refineHookProps({
9058                date: props.date,
9059                dateProfile: props.dateProfile,
9060                todayRange: props.todayRange,
9061                showDayNumber: props.showDayNumber,
9062                extraProps: props.extraHookProps,
9063                viewApi: context.viewApi,
9064                dateEnv: context.dateEnv
9065            });
9066            var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled
9067                ? [] // don't use custom classNames if disabled
9068                : this.normalizeClassNames(options.dayCellClassNames, hookProps));
9069            var dataAttrs = hookProps.isDisabled ? {} : {
9070                'data-date': formatDayString(props.date)
9071            };
9072            return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); }));
9073        };
9074        return DayCellRoot;
9075    }(BaseComponent));
9076    var DayCellContent = /** @class */ (function (_super) {
9077        __extends(DayCellContent, _super);
9078        function DayCellContent() {
9079            return _super !== null && _super.apply(this, arguments) || this;
9080        }
9081        DayCellContent.prototype.render = function () {
9082            var _a = this, props = _a.props, context = _a.context;
9083            var options = context.options;
9084            var hookProps = refineHookProps({
9085                date: props.date,
9086                dateProfile: props.dateProfile,
9087                todayRange: props.todayRange,
9088                showDayNumber: props.showDayNumber,
9089                extraProps: props.extraHookProps,
9090                viewApi: context.viewApi,
9091                dateEnv: context.dateEnv
9092            });
9093            return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children));
9094        };
9095        return DayCellContent;
9096    }(BaseComponent));
9097    function refineHookProps(raw) {
9098        var date = raw.date, dateEnv = raw.dateEnv;
9099        var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile);
9100        return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraProps);
9101    }
9102
9103    function renderFill(fillType) {
9104        return (createElement("div", { className: "fc-" + fillType }));
9105    }
9106    var BgEvent = function (props) { return (createElement(EventRoot, { defaultContent: renderInnerContent$1, seg: props.seg /* uselesss i think */, timeText: '' /* weird */, disableDragging: true, disableResizing: true, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("div", { ref: rootElRef, className: ['fc-bg-event'].concat(classNames).join(' '), style: {
9107            backgroundColor: hookProps.backgroundColor
9108        } }, innerContent)); })); };
9109    function renderInnerContent$1(props) {
9110        var title = props.event.title;
9111        return title && (createElement("div", { className: 'fc-event-title' }, props.event.title));
9112    }
9113
9114    var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
9115        var dateEnv = context.dateEnv, options = context.options;
9116        var date = props.date;
9117        var format = options.weekNumberFormat || props.defaultFormat;
9118        var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well?
9119        var text = dateEnv.format(date, format);
9120        var hookProps = { num: num, text: text, date: date };
9121        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner$1, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children));
9122    })); };
9123    function renderInner$1(innerProps) {
9124        return innerProps.text;
9125    }
9126
9127    // exports
9128    // --------------------------------------------------------------------------------------------------
9129    var version = '<%= version %>'; // important to type it, so .d.ts has generic string
9130
9131    var Calendar = /** @class */ (function (_super) {
9132        __extends(Calendar, _super);
9133        function Calendar(el, optionOverrides) {
9134            if (optionOverrides === void 0) { optionOverrides = {}; }
9135            var _this = _super.call(this) || this;
9136            _this.isRendering = false;
9137            _this.isRendered = false;
9138            _this.currentClassNames = [];
9139            _this.customContentRenderId = 0; // will affect custom generated classNames?
9140            _this.handleAction = function (action) {
9141                // actions we know we want to render immediately
9142                switch (action.type) {
9143                    case 'SET_EVENT_DRAG':
9144                    case 'SET_EVENT_RESIZE':
9145                        _this.renderRunner.tryDrain();
9146                }
9147            };
9148            _this.handleData = function (data) {
9149                _this.currentData = data;
9150                _this.renderRunner.request(data.calendarOptions.rerenderDelay);
9151            };
9152            _this.handleRenderRequest = function () {
9153                if (_this.isRendering) {
9154                    _this.isRendered = true;
9155                    var currentData_1 = _this.currentData;
9156                    render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) {
9157                        _this.setClassNames(classNames);
9158                        _this.setHeight(height);
9159                        return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId },
9160                            createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1))));
9161                    }), _this.el);
9162                }
9163                else if (_this.isRendered) {
9164                    _this.isRendered = false;
9165                    render(null, _this.el);
9166                    _this.setClassNames([]);
9167                    _this.setHeight('');
9168                }
9169                flushToDom$1();
9170            };
9171            _this.el = el;
9172            _this.renderRunner = new DelayedRunner(_this.handleRenderRequest);
9173            new CalendarDataManager({
9174                optionOverrides: optionOverrides,
9175                calendarApi: _this,
9176                onAction: _this.handleAction,
9177                onData: _this.handleData
9178            });
9179            return _this;
9180        }
9181        Object.defineProperty(Calendar.prototype, "view", {
9182            get: function () { return this.currentData.viewApi; } // for public API
9183            ,
9184            enumerable: false,
9185            configurable: true
9186        });
9187        Calendar.prototype.render = function () {
9188            var wasRendering = this.isRendering;
9189            if (!wasRendering) {
9190                this.isRendering = true;
9191            }
9192            else {
9193                this.customContentRenderId++;
9194            }
9195            this.renderRunner.request();
9196            if (wasRendering) {
9197                this.updateSize();
9198            }
9199        };
9200        Calendar.prototype.destroy = function () {
9201            if (this.isRendering) {
9202                this.isRendering = false;
9203                this.renderRunner.request();
9204            }
9205        };
9206        Calendar.prototype.updateSize = function () {
9207            _super.prototype.updateSize.call(this);
9208            flushToDom$1();
9209        };
9210        Calendar.prototype.batchRendering = function (func) {
9211            this.renderRunner.pause('batchRendering');
9212            func();
9213            this.renderRunner.resume('batchRendering');
9214        };
9215        Calendar.prototype.pauseRendering = function () {
9216            this.renderRunner.pause('pauseRendering');
9217        };
9218        Calendar.prototype.resumeRendering = function () {
9219            this.renderRunner.resume('pauseRendering', true);
9220        };
9221        Calendar.prototype.resetOptions = function (optionOverrides, append) {
9222            this.currentDataManager.resetOptions(optionOverrides, append);
9223        };
9224        Calendar.prototype.setClassNames = function (classNames) {
9225            if (!isArraysEqual(classNames, this.currentClassNames)) {
9226                var classList = this.el.classList;
9227                for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) {
9228                    var className = _a[_i];
9229                    classList.remove(className);
9230                }
9231                for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) {
9232                    var className = classNames_1[_b];
9233                    classList.add(className);
9234                }
9235                this.currentClassNames = classNames;
9236            }
9237        };
9238        Calendar.prototype.setHeight = function (height) {
9239            applyStyleProp(this.el, 'height', height);
9240        };
9241        return Calendar;
9242    }(CalendarApi));
9243
9244    config.touchMouseIgnoreWait = 500;
9245    var ignoreMouseDepth = 0;
9246    var listenerCnt = 0;
9247    var isWindowTouchMoveCancelled = false;
9248    /*
9249    Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
9250    Tracks when the pointer "drags" on a certain element, meaning down+move+up.
9251
9252    Also, tracks if there was touch-scrolling.
9253    Also, can prevent touch-scrolling from happening.
9254    Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
9255
9256    emits:
9257    - pointerdown
9258    - pointermove
9259    - pointerup
9260    */
9261    var PointerDragging = /** @class */ (function () {
9262        function PointerDragging(containerEl) {
9263            var _this = this;
9264            this.subjectEl = null;
9265            // options that can be directly assigned by caller
9266            this.selector = ''; // will cause subjectEl in all emitted events to be this element
9267            this.handleSelector = '';
9268            this.shouldIgnoreMove = false;
9269            this.shouldWatchScroll = true; // for simulating pointermove on scroll
9270            // internal states
9271            this.isDragging = false;
9272            this.isTouchDragging = false;
9273            this.wasTouchScroll = false;
9274            // Mouse
9275            // ----------------------------------------------------------------------------------------------------
9276            this.handleMouseDown = function (ev) {
9277                if (!_this.shouldIgnoreMouse() &&
9278                    isPrimaryMouseButton(ev) &&
9279                    _this.tryStart(ev)) {
9280                    var pev = _this.createEventFromMouse(ev, true);
9281                    _this.emitter.trigger('pointerdown', pev);
9282                    _this.initScrollWatch(pev);
9283                    if (!_this.shouldIgnoreMove) {
9284                        document.addEventListener('mousemove', _this.handleMouseMove);
9285                    }
9286                    document.addEventListener('mouseup', _this.handleMouseUp);
9287                }
9288            };
9289            this.handleMouseMove = function (ev) {
9290                var pev = _this.createEventFromMouse(ev);
9291                _this.recordCoords(pev);
9292                _this.emitter.trigger('pointermove', pev);
9293            };
9294            this.handleMouseUp = function (ev) {
9295                document.removeEventListener('mousemove', _this.handleMouseMove);
9296                document.removeEventListener('mouseup', _this.handleMouseUp);
9297                _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
9298                _this.cleanup(); // call last so that pointerup has access to props
9299            };
9300            // Touch
9301            // ----------------------------------------------------------------------------------------------------
9302            this.handleTouchStart = function (ev) {
9303                if (_this.tryStart(ev)) {
9304                    _this.isTouchDragging = true;
9305                    var pev = _this.createEventFromTouch(ev, true);
9306                    _this.emitter.trigger('pointerdown', pev);
9307                    _this.initScrollWatch(pev);
9308                    // unlike mouse, need to attach to target, not document
9309                    // https://stackoverflow.com/a/45760014
9310                    var targetEl = ev.target;
9311                    if (!_this.shouldIgnoreMove) {
9312                        targetEl.addEventListener('touchmove', _this.handleTouchMove);
9313                    }
9314                    targetEl.addEventListener('touchend', _this.handleTouchEnd);
9315                    targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
9316                    // attach a handler to get called when ANY scroll action happens on the page.
9317                    // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
9318                    // http://stackoverflow.com/a/32954565/96342
9319                    window.addEventListener('scroll', _this.handleTouchScroll, true // useCapture
9320                    );
9321                }
9322            };
9323            this.handleTouchMove = function (ev) {
9324                var pev = _this.createEventFromTouch(ev);
9325                _this.recordCoords(pev);
9326                _this.emitter.trigger('pointermove', pev);
9327            };
9328            this.handleTouchEnd = function (ev) {
9329                if (_this.isDragging) { // done to guard against touchend followed by touchcancel
9330                    var targetEl = ev.target;
9331                    targetEl.removeEventListener('touchmove', _this.handleTouchMove);
9332                    targetEl.removeEventListener('touchend', _this.handleTouchEnd);
9333                    targetEl.removeEventListener('touchcancel', _this.handleTouchEnd);
9334                    window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
9335                    _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
9336                    _this.cleanup(); // call last so that pointerup has access to props
9337                    _this.isTouchDragging = false;
9338                    startIgnoringMouse();
9339                }
9340            };
9341            this.handleTouchScroll = function () {
9342                _this.wasTouchScroll = true;
9343            };
9344            this.handleScroll = function (ev) {
9345                if (!_this.shouldIgnoreMove) {
9346                    var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
9347                    var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
9348                    _this.emitter.trigger('pointermove', {
9349                        origEvent: ev,
9350                        isTouch: _this.isTouchDragging,
9351                        subjectEl: _this.subjectEl,
9352                        pageX: pageX,
9353                        pageY: pageY,
9354                        deltaX: pageX - _this.origPageX,
9355                        deltaY: pageY - _this.origPageY
9356                    });
9357                }
9358            };
9359            this.containerEl = containerEl;
9360            this.emitter = new Emitter();
9361            containerEl.addEventListener('mousedown', this.handleMouseDown);
9362            containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
9363            listenerCreated();
9364        }
9365        PointerDragging.prototype.destroy = function () {
9366            this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
9367            this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
9368            listenerDestroyed();
9369        };
9370        PointerDragging.prototype.tryStart = function (ev) {
9371            var subjectEl = this.querySubjectEl(ev);
9372            var downEl = ev.target;
9373            if (subjectEl &&
9374                (!this.handleSelector || elementClosest(downEl, this.handleSelector))) {
9375                this.subjectEl = subjectEl;
9376                this.isDragging = true; // do this first so cancelTouchScroll will work
9377                this.wasTouchScroll = false;
9378                return true;
9379            }
9380            return false;
9381        };
9382        PointerDragging.prototype.cleanup = function () {
9383            isWindowTouchMoveCancelled = false;
9384            this.isDragging = false;
9385            this.subjectEl = null;
9386            // keep wasTouchScroll around for later access
9387            this.destroyScrollWatch();
9388        };
9389        PointerDragging.prototype.querySubjectEl = function (ev) {
9390            if (this.selector) {
9391                return elementClosest(ev.target, this.selector);
9392            }
9393            else {
9394                return this.containerEl;
9395            }
9396        };
9397        PointerDragging.prototype.shouldIgnoreMouse = function () {
9398            return ignoreMouseDepth || this.isTouchDragging;
9399        };
9400        // can be called by user of this class, to cancel touch-based scrolling for the current drag
9401        PointerDragging.prototype.cancelTouchScroll = function () {
9402            if (this.isDragging) {
9403                isWindowTouchMoveCancelled = true;
9404            }
9405        };
9406        // Scrolling that simulates pointermoves
9407        // ----------------------------------------------------------------------------------------------------
9408        PointerDragging.prototype.initScrollWatch = function (ev) {
9409            if (this.shouldWatchScroll) {
9410                this.recordCoords(ev);
9411                window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
9412            }
9413        };
9414        PointerDragging.prototype.recordCoords = function (ev) {
9415            if (this.shouldWatchScroll) {
9416                this.prevPageX = ev.pageX;
9417                this.prevPageY = ev.pageY;
9418                this.prevScrollX = window.pageXOffset;
9419                this.prevScrollY = window.pageYOffset;
9420            }
9421        };
9422        PointerDragging.prototype.destroyScrollWatch = function () {
9423            if (this.shouldWatchScroll) {
9424                window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
9425            }
9426        };
9427        // Event Normalization
9428        // ----------------------------------------------------------------------------------------------------
9429        PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
9430            var deltaX = 0;
9431            var deltaY = 0;
9432            // TODO: repeat code
9433            if (isFirst) {
9434                this.origPageX = ev.pageX;
9435                this.origPageY = ev.pageY;
9436            }
9437            else {
9438                deltaX = ev.pageX - this.origPageX;
9439                deltaY = ev.pageY - this.origPageY;
9440            }
9441            return {
9442                origEvent: ev,
9443                isTouch: false,
9444                subjectEl: this.subjectEl,
9445                pageX: ev.pageX,
9446                pageY: ev.pageY,
9447                deltaX: deltaX,
9448                deltaY: deltaY
9449            };
9450        };
9451        PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
9452            var touches = ev.touches;
9453            var pageX;
9454            var pageY;
9455            var deltaX = 0;
9456            var deltaY = 0;
9457            // if touch coords available, prefer,
9458            // because FF would give bad ev.pageX ev.pageY
9459            if (touches && touches.length) {
9460                pageX = touches[0].pageX;
9461                pageY = touches[0].pageY;
9462            }
9463            else {
9464                pageX = ev.pageX;
9465                pageY = ev.pageY;
9466            }
9467            // TODO: repeat code
9468            if (isFirst) {
9469                this.origPageX = pageX;
9470                this.origPageY = pageY;
9471            }
9472            else {
9473                deltaX = pageX - this.origPageX;
9474                deltaY = pageY - this.origPageY;
9475            }
9476            return {
9477                origEvent: ev,
9478                isTouch: true,
9479                subjectEl: this.subjectEl,
9480                pageX: pageX,
9481                pageY: pageY,
9482                deltaX: deltaX,
9483                deltaY: deltaY
9484            };
9485        };
9486        return PointerDragging;
9487    }());
9488    // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
9489    function isPrimaryMouseButton(ev) {
9490        return ev.button === 0 && !ev.ctrlKey;
9491    }
9492    // Ignoring fake mouse events generated by touch
9493    // ----------------------------------------------------------------------------------------------------
9494    function startIgnoringMouse() {
9495        ignoreMouseDepth++;
9496        setTimeout(function () {
9497            ignoreMouseDepth--;
9498        }, config.touchMouseIgnoreWait);
9499    }
9500    // We want to attach touchmove as early as possible for Safari
9501    // ----------------------------------------------------------------------------------------------------
9502    function listenerCreated() {
9503        if (!(listenerCnt++)) {
9504            window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
9505        }
9506    }
9507    function listenerDestroyed() {
9508        if (!(--listenerCnt)) {
9509            window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
9510        }
9511    }
9512    function onWindowTouchMove(ev) {
9513        if (isWindowTouchMoveCancelled) {
9514            ev.preventDefault();
9515        }
9516    }
9517
9518    /*
9519    An effect in which an element follows the movement of a pointer across the screen.
9520    The moving element is a clone of some other element.
9521    Must call start + handleMove + stop.
9522    */
9523    var ElementMirror = /** @class */ (function () {
9524        function ElementMirror() {
9525            this.isVisible = false; // must be explicitly enabled
9526            this.sourceEl = null;
9527            this.mirrorEl = null;
9528            this.sourceElRect = null; // screen coords relative to viewport
9529            // options that can be set directly by caller
9530            this.parentNode = document.body;
9531            this.zIndex = 9999;
9532            this.revertDuration = 0;
9533        }
9534        ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
9535            this.sourceEl = sourceEl;
9536            this.sourceElRect = this.sourceEl.getBoundingClientRect();
9537            this.origScreenX = pageX - window.pageXOffset;
9538            this.origScreenY = pageY - window.pageYOffset;
9539            this.deltaX = 0;
9540            this.deltaY = 0;
9541            this.updateElPosition();
9542        };
9543        ElementMirror.prototype.handleMove = function (pageX, pageY) {
9544            this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
9545            this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
9546            this.updateElPosition();
9547        };
9548        // can be called before start
9549        ElementMirror.prototype.setIsVisible = function (bool) {
9550            if (bool) {
9551                if (!this.isVisible) {
9552                    if (this.mirrorEl) {
9553                        this.mirrorEl.style.display = '';
9554                    }
9555                    this.isVisible = bool; // needs to happen before updateElPosition
9556                    this.updateElPosition(); // because was not updating the position while invisible
9557                }
9558            }
9559            else {
9560                if (this.isVisible) {
9561                    if (this.mirrorEl) {
9562                        this.mirrorEl.style.display = 'none';
9563                    }
9564                    this.isVisible = bool;
9565                }
9566            }
9567        };
9568        // always async
9569        ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
9570            var _this = this;
9571            var done = function () {
9572                _this.cleanup();
9573                callback();
9574            };
9575            if (needsRevertAnimation &&
9576                this.mirrorEl &&
9577                this.isVisible &&
9578                this.revertDuration && // if 0, transition won't work
9579                (this.deltaX || this.deltaY) // if same coords, transition won't work
9580            ) {
9581                this.doRevertAnimation(done, this.revertDuration);
9582            }
9583            else {
9584                setTimeout(done, 0);
9585            }
9586        };
9587        ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
9588            var mirrorEl = this.mirrorEl;
9589            var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
9590            mirrorEl.style.transition =
9591                'top ' + revertDuration + 'ms,' +
9592                    'left ' + revertDuration + 'ms';
9593            applyStyle(mirrorEl, {
9594                left: finalSourceElRect.left,
9595                top: finalSourceElRect.top
9596            });
9597            whenTransitionDone(mirrorEl, function () {
9598                mirrorEl.style.transition = '';
9599                callback();
9600            });
9601        };
9602        ElementMirror.prototype.cleanup = function () {
9603            if (this.mirrorEl) {
9604                removeElement(this.mirrorEl);
9605                this.mirrorEl = null;
9606            }
9607            this.sourceEl = null;
9608        };
9609        ElementMirror.prototype.updateElPosition = function () {
9610            if (this.sourceEl && this.isVisible) {
9611                applyStyle(this.getMirrorEl(), {
9612                    left: this.sourceElRect.left + this.deltaX,
9613                    top: this.sourceElRect.top + this.deltaY
9614                });
9615            }
9616        };
9617        ElementMirror.prototype.getMirrorEl = function () {
9618            var sourceElRect = this.sourceElRect;
9619            var mirrorEl = this.mirrorEl;
9620            if (!mirrorEl) {
9621                mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
9622                // we don't want long taps or any mouse interaction causing selection/menus.
9623                // would use preventSelection(), but that prevents selectstart, causing problems.
9624                mirrorEl.classList.add('fc-unselectable');
9625                mirrorEl.classList.add('fc-event-dragging');
9626                applyStyle(mirrorEl, {
9627                    position: 'fixed',
9628                    zIndex: this.zIndex,
9629                    visibility: '',
9630                    boxSizing: 'border-box',
9631                    width: sourceElRect.right - sourceElRect.left,
9632                    height: sourceElRect.bottom - sourceElRect.top,
9633                    right: 'auto',
9634                    bottom: 'auto',
9635                    margin: 0
9636                });
9637                this.parentNode.appendChild(mirrorEl);
9638            }
9639            return mirrorEl;
9640        };
9641        return ElementMirror;
9642    }());
9643
9644    /*
9645    Is a cache for a given element's scroll information (all the info that ScrollController stores)
9646    in addition the "client rectangle" of the element.. the area within the scrollbars.
9647
9648    The cache can be in one of two modes:
9649    - doesListening:false - ignores when the container is scrolled by someone else
9650    - doesListening:true - watch for scrolling and update the cache
9651    */
9652    var ScrollGeomCache = /** @class */ (function (_super) {
9653        __extends(ScrollGeomCache, _super);
9654        function ScrollGeomCache(scrollController, doesListening) {
9655            var _this = _super.call(this) || this;
9656            _this.handleScroll = function () {
9657                _this.scrollTop = _this.scrollController.getScrollTop();
9658                _this.scrollLeft = _this.scrollController.getScrollLeft();
9659                _this.handleScrollChange();
9660            };
9661            _this.scrollController = scrollController;
9662            _this.doesListening = doesListening;
9663            _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
9664            _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
9665            _this.scrollWidth = scrollController.getScrollWidth();
9666            _this.scrollHeight = scrollController.getScrollHeight();
9667            _this.clientWidth = scrollController.getClientWidth();
9668            _this.clientHeight = scrollController.getClientHeight();
9669            _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
9670            if (_this.doesListening) {
9671                _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
9672            }
9673            return _this;
9674        }
9675        ScrollGeomCache.prototype.destroy = function () {
9676            if (this.doesListening) {
9677                this.getEventTarget().removeEventListener('scroll', this.handleScroll);
9678            }
9679        };
9680        ScrollGeomCache.prototype.getScrollTop = function () {
9681            return this.scrollTop;
9682        };
9683        ScrollGeomCache.prototype.getScrollLeft = function () {
9684            return this.scrollLeft;
9685        };
9686        ScrollGeomCache.prototype.setScrollTop = function (top) {
9687            this.scrollController.setScrollTop(top);
9688            if (!this.doesListening) {
9689                // we are not relying on the element to normalize out-of-bounds scroll values
9690                // so we need to sanitize ourselves
9691                this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
9692                this.handleScrollChange();
9693            }
9694        };
9695        ScrollGeomCache.prototype.setScrollLeft = function (top) {
9696            this.scrollController.setScrollLeft(top);
9697            if (!this.doesListening) {
9698                // we are not relying on the element to normalize out-of-bounds scroll values
9699                // so we need to sanitize ourselves
9700                this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
9701                this.handleScrollChange();
9702            }
9703        };
9704        ScrollGeomCache.prototype.getClientWidth = function () {
9705            return this.clientWidth;
9706        };
9707        ScrollGeomCache.prototype.getClientHeight = function () {
9708            return this.clientHeight;
9709        };
9710        ScrollGeomCache.prototype.getScrollWidth = function () {
9711            return this.scrollWidth;
9712        };
9713        ScrollGeomCache.prototype.getScrollHeight = function () {
9714            return this.scrollHeight;
9715        };
9716        ScrollGeomCache.prototype.handleScrollChange = function () {
9717        };
9718        return ScrollGeomCache;
9719    }(ScrollController));
9720    var ElementScrollGeomCache = /** @class */ (function (_super) {
9721        __extends(ElementScrollGeomCache, _super);
9722        function ElementScrollGeomCache(el, doesListening) {
9723            return _super.call(this, new ElementScrollController(el), doesListening) || this;
9724        }
9725        ElementScrollGeomCache.prototype.getEventTarget = function () {
9726            return this.scrollController.el;
9727        };
9728        ElementScrollGeomCache.prototype.computeClientRect = function () {
9729            return computeInnerRect(this.scrollController.el);
9730        };
9731        return ElementScrollGeomCache;
9732    }(ScrollGeomCache));
9733    var WindowScrollGeomCache = /** @class */ (function (_super) {
9734        __extends(WindowScrollGeomCache, _super);
9735        function WindowScrollGeomCache(doesListening) {
9736            return _super.call(this, new WindowScrollController(), doesListening) || this;
9737        }
9738        WindowScrollGeomCache.prototype.getEventTarget = function () {
9739            return window;
9740        };
9741        WindowScrollGeomCache.prototype.computeClientRect = function () {
9742            return {
9743                left: this.scrollLeft,
9744                right: this.scrollLeft + this.clientWidth,
9745                top: this.scrollTop,
9746                bottom: this.scrollTop + this.clientHeight
9747            };
9748        };
9749        // the window is the only scroll object that changes it's rectangle relative
9750        // to the document's topleft as it scrolls
9751        WindowScrollGeomCache.prototype.handleScrollChange = function () {
9752            this.clientRect = this.computeClientRect();
9753        };
9754        return WindowScrollGeomCache;
9755    }(ScrollGeomCache));
9756
9757    // If available we are using native "performance" API instead of "Date"
9758    // Read more about it on MDN:
9759    // https://developer.mozilla.org/en-US/docs/Web/API/Performance
9760    var getTime = typeof performance === 'function' ? performance.now : Date.now;
9761    /*
9762    For a pointer interaction, automatically scrolls certain scroll containers when the pointer
9763    approaches the edge.
9764
9765    The caller must call start + handleMove + stop.
9766    */
9767    var AutoScroller = /** @class */ (function () {
9768        function AutoScroller() {
9769            var _this = this;
9770            // options that can be set by caller
9771            this.isEnabled = true;
9772            this.scrollQuery = [window, '.fc-scroller'];
9773            this.edgeThreshold = 50; // pixels
9774            this.maxVelocity = 300; // pixels per second
9775            // internal state
9776            this.pointerScreenX = null;
9777            this.pointerScreenY = null;
9778            this.isAnimating = false;
9779            this.scrollCaches = null;
9780            // protect against the initial pointerdown being too close to an edge and starting the scroll
9781            this.everMovedUp = false;
9782            this.everMovedDown = false;
9783            this.everMovedLeft = false;
9784            this.everMovedRight = false;
9785            this.animate = function () {
9786                if (_this.isAnimating) { // wasn't cancelled between animation calls
9787                    var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
9788                    if (edge) {
9789                        var now = getTime();
9790                        _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
9791                        _this.requestAnimation(now);
9792                    }
9793                    else {
9794                        _this.isAnimating = false; // will stop animation
9795                    }
9796                }
9797            };
9798        }
9799        AutoScroller.prototype.start = function (pageX, pageY) {
9800            if (this.isEnabled) {
9801                this.scrollCaches = this.buildCaches();
9802                this.pointerScreenX = null;
9803                this.pointerScreenY = null;
9804                this.everMovedUp = false;
9805                this.everMovedDown = false;
9806                this.everMovedLeft = false;
9807                this.everMovedRight = false;
9808                this.handleMove(pageX, pageY);
9809            }
9810        };
9811        AutoScroller.prototype.handleMove = function (pageX, pageY) {
9812            if (this.isEnabled) {
9813                var pointerScreenX = pageX - window.pageXOffset;
9814                var pointerScreenY = pageY - window.pageYOffset;
9815                var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
9816                var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
9817                if (yDelta < 0) {
9818                    this.everMovedUp = true;
9819                }
9820                else if (yDelta > 0) {
9821                    this.everMovedDown = true;
9822                }
9823                if (xDelta < 0) {
9824                    this.everMovedLeft = true;
9825                }
9826                else if (xDelta > 0) {
9827                    this.everMovedRight = true;
9828                }
9829                this.pointerScreenX = pointerScreenX;
9830                this.pointerScreenY = pointerScreenY;
9831                if (!this.isAnimating) {
9832                    this.isAnimating = true;
9833                    this.requestAnimation(getTime());
9834                }
9835            }
9836        };
9837        AutoScroller.prototype.stop = function () {
9838            if (this.isEnabled) {
9839                this.isAnimating = false; // will stop animation
9840                for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
9841                    var scrollCache = _a[_i];
9842                    scrollCache.destroy();
9843                }
9844                this.scrollCaches = null;
9845            }
9846        };
9847        AutoScroller.prototype.requestAnimation = function (now) {
9848            this.msSinceRequest = now;
9849            requestAnimationFrame(this.animate);
9850        };
9851        AutoScroller.prototype.handleSide = function (edge, seconds) {
9852            var scrollCache = edge.scrollCache;
9853            var edgeThreshold = this.edgeThreshold;
9854            var invDistance = edgeThreshold - edge.distance;
9855            var velocity = // the closer to the edge, the faster we scroll
9856             (invDistance * invDistance) / (edgeThreshold * edgeThreshold) * // quadratic
9857                this.maxVelocity * seconds;
9858            var sign = 1;
9859            switch (edge.name) {
9860                case 'left':
9861                    sign = -1;
9862                // falls through
9863                case 'right':
9864                    scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
9865                    break;
9866                case 'top':
9867                    sign = -1;
9868                // falls through
9869                case 'bottom':
9870                    scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
9871                    break;
9872            }
9873        };
9874        // left/top are relative to document topleft
9875        AutoScroller.prototype.computeBestEdge = function (left, top) {
9876            var edgeThreshold = this.edgeThreshold;
9877            var bestSide = null;
9878            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
9879                var scrollCache = _a[_i];
9880                var rect = scrollCache.clientRect;
9881                var leftDist = left - rect.left;
9882                var rightDist = rect.right - left;
9883                var topDist = top - rect.top;
9884                var bottomDist = rect.bottom - top;
9885                // completely within the rect?
9886                if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
9887                    if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
9888                        (!bestSide || bestSide.distance > topDist)) {
9889                        bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
9890                    }
9891                    if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
9892                        (!bestSide || bestSide.distance > bottomDist)) {
9893                        bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
9894                    }
9895                    if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
9896                        (!bestSide || bestSide.distance > leftDist)) {
9897                        bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
9898                    }
9899                    if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
9900                        (!bestSide || bestSide.distance > rightDist)) {
9901                        bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
9902                    }
9903                }
9904            }
9905            return bestSide;
9906        };
9907        AutoScroller.prototype.buildCaches = function () {
9908            return this.queryScrollEls().map(function (el) {
9909                if (el === window) {
9910                    return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
9911                }
9912                else {
9913                    return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
9914                }
9915            });
9916        };
9917        AutoScroller.prototype.queryScrollEls = function () {
9918            var els = [];
9919            for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
9920                var query = _a[_i];
9921                if (typeof query === 'object') {
9922                    els.push(query);
9923                }
9924                else {
9925                    els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query)));
9926                }
9927            }
9928            return els;
9929        };
9930        return AutoScroller;
9931    }());
9932
9933    /*
9934    Monitors dragging on an element. Has a number of high-level features:
9935    - minimum distance required before dragging
9936    - minimum wait time ("delay") before dragging
9937    - a mirror element that follows the pointer
9938    */
9939    var FeaturefulElementDragging = /** @class */ (function (_super) {
9940        __extends(FeaturefulElementDragging, _super);
9941        function FeaturefulElementDragging(containerEl, selector) {
9942            var _this = _super.call(this, containerEl) || this;
9943            // options that can be directly set by caller
9944            // the caller can also set the PointerDragging's options as well
9945            _this.delay = null;
9946            _this.minDistance = 0;
9947            _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
9948            _this.mirrorNeedsRevert = false;
9949            _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
9950            _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
9951            _this.isDelayEnded = false;
9952            _this.isDistanceSurpassed = false;
9953            _this.delayTimeoutId = null;
9954            _this.onPointerDown = function (ev) {
9955                if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
9956                    _this.isInteracting = true;
9957                    _this.isDelayEnded = false;
9958                    _this.isDistanceSurpassed = false;
9959                    preventSelection(document.body);
9960                    preventContextMenu(document.body);
9961                    // prevent links from being visited if there's an eventual drag.
9962                    // also prevents selection in older browsers (maybe?).
9963                    // not necessary for touch, besides, browser would complain about passiveness.
9964                    if (!ev.isTouch) {
9965                        ev.origEvent.preventDefault();
9966                    }
9967                    _this.emitter.trigger('pointerdown', ev);
9968                    if (_this.isInteracting && // not destroyed via pointerdown handler
9969                        !_this.pointer.shouldIgnoreMove) {
9970                        // actions related to initiating dragstart+dragmove+dragend...
9971                        _this.mirror.setIsVisible(false); // reset. caller must set-visible
9972                        _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
9973                        _this.startDelay(ev);
9974                        if (!_this.minDistance) {
9975                            _this.handleDistanceSurpassed(ev);
9976                        }
9977                    }
9978                }
9979            };
9980            _this.onPointerMove = function (ev) {
9981                if (_this.isInteracting) {
9982                    _this.emitter.trigger('pointermove', ev);
9983                    if (!_this.isDistanceSurpassed) {
9984                        var minDistance = _this.minDistance;
9985                        var distanceSq = void 0; // current distance from the origin, squared
9986                        var deltaX = ev.deltaX, deltaY = ev.deltaY;
9987                        distanceSq = deltaX * deltaX + deltaY * deltaY;
9988                        if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
9989                            _this.handleDistanceSurpassed(ev);
9990                        }
9991                    }
9992                    if (_this.isDragging) {
9993                        // a real pointer move? (not one simulated by scrolling)
9994                        if (ev.origEvent.type !== 'scroll') {
9995                            _this.mirror.handleMove(ev.pageX, ev.pageY);
9996                            _this.autoScroller.handleMove(ev.pageX, ev.pageY);
9997                        }
9998                        _this.emitter.trigger('dragmove', ev);
9999                    }
10000                }
10001            };
10002            _this.onPointerUp = function (ev) {
10003                if (_this.isInteracting) {
10004                    _this.isInteracting = false;
10005                    allowSelection(document.body);
10006                    allowContextMenu(document.body);
10007                    _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
10008                    if (_this.isDragging) {
10009                        _this.autoScroller.stop();
10010                        _this.tryStopDrag(ev); // which will stop the mirror
10011                    }
10012                    if (_this.delayTimeoutId) {
10013                        clearTimeout(_this.delayTimeoutId);
10014                        _this.delayTimeoutId = null;
10015                    }
10016                }
10017            };
10018            var pointer = _this.pointer = new PointerDragging(containerEl);
10019            pointer.emitter.on('pointerdown', _this.onPointerDown);
10020            pointer.emitter.on('pointermove', _this.onPointerMove);
10021            pointer.emitter.on('pointerup', _this.onPointerUp);
10022            if (selector) {
10023                pointer.selector = selector;
10024            }
10025            _this.mirror = new ElementMirror();
10026            _this.autoScroller = new AutoScroller();
10027            return _this;
10028        }
10029        FeaturefulElementDragging.prototype.destroy = function () {
10030            this.pointer.destroy();
10031            // HACK: simulate a pointer-up to end the current drag
10032            // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire)
10033            this.onPointerUp({});
10034        };
10035        FeaturefulElementDragging.prototype.startDelay = function (ev) {
10036            var _this = this;
10037            if (typeof this.delay === 'number') {
10038                this.delayTimeoutId = setTimeout(function () {
10039                    _this.delayTimeoutId = null;
10040                    _this.handleDelayEnd(ev);
10041                }, this.delay); // not assignable to number!
10042            }
10043            else {
10044                this.handleDelayEnd(ev);
10045            }
10046        };
10047        FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
10048            this.isDelayEnded = true;
10049            this.tryStartDrag(ev);
10050        };
10051        FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
10052            this.isDistanceSurpassed = true;
10053            this.tryStartDrag(ev);
10054        };
10055        FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
10056            if (this.isDelayEnded && this.isDistanceSurpassed) {
10057                if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
10058                    this.isDragging = true;
10059                    this.mirrorNeedsRevert = false;
10060                    this.autoScroller.start(ev.pageX, ev.pageY);
10061                    this.emitter.trigger('dragstart', ev);
10062                    if (this.touchScrollAllowed === false) {
10063                        this.pointer.cancelTouchScroll();
10064                    }
10065                }
10066            }
10067        };
10068        FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
10069            // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
10070            // that come from the document to fire beforehand. much more convenient this way.
10071            this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev) // bound with args
10072            );
10073        };
10074        FeaturefulElementDragging.prototype.stopDrag = function (ev) {
10075            this.isDragging = false;
10076            this.emitter.trigger('dragend', ev);
10077        };
10078        // fill in the implementations...
10079        FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
10080            this.pointer.shouldIgnoreMove = bool;
10081        };
10082        FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
10083            this.mirror.setIsVisible(bool);
10084        };
10085        FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
10086            this.mirrorNeedsRevert = bool;
10087        };
10088        FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
10089            this.autoScroller.isEnabled = bool;
10090        };
10091        return FeaturefulElementDragging;
10092    }(ElementDragging));
10093
10094    /*
10095    When this class is instantiated, it records the offset of an element (relative to the document topleft),
10096    and continues to monitor scrolling, updating the cached coordinates if it needs to.
10097    Does not access the DOM after instantiation, so highly performant.
10098
10099    Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
10100    and an determine if a given point is inside the combined clipping rectangle.
10101    */
10102    var OffsetTracker = /** @class */ (function () {
10103        function OffsetTracker(el) {
10104            this.origRect = computeRect(el);
10105            // will work fine for divs that have overflow:hidden
10106            this.scrollCaches = getClippingParents(el).map(function (el) {
10107                return new ElementScrollGeomCache(el, true); // listen=true
10108            });
10109        }
10110        OffsetTracker.prototype.destroy = function () {
10111            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10112                var scrollCache = _a[_i];
10113                scrollCache.destroy();
10114            }
10115        };
10116        OffsetTracker.prototype.computeLeft = function () {
10117            var left = this.origRect.left;
10118            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10119                var scrollCache = _a[_i];
10120                left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
10121            }
10122            return left;
10123        };
10124        OffsetTracker.prototype.computeTop = function () {
10125            var top = this.origRect.top;
10126            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10127                var scrollCache = _a[_i];
10128                top += scrollCache.origScrollTop - scrollCache.getScrollTop();
10129            }
10130            return top;
10131        };
10132        OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
10133            var point = { left: pageX, top: pageY };
10134            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10135                var scrollCache = _a[_i];
10136                if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
10137                    !pointInsideRect(point, scrollCache.clientRect)) {
10138                    return false;
10139                }
10140            }
10141            return true;
10142        };
10143        return OffsetTracker;
10144    }());
10145    // certain clipping containers should never constrain interactions, like <html> and <body>
10146    // https://github.com/fullcalendar/fullcalendar/issues/3615
10147    function isIgnoredClipping(node) {
10148        var tagName = node.tagName;
10149        return tagName === 'HTML' || tagName === 'BODY';
10150    }
10151
10152    /*
10153    Tracks movement over multiple droppable areas (aka "hits")
10154    that exist in one or more DateComponents.
10155    Relies on an existing draggable.
10156
10157    emits:
10158    - pointerdown
10159    - dragstart
10160    - hitchange - fires initially, even if not over a hit
10161    - pointerup
10162    - (hitchange - again, to null, if ended over a hit)
10163    - dragend
10164    */
10165    var HitDragging = /** @class */ (function () {
10166        function HitDragging(dragging, droppableStore) {
10167            var _this = this;
10168            // options that can be set by caller
10169            this.useSubjectCenter = false;
10170            this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
10171            this.initialHit = null;
10172            this.movingHit = null;
10173            this.finalHit = null; // won't ever be populated if shouldIgnoreMove
10174            this.handlePointerDown = function (ev) {
10175                var dragging = _this.dragging;
10176                _this.initialHit = null;
10177                _this.movingHit = null;
10178                _this.finalHit = null;
10179                _this.prepareHits();
10180                _this.processFirstCoord(ev);
10181                if (_this.initialHit || !_this.requireInitial) {
10182                    dragging.setIgnoreMove(false);
10183                    _this.emitter.trigger('pointerdown', ev); // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
10184                }
10185                else {
10186                    dragging.setIgnoreMove(true);
10187                }
10188            };
10189            this.handleDragStart = function (ev) {
10190                _this.emitter.trigger('dragstart', ev);
10191                _this.handleMove(ev, true); // force = fire even if initially null
10192            };
10193            this.handleDragMove = function (ev) {
10194                _this.emitter.trigger('dragmove', ev);
10195                _this.handleMove(ev);
10196            };
10197            this.handlePointerUp = function (ev) {
10198                _this.releaseHits();
10199                _this.emitter.trigger('pointerup', ev);
10200            };
10201            this.handleDragEnd = function (ev) {
10202                if (_this.movingHit) {
10203                    _this.emitter.trigger('hitupdate', null, true, ev);
10204                }
10205                _this.finalHit = _this.movingHit;
10206                _this.movingHit = null;
10207                _this.emitter.trigger('dragend', ev);
10208            };
10209            this.droppableStore = droppableStore;
10210            dragging.emitter.on('pointerdown', this.handlePointerDown);
10211            dragging.emitter.on('dragstart', this.handleDragStart);
10212            dragging.emitter.on('dragmove', this.handleDragMove);
10213            dragging.emitter.on('pointerup', this.handlePointerUp);
10214            dragging.emitter.on('dragend', this.handleDragEnd);
10215            this.dragging = dragging;
10216            this.emitter = new Emitter();
10217        }
10218        // sets initialHit
10219        // sets coordAdjust
10220        HitDragging.prototype.processFirstCoord = function (ev) {
10221            var origPoint = { left: ev.pageX, top: ev.pageY };
10222            var adjustedPoint = origPoint;
10223            var subjectEl = ev.subjectEl;
10224            var subjectRect;
10225            if (subjectEl !== document) {
10226                subjectRect = computeRect(subjectEl);
10227                adjustedPoint = constrainPoint(adjustedPoint, subjectRect);
10228            }
10229            var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
10230            if (initialHit) {
10231                if (this.useSubjectCenter && subjectRect) {
10232                    var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect);
10233                    if (slicedSubjectRect) {
10234                        adjustedPoint = getRectCenter(slicedSubjectRect);
10235                    }
10236                }
10237                this.coordAdjust = diffPoints(adjustedPoint, origPoint);
10238            }
10239            else {
10240                this.coordAdjust = { left: 0, top: 0 };
10241            }
10242        };
10243        HitDragging.prototype.handleMove = function (ev, forceHandle) {
10244            var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
10245            if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
10246                this.movingHit = hit;
10247                this.emitter.trigger('hitupdate', hit, false, ev);
10248            }
10249        };
10250        HitDragging.prototype.prepareHits = function () {
10251            this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) {
10252                interactionSettings.component.prepareHits();
10253                return new OffsetTracker(interactionSettings.el);
10254            });
10255        };
10256        HitDragging.prototype.releaseHits = function () {
10257            var offsetTrackers = this.offsetTrackers;
10258            for (var id in offsetTrackers) {
10259                offsetTrackers[id].destroy();
10260            }
10261            this.offsetTrackers = {};
10262        };
10263        HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
10264            var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
10265            var bestHit = null;
10266            for (var id in droppableStore) {
10267                var component = droppableStore[id].component;
10268                var offsetTracker = offsetTrackers[id];
10269                if (offsetTracker && // wasn't destroyed mid-drag
10270                    offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
10271                    var originLeft = offsetTracker.computeLeft();
10272                    var originTop = offsetTracker.computeTop();
10273                    var positionLeft = offsetLeft - originLeft;
10274                    var positionTop = offsetTop - originTop;
10275                    var origRect = offsetTracker.origRect;
10276                    var width = origRect.right - origRect.left;
10277                    var height = origRect.bottom - origRect.top;
10278                    if (
10279                    // must be within the element's bounds
10280                    positionLeft >= 0 && positionLeft < width &&
10281                        positionTop >= 0 && positionTop < height) {
10282                        var hit = component.queryHit(positionLeft, positionTop, width, height);
10283                        var dateProfile = component.context.getCurrentData().dateProfile;
10284                        if (hit &&
10285                            (
10286                            // make sure the hit is within activeRange, meaning it's not a deal cell
10287                            rangeContainsRange(dateProfile.activeRange, hit.dateSpan.range)) &&
10288                            (!bestHit || hit.layer > bestHit.layer)) {
10289                            // TODO: better way to re-orient rectangle
10290                            hit.rect.left += originLeft;
10291                            hit.rect.right += originLeft;
10292                            hit.rect.top += originTop;
10293                            hit.rect.bottom += originTop;
10294                            bestHit = hit;
10295                        }
10296                    }
10297                }
10298            }
10299            return bestHit;
10300        };
10301        return HitDragging;
10302    }());
10303    function isHitsEqual(hit0, hit1) {
10304        if (!hit0 && !hit1) {
10305            return true;
10306        }
10307        if (Boolean(hit0) !== Boolean(hit1)) {
10308            return false;
10309        }
10310        return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
10311    }
10312
10313    function buildDatePointApiWithContext(dateSpan, context) {
10314        var props = {};
10315        for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) {
10316            var transform = _a[_i];
10317            __assign(props, transform(dateSpan, context));
10318        }
10319        __assign(props, buildDatePointApi(dateSpan, context.dateEnv));
10320        return props;
10321    }
10322    function buildDatePointApi(span, dateEnv) {
10323        return {
10324            date: dateEnv.toDate(span.range.start),
10325            dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
10326            allDay: span.allDay
10327        };
10328    }
10329
10330    /*
10331    Monitors when the user clicks on a specific date/time of a component.
10332    A pointerdown+pointerup on the same "hit" constitutes a click.
10333    */
10334    var DateClicking = /** @class */ (function (_super) {
10335        __extends(DateClicking, _super);
10336        function DateClicking(settings) {
10337            var _this = _super.call(this, settings) || this;
10338            _this.handlePointerDown = function (pev) {
10339                var dragging = _this.dragging;
10340                var downEl = pev.origEvent.target;
10341                // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
10342                dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl));
10343            };
10344            // won't even fire if moving was ignored
10345            _this.handleDragEnd = function (ev) {
10346                var component = _this.component;
10347                var pointer = _this.dragging.pointer;
10348                if (!pointer.wasTouchScroll) {
10349                    var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
10350                    if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
10351                        var context = component.context;
10352                        var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view });
10353                        context.emitter.trigger('dateClick', arg);
10354                    }
10355                }
10356            };
10357            // we DO want to watch pointer moves because otherwise finalHit won't get populated
10358            _this.dragging = new FeaturefulElementDragging(settings.el);
10359            _this.dragging.autoScroller.isEnabled = false;
10360            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10361            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10362            hitDragging.emitter.on('dragend', _this.handleDragEnd);
10363            return _this;
10364        }
10365        DateClicking.prototype.destroy = function () {
10366            this.dragging.destroy();
10367        };
10368        return DateClicking;
10369    }(Interaction));
10370
10371    /*
10372    Tracks when the user selects a portion of time of a component,
10373    constituted by a drag over date cells, with a possible delay at the beginning of the drag.
10374    */
10375    var DateSelecting = /** @class */ (function (_super) {
10376        __extends(DateSelecting, _super);
10377        function DateSelecting(settings) {
10378            var _this = _super.call(this, settings) || this;
10379            _this.dragSelection = null;
10380            _this.handlePointerDown = function (ev) {
10381                var _a = _this, component = _a.component, dragging = _a.dragging;
10382                var options = component.context.options;
10383                var canSelect = options.selectable &&
10384                    component.isValidDateDownEl(ev.origEvent.target);
10385                // don't bother to watch expensive moves if component won't do selection
10386                dragging.setIgnoreMove(!canSelect);
10387                // if touch, require user to hold down
10388                dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null;
10389            };
10390            _this.handleDragStart = function (ev) {
10391                _this.component.context.calendarApi.unselect(ev); // unselect previous selections
10392            };
10393            _this.handleHitUpdate = function (hit, isFinal) {
10394                var context = _this.component.context;
10395                var dragSelection = null;
10396                var isInvalid = false;
10397                if (hit) {
10398                    dragSelection = joinHitsIntoSelection(_this.hitDragging.initialHit, hit, context.pluginHooks.dateSelectionTransformers);
10399                    if (!dragSelection || !_this.component.isDateSelectionValid(dragSelection)) {
10400                        isInvalid = true;
10401                        dragSelection = null;
10402                    }
10403                }
10404                if (dragSelection) {
10405                    context.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
10406                }
10407                else if (!isFinal) { // only unselect if moved away while dragging
10408                    context.dispatch({ type: 'UNSELECT_DATES' });
10409                }
10410                if (!isInvalid) {
10411                    enableCursor();
10412                }
10413                else {
10414                    disableCursor();
10415                }
10416                if (!isFinal) {
10417                    _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
10418                }
10419            };
10420            _this.handlePointerUp = function (pev) {
10421                if (_this.dragSelection) {
10422                    // selection is already rendered, so just need to report selection
10423                    triggerDateSelect(_this.dragSelection, pev, _this.component.context);
10424                    _this.dragSelection = null;
10425                }
10426            };
10427            var component = settings.component;
10428            var options = component.context.options;
10429            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
10430            dragging.touchScrollAllowed = false;
10431            dragging.minDistance = options.selectMinDistance || 0;
10432            dragging.autoScroller.isEnabled = options.dragScroll;
10433            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10434            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10435            hitDragging.emitter.on('dragstart', _this.handleDragStart);
10436            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
10437            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
10438            return _this;
10439        }
10440        DateSelecting.prototype.destroy = function () {
10441            this.dragging.destroy();
10442        };
10443        return DateSelecting;
10444    }(Interaction));
10445    function getComponentTouchDelay(component) {
10446        var options = component.context.options;
10447        var delay = options.selectLongPressDelay;
10448        if (delay == null) {
10449            delay = options.longPressDelay;
10450        }
10451        return delay;
10452    }
10453    function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
10454        var dateSpan0 = hit0.dateSpan;
10455        var dateSpan1 = hit1.dateSpan;
10456        var ms = [
10457            dateSpan0.range.start,
10458            dateSpan0.range.end,
10459            dateSpan1.range.start,
10460            dateSpan1.range.end
10461        ];
10462        ms.sort(compareNumbers);
10463        var props = {};
10464        for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
10465            var transformer = dateSelectionTransformers_1[_i];
10466            var res = transformer(hit0, hit1);
10467            if (res === false) {
10468                return null;
10469            }
10470            else if (res) {
10471                __assign(props, res);
10472            }
10473        }
10474        props.range = { start: ms[0], end: ms[3] };
10475        props.allDay = dateSpan0.allDay;
10476        return props;
10477    }
10478
10479    var EventDragging = /** @class */ (function (_super) {
10480        __extends(EventDragging, _super);
10481        function EventDragging(settings) {
10482            var _this = _super.call(this, settings) || this;
10483            // internal state
10484            _this.subjectEl = null;
10485            _this.subjectSeg = null; // the seg being selected/dragged
10486            _this.isDragging = false;
10487            _this.eventRange = null;
10488            _this.relevantEvents = null; // the events being dragged
10489            _this.receivingContext = null;
10490            _this.validMutation = null;
10491            _this.mutatedRelevantEvents = null;
10492            _this.handlePointerDown = function (ev) {
10493                var origTarget = ev.origEvent.target;
10494                var _a = _this, component = _a.component, dragging = _a.dragging;
10495                var mirror = dragging.mirror;
10496                var options = component.context.options;
10497                var initialContext = component.context;
10498                _this.subjectEl = ev.subjectEl;
10499                var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl);
10500                var eventRange = _this.eventRange = subjectSeg.eventRange;
10501                var eventInstanceId = eventRange.instance.instanceId;
10502                _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId);
10503                dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance;
10504                dragging.delay =
10505                    // only do a touch delay if touch and this event hasn't been selected yet
10506                    (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
10507                        getComponentTouchDelay$1(component) :
10508                        null;
10509                mirror.parentNode = elementClosest(origTarget, '.fc');
10510                mirror.revertDuration = options.dragRevertDuration;
10511                var isValid = component.isValidSegDownEl(origTarget) &&
10512                    !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer
10513                dragging.setIgnoreMove(!isValid);
10514                // disable dragging for elements that are resizable (ie, selectable)
10515                // but are not draggable
10516                _this.isDragging = isValid &&
10517                    ev.subjectEl.classList.contains('fc-event-draggable');
10518            };
10519            _this.handleDragStart = function (ev) {
10520                var initialContext = _this.component.context;
10521                var eventRange = _this.eventRange;
10522                var eventInstanceId = eventRange.instance.instanceId;
10523                if (ev.isTouch) {
10524                    // need to select a different event?
10525                    if (eventInstanceId !== _this.component.props.eventSelection) {
10526                        initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
10527                    }
10528                }
10529                else {
10530                    // if now using mouse, but was previous touch interaction, clear selected event
10531                    initialContext.dispatch({ type: 'UNSELECT_EVENT' });
10532                }
10533                if (_this.isDragging) {
10534                    initialContext.calendarApi.unselect(ev); // unselect *date* selection
10535                    initialContext.emitter.trigger('eventDragStart', {
10536                        el: _this.subjectEl,
10537                        event: new EventApi(initialContext, eventRange.def, eventRange.instance),
10538                        jsEvent: ev.origEvent,
10539                        view: initialContext.viewApi
10540                    });
10541                }
10542            };
10543            _this.handleHitUpdate = function (hit, isFinal) {
10544                if (!_this.isDragging) {
10545                    return;
10546                }
10547                var relevantEvents = _this.relevantEvents;
10548                var initialHit = _this.hitDragging.initialHit;
10549                var initialContext = _this.component.context;
10550                // states based on new hit
10551                var receivingContext = null;
10552                var mutation = null;
10553                var mutatedRelevantEvents = null;
10554                var isInvalid = false;
10555                var interaction = {
10556                    affectedEvents: relevantEvents,
10557                    mutatedEvents: createEmptyEventStore(),
10558                    isEvent: true
10559                };
10560                if (hit) {
10561                    var receivingComponent = hit.component;
10562                    receivingContext = receivingComponent.context;
10563                    var receivingOptions = receivingContext.options;
10564                    if (initialContext === receivingContext ||
10565                        receivingOptions.editable && receivingOptions.droppable) {
10566                        mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers);
10567                        if (mutation) {
10568                            mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext);
10569                            interaction.mutatedEvents = mutatedRelevantEvents;
10570                            if (!receivingComponent.isInteractionValid(interaction)) {
10571                                isInvalid = true;
10572                                mutation = null;
10573                                mutatedRelevantEvents = null;
10574                                interaction.mutatedEvents = createEmptyEventStore();
10575                            }
10576                        }
10577                    }
10578                    else {
10579                        receivingContext = null;
10580                    }
10581                }
10582                _this.displayDrag(receivingContext, interaction);
10583                if (!isInvalid) {
10584                    enableCursor();
10585                }
10586                else {
10587                    disableCursor();
10588                }
10589                if (!isFinal) {
10590                    if (initialContext === receivingContext && // TODO: write test for this
10591                        isHitsEqual(initialHit, hit)) {
10592                        mutation = null;
10593                    }
10594                    _this.dragging.setMirrorNeedsRevert(!mutation);
10595                    // render the mirror if no already-rendered mirror
10596                    // TODO: wish we could somehow wait for dispatch to guarantee render
10597                    _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-event-mirror'));
10598                    // assign states based on new hit
10599                    _this.receivingContext = receivingContext;
10600                    _this.validMutation = mutation;
10601                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
10602                }
10603            };
10604            _this.handlePointerUp = function () {
10605                if (!_this.isDragging) {
10606                    _this.cleanup(); // because handleDragEnd won't fire
10607                }
10608            };
10609            _this.handleDragEnd = function (ev) {
10610                if (_this.isDragging) {
10611                    var initialContext_1 = _this.component.context;
10612                    var initialView = initialContext_1.viewApi;
10613                    var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation;
10614                    var eventDef = _this.eventRange.def;
10615                    var eventInstance = _this.eventRange.instance;
10616                    var eventApi = new EventApi(initialContext_1, eventDef, eventInstance);
10617                    var relevantEvents_1 = _this.relevantEvents;
10618                    var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents;
10619                    var finalHit = _this.hitDragging.finalHit;
10620                    _this.clearDrag(); // must happen after revert animation
10621                    initialContext_1.emitter.trigger('eventDragStop', {
10622                        el: _this.subjectEl,
10623                        event: eventApi,
10624                        jsEvent: ev.origEvent,
10625                        view: initialView
10626                    });
10627                    if (validMutation) {
10628                        // dropped within same calendar
10629                        if (receivingContext_1 === initialContext_1) {
10630                            var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null);
10631                            initialContext_1.dispatch({
10632                                type: 'MERGE_EVENTS',
10633                                eventStore: mutatedRelevantEvents_1
10634                            });
10635                            var eventChangeArg = {
10636                                oldEvent: eventApi,
10637                                event: updatedEventApi,
10638                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance),
10639                                revert: function () {
10640                                    initialContext_1.dispatch({
10641                                        type: 'MERGE_EVENTS',
10642                                        eventStore: relevantEvents_1 // the pre-change data
10643                                    });
10644                                }
10645                            };
10646                            var transformed = {};
10647                            for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) {
10648                                var transformer = _b[_i];
10649                                __assign(transformed, transformer(validMutation, initialContext_1));
10650                            }
10651                            initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView }));
10652                            initialContext_1.emitter.trigger('eventChange', eventChangeArg);
10653                            // dropped in different calendar
10654                        }
10655                        else if (receivingContext_1) {
10656                            var eventRemoveArg = {
10657                                event: eventApi,
10658                                relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance),
10659                                revert: function () {
10660                                    initialContext_1.dispatch({
10661                                        type: 'MERGE_EVENTS',
10662                                        eventStore: relevantEvents_1
10663                                    });
10664                                }
10665                            };
10666                            initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView }));
10667                            initialContext_1.dispatch({
10668                                type: 'REMOVE_EVENTS',
10669                                eventStore: relevantEvents_1
10670                            });
10671                            initialContext_1.emitter.trigger('eventRemove', eventRemoveArg);
10672                            var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId];
10673                            var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId];
10674                            var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance);
10675                            receivingContext_1.dispatch({
10676                                type: 'MERGE_EVENTS',
10677                                eventStore: mutatedRelevantEvents_1
10678                            });
10679                            var eventAddArg = {
10680                                event: addedEventApi,
10681                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance),
10682                                revert: function () {
10683                                    receivingContext_1.dispatch({
10684                                        type: 'REMOVE_EVENTS',
10685                                        eventStore: mutatedRelevantEvents_1
10686                                    });
10687                                }
10688                            };
10689                            receivingContext_1.emitter.trigger('eventAdd', eventAddArg);
10690                            if (ev.isTouch) {
10691                                receivingContext_1.dispatch({
10692                                    type: 'SELECT_EVENT',
10693                                    eventInstanceId: eventInstance.instanceId
10694                                });
10695                            }
10696                            receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.component.context.viewApi }));
10697                            receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.component.context.viewApi }));
10698                        }
10699                    }
10700                    else {
10701                        initialContext_1.emitter.trigger('_noEventDrop');
10702                    }
10703                }
10704                _this.cleanup();
10705            };
10706            var component = _this.component;
10707            var options = component.context.options;
10708            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
10709            dragging.pointer.selector = EventDragging.SELECTOR;
10710            dragging.touchScrollAllowed = false;
10711            dragging.autoScroller.isEnabled = options.dragScroll;
10712            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore);
10713            hitDragging.useSubjectCenter = settings.useEventCenter;
10714            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10715            hitDragging.emitter.on('dragstart', _this.handleDragStart);
10716            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
10717            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
10718            hitDragging.emitter.on('dragend', _this.handleDragEnd);
10719            return _this;
10720        }
10721        EventDragging.prototype.destroy = function () {
10722            this.dragging.destroy();
10723        };
10724        // render a drag state on the next receivingCalendar
10725        EventDragging.prototype.displayDrag = function (nextContext, state) {
10726            var initialContext = this.component.context;
10727            var prevContext = this.receivingContext;
10728            // does the previous calendar need to be cleared?
10729            if (prevContext && prevContext !== nextContext) {
10730                // does the initial calendar need to be cleared?
10731                // if so, don't clear all the way. we still need to to hide the affectedEvents
10732                if (prevContext === initialContext) {
10733                    prevContext.dispatch({
10734                        type: 'SET_EVENT_DRAG',
10735                        state: {
10736                            affectedEvents: state.affectedEvents,
10737                            mutatedEvents: createEmptyEventStore(),
10738                            isEvent: true
10739                        }
10740                    });
10741                    // completely clear the old calendar if it wasn't the initial
10742                }
10743                else {
10744                    prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
10745                }
10746            }
10747            if (nextContext) {
10748                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
10749            }
10750        };
10751        EventDragging.prototype.clearDrag = function () {
10752            var initialCalendar = this.component.context;
10753            var receivingContext = this.receivingContext;
10754            if (receivingContext) {
10755                receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
10756            }
10757            // the initial calendar might have an dummy drag state from displayDrag
10758            if (initialCalendar !== receivingContext) {
10759                initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
10760            }
10761        };
10762        EventDragging.prototype.cleanup = function () {
10763            this.subjectSeg = null;
10764            this.isDragging = false;
10765            this.eventRange = null;
10766            this.relevantEvents = null;
10767            this.receivingContext = null;
10768            this.validMutation = null;
10769            this.mutatedRelevantEvents = null;
10770        };
10771        // TODO: test this in IE11
10772        // QUESTION: why do we need it on the resizable???
10773        EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable';
10774        return EventDragging;
10775    }(Interaction));
10776    function computeEventMutation(hit0, hit1, massagers) {
10777        var dateSpan0 = hit0.dateSpan;
10778        var dateSpan1 = hit1.dateSpan;
10779        var date0 = dateSpan0.range.start;
10780        var date1 = dateSpan1.range.start;
10781        var standardProps = {};
10782        if (dateSpan0.allDay !== dateSpan1.allDay) {
10783            standardProps.allDay = dateSpan1.allDay;
10784            standardProps.hasEnd = hit1.component.context.options.allDayMaintainDuration;
10785            if (dateSpan1.allDay) {
10786                // means date1 is already start-of-day,
10787                // but date0 needs to be converted
10788                date0 = startOfDay(date0);
10789            }
10790        }
10791        var delta = diffDates(date0, date1, hit0.component.context.dateEnv, hit0.component === hit1.component ?
10792            hit0.component.largeUnit :
10793            null);
10794        if (delta.milliseconds) { // has hours/minutes/seconds
10795            standardProps.allDay = false;
10796        }
10797        var mutation = {
10798            datesDelta: delta,
10799            standardProps: standardProps
10800        };
10801        for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
10802            var massager = massagers_1[_i];
10803            massager(mutation, hit0, hit1);
10804        }
10805        return mutation;
10806    }
10807    function getComponentTouchDelay$1(component) {
10808        var options = component.context.options;
10809        var delay = options.eventLongPressDelay;
10810        if (delay == null) {
10811            delay = options.longPressDelay;
10812        }
10813        return delay;
10814    }
10815
10816    var EventResizing = /** @class */ (function (_super) {
10817        __extends(EventResizing, _super);
10818        function EventResizing(settings) {
10819            var _this = _super.call(this, settings) || this;
10820            // internal state
10821            _this.draggingSegEl = null;
10822            _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
10823            _this.eventRange = null;
10824            _this.relevantEvents = null;
10825            _this.validMutation = null;
10826            _this.mutatedRelevantEvents = null;
10827            _this.handlePointerDown = function (ev) {
10828                var component = _this.component;
10829                var segEl = _this.querySegEl(ev);
10830                var seg = getElSeg(segEl);
10831                var eventRange = _this.eventRange = seg.eventRange;
10832                _this.dragging.minDistance = component.context.options.eventDragMinDistance;
10833                // if touch, need to be working with a selected event
10834                _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
10835                    (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
10836            };
10837            _this.handleDragStart = function (ev) {
10838                var context = _this.component.context;
10839                var eventRange = _this.eventRange;
10840                _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId);
10841                var segEl = _this.querySegEl(ev);
10842                _this.draggingSegEl = segEl;
10843                _this.draggingSeg = getElSeg(segEl);
10844                context.calendarApi.unselect();
10845                context.emitter.trigger('eventResizeStart', {
10846                    el: segEl,
10847                    event: new EventApi(context, eventRange.def, eventRange.instance),
10848                    jsEvent: ev.origEvent,
10849                    view: context.viewApi
10850                });
10851            };
10852            _this.handleHitUpdate = function (hit, isFinal, ev) {
10853                var context = _this.component.context;
10854                var relevantEvents = _this.relevantEvents;
10855                var initialHit = _this.hitDragging.initialHit;
10856                var eventInstance = _this.eventRange.instance;
10857                var mutation = null;
10858                var mutatedRelevantEvents = null;
10859                var isInvalid = false;
10860                var interaction = {
10861                    affectedEvents: relevantEvents,
10862                    mutatedEvents: createEmptyEventStore(),
10863                    isEvent: true
10864                };
10865                if (hit) {
10866                    mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range, context.pluginHooks.eventResizeJoinTransforms);
10867                }
10868                if (mutation) {
10869                    mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context);
10870                    interaction.mutatedEvents = mutatedRelevantEvents;
10871                    if (!_this.component.isInteractionValid(interaction)) {
10872                        isInvalid = true;
10873                        mutation = null;
10874                        mutatedRelevantEvents = null;
10875                        interaction.mutatedEvents = null;
10876                    }
10877                }
10878                if (mutatedRelevantEvents) {
10879                    context.dispatch({
10880                        type: 'SET_EVENT_RESIZE',
10881                        state: interaction
10882                    });
10883                }
10884                else {
10885                    context.dispatch({ type: 'UNSET_EVENT_RESIZE' });
10886                }
10887                if (!isInvalid) {
10888                    enableCursor();
10889                }
10890                else {
10891                    disableCursor();
10892                }
10893                if (!isFinal) {
10894                    if (mutation && isHitsEqual(initialHit, hit)) {
10895                        mutation = null;
10896                    }
10897                    _this.validMutation = mutation;
10898                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
10899                }
10900            };
10901            _this.handleDragEnd = function (ev) {
10902                var context = _this.component.context;
10903                var eventDef = _this.eventRange.def;
10904                var eventInstance = _this.eventRange.instance;
10905                var eventApi = new EventApi(context, eventDef, eventInstance);
10906                var relevantEvents = _this.relevantEvents;
10907                var mutatedRelevantEvents = _this.mutatedRelevantEvents;
10908                context.emitter.trigger('eventResizeStop', {
10909                    el: _this.draggingSegEl,
10910                    event: eventApi,
10911                    jsEvent: ev.origEvent,
10912                    view: context.viewApi
10913                });
10914                if (_this.validMutation) {
10915                    var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
10916                    context.dispatch({
10917                        type: 'MERGE_EVENTS',
10918                        eventStore: mutatedRelevantEvents
10919                    });
10920                    var eventChangeArg = {
10921                        oldEvent: eventApi,
10922                        event: updatedEventApi,
10923                        relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance),
10924                        revert: function () {
10925                            context.dispatch({
10926                                type: 'MERGE_EVENTS',
10927                                eventStore: relevantEvents // the pre-change events
10928                            });
10929                        }
10930                    };
10931                    context.emitter.trigger('eventResize', __assign(__assign({}, eventChangeArg), { el: _this.draggingSegEl, startDelta: _this.validMutation.startDelta || createDuration(0), endDelta: _this.validMutation.endDelta || createDuration(0), jsEvent: ev.origEvent, view: context.viewApi }));
10932                    context.emitter.trigger('eventChange', eventChangeArg);
10933                }
10934                else {
10935                    context.emitter.trigger('_noEventResize');
10936                }
10937                // reset all internal state
10938                _this.draggingSeg = null;
10939                _this.relevantEvents = null;
10940                _this.validMutation = null;
10941                // okay to keep eventInstance around. useful to set it in handlePointerDown
10942            };
10943            var component = settings.component;
10944            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
10945            dragging.pointer.selector = '.fc-event-resizer';
10946            dragging.touchScrollAllowed = false;
10947            dragging.autoScroller.isEnabled = component.context.options.dragScroll;
10948            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10949            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10950            hitDragging.emitter.on('dragstart', _this.handleDragStart);
10951            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
10952            hitDragging.emitter.on('dragend', _this.handleDragEnd);
10953            return _this;
10954        }
10955        EventResizing.prototype.destroy = function () {
10956            this.dragging.destroy();
10957        };
10958        EventResizing.prototype.querySegEl = function (ev) {
10959            return elementClosest(ev.subjectEl, '.fc-event');
10960        };
10961        return EventResizing;
10962    }(Interaction));
10963    function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) {
10964        var dateEnv = hit0.component.context.dateEnv;
10965        var date0 = hit0.dateSpan.range.start;
10966        var date1 = hit1.dateSpan.range.start;
10967        var delta = diffDates(date0, date1, dateEnv, hit0.component.largeUnit);
10968        var props = {};
10969        for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) {
10970            var transform = transforms_1[_i];
10971            var res = transform(hit0, hit1);
10972            if (res === false) {
10973                return null;
10974            }
10975            else if (res) {
10976                __assign(props, res);
10977            }
10978        }
10979        if (isFromStart) {
10980            if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
10981                props.startDelta = delta;
10982                return props;
10983            }
10984        }
10985        else {
10986            if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
10987                props.endDelta = delta;
10988                return props;
10989            }
10990        }
10991        return null;
10992    }
10993
10994    var UnselectAuto = /** @class */ (function () {
10995        function UnselectAuto(context) {
10996            var _this = this;
10997            this.context = context;
10998            this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
10999            this.matchesCancel = false;
11000            this.matchesEvent = false;
11001            this.onSelect = function (selectInfo) {
11002                if (selectInfo.jsEvent) {
11003                    _this.isRecentPointerDateSelect = true;
11004                }
11005            };
11006            this.onDocumentPointerDown = function (pev) {
11007                var unselectCancel = _this.context.options.unselectCancel;
11008                var downEl = pev.origEvent.target;
11009                _this.matchesCancel = !!elementClosest(downEl, unselectCancel);
11010                _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event?
11011            };
11012            this.onDocumentPointerUp = function (pev) {
11013                var context = _this.context;
11014                var documentPointer = _this.documentPointer;
11015                var calendarState = context.getCurrentData();
11016                // touch-scrolling should never unfocus any type of selection
11017                if (!documentPointer.wasTouchScroll) {
11018                    if (calendarState.dateSelection && // an existing date selection?
11019                        !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
11020                    ) {
11021                        var unselectAuto = context.options.unselectAuto;
11022                        if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) {
11023                            context.calendarApi.unselect(pev);
11024                        }
11025                    }
11026                    if (calendarState.eventSelection && // an existing event selected?
11027                        !_this.matchesEvent // interaction DIDN'T start on an event
11028                    ) {
11029                        context.dispatch({ type: 'UNSELECT_EVENT' });
11030                    }
11031                }
11032                _this.isRecentPointerDateSelect = false;
11033            };
11034            var documentPointer = this.documentPointer = new PointerDragging(document);
11035            documentPointer.shouldIgnoreMove = true;
11036            documentPointer.shouldWatchScroll = false;
11037            documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);
11038            documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
11039            /*
11040            TODO: better way to know about whether there was a selection with the pointer
11041            */
11042            context.emitter.on('select', this.onSelect);
11043        }
11044        UnselectAuto.prototype.destroy = function () {
11045            this.context.emitter.off('select', this.onSelect);
11046            this.documentPointer.destroy();
11047        };
11048        return UnselectAuto;
11049    }());
11050
11051    var LISTENER_REFINERS = {
11052        dateClick: identity,
11053        eventDragStart: identity,
11054        eventDragStop: identity,
11055        eventDrop: identity,
11056        eventResizeStart: identity,
11057        eventResizeStop: identity,
11058        eventResize: identity,
11059        drop: identity,
11060        eventReceive: identity,
11061        eventLeave: identity
11062    };
11063
11064    /*
11065    Given an already instantiated draggable object for one-or-more elements,
11066    Interprets any dragging as an attempt to drag an events that lives outside
11067    of a calendar onto a calendar.
11068    */
11069    var ExternalElementDragging = /** @class */ (function () {
11070        function ExternalElementDragging(dragging, suppliedDragMeta) {
11071            var _this = this;
11072            this.receivingContext = null;
11073            this.droppableEvent = null; // will exist for all drags, even if create:false
11074            this.suppliedDragMeta = null;
11075            this.dragMeta = null;
11076            this.handleDragStart = function (ev) {
11077                _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
11078            };
11079            this.handleHitUpdate = function (hit, isFinal, ev) {
11080                var dragging = _this.hitDragging.dragging;
11081                var receivingContext = null;
11082                var droppableEvent = null;
11083                var isInvalid = false;
11084                var interaction = {
11085                    affectedEvents: createEmptyEventStore(),
11086                    mutatedEvents: createEmptyEventStore(),
11087                    isEvent: _this.dragMeta.create
11088                };
11089                if (hit) {
11090                    receivingContext = hit.component.context;
11091                    if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) {
11092                        droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext);
11093                        interaction.mutatedEvents = eventTupleToStore(droppableEvent);
11094                        isInvalid = !isInteractionValid(interaction, receivingContext);
11095                        if (isInvalid) {
11096                            interaction.mutatedEvents = createEmptyEventStore();
11097                            droppableEvent = null;
11098                        }
11099                    }
11100                }
11101                _this.displayDrag(receivingContext, interaction);
11102                // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
11103                // TODO: wish we could somehow wait for dispatch to guarantee render
11104                dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror'));
11105                if (!isInvalid) {
11106                    enableCursor();
11107                }
11108                else {
11109                    disableCursor();
11110                }
11111                if (!isFinal) {
11112                    dragging.setMirrorNeedsRevert(!droppableEvent);
11113                    _this.receivingContext = receivingContext;
11114                    _this.droppableEvent = droppableEvent;
11115                }
11116            };
11117            this.handleDragEnd = function (pev) {
11118                var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent;
11119                _this.clearDrag();
11120                if (receivingContext && droppableEvent) {
11121                    var finalHit = _this.hitDragging.finalHit;
11122                    var finalView = finalHit.component.context.viewApi;
11123                    var dragMeta = _this.dragMeta;
11124                    receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView }));
11125                    if (dragMeta.create) {
11126                        var addingEvents_1 = eventTupleToStore(droppableEvent);
11127                        receivingContext.dispatch({
11128                            type: 'MERGE_EVENTS',
11129                            eventStore: addingEvents_1
11130                        });
11131                        if (pev.isTouch) {
11132                            receivingContext.dispatch({
11133                                type: 'SELECT_EVENT',
11134                                eventInstanceId: droppableEvent.instance.instanceId
11135                            });
11136                        }
11137                        // signal that an external event landed
11138                        receivingContext.emitter.trigger('eventReceive', {
11139                            event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance),
11140                            relatedEvents: [],
11141                            revert: function () {
11142                                receivingContext.dispatch({
11143                                    type: 'REMOVE_EVENTS',
11144                                    eventStore: addingEvents_1
11145                                });
11146                            },
11147                            draggedEl: pev.subjectEl,
11148                            view: finalView
11149                        });
11150                    }
11151                }
11152                _this.receivingContext = null;
11153                _this.droppableEvent = null;
11154            };
11155            var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore);
11156            hitDragging.requireInitial = false; // will start outside of a component
11157            hitDragging.emitter.on('dragstart', this.handleDragStart);
11158            hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
11159            hitDragging.emitter.on('dragend', this.handleDragEnd);
11160            this.suppliedDragMeta = suppliedDragMeta;
11161        }
11162        ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) {
11163            if (typeof this.suppliedDragMeta === 'object') {
11164                return parseDragMeta(this.suppliedDragMeta);
11165            }
11166            else if (typeof this.suppliedDragMeta === 'function') {
11167                return parseDragMeta(this.suppliedDragMeta(subjectEl));
11168            }
11169            else {
11170                return getDragMetaFromEl(subjectEl);
11171            }
11172        };
11173        ExternalElementDragging.prototype.displayDrag = function (nextContext, state) {
11174            var prevContext = this.receivingContext;
11175            if (prevContext && prevContext !== nextContext) {
11176                prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11177            }
11178            if (nextContext) {
11179                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
11180            }
11181        };
11182        ExternalElementDragging.prototype.clearDrag = function () {
11183            if (this.receivingContext) {
11184                this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11185            }
11186        };
11187        ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) {
11188            var dropAccept = receivingContext.options.dropAccept;
11189            if (typeof dropAccept === 'function') {
11190                return dropAccept.call(receivingContext.calendarApi, el);
11191            }
11192            else if (typeof dropAccept === 'string' && dropAccept) {
11193                return Boolean(elementMatches(el, dropAccept));
11194            }
11195            return true;
11196        };
11197        return ExternalElementDragging;
11198    }());
11199    // Utils for computing event store from the DragMeta
11200    // ----------------------------------------------------------------------------------------------------
11201    function computeEventForDateSpan(dateSpan, dragMeta, context) {
11202        var defProps = __assign({}, dragMeta.leftoverProps);
11203        for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) {
11204            var transform = _a[_i];
11205            __assign(defProps, transform(dateSpan, dragMeta));
11206        }
11207        var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra;
11208        var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd
11209        context);
11210        var start = dateSpan.range.start;
11211        // only rely on time info if drop zone is all-day,
11212        // otherwise, we already know the time
11213        if (dateSpan.allDay && dragMeta.startTime) {
11214            start = context.dateEnv.add(start, dragMeta.startTime);
11215        }
11216        var end = dragMeta.duration ?
11217            context.dateEnv.add(start, dragMeta.duration) :
11218            getDefaultEventEnd(dateSpan.allDay, start, context);
11219        var instance = createEventInstance(def.defId, { start: start, end: end });
11220        return { def: def, instance: instance };
11221    }
11222    // Utils for extracting data from element
11223    // ----------------------------------------------------------------------------------------------------
11224    function getDragMetaFromEl(el) {
11225        var str = getEmbeddedElData(el, 'event');
11226        var obj = str ?
11227            JSON.parse(str) :
11228            { create: false }; // if no embedded data, assume no event creation
11229        return parseDragMeta(obj);
11230    }
11231    config.dataAttrPrefix = '';
11232    function getEmbeddedElData(el, name) {
11233        var prefix = config.dataAttrPrefix;
11234        var prefixedName = (prefix ? prefix + '-' : '') + name;
11235        return el.getAttribute('data-' + prefixedName) || '';
11236    }
11237
11238    /*
11239    Makes an element (that is *external* to any calendar) draggable.
11240    Can pass in data that determines how an event will be created when dropped onto a calendar.
11241    Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
11242    */
11243    var ExternalDraggable = /** @class */ (function () {
11244        function ExternalDraggable(el, settings) {
11245            var _this = this;
11246            if (settings === void 0) { settings = {}; }
11247            this.handlePointerDown = function (ev) {
11248                var dragging = _this.dragging;
11249                var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
11250                dragging.minDistance =
11251                    minDistance != null ?
11252                        minDistance :
11253                        (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance);
11254                dragging.delay =
11255                    ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
11256                        (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) :
11257                        0;
11258            };
11259            this.handleDragStart = function (ev) {
11260                if (ev.isTouch &&
11261                    _this.dragging.delay &&
11262                    ev.subjectEl.classList.contains('fc-event')) {
11263                    _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected');
11264                }
11265            };
11266            this.settings = settings;
11267            var dragging = this.dragging = new FeaturefulElementDragging(el);
11268            dragging.touchScrollAllowed = false;
11269            if (settings.itemSelector != null) {
11270                dragging.pointer.selector = settings.itemSelector;
11271            }
11272            if (settings.appendTo != null) {
11273                dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
11274            }
11275            dragging.emitter.on('pointerdown', this.handlePointerDown);
11276            dragging.emitter.on('dragstart', this.handleDragStart);
11277            new ExternalElementDragging(dragging, settings.eventData);
11278        }
11279        ExternalDraggable.prototype.destroy = function () {
11280            this.dragging.destroy();
11281        };
11282        return ExternalDraggable;
11283    }());
11284
11285    /*
11286    Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
11287    The third-party system is responsible for drawing the visuals effects of the drag.
11288    This class simply monitors for pointer movements and fires events.
11289    It also has the ability to hide the moving element (the "mirror") during the drag.
11290    */
11291    var InferredElementDragging = /** @class */ (function (_super) {
11292        __extends(InferredElementDragging, _super);
11293        function InferredElementDragging(containerEl) {
11294            var _this = _super.call(this, containerEl) || this;
11295            _this.shouldIgnoreMove = false;
11296            _this.mirrorSelector = '';
11297            _this.currentMirrorEl = null;
11298            _this.handlePointerDown = function (ev) {
11299                _this.emitter.trigger('pointerdown', ev);
11300                if (!_this.shouldIgnoreMove) {
11301                    // fire dragstart right away. does not support delay or min-distance
11302                    _this.emitter.trigger('dragstart', ev);
11303                }
11304            };
11305            _this.handlePointerMove = function (ev) {
11306                if (!_this.shouldIgnoreMove) {
11307                    _this.emitter.trigger('dragmove', ev);
11308                }
11309            };
11310            _this.handlePointerUp = function (ev) {
11311                _this.emitter.trigger('pointerup', ev);
11312                if (!_this.shouldIgnoreMove) {
11313                    // fire dragend right away. does not support a revert animation
11314                    _this.emitter.trigger('dragend', ev);
11315                }
11316            };
11317            var pointer = _this.pointer = new PointerDragging(containerEl);
11318            pointer.emitter.on('pointerdown', _this.handlePointerDown);
11319            pointer.emitter.on('pointermove', _this.handlePointerMove);
11320            pointer.emitter.on('pointerup', _this.handlePointerUp);
11321            return _this;
11322        }
11323        InferredElementDragging.prototype.destroy = function () {
11324            this.pointer.destroy();
11325        };
11326        InferredElementDragging.prototype.setIgnoreMove = function (bool) {
11327            this.shouldIgnoreMove = bool;
11328        };
11329        InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
11330            if (bool) {
11331                // restore a previously hidden element.
11332                // use the reference in case the selector class has already been removed.
11333                if (this.currentMirrorEl) {
11334                    this.currentMirrorEl.style.visibility = '';
11335                    this.currentMirrorEl = null;
11336                }
11337            }
11338            else {
11339                var mirrorEl = this.mirrorSelector ?
11340                    document.querySelector(this.mirrorSelector) :
11341                    null;
11342                if (mirrorEl) {
11343                    this.currentMirrorEl = mirrorEl;
11344                    mirrorEl.style.visibility = 'hidden';
11345                }
11346            }
11347        };
11348        return InferredElementDragging;
11349    }(ElementDragging));
11350
11351    /*
11352    Bridges third-party drag-n-drop systems with FullCalendar.
11353    Must be instantiated and destroyed by caller.
11354    */
11355    var ThirdPartyDraggable = /** @class */ (function () {
11356        function ThirdPartyDraggable(containerOrSettings, settings) {
11357            var containerEl = document;
11358            if (
11359            // wish we could just test instanceof EventTarget, but doesn't work in IE11
11360            containerOrSettings === document ||
11361                containerOrSettings instanceof Element) {
11362                containerEl = containerOrSettings;
11363                settings = settings || {};
11364            }
11365            else {
11366                settings = (containerOrSettings || {});
11367            }
11368            var dragging = this.dragging = new InferredElementDragging(containerEl);
11369            if (typeof settings.itemSelector === 'string') {
11370                dragging.pointer.selector = settings.itemSelector;
11371            }
11372            else if (containerEl === document) {
11373                dragging.pointer.selector = '[data-event]';
11374            }
11375            if (typeof settings.mirrorSelector === 'string') {
11376                dragging.mirrorSelector = settings.mirrorSelector;
11377            }
11378            new ExternalElementDragging(dragging, settings.eventData);
11379        }
11380        ThirdPartyDraggable.prototype.destroy = function () {
11381            this.dragging.destroy();
11382        };
11383        return ThirdPartyDraggable;
11384    }());
11385
11386    var interactionPlugin = createPlugin({
11387        componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing],
11388        calendarInteractions: [UnselectAuto],
11389        elementDraggingImpl: FeaturefulElementDragging,
11390        listenerRefiners: LISTENER_REFINERS
11391    });
11392
11393    /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
11394    ----------------------------------------------------------------------------------------------------------------------*/
11395    // It is a manager for a Table subcomponent, which does most of the heavy lifting.
11396    // It is responsible for managing width/height.
11397    var TableView = /** @class */ (function (_super) {
11398        __extends(TableView, _super);
11399        function TableView() {
11400            var _this = _super !== null && _super.apply(this, arguments) || this;
11401            _this.headerElRef = createRef();
11402            return _this;
11403        }
11404        TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) {
11405            var _a = this, props = _a.props, context = _a.context;
11406            var sections = [];
11407            var stickyHeaderDates = getStickyHeaderDates(context.options);
11408            if (headerRowContent) {
11409                sections.push({
11410                    type: 'header',
11411                    key: 'header',
11412                    isSticky: stickyHeaderDates,
11413                    chunk: {
11414                        elRef: this.headerElRef,
11415                        tableClassName: 'fc-col-header',
11416                        rowContent: headerRowContent
11417                    }
11418                });
11419            }
11420            sections.push({
11421                type: 'body',
11422                key: 'body',
11423                liquid: true,
11424                chunk: { content: bodyContent }
11425            });
11426            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygri
11426d'].concat(classNames).join(' ') },
11427                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); }));
11428        };
11429        TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) {
11430            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
11431            if (!ScrollGrid) {
11432                throw new Error('No ScrollGrid implementation');
11433            }
11434            var _a = this, props = _a.props, context = _a.context;
11435            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
11436            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
11437            var sections = [];
11438            if (headerRowContent) {
11439                sections.push({
11440                    type: 'header',
11441                    key: 'header',
11442                    isSticky: stickyHeaderDates,
11443                    chunks: [{
11444                            key: 'main',
11445                            elRef: this.headerElRef,
11446                            tableClassName: 'fc-col-header',
11447                            rowContent: headerRowContent
11448                        }]
11449                });
11450            }
11451            sections.push({
11452                type: 'body',
11453                key: 'body',
11454                liquid: true,
11455                chunks: [{
11456                        key: 'main',
11457                        content: bodyContent
11458                    }]
11459            });
11460            if (stickyFooterScrollbar) {
11461                sections.push({
11462                    type: 'footer',
11463                    key: 'footer',
11464                    isSticky: true,
11465                    chunks: [{
11466                            key: 'main',
11467                            content: renderScrollShim
11468                        }]
11469                });
11470            }
11471            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') },
11472                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); }));
11473        };
11474        return TableView;
11475    }(DateComponent));
11476
11477    function splitSegsByRow(segs, rowCnt) {
11478        var byRow = [];
11479        for (var i = 0; i < rowCnt; i++) {
11480            byRow[i] = [];
11481        }
11482        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
11483            var seg = segs_1[_i];
11484            byRow[seg.row].push(seg);
11485        }
11486        return byRow;
11487    }
11488    function splitSegsByFirstCol(segs, colCnt) {
11489        var byCol = [];
11490        for (var i = 0; i < colCnt; i++) {
11491            byCol[i] = [];
11492        }
11493        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
11494            var seg = segs_2[_i];
11495            byCol[seg.firstCol].push(seg);
11496        }
11497        return byCol;
11498    }
11499    function splitInteractionByRow(ui, rowCnt) {
11500        var byRow = [];
11501        if (!ui) {
11502            for (var i = 0; i < rowCnt; i++) {
11503                byRow[i] = null;
11504            }
11505        }
11506        else {
11507            for (var i = 0; i < rowCnt; i++) {
11508                byRow[i] = {
11509                    affectedInstances: ui.affectedInstances,
11510                    isEvent: ui.isEvent,
11511                    segs: []
11512                };
11513            }
11514            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
11515                var seg = _a[_i];
11516                byRow[seg.row].segs.push(seg);
11517            }
11518        }
11519        return byRow;
11520    }
11521
11522    var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'narrow' });
11523    var TableCell = /** @class */ (function (_super) {
11524        __extends(TableCell, _super);
11525        function TableCell() {
11526            var _this = _super !== null && _super.apply(this, arguments) || this;
11527            _this.handleRootEl = function (el) {
11528                _this.rootEl = el;
11529                setRef(_this.props.elRef, el);
11530            };
11531            _this.handleMoreLinkClick = function (ev) {
11532                var props = _this.props;
11533                if (props.onMoreClick) {
11534                    var allSegs = props.segsByEachCol;
11535                    var hiddenSegs = allSegs.filter(function (seg) { return props.segIsHidden[seg.eventRange.instance.instanceId]; });
11536                    props.onMoreClick({
11537                        date: props.date,
11538                        allSegs: allSegs,
11539                        hiddenSegs: hiddenSegs,
11540                        moreCnt: props.moreCnt,
11541                        dayEl: _this.rootEl,
11542                        ev: ev
11543                    });
11544                }
11545            };
11546            return _this;
11547        }
11548        TableCell.prototype.render = function () {
11549            var _this = this;
11550            var _a = this.context, options = _a.options, viewApi = _a.viewApi;
11551            var props = this.props;
11552            var date = props.date, dateProfile = props.dateProfile;
11553            var hookProps = {
11554                num: props.moreCnt,
11555                text: props.buildMoreLinkText(props.moreCnt),
11556                view: viewApi
11557            };
11558            var navLinkAttrs = options.navLinks
11559                ? { 'data-navlink': buildNavLinkData(date, 'week'), tabIndex: 0 }
11560                : {};
11561            return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, elRef: this.handleRootEl }, function (rootElRef, classNames, rootDataAttrs, isDisabled) { return (createElement("td", __assign({ ref: rootElRef, className: ['fc-daygri
11561d-day'].concat(classNames, props.extraClassNames || []).join(' ') }, rootDataAttrs, props.extraDataAttrs),
11562                createElement("div", { className: 'fc-daygrid-day-frame fc-scrollgrid-sync-inner', ref: props.innerElRef /* different from hook system! RENAME */ },
11563                    props.showWeekNumber &&
11564                        createElement(WeekNumberRoot, { date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("a", __assign({ ref: rootElRef, className: ['fc-daygrid-week-number'].concat(classNames).join(' ') }, navLinkAttrs), innerContent)); }),
11565                    !isDisabled &&
11566                        createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps }),
11567                    createElement("div", { className: 'fc-daygrid-day-events', ref: props.fgContentElRef, style: { paddingBottom: props.fgPaddingBottom } },
11568                        props.fgContent,
11569                        Boolean(props.moreCnt) &&
11570                            createElement("div", { className: 'fc-daygrid-day-bottom', style: { marginTop: props.moreMarginTop } },
11571                                createElement(RenderHook, { hookProps: hookProps, classNames: options.moreLinkClassNames, content: options.moreLinkContent, defaultContent: renderMoreLinkInner, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("a", { onClick: _this.handleMoreLinkClick, ref: rootElRef, className: ['fc-daygrid-more-link'].concat(classNames).join(' ') }, innerContent)); }))),
11572                    createElement("div", { className: 'fc-daygrid-day-bg' }, props.bgContent)))); }));
11573        };
11574        return TableCell;
11575    }(DateComponent));
11576    function renderTopInner(props) {
11577        return props.dayNumberText;
11578    }
11579    function renderMoreLinkInner(props) {
11580        return props.text;
11581    }
11582    var TableCellTop = /** @class */ (function (_super) {
11583        __extends(TableCellTop, _super);
11584        function TableCellTop() {
11585            return _super !== null && _super.apply(this, arguments) || this;
11586        }
11587        TableCellTop.prototype.render = function () {
11588            var props = this.props;
11589            var navLinkAttrs = this.context.options.navLinks
11590                ? { 'data-navlink': buildNavLinkData(props.date), tabIndex: 0 }
11591                : {};
11592            return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, defaultContent: renderTopInner }, function (innerElRef, innerContent) { return ((innerContent || props.forceDayTop) &&
11593                createElement("div", { className: 'fc-daygrid-day-top', ref: innerElRef },
11594                    createElement("a", __assign({ className: 'fc-daygrid-day-number' }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0")))); }));
11595        };
11596        return TableCellTop;
11597    }(BaseComponent));
11598
11599    var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({
11600        hour: 'numeric',
11601        minute: '2-digit',
11602        omitZeroMinute: true,
11603        meridiem: 'narrow'
11604    });
11605    function hasListItemDisplay(seg) {
11606        var display = seg.eventRange.ui.display;
11607        return display === 'list-item' || (display === 'auto' &&
11608            !seg.eventRange.def.allDay &&
11609            seg.firstCol === seg.lastCol && // can't be multi-day
11610            seg.isStart && // "
11611            seg.isEnd // "
11612        );
11613    }
11614
11615    var TableListItemEvent = /** @class */ (function (_super) {
11616        __extends(TableListItemEvent, _super);
11617        function TableListItemEvent() {
11618            return _super !== null && _super.apply(this, arguments) || this;
11619        }
11620        TableListItemEvent.prototype.render = function () {
11621            var _a = this, props = _a.props, context = _a.context;
11622            var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT;
11623            var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd);
11624            return (createElement(EventRoot, { seg: props.seg, timeText: timeText, defaultContent: renderInnerContent$2, isDragging: props.isDragging, isResizing: false, isDateSelecting: false, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent) { return ( // we don't use styles!
11625            createElement("a", __assign({ className: ['fc-daygri
11625d-event', 'fc-daygrid-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs$1(props.seg)), innerContent)); }));
11626        };
11627        return TableListItemEvent;
11628    }(BaseComponent));
11629    function renderInnerContent$2(innerProps) {
11630        return (createElement(Fragment, null,
11631            createElement("div", { className: 'fc-daygrid-event-dot', style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }),
11632            innerProps.timeText &&
11633                createElement("div", { className: 'fc-event-time' }, innerProps.timeText),
11634            createElement("div", { className: 'fc-event-title' }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))));
11635    }
11636    function getSegAnchorAttrs$1(seg) {
11637        var url = seg.eventRange.def.url;
11638        return url ? { href: url } : {};
11639    }
11640
11641    var TableBlockEvent = /** @class */ (function (_super) {
11642        __extends(TableBlockEvent, _super);
11643        function TableBlockEvent() {
11644            return _super !== null && _super.apply(this, arguments) || this;
11645        }
11646        TableBlockEvent.prototype.render = function () {
11647            var props = this.props;
11648            return (createElement(StandardEvent, __assign({}
11648, props, { extraClassNames: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay })));
11649        };
11650        return TableBlockEvent;
11651    }(BaseComponent));
11652
11653    function computeFgSegPlacement(// for one row. TODO: print mode?
11654    cellModels, segs, dayMaxEvents, dayMaxEventRows, eventHeights, maxContentHeight, colCnt, eventOrderSpecs) {
11655        var colPlacements = []; // if event spans multiple cols, its present in each col
11656        var moreCnts = []; // by-col
11657        var segIsHidden = {};
11658        var segTops = {}; // always populated for each seg
11659        var segMarginTops = {}; // simetimes populated for each seg
11660        var moreTops = {};
11661        var paddingBottoms = {}; // for each cell's inner-wrapper div
11662        for (var i = 0; i < colCnt; i++) {
11663            colPlacements.push([]);
11664            moreCnts.push(0);
11665        }
11666        segs = sortEventSegs(segs, eventOrderSpecs);
11667        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
11668            var seg = segs_1[_i];
11669            var instanceId = seg.eventRange.instance.instanceId;
11670            var eventHeight = eventHeights[instanceId + ':' + seg.firstCol];
11671            placeSeg(seg, eventHeight || 0); // will keep colPlacements sorted by top
11672        }
11673        if (dayMaxEvents === true || dayMaxEventRows === true) {
11674            limitByMaxHeight(moreCnts, segIsHidden, colPlacements, maxContentHeight); // populates moreCnts/segIsHidden
11675        }
11676        else if (typeof dayMaxEvents === 'number') {
11677            limitByMaxEvents(moreCnts, segIsHidden, colPlacements, dayMaxEvents); // populates moreCnts/segIsHidden
11678        }
11679        else if (typeof dayMaxEventRows === 'number') {
11680            limitByMaxRows(moreCnts, segIsHidden, colPlacements, dayMaxEventRows); // populates moreCnts/segIsHidden
11681        }
11682        // computes segTops/segMarginTops/moreTops/paddingBottoms
11683        for (var col = 0; col < colCnt; col++) {
11684            var placements = colPlacements[col];
11685            var currentNonAbsBottom = 0;
11686            var runningAbsHeight = 0;
11687            for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) {
11688                var placement = placements_1[_a];
11689                var seg = placement.seg;
11690                if (!segIsHidden[seg.eventRange.instance.instanceId]) {
11691                    segTops[seg.eventRange.instance.instanceId] = placement.top; // from top of container
11692                    if (seg.firstCol === seg.lastCol && seg.isStart && seg.isEnd) { // TODO: simpler way? NOT DRY
11693                        segMarginTops[seg.eventRange.instance.instanceId] =
11694                            placement.top - currentNonAbsBottom; // from previous seg bottom
11695                        runningAbsHeight = 0;
11696                        currentNonAbsBottom = placement.bottom;
11697                    }
11698                    else { // multi-col event, abs positioned
11699                        runningAbsHeight += placement.bottom - placement.top;
11700                    }
11701                }
11702            }
11703            if (runningAbsHeight) {
11704                if (moreCnts[col]) {
11705                    moreTops[col] = runningAbsHeight;
11706                }
11707                else {
11708                    paddingBottoms[col] = runningAbsHeight;
11709                }
11710            }
11711        }
11712        function placeSeg(seg, segHeight) {
11713            if (!tryPlaceSegAt(seg, segHeight, 0)) {
11714                for (var col = seg.firstCol; col <= seg.lastCol; col++) {
11715                    for (var _i = 0, _a = colPlacements[col]; _i < _a.length; _i++) { // will repeat multi-day segs!!!!!!! bad!!!!!!
11716                        var placement = _a[_i];
11717                        if (tryPlaceSegAt(seg, segHeight, placement.bottom)) {
11718                            return;
11719                        }
11720                    }
11721                }
11722            }
11723        }
11724        function tryPlaceSegAt(seg, segHeight, top) {
11725            if (canPlaceSegAt(seg, segHeight, top)) {
11726                for (var col = seg.firstCol; col <= seg.lastCol; col++) {
11727                    var placements = colPlacements[col];
11728                    var insertionIndex = 0;
11729                    while (insertionIndex < placements.length &&
11730                        top >= placements[insertionIndex].top) {
11731                        insertionIndex++;
11732                    }
11733                    placements.splice(insertionIndex, 0, {
11734                        seg: seg,
11735                        top: top,
11736                        bottom: top + segHeight
11737                    });
11738                }
11739                return true;
11740            }
11741            else {
11742                return false;
11743            }
11744        }
11745        function canPlaceSegAt(seg, segHeight, top) {
11746            for (var col = seg.firstCol; col <= seg.lastCol; col++) {
11747                for (var _i = 0, _a = colPlacements[col]; _i < _a.length; _i++) {
11748                    var placement = _a[_i];
11749                    if (top < placement.bottom && top + segHeight > placement.top) { // collide?
11750                        return false;
11751                    }
11752                }
11753            }
11754            return true;
11755        }
11756        // what does this do!?
11757        for (var instanceIdAndFirstCol in eventHeights) {
11758            if (!eventHeights[instanceIdAndFirstCol]) {
11759                segIsHidden[instanceIdAndFirstCol.split(':')[0]] = true;
11760            }
11761        }
11762        var segsByFirstCol = colPlacements.map(extractFirstColSegs); // operates on the sorted cols
11763        var segsByEachCol = colPlacements.map(function (placements, col) {
11764            var segs = extractAllColSegs(placements);
11765            segs = resliceDaySegs(segs, cellModels[col].date, col);
11766            return segs;
11767        });
11768        return {
11769            segsByFirstCol: segsByFirstCol,
11770            segsByEachCol: segsByEachCol,
11771            segIsHidden: segIsHidden,
11772            segTops: segTops,
11773            segMarginTops: segMarginTops,
11774            moreCnts: moreCnts,
11775            moreTops: moreTops,
11776            paddingBottoms: paddingBottoms
11777        };
11778    }
11779    function extractFirstColSegs(oneColPlacements, col) {
11780        var segs = [];
11781        for (var _i = 0, oneColPlacements_1 = oneColPlacements; _i < oneColPlacements_1.length; _i++) {
11782            var placement = oneColPlacements_1[_i];
11783            if (placement.seg.firstCol === col) {
11784                segs.push(placement.seg);
11785            }
11786        }
11787        return segs;
11788    }
11789    function extractAllColSegs(oneColPlacements) {
11790        var segs = [];
11791        for (var _i = 0, oneColPlacements_2 = oneColPlacements; _i < oneColPlacements_2.length; _i++) {
11792            var placement = oneColPlacements_2[_i];
11793            segs.push(placement.seg);
11794        }
11795        return segs;
11796    }
11797    function limitByMaxHeight(hiddenCnts, segIsHidden, colPlacements, maxContentHeight) {
11798        limitEvents(hiddenCnts, segIsHidden, colPlacements, true, function (placement) {
11799            return placement.bottom <= maxContentHeight;
11800        });
11801    }
11802    function limitByMaxEvents(hiddenCnts, segIsHidden, colPlacements, dayMaxEvents) {
11803        limitEvents(hiddenCnts, segIsHidden, colPlacements, false, function (placement, levelIndex) {
11804            return levelIndex < dayMaxEvents;
11805        });
11806    }
11807    function limitByMaxRows(hiddenCnts, segIsHidden, colPlacements, dayMaxEventRows) {
11808        limitEvents(hiddenCnts, segIsHidden, colPlacements, true, function (placement, levelIndex) {
11809            return levelIndex < dayMaxEventRows;
11810        });
11811    }
11812    /*
11813    populates the given hiddenCnts/segIsHidden, which are supplied empty.
11814    TODO: return them instead
11815    */
11816    function limitEvents(hiddenCnts, segIsHidden, colPlacements, moreLinkConsumesLevel, isPlacementInBounds) {
11817        var colCnt = hiddenCnts.length;
11818        var segIsVisible = {}; // TODO: instead, use segIsHidden with true/false?
11819        var visibleColPlacements = []; // will mirror colPlacements
11820        for (var col = 0; col < colCnt; col++) {
11821            visibleColPlacements.push([]);
11822        }
11823        for (var col = 0; col < colCnt; col++) {
11824            var placements = colPlacements[col];
11825            var level = 0;
11826            for (var _i = 0, placements_2 = placements; _i < placements_2.length; _i++) {
11827                var placement = placements_2[_i];
11828                if (isPlacementInBounds(placement, level)) {
11829                    recordVisible(placement);
11830                }
11831                else {
11832                    recordHidden(placement);
11833                }
11834                // only considered a level if the seg had height
11835                if (placement.top !== placement.bottom) {
11836                    level++;
11837                }
11838            }
11839        }
11840        function recordVisible(placement) {
11841            var seg = placement.seg;
11842            var instanceId = seg.eventRange.instance.instanceId;
11843            if (!segIsVisible[instanceId]) {
11844                segIsVisible[instanceId] = true;
11845                for (var col = seg.firstCol; col <= seg.lastCol; col++) {
11846                    visibleColPlacements[col].push(placement);
11847                }
11848            }
11849        }
11850        function recordHidden(placement) {
11851            var seg = placement.seg;
11852            var instanceId = seg.eventRange.instance.instanceId;
11853            if (!segIsHidden[instanceId]) {
11854                segIsHidden[instanceId] = true;
11855                for (var col = seg.firstCol; col <= seg.lastCol; col++) {
11856                    var hiddenCnt = ++hiddenCnts[col];
11857                    if (moreLinkConsumesLevel && hiddenCnt === 1) {
11858                        var lastVisiblePlacement = visibleColPlacements[col].pop();
11859                        if (lastVisiblePlacement) {
11860                            recordHidden(lastVisiblePlacement);
11861                        }
11862                    }
11863                }
11864            }
11865        }
11866    }
11867    // Given the events within an array of segment objects, reslice them to be in a single day
11868    function resliceDaySegs(segs, dayDate, colIndex) {
11869        var dayStart = dayDate;
11870        var dayEnd = addDays(dayStart, 1);
11871        var dayRange = { start: dayStart, end: dayEnd };
11872        var newSegs = [];
11873        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
11874            var seg = segs_2[_i];
11875            var eventRange = seg.eventRange;
11876            var origRange = eventRange.range;
11877            var slicedRange = intersectRanges(origRange, dayRange);
11878            if (slicedRange) {
11879                newSegs.push(__assign(__assign({}, seg), { firstCol: colIndex, lastCol: colIndex, eventRange: {
11880                        def: eventRange.def,
11881                        ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }),
11882                        instance: eventRange.instance,
11883                        range: slicedRange
11884                    }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }));
11885            }
11886        }
11887        return newSegs;
11888    }
11889
11890    var TableRow = /** @class */ (function (_super) {
11891        __extends(TableRow, _super);
11892        function TableRow() {
11893            var _this = _super !== null && _super.apply(this, arguments) || this;
11894            _this.cellElRefs = new RefMap(); // the <td>
11895            _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame
11896            _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events
11897            _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol"
11898            _this.rootElRef = createRef();
11899            _this.state = {
11900                framePositions: null,
11901                maxContentHeight: null,
11902                segHeights: {}
11903            };
11904            return _this;
11905        }
11906        TableRow.prototype.render = function () {
11907            var _this = this;
11908            var _a = this, props = _a.props, state = _a.state, context = _a.context;
11909            var colCnt = props.cells.length;
11910            var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt);
11911            var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt);
11912            var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt);
11913            var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt);
11914            var _b = computeFgSegPlacement(props.cells, props.fgEventSegs, props.dayMaxEvents, props.dayMaxEventRows, state.segHeights, state.maxContentHeight, colCnt, context.options.eventOrder), paddingBottoms = _b.paddingBottoms, segsByFirstCol = _b.segsByFirstCol, segsByEachCol = _b.segsByEachCol, segIsHidden = _b.segIsHidden, segTops = _b.segTops, segMarginTops = _b.segMarginTops, moreCnts = _b.moreCnts, moreTops = _b.moreTops;
11915            var selectedInstanceHash = // TODO: messy way to compute this
11916             (props.eventDrag && props.eventDrag.affectedInstances) ||
11917                (props.eventResize && props.eventResize.affectedInstances) ||
11918                {};
11919            return (createElement("tr", { ref: this.rootElRef },
11920                props.renderIntro && props.renderIntro(),
11921                props.cells.map(function (cell, col) {
11922                    var normalFgNodes = _this.renderFgSegs(segsByFirstCol[col], segIsHidden, segTops, segMarginTops, selectedInstanceHash, props.todayRange);
11923                    var mirrorFgNodes = _this.renderFgSegs(mirrorSegsByCol[col], {}, segTops, // use same tops as real rendering
11924                    {}, {}, props.todayRange, Boolean(props.eventDrag), Boolean(props.eventResize), false // date-selecting (because mirror is never drawn for date selection)
11925                    );
11926                    return (createElement(TableCell, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), innerElRef: _this.frameElRefs.createRef(cell.key) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */, dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, moreCnt: moreCnts[col], buildMoreLinkText: props.buildMoreLinkText, onMoreClick: props.onMoreClick, segIsHidden: segIsHidden, moreMarginTop: moreTops[col] /* rename */, segsByEachCol: segsByEachCol[col], fgPaddingBottom: paddingBottoms[col], fgContentElRef: _this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys
11927                        createElement(Fragment, null,
11928                            createElement(Fragment, null, normalFgNodes),
11929                            createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys
11930                        createElement(Fragment, null,
11931                            _this.renderFillSegs(highlightSegsByCol[col], 'highlight'),
11932                            _this.renderFillSegs(businessHoursByCol[col], 'non-business'),
11933                            _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) }));
11934                })));
11935        };
11936        TableRow.prototype.componentDidMount = function () {
11937            this.updateSizing(true);
11938        };
11939        TableRow.prototype.componentDidUpdate = function (prevProps, prevState) {
11940            var currentProps = this.props;
11941            this.updateSizing(!isPropsEqual(prevProps, currentProps));
11942        };
11943        TableRow.prototype.getHighlightSegs = function () {
11944            var props = this.props;
11945            if (props.eventDrag && props.eventDrag.segs.length) { // messy check
11946                return props.eventDrag.segs;
11947            }
11948            else if (props.eventResize && props.eventResize.segs.length) { // messy check
11949                return props.eventResize.segs;
11950            }
11951            else {
11952                return props.dateSelectionSegs;
11953            }
11954        };
11955        TableRow.prototype.getMirrorSegs = function () {
11956            var props = this.props;
11957            if (props.eventResize && props.eventResize.segs.length) { // messy check
11958                return props.eventResize.segs;
11959            }
11960            else {
11961                return [];
11962            }
11963        };
11964        TableRow.prototype.renderFgSegs = function (segs, segIsHidden, // does NOT mean display:hidden
11965        segTops, segMarginTops, selectedInstanceHash, todayRange, isDragging, isResizing, isDateSelecting) {
11966            var context = this.context;
11967            var eventSelection = this.props.eventSelection;
11968            var framePositions = this.state.framePositions;
11969            var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1
11970            var nodes = [];
11971            if (framePositions) {
11972                for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
11973                    var seg = segs_1[_i];
11974                    var instanceId = seg.eventRange.instance.instanceId;
11975                    var isMirror = isDragging || isResizing || isDateSelecting;
11976                    var isSelected = selectedInstanceHash[instanceId];
11977                    var isInvisible = segIsHidden[instanceId] || isSelected;
11978                    var isAbsolute = segIsHidden[instanceId] || isMirror || seg.firstCol !== seg.lastCol || !seg.isStart || !seg.isEnd; // TODO: simpler way? NOT DRY
11979                    var marginTop = void 0;
11980                    var top_1 = void 0;
11981                    var left = void 0;
11982                    var right = void 0;
11983                    if (isAbsolute) {
11984                        top_1 = segTops[instanceId];
11985                        if (context.isRtl) {
11986                            right = 0;
11987                            left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol];
11988                        }
11989                        else {
11990                            left = 0;
11991                            right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol];
11992                        }
11993                    }
11994                    else {
11995                        marginTop = segMarginTops[instanceId];
11996                    }
11997                    /*
11998                    known bug: events that are force to be list-item but span multiple days still take up space in later columns
11999                    */
12000                    nodes.push(createElement("div", { className: 'fc-daygri
12000d-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: instanceId, ref: isMirror ? null : this.segHarnessRefs.createRef(instanceId + ':' + seg.firstCol) /* in print mode when in mult cols, could collide */, style: {
12001                            visibility: isInvisible ? 'hidden' : '',
12002                            marginTop: marginTop || '',
12003                            top: top_1 || '',
12004                            left: left || '',
12005                            right: right || ''
12006                        } }, hasListItemDisplay(seg) ?
12007                        createElement(TableListItemEvent, __assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange))) :
12008                        createElement(TableBlockEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))));
12009                }
12010            }
12011            return nodes;
12012        };
12013        TableRow.prototype.renderFillSegs = function (segs, fillType) {
12014            var isRtl = this.context.isRtl;
12015            var todayRange = this.props.todayRange;
12016            var framePositions = this.state.framePositions;
12017            var nodes = [];
12018            if (framePositions) {
12019                for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
12020                    var seg = segs_2[_i];
12021                    var leftRightCss = isRtl ? {
12022                        right: 0,
12023                        left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol]
12024                    } : {
12025                        left: 0,
12026                        right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol],
12027                    };
12028                    nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: 'fc-daygrid-bg-harness', style: leftRightCss }, fillType === 'bg-event' ?
12029                        createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) :
12030                        renderFill(fillType)));
12031                }
12032            }
12033            return createElement.apply(void 0, __spreadArrays([Fragment, {}], nodes));
12034        };
12035        TableRow.prototype.updateSizing = function (isExternalSizingChange) {
12036            var _a = this, props = _a.props, frameElRefs = _a.frameElRefs;
12037            if (props.clientWidth !== null) { // positioning ready?
12038                if (isExternalSizingChange) {
12039                    var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; });
12040                    if (frameEls.length) {
12041                        var originEl = this.rootElRef.current;
12042                        this.setState({
12043                            framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal
12044                            false)
12045                        });
12046                    }
12047                }
12048                var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
12049                this.setState({
12050                    segHeights: this.computeSegHeights(),
12051                    maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null
12052                });
12053            }
12054        };
12055        TableRow.prototype.computeSegHeights = function () {
12056            return mapHash(this.segHarnessRefs.currentMap, function (eventHarnessEl) { return (eventHarnessEl.getBoundingClientRect().height); });
12057        };
12058        TableRow.prototype.computeMaxContentHeight = function () {
12059            var firstKey = this.props.cells[0].key;
12060            var cellEl = this.cellElRefs.currentMap[firstKey];
12061            var fcContainerEl = this.fgElRefs.currentMap[firstKey];
12062            return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top;
12063        };
12064        TableRow.prototype.getCellEls = function () {
12065            var elMap = this.cellElRefs.currentMap;
12066            return this.props.cells.map(function (cell) { return elMap[cell.key]; });
12067        };
12068        return TableRow;
12069    }(DateComponent));
12070    TableRow.addStateEquality({
12071        segHeights: isPropsEqual
12072    });
12073
12074    var PADDING_FROM_VIEWPORT = 10;
12075    var SCROLL_DEBOUNCE = 10;
12076    var Popover = /** @class */ (function (_super) {
12077        __extends(Popover, _super);
12078        function Popover() {
12079            var _this = _super !== null && _super.apply(this, arguments) || this;
12080            _this.repositioner = new DelayedRunner(_this.updateSize.bind(_this));
12081            _this.handleRootEl = function (el) {
12082                _this.rootEl = el;
12083                if (_this.props.elRef) {
12084                    setRef(_this.props.elRef, el);
12085                }
12086            };
12087            // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
12088            _this.handleDocumentMousedown = function (ev) {
12089                var onClose = _this.props.onClose;
12090                // only hide the popover if the click happened outside the popover
12091                if (onClose && !_this.rootEl.contains(ev.target)) {
12092                    onClose();
12093                }
12094            };
12095            _this.handleDocumentScroll = function () {
12096                _this.repositioner.request(SCROLL_DEBOUNCE);
12097            };
12098            _this.handleCloseClick = function () {
12099                var onClose = _this.props.onClose;
12100                if (onClose) {
12101                    onClose();
12102                }
12103            };
12104            return _this;
12105        }
12106        Popover.prototype.render = function () {
12107            var theme = this.context.theme;
12108            var props = this.props;
12109            var classNames = [
12110                'fc-popover',
12111                theme.getClass('popover')
12112            ].concat(props.extraClassNames || []);
12113            return (createElement("div", __assign({ className: classNames.join(' ') }, props.extraAttrs, { ref: this.handleRootEl }),
12114                createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') },
12115                    createElement("span", { className: 'fc-popover-title' }, props.title),
12116                    createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), onClick: this.handleCloseClick })),
12117                createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)));
12118        };
12119        Popover.prototype.componentDidMount = function () {
12120            document.addEventListener('mousedown', this.handleDocumentMousedown);
12121            document.addEventListener('scroll', this.handleDocumentScroll);
12122            this.updateSize();
12123        };
12124        Popover.prototype.componentWillUnmount = function () {
12125            document.removeEventListener('mousedown', this.handleDocumentMousedown);
12126            document.removeEventListener('scroll', this.handleDocumentScroll);
12127        };
12128        // TODO: adjust on window resize
12129        /*
12130        NOTE: the popover is position:fixed, so coordinates are relative to the viewport
12131        NOTE: the PARENT calls this as well, on window resize. we would have wanted to use the repositioner,
12132              but need to ensure that all other components have updated size first (for alignmentEl)
12133        */
12134        Popover.prototype.updateSize = function () {
12135            var _a = this.props, alignmentEl = _a.alignmentEl, topAlignmentEl = _a.topAlignmentEl;
12136            var rootEl = this.rootEl;
12137            if (!rootEl) {
12138                return;
12138 // not sure why this was null, but we shouldn't let external components call updateSize() anyway
12139            }
12140            var dims = rootEl.getBoundingClientRect(); // only used for width,height
12141            var alignment = alignmentEl.getBoundingClientRect();
12142            var top = topAlignmentEl ? topAlignmentEl.getBoundingClientRect().top : alignment.top;
12143            top = Math.min(top, window.innerHeight - dims.height - PADDING_FROM_VIEWPORT);
12144            top = Math.max(top, PADDING_FROM_VIEWPORT);
12145            var left;
12146            if (this.context.isRtl) {
12147                left = alignment.right - dims.width;
12148            }
12149            else {
12150                left = alignment.left;
12151            }
12152            left = Math.min(left, window.innerWidth - dims.width - PADDING_FROM_VIEWPORT);
12153            left = Math.max(left, PADDING_FROM_VIEWPORT);
12154            applyStyle(rootEl, { top: top, left: left });
12155        };
12156        return Popover;
12157    }(BaseComponent));
12158
12159    var MorePopover = /** @class */ (function (_super) {
12160        __extends(MorePopover, _super);
12161        function MorePopover() {
12162            var _this = _super !== null && _super.apply(this, arguments) || this;
12163            _this.handlePopoverEl = function (popoverEl) {
12164                _this.popoverEl = popoverEl;
12165                if (popoverEl) {
12166                    _this.context.registerInteractiveComponent(_this, {
12167                        el: popoverEl,
12168                        useEventCenter: false
12169                    });
12170                }
12171                else {
12172                    _this.context.unregisterInteractiveComponent(_this);
12173                }
12174            };
12175            return _this;
12176        }
12177        MorePopover.prototype.render = function () {
12178            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv;
12179            var props = this.props;
12180            var date = props.date, hiddenInstances = props.hiddenInstances, todayRange = props.todayRange, dateProfile = props.dateProfile, selectedInstanceId = props.selectedInstanceId;
12181            var title = dateEnv.format(date, options.dayPopoverFormat);
12182            return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: todayRange, elRef: this.handlePopoverEl }, function (rootElRef, dayClassNames, dataAttrs) { return (createElement(Popover, { elRef: rootElRef, title: title, extraClassNames: ['fc-more-popover'].concat(dayClassNames), extraAttrs: dataAttrs, onClose: props.onCloseClick, alignmentEl: props.alignmentEl, topAlignmentEl: props.topAlignmentEl },
12183                createElement(DayCellContent, { date: date, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent &&
12184                    createElement("div", { className: 'fc-more-popover-misc', ref: innerElRef }, innerContent)); }),
12185                props.segs.map(function (seg) {
12186                    var instanceId = seg.eventRange.instance.instanceId;
12187                    return (createElement("div", { className: 'fc-daygrid-event-harness', key: instanceId, style: {
12188                            visibility: hiddenInstances[instanceId] ? 'hidden' : ''
12189                        } }, hasListItemDisplay(seg) ?
12190                        createElement(TableListItemEvent, __assign({ seg: seg, isDragging: false, isSelected: instanceId === selectedInstanceId, defaultDisplayEventEnd: false }, getSegMeta(seg, todayRange))) :
12191                        createElement(TableBlockEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === selectedInstanceId, defaultDisplayEventEnd: false }, getSegMeta(seg, todayRange)))));
12192                }))); }));
12193        };
12194        MorePopover.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
12195            var date = this.props.date;
12196            if (positionLeft < elWidth && positionTop < elHeight) {
12197                return {
12198                    component: this,
12199                    dateSpan: {
12200                        allDay: true,
12201                        range: { start: date, end: addDays(date, 1) }
12202                    },
12203                    dayEl: this.popoverEl,
12204                    rect: {
12205                        left: 0,
12206                        top: 0,
12207                        right: elWidth,
12208                        bottom: elHeight
12209                    },
12210                    layer: 1
12211                };
12212            }
12213        };
12214        MorePopover.prototype.isPopover = function () {
12215            return true; // gross
12216        };
12217        return MorePopover;
12218    }(DateComponent));
12219
12220    var Table = /** @class */ (function (_super) {
12221        __extends(Table, _super);
12222        function Table() {
12223            var _this = _super !== null && _super.apply(this, arguments) || this;
12224            _this.splitBusinessHourSegs = memoize(splitSegsByRow);
12225            _this.splitBgEventSegs = memoize(splitSegsByRow);
12226            _this.splitFgEventSegs = memoize(splitSegsByRow);
12227            _this.splitDateSelectionSegs = memoize(splitSegsByRow);
12228            _this.splitEventDrag = memoize(splitInteractionByRow);
12229            _this.splitEventResize = memoize(splitInteractionByRow);
12230            _this.buildBuildMoreLinkText = memoize(buildBuildMoreLinkText);
12231            _this.rowRefs = new RefMap();
12232            _this.state = {
12233                morePopoverState: null
12234            };
12235            _this.handleRootEl = function (rootEl) {
12236                _this.rootEl = rootEl;
12237                setRef(_this.props.elRef, rootEl);
12238            };
12239            _this.handleMoreLinkClick = function (arg) {
12240                var context = _this.context;
12241                var dateEnv = context.dateEnv;
12242                var clickOption = context.options.moreLinkClick;
12243                function segForPublic(seg) {
12244                    var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range;
12245                    return {
12246                        event: new EventApi(context, def, instance),
12247                        start: dateEnv.toDate(range.start),
12248                        end: dateEnv.toDate(range.end),
12249                        isStart: seg.isStart,
12250                        isEnd: seg.isEnd
12251                    };
12252                }
12253                if (typeof clickOption === 'function') {
12254                    clickOption = clickOption({
12255                        date: dateEnv.toDate(arg.date),
12256                        allDay: true,
12257                        allSegs: arg.allSegs.map(segForPublic),
12258                        hiddenSegs: arg.hiddenSegs.map(segForPublic),
12259                        jsEvent: arg.ev,
12260                        view: context.viewApi
12261                    }); // hack to handle void
12262                }
12263                if (!clickOption || clickOption === 'popover') {
12264                    _this.setState({
12265                        morePopoverState: __assign(__assign({}, arg), { currentFgEventSegs: _this.props.fgEventSegs })
12266                    });
12267                }
12268                else if (typeof clickOption === 'string') { // a view n
12268ame
12269                    context.calendarApi.zoomTo(arg.date, clickOption);
12270                }
12271            };
12272            _this.handleMorePopoverClose = function () {
12273                _this.setState({
12274                    morePopoverState: null
12275                });
12276            };
12277            return _this;
12278        }
12279        Table.prototype.render = function () {
12280            var _this = this;
12281            var props = this.props;
12282            var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows;
12283            var morePopoverState = this.state.morePopoverState;
12284            var rowCnt = props.cells.length;
12285            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
12286            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
12287            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);
12288            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);
12289            var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);
12290            var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
12291            var buildMoreLinkText = this.buildBuildMoreLinkText(this.context.options.moreLinkText);
12292            var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true;
12293            // if rows can't expand to fill fixed height, can't do balanced-height event limit
12294            // TODO: best place to normalize these options?
12295            if (limitViaBalanced && !expandRows) {
12296                limitViaBalanced = false;
12297                dayMaxEventRows = null;
12298                dayMaxEvents = null;
12299            }
12300            var classNames = [
12301                'fc-daygrid-body',
12302                limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced',
12303                expandRows ? '' : 'fc-daygrid-body-natural' // will height of one row depend on the others?
12304            ];
12305            return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: {
12306                    // these props are important to give this wrapper correct dimensions for interactions
12307                    // TODO: if we set it here, can we avoid giving to inner tables?
12308                    width: props.clientWidth,
12309                    minWidth: props.tableMinWidth
12310                } },
12311                createElement(NowTimer, { unit: 'day' }, function (nowDate, todayRange) { return (createElement(Fragment, null,
12312                    createElement("table", { className: 'fc-scrollgrid-sync-table', style: {
12313                            width: props.clientWidth,
12314                            minWidth: props.tableMinWidth,
12315                            height: expandRows ? props.clientHeight : ''
12316                        } },
12317                        props.colGroupNode,
12318                        createElement("tbody", null, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length
12319                                ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */
12320                                : row // in case there are no cells (like when resource view is loading)
12321                            , showDayNumbers: rowCnt > 1, showWeekNumbers: props.showWeekNumbers, todayRange: todayRange, dateProfile: dateProfile, cells: cells, renderIntro: props.renderRowIntro, businessHourSegs: businessHourSegsByRow[row], eventSelection: props.eventSelection, bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, fgEventSegs: fgEventSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows, clientWidth: props.clientWidth, clientHeight: props.clientHeight, buildMoreLinkText: buildMoreLinkText, onMoreClick: _this.handleMoreLinkClick })); }))),
12322                    (!props.forPrint && morePopoverState && morePopoverState.currentFgEventSegs === props.fgEventSegs) && // clear popover on event mod
12323                        createElement(MorePopover, { date: morePopoverState.date, dateProfile: dateProfile, segs: morePopoverState.allSegs, alignmentEl: morePopoverState.dayEl, topAlignmentEl: rowCnt === 1 ? props.headerAlignElRef.current : null, onCloseClick: _this.handleMorePopoverClose, selectedInstanceId: props.eventSelection, hiddenInstances: // yuck
12324                            (props.eventDrag ? props.eventDrag.affectedInstances : null) ||
12325                                (props.eventResize ? props.eventResize.affectedInstances : null) ||
12326                                {}, todayRange: todayRange }))); })));
12327        };
12328        // Hit System
12329        // ----------------------------------------------------------------------------------------------------
12330        Table.prototype.prepareHits = function () {
12331            this.rowPositions = new PositionCache(this.rootEl, this.rowRefs.collect().map(function (rowObj) { return rowObj.getCellEls()[0]; }), // first cell el in each row. TODO: not optimal
12332            false, true // vertical
12333            );
12334            this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row
12335            true, // horizontal
12336            false);
12337        };
12338        Table.prototype.positionToHit = function (leftPosition, topPosition) {
12339            var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
12340            var col = colPositions.leftToIndex(leftPosition);
12341            var row = rowPositions.topToIndex(topPosition);
12342            if (row != null && col != null) {
12343                return {
12344                    row: row,
12345                    col: col,
12346                    dateSpan: {
12347                        range: this.getCellRange(row, col),
12348                        allDay: true
12349                    },
12350                    dayEl: this.getCellEl(row, col),
12351                    relativeRect: {
12352                        left: colPositions.lefts[col],
12353                        right: colPositions.rights[col],
12354                        top: rowPositions.tops[row],
12355                        bottom: rowPositions.bottoms[row]
12356                    }
12357                };
12358            }
12359        };
12360        Table.prototype.getCellEl = function (row, col) {
12361            return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal
12362        };
12363        Table.prototype.getCellRange = function (row, col) {
12364            var start = this.props.cells[row][col].date;
12365            var end = addDays(start, 1);
12366            return { start: start, end: end };
12367        };
12368        return Table;
12369    }(DateComponent));
12370    function buildBuildMoreLinkText(moreLinkTextInput) {
12371        if (typeof moreLinkTextInput === 'function') {
12372            return moreLinkTextInput;
12373        }
12374        else {
12375            return function (num) {
12376                return "+" + num + " " + moreLinkTextInput;
12377            };
12378        }
12379    }
12380    function isSegAllDay(seg) {
12381        return seg.eventRange.def.allDay;
12382    }
12383
12384    var DayTable = /** @class */ (function (_super) {
12385        __extends(DayTable, _super);
12386        function DayTable() {
12387            var _this = _super !== null && _super.apply(this, arguments) || this;
12388            _this.slicer = new DayTableSlicer();
12389            _this.tableRef = createRef();
12390            _this.handleRootEl = function (rootEl) {
12391                if (rootEl) {
12392                    _this.context.registerInteractiveComponent(_this, { el: rootEl });
12393                }
12394                else {
12395                    _this.context.unregisterInteractiveComponent(_this);
12396                }
12397            };
12398            return _this;
12399        }
12400        DayTable.prototype.render = function () {
12401            var _a = this, props = _a.props, context = _a.context;
12402            return (createElement(Table, __assign({ ref: this.tableRef, elRef: this.handleRootEl }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })));
12403        };
12404        DayTable.prototype.prepareHits = function () {
12405            this.tableRef.current.prepareHits();
12406        };
12407        DayTable.prototype.queryHit = function (positionLeft, positionTop) {
12408            var rawHit = this.tableRef.current.positionToHit(positionLeft, positionTop);
12409            if (rawHit) {
12410                return {
12411                    component: this,
12412                    dateSpan: rawHit.dateSpan,
12413                    dayEl: rawHit.dayEl,
12414                    rect: {
12415                        left: rawHit.relativeRect.left,
12416                        right: rawHit.relativeRect.right,
12417                        top: rawHit.relativeRect.top,
12418                        bottom: rawHit.relativeRect.bottom
12419                    },
12420                    layer: 0
12421                };
12422            }
12423        };
12424        return DayTable;
12425    }(DateComponent));
12426    var DayTableSlicer = /** @class */ (function (_super) {
12427        __extends(DayTableSlicer, _super);
12428        function DayTableSlicer() {
12429            var _this = _super !== null && _super.apply(this, arguments) || this;
12430            _this.forceDayIfListItem = true;
12431            return _this;
12432        }
12433        DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) {
12434            return dayTableModel.sliceRange(dateRange);
12435        };
12436        return DayTableSlicer;
12437    }(Slicer));
12438
12439    var DayTableView = /** @class */ (function (_super) {
12440        __extends(DayTableView, _super);
12441        function DayTableView() {
12442            var _this = _super !== null && _super.apply(this, arguments) || this;
12443            _this.buildDayTableModel = memoize(buildDayTableModel);
12444            _this.headerRef = createRef();
12445            _this.tableRef = createRef();
12446            return _this;
12447        }
12448        DayTableView.prototype.render = function () {
12449            var _this = this;
12450            var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator;
12451            var props = this.props;
12452            var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator);
12453            var headerContent = options.dayHeaders &&
12454                createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 });
12455            var bodyContent = function (contentArg) { return (createElement(DayTable, { ref: _this.tableRef, dateProfile: props.dateProfile, dayTableModel: dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint })); };
12456            return options.dayMinWidth
12457                ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth)
12458                : this.renderSimpleLayout(headerContent, bodyContent);
12459        };
12460        return DayTableView;
12461    }(TableView));
12462    function buildDayTableModel(dateProfile, dateProfileGenerator) {
12463        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
12464        return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
12465    }
12466
12467    var TableDateProfileGenerator = /** @class */ (function (_super) {
12468        __extends(TableDateProfileGenerator, _super);
12469        function TableDateProfileGenerator() {
12470            return _super !== null && _super.apply(this, arguments) || this;
12471        }
12472        // Computes the date range that will be rendered.
12473        TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
12474            var dateEnv = this.props.dateEnv;
12475            var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
12476            var start = renderRange.start;
12477            var end = renderRange.end;
12478            var endOfWeek;
12479            // year and month views should be aligned with weeks. this is already done for week
12480            if (/^(year|month)$/.test(currentRangeUnit)) {
12481                start = dateEnv.startOfWeek(start);
12482                // make end-of-week if not already
12483                endOfWeek = dateEnv.startOfWeek(end);
12484                if (endOfWeek.valueOf() !== end.valueOf()) {
12485                    end = addWeeks(endOfWeek, 1);
12486                }
12487            }
12488            // ensure 6 weeks
12489            if (this.props.monthMode &&
12490                this.props.fixedWeekCount) {
12491                var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
12492                diffWeeks(start, end));
12493                end = addWeeks(end, 6 - rowCnt);
12494            }
12495            return { start: start, end: end };
12496        };
12497        return TableDateProfileGenerator;
12498    }(DateProfileGenerator));
12499
12500    var OPTION_REFINERS = {
12501        moreLinkClick: identity,
12502        moreLinkClassNames: identity,
12503        moreLinkContent: identity,
12504        moreLinkDidMount: identity,
12505        moreLinkWillUnmount: identity,
12506    };
12507
12508    var dayGridPlugin = createPlugin({
12509        initialView: 'dayGridMonth',
12510        optionRefiners: OPTION_REFINERS,
12511        views: {
12512            dayGrid: {
12513                component: DayTableView,
12514                dateProfileGeneratorClass: TableDateProfileGenerator
12515            },
12516            dayGridDay: {
12517                type: 'dayGrid',
12518                duration: { days: 1 }
12519            },
12520            dayGridWeek: {
12521                type: 'dayGrid',
12522                duration: { weeks: 1 }
12523            },
12524            dayGridMonth: {
12525                type: 'dayGrid',
12526                duration: { months: 1 },
12527                monthMode: true,
12528                fixedWeekCount: true
12529            }
12530        }
12531    });
12532
12533    var AllDaySplitter = /** @class */ (function (_super) {
12534        __extends(AllDaySplitter, _super);
12535        function AllDaySplitter() {
12536            return _super !== null && _super.apply(this, arguments) || this;
12537        }
12538        AllDaySplitter.prototype.getKeyInfo = function () {
12539            return {
12540                allDay: {},
12541                timed: {}
12542            };
12543        };
12544        AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
12545            if (dateSpan.allDay) {
12546                return ['allDay'];
12547            }
12548            else {
12549                return ['timed'];
12550            }
12551        };
12552        AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
12553            if (!eventDef.allDay) {
12554                return ['timed'];
12555            }
12556            else if (hasBgRendering(eventDef)) {
12557                return ['timed', 'allDay'];
12558            }
12559            else {
12560                return ['allDay'];
12561            }
12562        };
12563        return AllDaySplitter;
12564    }(Splitter));
12565
12566    var TimeColsSlatsCoords = /** @class */ (function () {
12567        function TimeColsSlatsCoords(positions, dateProfile, slatMetas) {
12568            this.positions = positions;
12569            this.dateProfile = dateProfile;
12570            this.slatMetas = slatMetas;
12571        }
12572        TimeColsSlatsCoords.prototype.safeComputeTop = function (date) {
12573            var dateProfile = this.dateProfile;
12574            if (rangeContainsMarker(dateProfile.currentRange, date)) {
12575                var startOfDayDate = startOfDay(date);
12576                var timeMs = date.valueOf() - startOfDayDate.valueOf();
12577                if (timeMs >= asRoughMs(dateProfile.slotMinTime) &&
12578                    timeMs < asRoughMs(dateProfile.slotMaxTime)) {
12579                    return this.computeTimeTop(createDuration(timeMs));
12580                }
12581            }
12582        };
12583        // Computes the top coordinate, relative to the bounds of the grid, of the given date.
12584        // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
12585        TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) {
12586            if (!startOfDayDate) {
12587                startOfDayDate = startOfDay(when);
12588            }
12589            return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf()));
12590        };
12591        // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
12592        // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.
12593        // Eventually allow computation with arbirary slat dates.
12594        TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) {
12595            var _a = this, positions = _a.positions, dateProfile = _a.dateProfile, slatMetas = _a.slatMetas;
12596            var len = positions.els.length;
12597            var slotDurationMs = slatMetas[1].date.valueOf() - slatMetas[0].date.valueOf(); // we assume dates are uniform
12598            var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / slotDurationMs; // floating-point value of # of slots covered
12599            var slatIndex;
12600            var slatRemainder;
12601            // compute a floating-point number for how many slats should be progressed through.
12602            // from 0 to number of slats (inclusive)
12603            // constrained because slotMinTime/slotMaxTime might be customized.
12604            slatCoverage = Math.max(0, slatCoverage);
12605            slatCoverage = Math.min(len, slatCoverage);
12606            // an integer index of the furthest whole slat
12607            // from 0 to number slats (*exclusive*, so len-1)
12608            slatIndex = Math.floor(slatCoverage);
12609            slatIndex = Math.min(slatIndex, len - 1);
12610            // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
12611            // could be 1.0 if slatCoverage is covering *all* the slots
12612            slatRemainder = slatCoverage - slatIndex;
12613            return positions.tops[slatIndex] +
12614                positions.getHeight(slatIndex) * slatRemainder;
12615        };
12616        return TimeColsSlatsCoords;
12617    }());
12618
12619    // potential nice values for the slot-duration and interval-duration
12620    // from largest to smallest
12621    var STOCK_SUB_DURATIONS = [
12622        { hours: 1 },
12623        { minutes: 30 },
12624        { minutes: 15 },
12625        { seconds: 30 },
12626        { seconds: 15 }
12627    ];
12628    /*
12629    for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
12630    */
12631    var TimeColsSlats = /** @class */ (function (_super) {
12632        __extends(TimeColsSlats, _super);
12633        function TimeColsSlats() {
12634            var _this = _super !== null && _super.apply(this, arguments) || this;
12635            _this.rootElRef = createRef();
12636            _this.slatElRefs = new RefMap();
12637            return _this;
12638        }
12639        TimeColsSlats.prototype.render = function () {
12640            var _a = this, props = _a.props, context = _a.context;
12641            return (createElement("div", { className: 'fc-timegrid-slots', ref: this.rootElRef },
12642                createElement("table", { className: context.theme.getClass('table'), style: {
12643                        minWidth: props.tableMinWidth,
12644                        width: props.clientWidth,
12645                        height: props.minHeight
12646                    } },
12647                    props.tableColGroupNode /* relies on there only being a single <col> for the axis */,
12648                    createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));
12649        };
12650        TimeColsSlats.prototype.componentDidMount = function () {
12651            this.updateSizing();
12652        };
12653        TimeColsSlats.prototype.componentDidUpdate = function () {
12654            this.updateSizing();
12655        };
12656        TimeColsSlats.prototype.componentWillUnmount = function () {
12657            if (this.props.onCoords) {
12658                this.props.onCoords(null);
12659            }
12660        };
12661        TimeColsSlats.prototype.updateSizing = function () {
12662            var props = this.props;
12663            if (props.onCoords &&
12664                props.clientWidth !== null // means sizing has stabilized
12665            ) {
12666                var rootEl = this.rootElRef.current;
12667                if (rootEl.offsetHeight) { // not hidden by css
12668                    props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true // vertical
12669                    ), this.props.dateProfile, props.slatMetas));
12670                }
12671            }
12672        };
12673        return TimeColsSlats;
12674    }(BaseComponent));
12675    function collectSlatEls(elMap, slatMetas) {
12676        return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; });
12677    }
12678    var TimeColsSlatsBody = /** @class */ (function (_super) {
12679        __extends(TimeColsSlatsBody, _super);
12680        function TimeColsSlatsBody() {
12681            return _super !== null && _super.apply(this, arguments) || this;
12682        }
12683        TimeColsSlatsBody.prototype.render = function () {
12684            var _a = this, props = _a.props, context = _a.context;
12685            var options = context.options;
12686            var slatElRefs = props.slatElRefs;
12687            return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) {
12688                var hookProps = {
12689                    time: slatMeta.time,
12690                    date: context.dateEnv.toDate(slatMeta.date),
12691                    view: context.viewApi
12692                };
12693                var classNames = [
12694                    'fc-timegrid-slot',
12695                    'fc-timegrid-slot-lane',
12696                    slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor'
12697                ];
12698                return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },
12699                    props.axis &&
12700                        createElement(TimeColsAxisCell, __assign({}, slatMeta)),
12701                    createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLaneClassNames, content: options.slotLaneContent, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); })));
12702            })));
12703        };
12704        return TimeColsSlatsBody;
12705    }(BaseComponent));
12706    var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({
12707        hour: 'numeric',
12708        minute: '2-digit',
12709        omitZeroMinute: true,
12710        meridiem: 'short'
12711    });
12712    function TimeColsAxisCell(props) {
12713        var classNames = [
12714            'fc-timegrid-slot',
12715            'fc-timegrid-slot-label',
12716            props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor'
12717        ];
12718        return (createElement(ViewContextType.Consumer, null, function (context) {
12719            if (!props.isLabeled) {
12720                return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr }));
12721            }
12722            else {
12723                var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi;
12724                var labelFormat = // TODO: fully pre-parse
12725                 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :
12726                    Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) :
12727                        createFormatter(options.slotLabelFormat);
12728                var hookProps = {
12729                    level: 0,
12730                    time: props.time,
12731                    date: dateEnv.toDate(props.date),
12732                    view: viewApi,
12733                    text: dateEnv.format(props.date, labelFormat)
12734                };
12735                return (createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent$3, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
12735oncat(customClassNames).join(' '), "data-time": props.isoTimeStr },
12736                    createElement("div", { className: 'fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame' },
12737                        createElement("div", { className: 'fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion', ref: innerElRef }, innerContent)))); }));
12738            }
12739        }));
12740    }
12741    function renderInnerContent$3(props) {
12742        return props.text;
12743    }
12744    function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {
12745        var dayStart = new Date(0);
12746        var slatTime = slotMinTime;
12747        var slatIterator = createDuration(0);
12748        var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);
12749        var metas = [];
12750        while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) {
12751            var date = dateEnv.add(dayStart, slatTime);
12752            var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null;
12753            metas.push({
12754                date: date,
12755                time: slatTime,
12756                key: date.toISOString(),
12757                isoTimeStr: formatIsoTimeString(date),
12758                isLabeled: isLabeled
12759            });
12760            slatTime = addDurations(slatTime, slotDuration);
12761            slatIterator = addDurations(slatIterator, slotDuration);
12762        }
12763        return metas;
12764    }
12765    // Computes an automatic value for slotLabelInterval
12766    function computeLabelInterval(slotDuration) {
12767        var i;
12768        var labelInterval;
12769        var slotsPerLabel;
12770        // find the smallest stock label interval that results in more than one slots-per-label
12771        for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
12772            labelInterval = createDuration(STOCK_SUB_DURATIONS[i]);
12773            slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
12774            if (slotsPerLabel !== null && slotsPerLabel > 1) {
12775                return labelInterval;
12776            }
12777        }
12778        return slotDuration; // fall back
12779    }
12780
12781    var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'short' });
12782    var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;
12783    var TimeColsView = /** @class */ (function (_super) {
12784        __extends(TimeColsView, _super);
12785        function TimeColsView() {
12786            var _this = _super !== null && _super.apply(this, arguments) || this;
12787            _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses
12788            _this.headerElRef = createRef();
12789            _this.rootElRef = createRef();
12790            _this.scrollerElRef = createRef();
12791            _this.state = {
12792                slatCoords: null
12793            };
12794            _this.handleScrollTopRequest = function (scrollTop) {
12795                var scrollerEl = _this.scrollerElRef.current;
12796                if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer
12797                    scrollerEl.scrollTop = scrollTop;
12798                }
12799            };
12800            /* Header Render Methods
12801            ------------------------------------------------------------------------------------------------------------------*/
12802            _this.renderHeadAxis = function (frameHeight) {
12803                if (frameHeight === void 0) { frameHeight = ''; }
12804                var options = _this.context.options;
12805                var dateProfile = _this.props.dateProfile;
12806                var range = dateProfile.renderRange;
12807                var dayCnt = diffDays(range.start, range.end);
12808                var navLinkAttrs = (options.navLinks && dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it)
12809                    ? { 'data-navlink': buildNavLinkData(range.start, 'week'), tabIndex: 0 }
12810                    : {};
12811                if (options.weekNumbers) {
12812                    return (createElement(WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("th", { ref: rootElRef, className: [
12813                            'fc-timegrid-axis',
12814                            'fc-scrollgrid-shrink'
12815                        ].concat(classNames).join(' ') },
12816                        createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid', style: { height: frameHeight } },
12817                            createElement("a", __assign({ ref: innerElRef, className: 'fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner' }, navLinkAttrs), innerContent)))); }));
12818                }
12819                return (createElement("th", { className: 'fc-timegrid-axis' },
12820                    createElement("div", { className: 'fc-timegrid-axis-frame', style: { height: frameHeight } })));
12821            };
12822            /* Table Component Render Methods
12823            ------------------------------------------------------------------------------------------------------------------*/
12824            // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,
12825            // but DayGrid still needs to have classNames on inner elements in order to measure.
12826            _this.renderTableRowAxis = function (rowHeight) {
12827                var _a = _this.context, options = _a.options, viewApi = _a.viewApi;
12828                var hookProps = {
12829                    text: options.allDayText,
12830                    view: viewApi
12831                };
12832                return (
12833                // TODO: make reusable hook. used in list view too
12834                createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: [
12835                        'fc-timegrid-axis',
12836                        'fc-scrollgrid-shrink'
12837                    ].concat(classNames).join(' ') },
12838                    createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } },
12839                        createElement("span", { className: 'fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner', ref: innerElRef }, innerContent)))); }));
12840            };
12841            _this.handleSlatCoords = function (slatCoords) {
12842                _this.setState({ slatCoords: slatCoords });
12843            };
12844            return _this;
12845        }
12846        // rendering
12847        // ----------------------------------------------------------------------------------------------------
12848        TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) {
12849            var _a = this, context = _a.context, props = _a.props;
12850            var sections = [];
12851            var stickyHeaderDates = getStickyHeaderDates(context.options);
12852            if (headerRowContent) {
12853                sections.push({
12854                    type: 'header',
12855                    key: 'header',
12856                    isSticky: stickyHeaderDates,
12857                    chunk: {
12858                        elRef: this.headerElRef,
12859                        tableClassName: 'fc-col-header',
12860                        rowContent: headerRowContent
12861                    }
12862                });
12863            }
12864            if (allDayContent) {
12865                sections.push({
12866                    type: 'body',
12867                    key: 'all-day',
12868                    chunk: { content: allDayContent }
12869                });
12870                sections.push({
12871                    type: 'body',
12872                    key: 'all-day-divider',
12873                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
12874                    createElement("tr", { className: 'fc-scrollgrid-section' },
12875                        createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') })))
12876                });
12877            }
12878            sections.push({
12879                type: 'body',
12880                key: 'body',
12881                liquid: true,
12882                expandRows: Boolean(context.options.expandRows),
12883                chunk: {
12884                    scrollerElRef: this.scrollerElRef,
12885                    content: timeContent
12886                }
12887            });
12888            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
12889                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); }));
12890        };
12891        TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords // yuck
12892        ) {
12893            var _this = this;
12894            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
12895            if (!ScrollGrid) {
12896                throw new Error('No ScrollGrid implementation');
12897            }
12898            var _a = this, context = _a.context, props = _a.props;
12899            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
12900            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
12901            var sections = [];
12902            if (headerRowContent) {
12903                sections.push({
12904                    type: 'header',
12905                    key: 'header',
12906                    isSticky: stickyHeaderDates,
12907                    syncRowHeights: true,
12908                    chunks: [
12909                        {
12910                            key: 'axis',
12911                            rowContent: function (arg) { return (createElement("tr", null, _this.renderHeadAxis(arg.rowSyncHeights[0]))); }
12912                        },
12913                        {
12914                            key: 'cols',
12915                            elRef: this.headerElRef,
12916                            tableClassName: 'fc-col-header',
12917                            rowContent: headerRowContent
12918                        }
12919                    ]
12920                });
12921            }
12922            if (allDayContent) {
12923                sections.push({
12924                    type: 'body',
12925                    key: 'all-day',
12926                    syncRowHeights: true,
12927                    chunks: [
12928                        {
12929                            key: 'axis',
12930                            rowContent: function (contentArg) { return (createElement("tr", null, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); },
12931                        },
12932                        {
12933                            key: 'cols',
12934                            content: allDayContent
12935                        }
12936                    ]
12937                });
12938                sections.push({
12939                    key: 'all-day-divider',
12940                    type: 'body',
12941                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
12942                    createElement("tr", { className: 'fc-scrollgrid-section' },
12943                        createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') })))
12944                });
12945            }
12946            var isNowIndicator = context.options.nowIndicator;
12947            sections.push({
12948                type: 'body',
12949                key: 'body',
12950                liquid: true,
12951                expandRows: Boolean(context.options.expandRows),
12952                chunks: [
12953                    {
12954                        key: 'axis',
12955                        content: function (arg) {
12956                            // TODO: make this now-indicator arrow more DRY with TimeColsContent
12957                            return (createElement("div", { className: 'fc-timegrid-axis-chunk' },
12958                                createElement("table", { style: { height: arg.expandRows ? arg.clientHeight : '' } },
12959                                    arg.tableColGroupNode,
12960                                    createElement("tbody", null,
12961                                        createElement(TimeBodyAxis, { slatMetas: slatMetas }))),
12962                                createElement("div", { className: 'fc-timegrid-now-indicator-container' },
12963                                    createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) {
12964                                        var nowIndicatorTop = isNowIndicator &&
12965                                            slatCoords &&
12966                                            slatCoords.safeComputeTop(nowDate); // might return void
12967                                        if (typeof nowIndicatorTop === 'number') {
12968                                            return (createElement(NowIndicatorRoot, { isAxis: true, date: nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); }));
12969                                        }
12970                                        return null;
12971                                    }))));
12972                        }
12973                    },
12974                    {
12975                        key: 'cols',
12976                        scrollerElRef: this.scrollerElRef,
12977                        content: timeContent
12978                    }
12979                ]
12980            });
12981            if (stickyFooterScrollbar) {
12982                sections.push({
12983                    key: 'footer',
12984                    type: 'footer',
12985                    isSticky: true,
12986                    chunks: [
12987                        {
12988                            key: 'axis',
12989                            content: renderScrollShim
12990                        },
12991                        {
12992                            key: 'cols',
12993                            content: renderScrollShim
12994                        }
12995                    ]
12996                });
12997            }
12998            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].
12998concat(classNames).join(' '), ref: rootElRef },
12999                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, colGroups: [
13000                        { width: 'shrink', cols: [{ width: 'shrink' }] },
13001                        { cols: [{ span: colCnt, minWidth: dayMinWidth }] }
13002                    ], sections: sections }))); }));
13003        };
13004        /* Dimensions
13005        ------------------------------------------------------------------------------------------------------------------*/
13006        TimeColsView.prototype.getAllDayMaxEventProps = function () {
13007            var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows;
13008            if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?
13009                dayMaxEvents = undefined;
13010                dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number
13011            }
13012            return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows };
13013        };
13014        return TimeColsView;
13015    }(DateComponent));
13016    function renderAllDayInner(hookProps) {
13017        return hookProps.text;
13018    }
13019    var TimeBodyAxis = /** @class */ (function (_super) {
13020        __extends(TimeBodyAxis, _super);
13021        function TimeBodyAxis() {
13022            return _super !== null && _super.apply(this, arguments) || this;
13023        }
13024        TimeBodyAxis.prototype.render = function () {
13025            return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key },
13026                createElement(TimeColsAxisCell, __assign({}, slatMeta)))); });
13027        };
13028        return TimeBodyAxis;
13029    }(BaseComponent));
13030
13031    function splitSegsByCol(segs, colCnt) {
13032        var segsByCol = [];
13033        var i;
13034        for (i = 0; i < colCnt; i++) {
13035            segsByCol.push([]);
13036        }
13037        if (segs) {
13038            for (i = 0; i < segs.length; i++) {
13039                segsByCol[segs[i].col].push(segs[i]);
13040            }
13041        }
13042        return segsByCol;
13043    }
13044    function splitInteractionByCol(ui, colCnt) {
13045        var byRow = [];
13046        if (!ui) {
13047            for (var i = 0; i < colCnt; i++) {
13048                byRow[i] = null;
13049            }
13050        }
13051        else {
13052            for (var i = 0; i < colCnt; i++) {
13053                byRow[i] = {
13054                    affectedInstances: ui.affectedInstances,
13055                    isEvent: ui.isEvent,
13056                    segs: []
13057                };
13058            }
13059            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
13060                var seg = _a[_i];
13061                byRow[seg.col].segs.push(seg);
13062            }
13063        }
13064        return byRow;
13065    }
13066
13067    // UNFORTUNATELY, assigns results to the top/bottom/level/forwardCoord/backwardCoord props of the actual segs.
13068    // TODO: return hash (by instanceId) of results
13069    function computeSegCoords(segs, dayDate, slatCoords, eventMinHeight, eventOrderSpecs) {
13070        computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight);
13071        return computeSegHorizontals(segs, eventOrderSpecs); // requires top/bottom from computeSegVerticals
13072    }
13073    // For each segment in an array, computes and assigns its top and bottom properties
13074    function computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight) {
13075        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
13076            var seg = segs_1[_i];
13077            seg.top = slatCoords.computeDateTop(seg.start, dayDate);
13078            seg.bottom = Math.max(seg.top + (eventMinHeight || 0), // yuck
13079            slatCoords.computeDateTop(seg.end, dayDate));
13080        }
13081    }
13082    // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
13083    // Assumed the segs are already ordered.
13084    // NOTE: Also reorders the given array by date!
13085    function computeSegHorizontals(segs, eventOrderSpecs) {
13086        // IMPORTANT TO CLEAR OLD RESULTS :(
13087        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
13088            var seg = segs_2[_i];
13089            seg.level = null;
13090            seg.forwardCoord = null;
13091            seg.backwardCoord = null;
13092            seg.forwardPressure = null;
13093        }
13094        segs = sortEventSegs(segs, eventOrderSpecs);
13095        var level0;
13096        var levels = buildSlotSegLevels(segs);
13097        computeForwardSlotSegs(levels);
13098        if ((level0 = levels[0])) {
13099            for (var _a = 0, level0_1 = level0; _a < level0_1.length; _a++) {
13100                var seg = level0_1[_a];
13101                computeSlotSegPressures(seg);
13102            }
13103            for (var _b = 0, level0_2 = level0; _b < level0_2.length; _b++) {
13104                var seg = level0_2[_b];
13105                computeSegForwardBack(seg, 0, 0, eventOrderSpecs);
13106            }
13107        }
13108        return segs;
13109    }
13110    // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
13111    // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
13112    function buildSlotSegLevels(segs) {
13113        var levels = [];
13114        var i;
13115        var seg;
13116        var j;
13117        for (i = 0; i < segs.length; i++) {
13118            seg = segs[i];
13119            // go through all the levels and stop on the first level where there are no collisions
13120            for (j = 0; j < levels.length; j++) {
13121                if (!computeSlotSegCollisions(seg, levels[j]).length) {
13122                    break;
13123                }
13124            }
13125            seg.level = j;
13126            (levels[j] || (levels[j] = [])).push(seg);
13127        }
13128        return levels;
13129    }
13130    // Find all the segments in `otherSegs` that vertically collide with `seg`.
13131    // Append into an optionally-supplied `results` array and return.
13132    function computeSlotSegCollisions(seg, otherSegs, results) {
13133        if (results === void 0) { results = []; }
13134        for (var i = 0; i < otherSegs.length; i++) {
13135            if (isSlotSegCollision(seg, otherSegs[i])) {
13136                results.push(otherSegs[i]);
13137            }
13138        }
13139        return results;
13140    }
13141    // Do these segments occupy the same vertical space?
13142    function isSlotSegCollision(seg1, seg2) {
13143        return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
13144    }
13145    // For every segment, figure out the other segments that are in subsequent
13146    // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
13147    function computeForwardSlotSegs(levels) {
13148        var i;
13149        var level;
13150        var j;
13151        var seg;
13152        var k;
13153        for (i = 0; i < levels.length; i++) {
13154            level = levels[i];
13155            for (j = 0; j < level.length; j++) {
13156                seg = level[j];
13157                seg.forwardSegs = [];
13158                for (k = i + 1; k < levels.length; k++) {
13159                    computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
13160                }
13161            }
13162        }
13163    }
13164    // Figure out which path forward (via seg.forwardSegs) results in the longest path until
13165    // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
13166    function computeSlotSegPressures(seg) {
13167        var forwardSegs = seg.forwardSegs;
13168        var forwardPressure = 0;
13169        var i;
13170        var forwardSeg;
13171        if (seg.forwardPressure == null) { // not already computed
13172            for (i = 0; i < forwardSegs.length; i++) {
13173                forwardSeg = forwardSegs[i];
13174                // figure out the child's maximum forward path
13175                computeSlotSegPressures(forwardSeg);
13176                // either use the existing maximum, or use the child's forward pressure
13177                // plus one (for the forwardSeg itself)
13178                forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
13179            }
13180            seg.forwardPressure = forwardPressure;
13181        }
13182    }
13183    // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
13184    // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
13185    // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
13186    //
13187    // The segment might be part of a "series", which means consecutive segments with the same pressure
13188    // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
13189    // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
13190    // coordinate of the first segment in the series.
13191    function computeSegForwardBack(seg, seriesBackwardPressure, seriesBackwardCoord, eventOrderSpecs) {
13192        var forwardSegs = seg.forwardSegs;
13193        var i;
13194        if (seg.forwardCoord == null) { // not already computed
13195            if (!forwardSegs.length) {
13196                // if there are no forward segments, this segment should butt up against the edge
13197                seg.forwardCoord = 1;
13198            }
13199            else {
13200                // sort highest pressure first
13201                sortForwardSegs(forwardSegs, eventOrderSpecs);
13202                // this segment's forwardCoord will be calculated from the backwardCoord of the
13203                // highest-pressure forward segment.
13204                computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord, eventOrderSpecs);
13205                seg.forwardCoord = forwardSegs[0].backwardCoord;
13206            }
13207            // calculate the backwardCoord from the forwardCoord. consider the series
13208            seg.backwardCoord = seg.forwardCoord -
13209                (seg.forwardCoord - seriesBackwardCoord) / // available width for series
13210                    (seriesBackwardPressure + 1); // # of segments in the series
13211            // use this segment's coordinates to computed the coordinates of the less-pressurized
13212            // forward segments
13213            for (i = 0; i < forwardSegs.length; i++) {
13214                computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord, eventOrderSpecs);
13215            }
13216        }
13217    }
13218    function sortForwardSegs(forwardSegs, eventOrderSpecs) {
13219        var objs = forwardSegs.map(buildTimeGridSegCompareObj);
13220        var specs = [
13221            // put higher-pressure first
13222            { field: 'forwardPressure', order: -1 },
13223            // put segments that are closer to initial edge first (and favor ones with no coords yet)
13224            { field: 'backwardCoord', order: 1 }
13225        ].concat(eventOrderSpecs);
13226        objs.sort(function (obj0, obj1) {
13227            return compareByFieldSpecs(obj0, obj1, specs);
13228        });
13229        return objs.map(function (c) {
13230            return c._seg;
13231        });
13232    }
13233    function buildTimeGridSegCompareObj(seg) {
13234        var obj = buildSegCompareObj(seg);
13235        obj.forwardPressure = seg.forwardPressure;
13236        obj.backwardCoord = seg.backwardCoord;
13237        return obj;
13238    }
13239
13240    var DEFAULT_TIME_FORMAT = createFormatter({
13241        hour: 'numeric',
13242        minute: '2-digit',
13243        meridiem: false
13244    });
13245    var TimeColEvent = /** @class */ (function (_super) {
13246        __extends(TimeColEvent, _super);
13247        function TimeColEvent() {
13248            return _super !== null && _super.apply(this, arguments) || this;
13249        }
13250        TimeColEvent.prototype.render = function () {
13251            var classNames = [
13252                'fc-timegrid-event',
13253                'fc-v-event'
13254            ];
13255            if (this.props.isCondensed) {
13256                classNames.push('fc-timegrid-event-condensed');
13257            }
13258            return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT, extraClassNames: classNames })));
13259        };
13260        return TimeColEvent;
13261    }(BaseComponent));
13262
13263    config.timeGridEventCondensedHeight = 30;
13264    var TimeCol = /** @class */ (function (_super) {
13265        __extends(TimeCol, _super);
13266        function TimeCol() {
13267            return _super !== null && _super.apply(this, arguments) || this;
13268        }
13269        TimeCol.prototype.render = function () {
13270            var _this = this;
13271            var _a = this, props = _a.props, context = _a.context;
13272            var isSelectMirror = context.options.selectMirror;
13273            var mirrorSegs = (props.eventDrag && props.eventDrag.segs) ||
13274                (props.eventResize && props.eventResize.segs) ||
13275                (isSelectMirror && props.dateSelectionSegs) ||
13276                [];
13277            var interactionAffectedInstances = // TODO: messy way to compute this
13278             (props.eventDrag && props.eventDrag.affectedInstances) ||
13279                (props.eventResize && props.eventResize.affectedInstances) ||
13280                {};
13281            return (createElement(DayCellRoot, { elRef: props.elRef, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (rootElRef, classNames, dataAttrs) { return (createElement("td", __assign({ ref: rootElRef, className: ['fc-timegrid-col'].concat(classNames, props.extraClassNames || []).join(' ') }, dataAttrs, props.extraDataAttrs),
13282                createElement("div", { className: 'fc-timegrid-col-frame' },
13283                    createElement("div", { className: 'fc-timegrid-col-bg' },
13284                        _this.renderFillSegs(props.businessHourSegs, 'non-business'),
13285                        _this.renderFillSegs(props.bgEventSegs, 'bg-event'),
13286                        _this.renderFillSegs(props.dateSelectionSegs, 'highlight')),
13287                    createElement("div", { className: 'fc-timegrid-col-events' }, _this.renderFgSegs(props.fgEventSegs, interactionAffectedInstances)),
13288                    createElement("div", { className: 'fc-timegrid-col-events' }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror)
13289                    // TODO: pass in left/right instead of using only computeSegTopB
13289ottomCss
13290                    )),
13291                    createElement("div", { className: 'fc-timegrid-now-indicator-container' }, _this.renderNowIndicator(props.nowIndicatorSegs)),
13292                    createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); }));
13293        };
13294        TimeCol.prototype.renderFgSegs = function (segs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
13295            var props = this.props;
13296            if (props.forPrint) {
13297                return this.renderPrintFgSegs(segs);
13298            }
13299            else if (props.slatCoords) {
13300                return this.renderPositionedFgSegs(segs, segIsInvisible, isDragging, isResizing, isDateSelecting);
13301            }
13302        };
13303        TimeCol.prototype.renderPrintFgSegs = function (segs) {
13304            var _a = this, props = _a.props, context = _a.context;
13305            // not DRY
13306            segs = sortEventSegs(segs, context.options.eventOrder);
13307            return segs.map(function (seg) { return (createElement("div", { className: 'fc-timegrid-event-harness', key: seg.eventRange.instance.instanceId },
13308                createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isCondensed: false }, getSegMeta(seg, props.todayRange, props.nowDate))))); });
13309        };
13310        TimeCol.prototype.renderPositionedFgSegs = function (segs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
13311            var _this = this;
13312            var _a = this, context = _a.context, props = _a.props;
13313            // assigns TO THE SEGS THEMSELVES
13314            // also, receives resorted array
13315            segs = computeSegCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight, context.options.eventOrder);
13316            return segs.map(function (seg) {
13317                var instanceId = seg.eventRange.instance.instanceId;
13318                var isMirror = isDragging || isResizing || isDateSelecting;
13319                var positionCss = isMirror ? __assign({ left: 0, right: 0 }, _this.computeSegTopBottomCss(seg)) :
13320                    _this.computeFgSegPositionCss(seg);
13321                return (createElement("div", { className: 'fc-timegrid-event-harness' + (seg.level > 0 ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign({ visibility: segIsInvisible[instanceId] ? 'hidden' : '' }, positionCss) },
13322                    createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === props.eventSelection, isCondensed: (seg.bottom - seg.top) < config.timeGridEventCondensedHeight }, getSegMeta(seg, props.todayRange, props.nowDate)))));
13323            });
13324        };
13325        TimeCol.prototype.renderFillSegs = function (segs, fillType) {
13326            var _this = this;
13327            var _a = this, context = _a.context, props = _a.props;
13328            if (!props.slatCoords) {
13329                return;
13330            }
13331            // BAD: assigns TO THE SEGS THEMSELVES
13332            computeSegVerticals(segs, props.date, props.slatCoords, context.options.eventMinHeight);
13333            var children = segs.map(function (seg) { return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: 'fc-timegrid-bg-harness', style: _this.computeSegTopBottomCss(seg) }, fillType === 'bg-event' ?
13334                createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) :
13335                renderFill(fillType))); });
13336            return createElement(Fragment, null, children);
13337        };
13338        TimeCol.prototype.renderNowIndicator = function (segs) {
13339            var _a = this.props, slatCoords = _a.slatCoords, date = _a.date;
13340            if (!slatCoords) {
13341                return;
13342            }
13343            return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, key: i /* key doesn't matter. will only ever be one */ }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); });
13344        };
13345        TimeCol.prototype.computeFgSegPositionCss = function (seg) {
13346            var _a = this.context, isRtl = _a.isRtl, options = _a.options;
13347            var shouldOverlap = options.slotEventOverlap;
13348            var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
13349            var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
13350            var left; // amount of space from left edge, a fraction of the total width
13351            var right; // amount of space from right edge, a fraction of the total width
13352            if (shouldOverlap) {
13353                // double the width, but don't go beyond the maximum forward coordinate (1.0)
13354                forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
13355            }
13356            if (isRtl) {
13357                left = 1 - forwardCoord;
13358                right = backwardCoord;
13359            }
13360            else {
13361                left = backwardCoord;
13362                right = 1 - forwardCoord;
13363            }
13364            var props = {
13365                zIndex: seg.level + 1,
13366                left: left * 100 + '%',
13367                right: right * 100 + '%'
13368            };
13369            if (shouldOverlap && seg.forwardPressure) {
13370                // add padding to the edge so that forward stacked events don't cover the resizer's icon
13371                props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
13372            }
13373            return __assign(__assign({}
13373, props), this.computeSegTopBottomCss(seg));
13374        };
13375        TimeCol.prototype.computeSegTopBottomCss = function (seg) {
13376            return {
13377                top: seg.top,
13378                bottom: -seg.bottom
13379            };
13380        };
13381        return TimeCol;
13382    }(BaseComponent));
13383    var TimeColMisc = /** @class */ (function (_super) {
13384        __extends(TimeColMisc, _super);
13385        function TimeColMisc() {
13386            return _super !== null && _super.apply(this, arguments) || this;
13387        }
13388        TimeColMisc.prototype.render = function () {
13389            var props = this.props;
13390            return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent &&
13391                createElement("div", { className: 'fc-timegrid-col-misc', ref: innerElRef }, innerContent)); }));
13392        };
13393        return TimeColMisc;
13394    }(BaseComponent));
13395
13396    var TimeColsContent = /** @class */ (function (_super) {
13397        __extends(TimeColsContent, _super);
13398        function TimeColsContent() {
13399            var _this = _super !== null && _super.apply(this, arguments) || this;
13400            _this.splitFgEventSegs = memoize(splitSegsByCol);
13401            _this.splitBgEventSegs = memoize(splitSegsByCol);
13402            _this.splitBusinessHourSegs = memoize(splitSegsByCol);
13403            _this.splitNowIndicatorSegs = memoize(splitSegsByCol);
13404            _this.splitDateSelectionSegs = memoize(splitSegsByCol);
13405            _this.splitEventDrag = memoize(splitInteractionByCol);
13406            _this.splitEventResize = memoize(splitInteractionByCol);
13407            _this.rootElRef = createRef();
13408            _this.cellElRefs = new RefMap();
13409            return _this;
13410        }
13411        TimeColsContent.prototype.render = function () {
13412            var _this = this;
13413            var _a = this, props = _a.props, context = _a.context;
13414            var nowIndicatorTop = context.options.nowIndicator &&
13415                props.slatCoords &&
13416                props.slatCoords.safeComputeTop(props.nowDate); // might return void
13417            var colCnt = props.cells.length;
13418            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);
13419            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);
13420            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);
13421            var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);
13422            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);
13423            var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);
13424            var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);
13425            return (createElement("div", { className: 'fc-timegrid-cols', ref: this.rootElRef },
13426                createElement("table", { style: {
13427                        minWidth: props.tableMinWidth,
13428                        width: props.clientWidth
13429                    } },
13430                    props.tableColGroupNode,
13431                    createElement("tbody", null,
13432                        createElement("tr", null,
13433                            props.axis &&
13434                                createElement("td", { className: 'fc-timegrid-col fc-timegrid-axis' },
13435                                    createElement("div", { className: 'fc-timegrid-col-frame' },
13436                                        createElement("div", { className: 'fc-timegrid-now-indicator-container' }, typeof nowIndicatorTop === 'number' &&
13437                                            createElement(NowIndicatorRoot, { isAxis: true, date: props.nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })))),
13438                            props.cells.map(function (cell, i) { return (createElement(TimeCol, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })); }))))));
13439        };
13440        TimeColsContent.prototype.componentDidMount = function () {
13441            this.updateCoords();
13442        };
13443        TimeColsContent.prototype.componentDidUpdate = function () {
13444            this.updateCoords();
13445        };
13446        TimeColsContent.prototype.updateCoords = function () {
13447            var props = this.props;
13448            if (props.onColCoords &&
13449                props.clientWidth !== null // means sizing has stabilized
13450            ) {
13451                props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal
13452                false));
13453            }
13454        };
13455        return TimeColsContent;
13456    }(BaseComponent));
13457    function collectCellEls(elMap, cells) {
13458        return cells.map(function (cell) { return elMap[cell.key]; });
13459    }
13460
13461    /* A component that renders one or more columns of vertical time slots
13462    ----------------------------------------------------------------------------------------------------------------------*/
13463    var TimeCols = /** @class */ (function (_super) {
13464        __extends(TimeCols, _super);
13465        function TimeCols() {
13466            var _this = _super !== null && _super.apply(this, arguments) || this;
13467            _this.processSlotOptions = memoize(processSlotOptions);
13468            _this.state = {
13469                slatCoords: null
13470            };
13471            _this.handleScrollRequest = function (request) {
13472                var onScrollTopRequest = _this.props.onScrollTopRequest;
13473                var slatCoords = _this.state.slatCoords;
13474                if (onScrollTopRequest && slatCoords) {
13475                    if (request.time) {
13476                        var top_1 = slatCoords.computeTimeTop(request.time);
13477                        top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further
13478                        if (top_1) {
13479                            top_1++;
13480                        } // to overcome top border that slots beyond the first have. looks better
13481                        onScrollTopRequest(top_1);
13482                    }
13483                    return true;
13484                }
13485            };
13486            _this.handleColCoords = function (colCoords) {
13487                _this.colCoords = colCoords;
13488            };
13489            _this.handleSlatCoords = function (slatCoords) {
13490                _this.setState({ slatCoords: slatCoords });
13491                if (_this.props.onSlatCoords) {
13492                    _this.props.onSlatCoords(slatCoords);
13493                }
13494            };
13495            return _this;
13496        }
13497        TimeCols.prototype.render = function () {
13498            var _a = this, props = _a.props, state = _a.state;
13499            return (createElement("div", { className: 'fc-timegrid-body', ref: props.rootElRef, style: {
13500                    // these props are important to give this wrapper correct dimensions for interactions
13501                    // TODO: if we set it here, can we avoid giving to inner tables?
13502                    width: props.clientWidth,
13503                    minWidth: props.tableMinWidth
13504                } },
13505                createElement(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }),
13506                createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
13506EventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint })));
13507        };
13508        TimeCols.prototype.componentDidMount = function () {
13509            this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);
13510        };
13511        TimeCols.prototype.componentDidUpdate = function (prevProps) {
13512            this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);
13513        };
13514        TimeCols.prototype.componentWillUnmount = function () {
13515            this.scrollResponder.detach();
13516        };
13517        TimeCols.prototype.positionToHit = function (positionLeft, positionTop) {
13518            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options;
13519            var colCoords = this.colCoords;
13520            var dateProfile = this.props.dateProfile;
13521            var slatCoords = this.state.slatCoords;
13522            var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot;
13523            var colIndex = colCoords.leftToIndex(positionLeft);
13524            var slatIndex = slatCoords.positions.topToIndex(positionTop);
13525            if (colIndex != null && slatIndex != null) {
13526                var slatTop = slatCoords.positions.tops[slatIndex];
13527                var slatHeight = slatCoords.positions.getHeight(slatIndex);
13528                var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
13529                var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
13530                var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
13531                var dayDate = this.props.cells[colIndex].date;
13532                var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex));
13533                var start = dateEnv.add(dayDate, time);
13534                var end = dateEnv.add(start, snapDuration);
13535                return {
13536                    col: colIndex,
13537                    dateSpan: {
13538                        range: { start: start, end: end },
13539                        allDay: false
13540                    },
13541                    dayEl: colCoords.els[colIndex],
13542                    relativeRect: {
13543                        left: colCoords.lefts[colIndex],
13544                        right: colCoords.rights[colIndex],
13545                        top: slatTop,
13546                        bottom: slatTop + slatHeight
13547                    }
13548                };
13549            }
13550        };
13551        return TimeCols;
13552    }(BaseComponent));
13553    function processSlotOptions(slotDuration, snapDurationOverride) {
13554        var snapDuration = snapDurationOverride || slotDuration;
13555        var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration);
13556        if (snapsPerSlot === null) {
13557            snapDuration = slotDuration;
13558            snapsPerSlot = 1;
13559            // TODO: say warning?
13560        }
13561        return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot };
13562    }
13563
13564    var DayTimeCols = /** @class */ (function (_super) {
13565        __extends(DayTimeCols, _super);
13566        function DayTimeCols() {
13567            var _this = _super !== null && _super.apply(this, arguments) || this;
13568            _this.buildDayRanges = memoize(buildDayRanges);
13569            _this.slicer = new DayTimeColsSlicer();
13570            _this.timeColsRef = createRef();
13571            _this.handleRootEl = function (rootEl) {
13572                if (rootEl) {
13573                    _this.context.registerInteractiveComponent(_this, { el: rootEl });
13574                }
13575                else {
13576                    _this.context.unregisterInteractiveComponent(_this);
13577                }
13578            };
13579            return _this;
13580        }
13581        DayTimeCols.prototype.render = function () {
13582            var _this = this;
13583            var _a = this, props = _a.props, context = _a.context;
13584            var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel;
13585            var isNowIndicator = context.options.nowIndicator;
13586            var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);
13587            // give it the first row of cells
13588            // TODO: would move this further down hierarchy, but sliceNowDate needs it
13589            return (createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (createElement(TimeCols, __assign({ ref: _this.timeColsRef, rootElRef: _this.handleRootEl }, _this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: n
13589owDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); }));
13590        };
13591        DayTimeCols.prototype.queryHit = function (positionLeft, positionTop) {
13592            var rawHit = this.timeColsRef.current.positionToHit(positionLeft, positionTop);
13593            if (rawHit) {
13594                return {
13595                    component: this,
13596                    dateSpan: rawHit.dateSpan,
13597                    dayEl: rawHit.dayEl,
13598                    rect: {
13599                        left: rawHit.relativeRect.left,
13600                        right: rawHit.relativeRect.right,
13601                        top: rawHit.relativeRect.top,
13602                        bottom: rawHit.relativeRect.bottom
13603                    },
13604                    layer: 0
13605                };
13606            }
13607        };
13608        return DayTimeCols;
13609    }(DateComponent));
13610    function buildDayRanges(dayTableModel, dateProfile, dateEnv) {
13611        var ranges = [];
13612        for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) {
13613            var date = _a[_i];
13614            ranges.push({
13615                start: dateEnv.add(date, dateProfile.slotMinTime),
13616                end: dateEnv.add(date, dateProfile.slotMaxTime)
13617            });
13618        }
13619        return ranges;
13620    }
13621    var DayTimeColsSlicer = /** @class */ (function (_super) {
13622        __extends(DayTimeColsSlicer, _super);
13623        function DayTimeColsSlicer() {
13624            return _super !== null && _super.apply(this, arguments) || this;
13625        }
13626        DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) {
13627            var segs = [];
13628            for (var col = 0; col < dayRanges.length; col++) {
13629                var segRange = intersectRanges(range, dayRanges[col]);
13630                if (segRange) {
13631                    segs.push({
13632                        start: segRange.start,
13633                        end: segRange.end,
13634                        isStart: segRange.start.valueOf() === range.start.valueOf(),
13635                        isEnd: segRange.end.valueOf() === range.end.valueOf(),
13636                        col: col
13637                    });
13638                }
13639            }
13640            return segs;
13641        };
13642        return DayTimeColsSlicer;
13643    }(Slicer));
13644
13645    var DayTimeColsView = /** @class */ (function (_super) {
13646        __extends(DayTimeColsView, _super);
13647        function DayTimeColsView() {
13648            var _this = _super !== null && _super.apply(this, arguments) || this;
13649            _this.buildTimeColsModel = memoize(buildTimeColsModel);
13650            _this.buildSlatMetas = memoize(buildSlatMetas);
13651            return _this;
13652        }
13653        DayTimeColsView.prototype.render = function () {
13654            var _this = this;
13655            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator;
13656            var props = this.props;
13657            var dateProfile = props.dateProfile;
13658            var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);
13659            var splitProps = this.allDaySplitter.splitProps(props);
13660            var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);
13661            var dayMinWidth = options.dayMinWidth;
13662            var hasAttachedAxis = !dayMinWidth;
13663            var hasDetachedAxis = dayMinWidth;
13664            var headerContent = options.dayHeaders &&
13665                createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null });
13666            var allDayContent = (options.allDaySlot !== false) && (function (contentArg) { return (createElement(DayTable, __assign({}, splitProps['allDay'], { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? _this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, _this.getAllDayMaxEventProps()))); });
13667            var timeGridContent = function (contentArg) { return (createElement(DayTimeCols, __assign({}, splitProps['timed'], { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: _this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: _this.handleScrollTopRequest }))); };
13668            return hasDetachedAxis
13669                ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)
13670                : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);
13671        };
13672        return DayTimeColsView;
13673    }(TimeColsView));
13674    function buildTimeColsModel(dateProfile, dateProfileGenerator) {
13675        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
13676        return new DayTableModel(daySeries, false);
13677    }
13678
13679    var OPTION_REFINERS$1 = {
13680        allDaySlot: Boolean
13681    };
13682
13683    var timeGridPlugin = createPlugin({
13684        initialView: 'timeGridWeek',
13685        optionRefiners: OPTION_REFINERS$1,
13686        views: {
13687            timeGrid: {
13688                component: DayTimeColsView,
13689                usesMinMaxTime: true,
13690                allDaySlot: true,
13691                slotDuration: '00:30:00',
13692                slotEventOverlap: true // a bad name. confused with overlap/constraint system
13693            },
13694            timeGridDay: {
13695                type: 'timeGrid',
13696                duration: { days: 1 }
13697            },
13698            timeGridWeek: {
13699                type: 'timeGrid',
13700                duration: { weeks: 1 }
13701            }
13702        }
13703    });
13704
13705    var ListViewHeaderRow = /** @class */ (function (_super) {
13706        __extends(ListViewHeaderRow, _super);
13707        function ListViewHeaderRow() {
13708            return _super !== null && _super.apply(this, arguments) || this;
13709        }
13710        ListViewHeaderRow.prototype.render = function () {
13711            var _a = this.props, dayDate = _a.dayDate, todayRange = _a.todayRange;
13712            var _b = this.context, theme = _b.theme, dateEnv = _b.dateEnv, options = _b.options, viewApi = _b.viewApi;
13713            var dayMeta = getDateMeta(dayDate, todayRange);
13714            var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : ''; // will ever be falsy?
13715            var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : ''; // will ever be falsy? also, BAD NAME "alt"
13716            var navLinkData = options.navLinks
13717                ? buildNavLinkData(dayDate)
13718                : null;
13719            var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, text: text,
13720                sideText: sideText,
13721                navLinkData: navLinkData }, dayMeta);
13722            var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme));
13723            // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)
13724            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInnerContent$4, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("tr", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": formatDayString(dayDate) },
13725                createElement("th", { colSpan: 3 },
13726                    createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); }));
13727        };
13728        return ListViewHeaderRow;
13729    }(BaseComponent));
13730    function renderInnerContent$4(props) {
13731        var navLinkAttrs = props.navLinkData // is there a type for this?
13732            ? { 'data-navlink': props.navLinkData, tabIndex: 0 }
13733            : {};
13734        return (createElement(Fragment, null,
13735            props.text &&
13736                createElement("a", __assign({ className: 'fc-list-day-text' }, navLinkAttrs), props.text),
13737            props.sideText &&
13738                createElement("a", __assign({ className: 'fc-list-day-side-text' }, navLinkAttrs), props.sideText)));
13739    }
13740
13741    var DEFAULT_TIME_FORMAT$1 = createFormatter({
13742        hour: 'numeric',
13743        minute: '2-digit',
13744        meridiem: 'short'
13745    });
13746    var ListViewEventRow = /** @class */ (function (_super) {
13747        __extends(ListViewEventRow, _super);
13748        function ListViewEventRow() {
13749            return _super !== null && _super.apply(this, arguments) || this;
13750        }
13751        ListViewEventRow.prototype.render = function () {
13752            var _a = this, props = _a.props, context = _a.context;
13753            var seg = props.seg;
13754            var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT$1;
13755            return (createElement(EventRoot, { seg: seg, timeText: '' /* BAD. because of all-day content */, disableDragging: true, disableResizing: true, defaultContent: renderEventInnerContent, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, isSelected: props.isSelected, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("tr", { className: ['fc-list-event', hookProps.event.url ? 'fc-event-forced-url' : ''].concat(classNames).join(' '), ref: rootElRef },
13756                buildTimeContent(seg, timeFormat, context),
13757                createElement("td", { className: 'fc-list-event-graphic' },
13758                    createElement("span", { className: 'fc-list-event-dot', style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })),
13759                createElement("td", { className: 'fc-list-event-title', ref: innerElRef }, innerContent))); }));
13760        };
13761        return ListViewEventRow;
13762    }(BaseComponent));
13763    function renderEventInnerContent(props) {
13764        var event = props.event;
13765        var url = event.url;
13766        var anchorAttrs = url ? { href: url } : {};
13767        return (createElement("a", __assign({}, anchorAttrs), event.title));
13768    }
13769    function buildTimeContent(seg, timeFormat, context) {
13770        var options = context.options;
13771        if (options.displayEventTime !== false) {
13772            var eventDef = seg.eventRange.def;
13773            var eventInstance = seg.eventRange.instance;
13774            var doAllDay = false;
13775            var timeText = void 0;
13776            if (eventDef.allDay) {
13777                doAllDay = true;
13778            }
13779            else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead?
13780                if (seg.isStart) {
13781                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end);
13782                }
13783                else if (seg.isEnd) {
13784                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end);
13785                }
13786                else {
13787                    doAllDay = true;
13788                }
13789            }
13790            else {
13791                timeText = buildSegTimeText(seg, timeFormat, context);
13792            }
13793            if (doAllDay) {
13794                var hookProps = {
13795                    text: context.options.allDayText,
13796                    view: context.viewApi
13797                };
13798                return (createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner$1, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { className: ['fc-list-event-time'].concat(classNames).join(' '), ref: rootElRef }, innerContent)); }));
13799            }
13800            else {
13801                return (createElement("td", { className: 'fc-list-event-time' }, timeText));
13802            }
13803        }
13804        return null;
13805    }
13806    function renderAllDayInner$1(hookProps) {
13807        return hookProps.text;
13808    }
13809
13810    /*
13811    Responsible for the scroller, and forwarding event-related actions into the "grid".
13812    */
13813    var ListView = /** @class */ (function (_super) {
13814        __extends(ListView, _super);
13815        function ListView() {
13816            var _this = _super !== null && _super.apply(this, arguments) || this;
13817            _this.computeDateVars = memoize(computeDateVars);
13818            _this.eventStoreToSegs = memoize(_this._eventStoreToSegs);
13819            _this.setRootEl = function (rootEl) {
13820                if (rootEl) {
13821                    _this.context.registerInteractiveComponent(_this, {
13822                        el: rootEl
13823                    });
13824                }
13825                else {
13826                    _this.context.unregisterInteractiveComponent(_this);
13827                }
13828            };
13829            return _this;
13830        }
13831        ListView.prototype.render = function () {
13832            var _this = this;
13833            var _a = this, props = _a.props, context = _a.context;
13834            var extraClassNames = [
13835                'fc-list',
13836                context.theme.getClass('table'),
13837                context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : ''
13838            ];
13839            var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges;
13840            var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
13841            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.concat(classNames).join(' ') },
13842                createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ?
13843                    _this.renderSegList(eventSegs, dayDates) :
13844                    _this.renderEmptyMessage()))); }));
13845        };
13846        ListView.prototype.renderEmptyMessage = function () {
13847            var _a = this.context, options = _a.options, viewApi = _a.viewApi;
13848            var hookProps = {
13849                text: options.noEventsText,
13850                view: viewApi
13851            };
13852            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.noEventsClassNames, content: options.noEventsContent, defaultContent: renderNoEventsInner, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { className: ['fc-list-empty'].concat(classNames).join(' '), ref: rootElRef },
13853                createElement("div", { className: 'fc-list-empty-cushion', ref: innerElRef }, innerContent))); }));
13854        };
13855        ListView.prototype.renderSegList = function (allSegs, dayDates) {
13856            var _a = this.context, theme = _a.theme, options = _a.options;
13857            var segsByDay = groupSegsByDay(allSegs); // sparse array
13858            return (createElement(NowTimer, { unit: 'day' }, function (nowDate, todayRange) {
13859                var innerNodes = [];
13860                for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
13861                    var daySegs = segsByDay[dayIndex];
13862                    if (daySegs) { // sparse array, so might be undefined
13863                        var dayStr = dayDates[dayIndex].toISOString();
13864                        // append a day header
13865                        innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, dayDate: dayDates[dayIndex], todayRange: todayRange }));
13866                        daySegs = sortEventSegs(daySegs, options.eventOrder);
13867                        for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) {
13868                            var seg = daySegs_1[_i];
13869                            innerNodes.push(createElement(ListViewEventRow, __assign({ key: dayStr + ':' + seg.eventRange.instance.instanceId /* are multiple segs for an instanceId */, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false }, getSegMeta(seg, todayRange, nowDate))));
13870                        }
13871                    }
13872                }
13873                return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') },
13874                    createElement("tbody", null, innerNodes)));
13875            }));
13876        };
13877        ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) {
13878            return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
13879        };
13880        ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) {
13881            var segs = [];
13882            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
13883                var eventRange = eventRanges_1[_i];
13884                segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges));
13885            }
13886            return segs;
13887        };
13888        ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) {
13889            var dateEnv = this.context.dateEnv;
13890            var nextDayThreshold = this.context.options.nextDayThreshold;
13891            var range = eventRange.range;
13892            var allDay = eventRange.def.allDay;
13893            var dayIndex;
13894            var segRange;
13895            var seg;
13896            var segs = [];
13897            for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) {
13898                segRange = intersectRanges(range, dayRanges[dayIndex]);
13899                if (segRange) {
13900                    seg = {
13901                        component: this,
13902                        eventRange: eventRange,
13903                        start: segRange.start,
13904                        end: segRange.end,
13905                        isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
13906                        isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
13907                        dayIndex: dayIndex
13908                    };
13909                    segs.push(seg);
13910                    // detect when range won't go fully into the next day,
13911                    // and mutate the latest seg to the be the end.
13912                    if (!seg.isEnd && !allDay &&
13913                        dayIndex + 1 < dayRanges.length &&
13914                        range.end <
13915                            dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
13916                        seg.end = range.end;
13917                        seg.isEnd = true;
13918                        break;
13919                    }
13920                }
13921            }
13922            return segs;
13923        };
13924        return ListView;
13925    }(DateComponent));
13926    function renderNoEventsInner(hookProps) {
13927        return hookProps.text;
13928    }
13929    function computeDateVars(dateProfile) {
13930        var dayStart = startOfDay(dateProfile.renderRange.start);
13931        var viewEnd = dateProfile.renderRange.end;
13932        var dayDates = [];
13933        var dayRanges = [];
13934        while (dayStart < viewEnd) {
13935            dayDates.push(dayStart);
13936            dayRanges.push({
13937                start: dayStart,
13938                end: addDays(dayStart, 1)
13939            });
13940            dayStart = addDays(dayStart, 1);
13941        }
13942        return { dayDates: dayDates, dayRanges: dayRanges };
13943    }
13944    // Returns a sparse array of arrays, segs grouped by their dayIndex
13945    function groupSegsByDay(segs) {
13946        var segsByDay = []; // sparse array
13947        var i;
13948        var seg;
13949        for (i = 0; i < segs.length; i++) {
13950            seg = segs[i];
13951            (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
13952                .push(seg);
13953        }
13954        return segsByDay;
13955    }
13956
13957    var OPTION_REFINERS$2 = {
13958        listDayFormat: createFalsableFormatter,
13959        listDaySideFormat: createFalsableFormatter,
13960        noEventsClassNames: identity,
13961        noEventsContent: identity,
13962        noEventsDidMount: identity,
13963        noEventsWillUnmount: identity
13964        // noEventsText is defined in base options
13965    };
13966    function createFalsableFormatter(input) {
13967        return input === false ? null : createFormatter(input);
13968    }
13969
13970    var listPlugin = createPlugin({
13971        optionRefiners: OPTION_REFINERS$2,
13972        views: {
13973            list: {
13974                component: ListView,
13975                buttonTextKey: 'list',
13976                listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' } // like "January 1, 2016"
13977            },
13978            listDay: {
13979                type: 'list',
13980                duration: { days: 1 },
13981                listDayFormat: { weekday: 'long' } // day-of-week is all we need. full date is probably in headerToolbar
13982            },
13983            listWeek: {
13984                type: 'list',
13985                duration: { weeks: 1 },
13986                listDayFormat: { weekday: 'long' },
13987                listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' }
13988            },
13989            listMonth: {
13990                type: 'list',
13991                duration: { month: 1 },
13992                listDaySideFormat: { weekday: 'long' } // day-of-week is nice-to-have
13993            },
13994            listYear: {
13995                type: 'list',
13996                duration: { year: 1 },
13997                listDaySideFormat: { weekday: 'long' } // day-of-week is nice-to-have
13998            }
13999        }
14000    });
14001
14002    var BootstrapTheme = /** @class */ (function (_super) {
14003        __extends(BootstrapTheme, _super);
14004        function BootstrapTheme() {
14005            return _super !== null && _super.apply(this, arguments) || this;
14006        }
14007        return BootstrapTheme;
14008    }(Theme));
14009    BootstrapTheme.prototype.classes = {
14010        root: 'fc-theme-bootstrap',
14011        table: 'table-bordered',
14012        tableCellShaded: 'table-active',
14013        buttonGroup: 'btn-group',
14014        button: 'btn btn-primary',
14015        buttonActive: 'active',
14016        popover: 'popover',
14017        popoverHeader: 'popover-header',
14018        popoverContent: 'popover-body'
14019    };
14020    BootstrapTheme.prototype.baseIconClass = 'fa';
14021    BootstrapTheme.prototype.iconClasses = {
14022        close: 'fa-times',
14023        prev: 'fa-chevron-left',
14024        next: 'fa-chevron-right',
14025        prevYear: 'fa-angle-double-left',
14026        nextYear: 'fa-angle-double-right'
14027    };
14028    BootstrapTheme.prototype.rtlIconClasses = {
14029        prev: 'fa-chevron-right',
14030        next: 'fa-chevron-left',
14031        prevYear: 'fa-angle-double-right',
14032        nextYear: 'fa-angle-double-left'
14033    };
14034    BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
14034 // TODO: make TS-friendly. move the option-processing into this plugin
14035    BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
14036    BootstrapTheme.prototype.iconOverridePrefix = 'fa-';
14037    var plugin = createPlugin({
14038        themeClasses: {
14039            bootstrap: BootstrapTheme
14040        }
14041    });
14042
14043    // rename this file to options.ts like other packages?
14044    var OPTION_REFINERS$3 = {
14045        googleCalendarApiKey: String
14046    };
14047
14048    var EVENT_SOURCE_REFINERS$1 = {
14049        googleCalendarApiKey: String,
14050        googleCalendarId: String,
14051        googleCalendarApiBase: String,
14052        extraParams: identity
14053    };
14054
14055    // TODO: expose somehow
14056    var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
14057    var eventSourceDef$3 = {
14058        parseMeta: function (refined) {
14059            var googleCalendarId = refined.googleCalendarId;
14060            if (!googleCalendarId && refined.url) {
14061                googleCalendarId = parseGoogleCalendarId(refined.url);
14062            }
14063            if (googleCalendarId) {
14064                return {
14065                    googleCalendarId: googleCalendarId,
14066                    googleCalendarApiKey: refined.googleCalendarApiKey,
14067                    googleCalendarApiBase: refined.googleCalendarApiBase,
14068                    extraParams: refined.extraParams
14069                };
14070            }
14071            return null;
14072        },
14073        fetch: function (arg, onSuccess, onFailure) {
14074            var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options;
14075            var meta = arg.eventSource.meta;
14076            var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey;
14077            if (!apiKey) {
14078                onFailure({
14079                    message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/'
14080                });
14081            }
14082            else {
14083                var url = buildUrl(meta);
14084                // TODO: make DRY with json-feed-event-source
14085                var extraParams = meta.extraParams;
14086                var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams;
14087                var requestParams_1 = buildRequestParams$1(arg.range, apiKey, extraParamsObj, dateEnv);
14088                requestJson('GET', url, requestParams_1, function (body, xhr) {
14089                    if (body.error) {
14090                        onFailure({
14091                            message: 'Google Calendar API: ' + body.error.message,
14092                            errors: body.error.errors,
14093                            xhr: xhr
14094                        });
14095                    }
14096                    else {
14097                        onSuccess({
14098                            rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
14099                            xhr: xhr
14100                        });
14101                    }
14102                }, function (message, xhr) {
14103                    onFailure({ message: message, xhr: xhr });
14104                });
14105            }
14106        }
14107    };
14108    function parseGoogleCalendarId(url) {
14109        var match;
14110        // detect if the ID was specified as a single string.
14111        // will match calendars like "[email protected]" in addition to person email calendars.
14112        if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
14113            return url;
14114        }
14115        else if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) ||
14116            (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) {
14117            return decodeURIComponent(match[1]);
14118        }
14119    }
14120    function buildUrl(meta) {
14121        var apiBase = meta.googleCalendarApiBase;
14122        if (!apiBase) {
14123            apiBase = API_BASE;
14124        }
14125        return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
14126    }
14127    function buildRequestParams$1(range, apiKey, extraParams, dateEnv) {
14128        var params;
14129        var startStr;
14130        var endStr;
14131        if (dateEnv.canComputeOffset) {
14132            // strings will naturally have offsets, which GCal needs
14133            startStr = dateEnv.formatIso(range.start);
14134            endStr = dateEnv.formatIso(range.end);
14135        }
14136        else {
14137            // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
14138            // from the UTC day-start to guarantee we're getting all the events
14139            // (start/end will be UTC-coerced dates, so toISOString is okay)
14140            startStr = addDays(range.start, -1).toISOString();
14141            endStr = addDays(range.end, 1).toISOString();
14142        }
14143        params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
14144        if (dateEnv.timeZone !== 'local') {
14145            params.timeZone = dateEnv.timeZone;
14146        }
14147        return params;
14148    }
14149    function gcalItemsToRawEventDefs(items, gcalTimezone) {
14150        return items.map(function (item) {
14151            return gcalItemToRawEventDef(item, gcalTimezone);
14152        });
14153    }
14154    function gcalItemToRawEventDef(item, gcalTimezone) {
14155        var url = item.htmlLink || null;
14156        // make the URLs for each event show times in the correct timezone
14157        if (url && gcalTimezone) {
14158            url = injectQsComponent(url, 'ctz=' + gcalTimezone);
14159        }
14160        return {
14161            id: item.id,
14162            title: item.summary,
14163            start: item.start.dateTime || item.start.date,
14164            end: item.end.dateTime || item.end.date,
14165            url: url,
14166            location: item.location,
14167            description: item.description
14168        };
14169    }
14170    // Injects a string like "arg=value" into the querystring of a URL
14171    // TODO: move to a general util file?
14172    function injectQsComponent(url, component) {
14173        // inject it after the querystring but before the fragment
14174        return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) {
14175            return (qs ? qs + '&' : '?') + component + hash;
14176        });
14177    }
14178    var googleCalendarPlugin = createPlugin({
14179        eventSourceDefs: [eventSourceDef$3],
14180        optionRefiners: OPTION_REFINERS$3,
14181        eventSourceRefiners: EVENT_SOURCE_REFINERS$1
14182    });
14183
14184    globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin, googleCalendarPlugin);
14185
14186    exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS;
14187    exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS;
14188    exports.BaseComponent = BaseComponent;
14189    exports.BgEvent = BgEvent;
14190    exports.BootstrapTheme = BootstrapTheme;
14191    exports.Calendar = Calendar;
14192    exports.CalendarApi = CalendarApi;
14193    exports.CalendarContent = CalendarContent;
14194    exports.CalendarDataManager = CalendarDataManager;
14195    exports.CalendarDataProvider = CalendarDataProvider;
14196    exports.CalendarRoot = CalendarRoot;
14197    exports.Component = Component;
14198    exports.ContentHook = ContentHook;
14199    exports.CustomContentRenderContext = CustomContentRenderContext;
14200    exports.DateComponent = DateComponent;
14201    exports.DateEnv = DateEnv;
14202    exports.DateProfileGenerator = DateProfileGenerator;
14203    exports.DayCellContent = DayCellContent;
14204    exports.DayCellRoot = DayCellRoot;
14205    exports.DayGridView = DayTableView;
14206    exports.DayHeader = DayHeader;
14207    exports.DaySeriesModel = DaySeriesModel;
14208    exports.DayTable = DayTable;
14209    exports.DayTableModel = DayTableModel;
14210    exports.DayTableSlicer = DayTableSlicer;
14211    exports.DayTimeCols = DayTimeCols;
14212    exports.DayTimeColsSlicer = DayTimeColsSlicer;
14213    exports.DayTimeColsView = DayTimeColsView;
14214    exports.DelayedRunner = DelayedRunner;
14215    exports.Draggable = ExternalDraggable;
14216    exports.ElementDragging = ElementDragging;
14217    exports.ElementScrollController = ElementScrollController;
14218    exports.Emitter = Emitter;
14219    exports.EventApi = EventApi;
14220    exports.EventRoot = EventRoot;
14221    exports.EventSourceApi = EventSourceApi;
14222    exports.FeaturefulElementDragging = FeaturefulElementDragging;
14223    exports.Fragment = Fragment;
14224    exports.Interaction = Interaction;
14225    exports.ListView = ListView;
14226    exports.MountHook = MountHook;
14227    exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
14228    exports.NowIndicatorRoot = NowIndicatorRoot;
14229    exports.NowTimer = NowTimer;
14230    exports.PointerDragging = PointerDragging;
14231    exports.PositionCache = PositionCache;
14232    exports.RefMap = RefMap;
14233    exports.RenderHook = RenderHook;
14234    exports.ScrollController = ScrollController;
14235    exports.ScrollResponder = ScrollResponder;
14236    exports.Scroller = Scroller;
14237    exports.SimpleScrollGrid = SimpleScrollGrid;
14238    exports.Slicer = Slicer;
14239    exports.Splitter = Splitter;
14240    exports.StandardEvent = StandardEvent;
14241    exports.Table = Table;
14242    exports.TableDateCell = TableDateCell;
14243    exports.TableDowCell = TableDowCell;
14244    exports.TableView = TableView;
14245    exports.Theme = Theme;
14246    exports.ThirdPartyDraggable = ThirdPartyDraggable;
14247    exports.TimeCols = TimeCols;
14248    exports.TimeColsSlatsCoords = TimeColsSlatsCoords;
14249    exports.TimeColsView = TimeColsView;
14250    exports.ViewApi = ViewApi;
14251    exports.ViewContextType = ViewContextType;
14252    exports.ViewRoot = ViewRoot;
14253    exports.WeekNumberRoot = WeekNumberRoot;
14254    exports.WindowScrollController = WindowScrollController;
14255    exports.addDays = addDays;
14256    exports.addDurations = addDurations;
14257    exports.addMs = addMs;
14258    exports.addWeeks = addWeeks;
14259    exports.allowContextMenu = allowContextMenu;
14260    exports.allowSelection = allowSelection;
14261    exports.applyMutationToEventStore = applyMutationToEventStore;
14262    exports.applyStyle = applyStyle;
14263    exports.applyStyleProp = applyStyleProp;
14264    exports.asCleanDays = asCleanDays;
14265    exports.asRoughMinutes = asRoughMinutes;
14266    exports.asRoughMs = asRoughMs;
14267    exports.asRoughSeconds = asRoughSeconds;
14268    exports.buildClassNameNormalizer = buildClassNameNormalizer;
14269    exports.buildDayRanges = buildDayRanges;
14270    exports.buildDayTableModel = buildDayTableModel;
14271    exports.buildEventApis = buildEventApis;
14272    exports.buildEventRangeKey = buildEventRangeKey;
14273    exports.buildHashFromArray = buildHashFromArray;
14274    exports.buildNavLinkData = buildNavLinkData;
14275    exports.buildSegCompareObj = buildSegCompareObj;
14276    exports.buildSegTimeText = buildSegTimeText;
14277    exports.buildSlatMetas = buildSlatMetas;
14278    exports.buildTimeColsModel = buildTimeColsModel;
14279    exports.collectFromHash = collectFromHash;
14280    exports.combineEventUis = combineEventUis;
14281    exports.compareByFieldSpec = compareByFieldSpec;
14282    exports.compareByFieldSpecs = compareByFieldSpecs;
14283    exports.compareNumbers = compareNumbers;
14284    exports.compareObjs = compareObjs;
14285    exports.computeEdges = computeEdges;
14286    exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
14287    exports.computeHeightAndMargins = computeHeightAndMargins;
14288    exports.computeInnerRect = computeInnerRect;
14289    exports.computeRect = computeRect;
14290    exports.computeSegDraggable = computeSegDraggable;
14291    exports.computeSegEndResizable = computeSegEndResizable;
14292    exports.computeSegStartResizable = computeSegStartResizable;
14293    exports.computeShrinkWidth = computeShrinkWidth;
14294    exports.computeSmallestCellWidth = computeSmallestCellWidth;
14295    exports.computeVisibleDayRange = computeVisibleDayRange;
14296    exports.config = config;
14297    exports.constrainPoint = constrainPoint;
14298    exports.createContext = createContext$1;
14299    exports.createDuration = createDuration;
14300    exports.createElement = createElement;
14301    exports.createEmptyEventStore = createEmptyEventStore;
14302    exports.createEventInstance = createEventInstance;
14303    exports.createEventUi = createEventUi;
14304    exports.createFormatter = createFormatter;
14305    exports.createPlugin = createPlugin;
14306    exports.createRef = createRef;
14307    exports.diffDates = diffDates;
14308    exports.diffDayAndTime = diffDayAndTime;
14309    exports.diffDays = diffDays;
14310    exports.diffPoints = diffPoints;
14311    exports.diffWeeks = diffWeeks;
14312    exports.diffWholeDays = diffWholeDays;
14313    exports.diffWholeWeeks = diffWholeWeeks;
14314    exports.disableCursor = disableCursor;
14315    exports.elementClosest = elementClosest;
14316    exports.elementMatches = elementMatches;
14317    exports.enableCursor = enableCursor;
14318    exports.eventTupleToStore = eventTupleToStore;
14319    exports.filterEventStoreDefs = filterEventStoreDefs;
14320    exports.filterHash = filterHash;
14321    exports.findDirectChildren = findDirectChildren;
14322    exports.findElements = findElements;
14323    exports.flexibleCompare = flexibleCompare;
14324    exports.flushToDom = flushToDom$1;
14325    exports.formatDate = formatDate;
14326    exports.formatDayString = formatDayString;
14327    exports.formatIsoTimeString = formatIsoTimeString;
14328    exports.formatRange = formatRange;
14329    exports.getAllowYScrolling = getAllowYScrolling;
14330    exports.getCanVGrowWithinCell = getCanVGrowWithinCell;
14331    exports.getClippingParents = getClippingParents;
14332    exports.getDateMeta = getDateMeta;
14333    exports.getDayClassNames = getDayClassNames;
14334    exports.getDefaultEventEnd = getDefaultEventEnd;
14335    exports.getElSeg = getElSeg;
14336    exports.getEventClassNames = getEventClassNames;
14337    exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft;
14338    exports.getRectCenter = getRectCenter;
14339    exports.getRelevantEvents = getRelevantEvents;
14340    exports.getScrollGridClassNames = getScrollGridClassNames;
14341    exports.getScrollbarWidths = getScrollbarWidths;
14342    exports.getSectionClassNames = getSectionClassNames;
14343    exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight;
14344    exports.getSegMeta = getSegMeta;
14345    exports.getSlotClassNames = getSlotClassNames;
14346    exports.getStickyFooterScrollbar = getStickyFooterScrollbar;
14347    exports.getStickyHeaderDates = getStickyHeaderDates;
14348    exports.getUnequalProps = getUnequalProps;
14349    exports.globalLocales = globalLocales;
14350    exports.globalPlugins = globalPlugins;
14351    exports.greatestDurationDenominator = greatestDurationDenominator;
14352    exports.guid = guid;
14353    exports.hasBgRendering = hasBgRendering;
14354    exports.hasShrinkWidth = hasShrinkWidth;
14355    exports.identity = identity;
14356    exports.interactionSettingsStore = interactionSettingsStore;
14357    exports.interactionSettingsToStore = interactionSettingsToStore;
14358    exports.intersectRanges = intersectRanges;
14359    exports.intersectRects = intersectRects;
14360    exports.isArraysEqual = isArraysEqual;
14361    exports.isColPropsEqual = isColPropsEqual;
14362    exports.isDateSpansEqual = isDateSpansEqual;
14363    exports.isInt = isInt;
14364    exports.isInteractionValid = isInteractionValid;
14365    exports.isMultiDayRange = isMultiDayRange;
14366    exports.isPropsEqual = isPropsEqual;
14367    exports.isPropsValid = isPropsValid;
14368    exports.isValidDate = isValidDate;
14369    exports.listenBySelector = listenBySelector;
14370    exports.mapHash = mapHash;
14371    exports.memoize = memoize;
14372    exports.memoizeArraylike = memoizeArraylike;
14373    exports.memoizeHashlike = memoizeHashlike;
14374    exports.memoizeObjArg = memoizeObjArg;
14375    exports.mergeEventStores = mergeEventStores;
14376    exports.multiplyDuration = multiplyDuration;
14377    exports.padStart = padStart;
14378    exports.parseBusinessHours = parseBusinessHours;
14379    exports.parseClassNames = parseClassNames;
14380    exports.parseDragMeta = parseDragMeta;
14381    exports.parseEventDef = parseEventDef;
14382    exports.parseFieldSpecs = parseFieldSpecs;
14383    exports.parseMarker = parse;
14384    exports.pointInsideRect = pointInsideRect;
14385    exports.preventContextMenu = preventContextMenu;
14386    exports.preventDefault = preventDefault;
14387    exports.preventSelection = preventSelection;
14388    exports.rangeContainsMarker = rangeContainsMarker;
14389    exports.rangeContainsRange = rangeContainsRange;
14390    exports.rangesEqual = rangesEqual;
14391    exports.rangesIntersect = rangesIntersect;
14392    exports.refineEventDef = refineEventDef;
14393    exports.refineProps = refineProps;
14394    exports.removeElement = removeElement;
14395    exports.removeExact = removeExact;
14396    exports.render = render;
14397    exports.renderChunkContent = renderChunkContent;
14398    exports.renderFill = renderFill;
14399    exports.renderMicroColGroup = renderMicroColGroup;
14400    exports.renderScrollShim = renderScrollShim;
14401    exports.requestJson = requestJson;
14402    exports.sanitizeShrinkWidth = sanitizeShrinkWidth;
14403    exports.setElSeg = setElSeg;
14404    exports.setRef = setRef;
14405    exports.sliceEventStore = sliceEventStore;
14406    exports.sliceEvents = sliceEvents;
14407    exports.sortEventSegs = sortEventSegs;
14408    exports.startOfDay = startOfDay;
14409    exports.translateRect = translateRect;
14410    exports.triggerDateSelect = triggerDateSelect;
14411    exports.unpromisify = unpromisify;
14412    exports.version = version;
14413    exports.whenTransitionDone = whenTransitionDone;
14414    exports.wholeDivideDurations = wholeDivideDurations;
14415
14416    return exports;
14417
14418}({}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.