PageSourceSearch

https://www.fukura-ph.co.jp/libs/plugin/fullcalendar/main.js

js fukura-ph.co.jp collected 2026-10-06 08:17:56 UTC 699,292 bytes, 14,639 lines download raw bytes

vendor: 4,325 bytes, lines 1-57
1/*!
2FullCalendar v5.7.2
3Docs & License: https://fullcalendar.io/
4(c) 2021 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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
29        return extendStatics(d, b);
30    };
31
32    function __extends(d, b) {
33        if (typeof b !== "function" && b !== null)
34            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
35        extendStatics(d, b);
36        function __() { this.constructor = d; }
37        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
38    }
39
40    var __assign = function() {
41        __assign = Object.assign || function __assign(t) {
42            for (var s, i = 1, n = arguments.length; i < n; i++) {
43                s = arguments[i];
44                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
45            }
46            return t;
47        };
48        return __assign.apply(this, arguments);
49    };
50
51    function __spreadArray(to, from) {
52        for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
53            to[j] = from[i];
54        return to;
55    }
56
57    var n,u,i$1,t,o,r$1={},f$1=[],e$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c$1(n,l){for(var u in l)n[u]=l[u];return n}function s(n){var l=n.parentNode;l&&l.removeChild(n);}function a$1(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return v$1(n,f,i,t,null)}function v$1(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n.__v:o};return null!=n.vnode&&n.vnode(r),r}function h(){return {current:null}}function y(n){return n.children}function p(n,l){this.props=n,this.context=l;}function d(n,l){if(null==l)return n.__?d(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?d(n):null}function _(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 _(n)}}function k(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!b$1.__r++||t!==n.debounceRendering)&&((t=n.debounceRendering)||i$1)(b$1);}function b$1(){for(var n;b$1.__r=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,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=c$1({},t)).__v=t.__v+1,I$1(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?d(t):o,t.__h),T$1(u,t),t.__e!=o&&_(t)));});}function m(n,l,u,i,t,o,e,c,s,a){var h,p,_,k,b,m,w,A=i&&i.__k||f$1,P=A.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?v$1(null,k,null,null,k):Array.isArray(k)?v$1(y,{children:k},null,null,null):k.__b>
vendor: 7,710 bytes, line 57
570?v$1(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(_=A[h])||_&&k.key==_.key&&k.type===_.type)A[h]=void 0;else for(p=0;p<P;p++){if((_=A[p])&&k.key==_.key&&k.type===_.type){A[p]=void 0;break}_=null;}I$1(n,k,_=_||r$1,t,o,e,c,s,a),b=k.__e,(p=k.ref)&&_.ref!=p&&(w||(w=[]),_.ref&&w.push(_.ref,null,k),w.push(p,k.__c||b,k)),null!=b?(null==m&&(m=b),"function"==typeof k.type&&null!=k.__k&&k.__k===_.__k?k.__d=s=g$1(k,s,n):s=x$1(n,k,_,A,b,s),a||"option"!==u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&_.__e==s&&s.parentNode!=n&&(s=d(_));}for(u.__e=m,h=P;h--;)null!=A[h]&&("function"==typeof u.type&&null!=A[h].__e&&A[h].__e==u.__d&&(u.__d=d(i,h+1)),L$1(A[h],A[h]));if(w)for(h=0;h<w.length;h++)z(w[h],w[++h],w[++h]);}function g$1(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l="function"==typeof t.type?g$1(t,l,u):x$1(u,t,t,n.__k,t.__e,l));return l}function w$1(n,l){return l=l||[],null==n||"boolean"==typeof n||(Array.isArray(n)?n.some(function(n){w$1(n,l);}):l.push(n)),l}function x$1(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else {for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o;}return void 0!==r?r:t.nextSibling}function A$1(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||C$1(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||C$1(n,o,l[o],u[o],i);}function P$1(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||e$1.test(l)?u:u+"px";}function C$1(n,l,u,i,t){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||P$1(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||P$1(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?H$1:$$1,o):n.removeEventListener(l,o?H$1:$$1,o);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeAttribute(l));}}function $$1(l){this.l[l.type+!1](n.event?n.event(l):l);}function H$1(l){this.l[l.type+!0](n.event?n.event(l):l);}function I$1(l,u,i,t,o,r,f,e,s){var a,v,h,d,_,k,b,g,w,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(s=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,w=(a=P.contextType)&&t[a.__c],x=a?w?w.props.value:a.__:t,i.__c?b=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new p(g,x),v.constructor=P,v.render=M$1),w&&w.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=c$1({},v.__s)),c$1(v.__s,P.getDerivedStateFromProps(g,v.__s))),d=v.props,_=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!==d&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){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,u.__k.forEach(function(n){n&&(n.__=u);}),v.__h.length&&f.push(v);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(d,_,k);});}v.context=x,v.props=g,v.state=v.__s,(a=n.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=c$1(c$1({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(k=v.getSnapshotBeforeUpdate(d,_)),A=null!=a&&a.type===y&&null==a.key?a.props.children:a,m(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,s),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),b&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=j$2(i.__e,u,i,t,o,r,f,s);(a=n.diffed)&&a(u);}catch(l){u.__v=null,(s||null!=r)&&(u.__e=e,u.__h=!!s,r[r.indexOf(e)]=null),n.__e(l,u,i);}}function T$1(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 j$2(n,l,u,i,t,o,e,c){var a,v,h,y,p=u.props,d=l.props,_=l.type,k=0;if("svg"===_&&(t=!0),null!=o)for(;k<o.length;k++)if((a=o[k])&&(a===n||(_?a.localName==_:3==a.nodeType))){n=a,o[k]=null;break}if(null==n){if(null===_)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",_):document.createElement(_,d.is&&d),o=null,c=!1;}if(null===_)p===d||c&&n.data===d||(n.data=d);else {if(o=o&&f$1.slice.call(n.childNodes),v=(p=u.props||r$1).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}if(A$1(n,d,p,t,c),h)l.__k=[];else if(k=l.props.children,m(n,Array.isArray(k)?k:[k],l,u,i,t&&"foreignObject"!==_,o,e,n.firstChild,c),null!=o)for(k=o.length;k--;)null!=o[k]&&s(o[k]);c||("value"in d&&void 0!==(k=d.value)&&(k!==n.value||"progress"===_&&!k)&&C$1(n,"value",k,p.value,!1),"checked"in d&&void 0!==(k=d.checked)&&k!==n.checked&&C$1(n,"checked",k,p.checked,!1));}return n}function z(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function L$1(l,u,i){var t,o,r;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||z(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=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(r=0;r<t.length;r++)t[r]&&L$1(t[r],u,i);null!=o&&s(o);}function M$1(n,l,u){return this.constructor(n,u)}function N(l,u,i){var t,o,e;n.__&&n.__(l,u),o=(t="function"==typeof i)?null:i&&i.__k||u.__k,e=[],I$1(u,l=(!t&&i||u).__k=a$1(y,null,[l]),o||r$1,r$1,void 0!==u.ownerSVGElement,!t&&i?[i]:o?null:u.firstChild?f$1.slice.call(u.childNodes):null,e,!t&&i?i:o?o.__e:u.firstChild,t),T$1(e,l);}function q(n,l){var u={__c:l="__cC"+o++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(k);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n},__v:0},p.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=c$1({},this.state),"function"==typeof n&&(n=n(c$1({},u),this.props)),n&&c$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this));},p.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this));},p.prototype.render=y,u=[],i$1="function"==typeof Promise?Promise.prototype.then.bind(Prom
vendor: 5,073 bytes, lines 57-61
57ise.resolve()):setTimeout,b$1.__r=0,o=0;
58
59    var r,i=[],c=n.__b,f=n.__r,e=n.diffed,a=n.__c,v=n.unmount;function x(){i.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],n.__e(u,t.__v);}}),i=[];}n.__b=function(n){c&&c(n);},n.__r=function(n){f&&f(n);var r=(n.__c).__H;r&&(r.__h.forEach(g),r.__h.forEach(j$1),r.__h=[]);},n.diffed=function(t){e&&e(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i.push(o)&&r===n.requestAnimationFrame||((r=n.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x));},n.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],n.__e(r,t.__v);}}),a&&a(t,u);},n.unmount=function(t){v&&v(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g);}catch(t){n.__e(t,u.__v);}};var b="function"==typeof requestAnimationFrame;function g(n){"function"==typeof n.__c&&n.__c();}function j$1(n){n.__c=n.__();}
60
61    function C(n,t){for(var e in t)n[e]=t[e];return n}function S(n,t){for(var e in n)if("__source"!==e&&!(e in t))return !0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return !0;return !1}function E(n){this.props=n;}(E.prototype=new p).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return S(this.props,n)||S(this.state,t)};var w=n.__b;n.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n);};var A=n.__e;n.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e);};var O=n.unmount;function L(){this.__u=0,this.t=null,this.__b=null;}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function F(){this.u=null,this.o=null;}n.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n);},(L.prototype=new p).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l());};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O);}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate();}},f=!0===t.__h;r.__u++||f||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i);},L.prototype.componentWillUnmount=function(){this.t=[];},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c();}),t.__c.__H=null),null!=(t=C({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P);}this.__b=null;}var u=t.__e&&a$1(y,null,n.fallback);return u&&(u.__h=null),[a$1(y,null,t.__e?null:n.children),u]};var M=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]<e[0])break;n.u=e=e[2];}};function T(n){return this.getChildContext=function(){return n.context},n.children}function j(n){var t=this,e=n.i;t.componentWillUnmount=function(){N(null,t.l),t.l=null,t.i=null;},t.i&&t.i!==e&&t.componentWillUnmount(),n.__v?(t.l||(t.i=e,t.l={nodeType:1,parentNode:e,childNodes:[],appendChild:function(n){this.childNodes.push(n),t.i.appendChild(n);},insertBefore:function(n,e){this.childNodes.push(n),t.i.appendChild(n);},removeChild:function(n){this.childNodes.splice(this.childNodes.indexOf(n)>>>1,1),t.i.removeChild(n);}}),N(a$1(T,{context:t.context},n.__v),t.l)):t.l&&t.componentWillUnmount();}function I(n,t){return a$1(j,{__v:n,i:t})}(F.prototype=new p).__e=function(n){var t=this,e=U(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),M(t,n,r)):u();};e?e(o):o();}},F.prototype.render=function(n){this.u=null,this.o=new Map;var t=w$1(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},F.prototype.componentDidUpdate=F.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){M(n,e,t);});};var W="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,P=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,V=function(n){return ("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};p.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(n){Object.defineProperty(p.prototype,n,{
61configurable:!0,get:function(){return this["UNSAFE_"+n]},set:function(t){Object.defineProperty(this,n,{configurable:!0,writable:!0,value:t});}});});var H=n.event;function Z(){}function Y(){return this.cancelBubble}function $(){return this.defaultPrevented}n.event=function(n){return H&&(n=H(n)),n.persist=Z,n.isPropagationStopped=Y,n.isDefaultPrevented=$,n.nativeEvent=n};var G={configurable:!0,get:function(){return this.class}},J=n.vnode;n.vnode=function(n){var t=n.type,e=n.props,r=e;if("string"==typeof t){for(var u in r={},e){var o=e[u];"value"===u&&"defaultValue"in e&&null==o||("defaultValue"===u&&"value"in e&&null==e.value?u="value":"download"===u&&!0===o?o="":/ondoubleclick/i.test(u)?u="ondblclick":/^onchange(textarea|input)/i.test(u+t)&&!V(e.type)?u="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(u)?u=u.toLowerCase():P.test(u)?u=u.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===o&&(o=void 0),r[u]=o);}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=-1!=r.value.indexOf(n.props.value);})),"select"==t&&null!=r.defaultValue&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=r.multiple?-1!=r.defaultValue.indexOf(n.props.value):r.defaultValue==n.props.value;})),n.props=r;}t&&e.class!=e.className&&(G.enumerable="className"in e,null!=e.className&&(r.class=e.className),Object.defineProperty(r,"className",G)),n.$$typeof=W,J&&J(n);};var K=n.__r;n.__r=function(n){K&&K(n);};"object"==typeof performance&&"function"==typeof performance.now?performance.now.bind(performance):function(){return Date.now()};
62
63    var globalObj = typeof globalThis !== 'undefined' ? globalThis : window; // // TODO: streamline when killing IE11 support
64    if (globalObj.FullCalendarVDom) {
65        console.warn('FullCalendar VDOM already loaded');
66    }
67    else {
68        globalObj.FullCalendarVDom = {
69            Component: p,
70            createElement: a$1,
71            render: N,
72            createRef: h,
73            Fragment: y,
74            createContext: createContext$1,
75            createPortal: I,
76            flushToDom: flushToDom$1,
77            unmountComponentAtNode: unmountComponentAtNode$1,
78        };
79    }
80    // HACKS...
81    // TODO: lock version
82    // TODO: link gh issues
83    function flushToDom$1() {
84        var oldDebounceRendering = n.debounceRendering; // orig
85        var callbackQ = [];
86        function execCallbackSync(callback) {
87            callbackQ.push(callback);
88        }
89        n.debounceRendering = execCallbackSync;
90        N(a$1(FakeComponent, {}), document.createElement('div'));
91        while (callbackQ.length) {
92            callbackQ.shift()();
93        }
94        n.debounceRendering = oldDebounceRendering;
95    }
96    var FakeComponent = /** @class */ (function (_super) {
97        __extends(FakeComponent, _super);
98        function FakeComponent() {
99            return _super !== null && _super.apply(this, arguments) || this;
100        }
101        FakeComponent.prototype.render = function () { return a$1('div', {}); };
102        FakeComponent.prototype.componentDidMount = function () { this.setState({}); };
103        return FakeComponent;
104    }(p));
105    function createContext$1(defaultValue) {
106        var ContextType = q(defaultValue);
107        var origProvider = ContextType.Provider;
108        ContextType.Provider = function () {
109            var _this = this;
110            var isNew = !this.getChildContext;
111            var children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params
112            if (isNew) {
113                var subs_1 = [];
114                this.shouldComponentUpdate = function (_props) {
115                    if (_this.props.value !== _props.value) {
116                        subs_1.forEach(function (c) {
117                            c.context = _props.value;
118                            c.forceUpdate();
119                        });
120                    }
121                };
122                this.sub = function (c) {
123                    subs_1.push(c);
124                    var old = c.componentWillUnmount;
125                    c.componentWillUnmount = function () {
126                        subs_1.splice(subs_1.indexOf(c), 1);
127                        old && old.call(c);
128                    };
129                };
130            }
131            return children;
132        };
133        return ContextType;
134    }
135    function unmountComponentAtNode$1(node) {
136        N(null, node);
137    }
138
139    // no public types yet. when there are, export from:
140    // import {} from './api-type-deps'
141    var EventSourceApi = /** @class */ (function () {
142        function EventSourceApi(context, internalEventSource) {
143            this.context = context;
144            this.internalEventSource = internalEventSource;
145        }
146        EventSourceApi.prototype.remove = function () {
147            this.context.dispatch({
148                type: 'REMOVE_EVENT_SOURCE',
149                sourceId: this.internalEventSource.sourceId,
150            });
151        };
152        EventSourceApi.prototype.refetch = function () {
153            this.context.dispatch({
154                type: 'FETCH_EVENT_SOURCES',
155                sourceIds: [this.internalEventSource.sourceId],
156                isRefetch: true,
157            });
158        };
159        Object.defineProperty(EventSourceApi.prototype, "id", {
160            get: function () {
161                return this.internalEventSource.publicId;
162            },
163            enumerable: false,
164            configurable: true
165        });
166        Object.defineProperty(EventSourceApi.prototype, "url", {
167            get: function () {
168                return this.internalEventSource.meta.url;
169            },
170            enumerable: false,
171            configurable: true
172        });
173        Object.defineProperty(EventSourceApi.prototype, "format", {
174            get: function () {
175                return this.internalEventSource.meta.format; // TODO: bad. not guaranteed
176            },
177            enumerable: false,
178            configurable: true
179        });
180        return EventSourceApi;
181    }());
182
183    function removeElement(el) {
184        if (el.parentNode) {
185            el.parentNode.removeChild(el);
186        }
187    }
188    // Querying
189    // ----------------------------------------------------------------------------------------------------------------
190    function elementClosest(el, selector) {
191        if (el.closest) {
192            return el.closest(selector);
193            // really bad fallback for IE
194            // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
195        }
196        if (!document.documentElement.contains(el)) {
197            return null;
198        }
199        do {
200            if (elementMatches(el, selector)) {
201                return el;
202            }
203            el = (el.parentElement || el.parentNode);
204        } while (el !== null && el.nodeType === 1);
205        return null;
206    }
207    function elementMatches(el, selector) {
208        var method = el.matches || el.matchesSelector || el.msMatchesSelector;
209        return method.call(el, selector);
210    }
211    // accepts multiple subject els
212    // returns a real array. good for methods like forEach
213    // TODO: accept the document
214    function findElements(container, selector) {
215        var containers = container instanceof HTMLElement ? [container] : container;
216        var allMatches = [];
217        for (var i = 0; i < containers.length; i += 1) {
218            var matches = containers[i].querySelectorAll(selector);
219            for (var j = 0; j < matches.length; j += 1) {
220                allMatches.push(matches[j]);
221            }
222        }
223        return allMatches;
224    }
225    // accepts multiple subject els
226    // only queries direct child elements // TODO: rename to findDirectChildren!
227    function findDirectChildren(parent, selector) {
228        var parents = parent instanceof HTMLElement ? [parent] : parent;
229        var allMatches = [];
230        for (var i = 0; i < parents.length; i += 1) {
231            var childNodes = parents[i].children; // only ever elements
232            for (var j = 0; j < childNodes.length; j += 1) {
233                var childNode = childNodes[j];
234                if (!selector || elementMatches(childNode, selector)) {
235                    allMatches.push(childNode);
236                }
237            }
238        }
239        return allMatches;
240    }
241    // Style
242    // ----------------------------------------------------------------------------------------------------------------
243    var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
244    function applyStyle(el, props) {
245        for (var propName in props) {
246            applyStyleProp(el, propName, props[propName]);
247        }
248    }
249    function applyStyleProp(el, name, val) {
250        if (val == null) {
251            el.style[name] = '';
252        }
253        else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
254            el.style[name] = val + "px";
255        }
256        else {
257            el.style[name] = val;
258        }
259    }
260    // Event Handling
261    // ----------------------------------------------------------------------------------------------------------------
262    // if intercepting bubbled events at the document/window/body level,
263    // and want to see originating element (the 'target'), use this util instead
264    // of `ev.target` because it goes within web-component boundaries.
265    function getEventTargetViaRoot(ev) {
266        var _a, _b;
267        return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target;
268    }
269
270    // Stops a mouse/touch event from doing it's native browser action
271    function preventDefault(ev) {
272        ev.preventDefault();
273    }
274    // Event Delegation
275    // ----------------------------------------------------------------------------------------------------------------
276    function buildDelegationHandler(selector, handler) {
277        return function (ev) {
vendor: 15,134 bytes, lines 278-709
278            var matchedChild = elementClosest(ev.target, selector);
279            if (matchedChild) {
280                handler.call(matchedChild, ev, matchedChild);
281            }
282        };
283    }
284    function listenBySelector(container, eventType, selector, handler) {
285        var attachedHandler = buildDelegationHandler(selector, handler);
286        container.addEventListener(eventType, attachedHandler);
287        return function () {
288            container.removeEventListener(eventType, attachedHandler);
289        };
290    }
291    function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
292        var currentMatchedChild;
293        return listenBySelector(container, 'mouseover', selector, function (mouseOverEv, matchedChild) {
294            if (matchedChild !== currentMatchedChild) {
295                currentMatchedChild = matchedChild;
296                onMouseEnter(mouseOverEv, matchedChild);
297                var realOnMouseLeave_1 = function (mouseLeaveEv) {
298                    currentMatchedChild = null;
299                    onMouseLeave(mouseLeaveEv, matchedChild);
300                    matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
301                };
302                // listen to the next mouseleave, and then unattach
303                matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
304            }
305        });
306    }
307    // Animation
308    // ----------------------------------------------------------------------------------------------------------------
309    var transitionEventNames = [
310        'webkitTransitionEnd',
311        'otransitionend',
312        'oTransitionEnd',
313        'msTransitionEnd',
314        'transitionend',
315    ];
316    // triggered only when the next single subsequent transition finishes
317    function whenTransitionDone(el, callback) {
318        var realCallback = function (ev) {
319            callback(ev);
320            transitionEventNames.forEach(function (eventName) {
321                el.removeEventListener(eventName, realCallback);
322            });
323        };
324        transitionEventNames.forEach(function (eventName) {
325            el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
326        });
327    }
328
329    var guidNumber = 0;
330    function guid() {
331        guidNumber += 1;
332        return String(guidNumber);
333    }
334    /* FullCalendar-specific DOM Utilities
335    ----------------------------------------------------------------------------------------------------------------------*/
336    // Make the mouse cursor express that an event is not allowed in the current area
337    function disableCursor() {
338        document.body.classList.add('fc-not-allowed');
339    }
340    // Returns the mouse cursor to its original look
341    function enableCursor() {
342        document.body.classList.remove('fc-not-allowed');
343    }
344    /* Selection
345    ----------------------------------------------------------------------------------------------------------------------*/
346    function preventSelection(el) {
347        el.classList.add('fc-unselectable');
348        el.addEventListener('selectstart', preventDefault);
349    }
350    function allowSelection(el) {
351        el.classList.remove('fc-unselectable');
352        el.removeEventListener('selectstart', preventDefault);
353    }
354    /* Context Menu
355    ----------------------------------------------------------------------------------------------------------------------*/
356    function preventContextMenu(el) {
357        el.addEventListener('contextmenu', preventDefault);
358    }
359    function allowContextMenu(el) {
360        el.removeEventListener('contextmenu', preventDefault);
361    }
362    function parseFieldSpecs(input) {
363        var specs = [];
364        var tokens = [];
365        var i;
366        var token;
367        if (typeof input === 'string') {
368            tokens = input.split(/\s*,\s*/);
369        }
370        else if (typeof input === 'function') {
371            tokens = [input];
372        }
373        else if (Array.isArray(input)) {
374            tokens = input;
375        }
376        for (i = 0; i < tokens.length; i += 1) {
377            token = tokens[i];
378            if (typeof token === 'string') {
379                specs.push(token.charAt(0) === '-' ?
380                    { field: token.substring(1), order: -1 } :
381                    { field: token, order: 1 });
382            }
383            else if (typeof token === 'function') {
384                specs.push({ func: token });
385            }
386        }
387        return specs;
388    }
389    function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
390        var i;
391        var cmp;
392        for (i = 0; i < fieldSpecs.length; i += 1) {
393            cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
394            if (cmp) {
395                return cmp;
396            }
397        }
398        return 0;
399    }
400    function compareByFieldSpec(obj0, obj1, fieldSpec) {
401        if (fieldSpec.func) {
402            return fieldSpec.func(obj0, obj1);
403        }
404        return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
405            * (fieldSpec.order || 1);
406    }
407    function flexibleCompare(a, b) {
408        if (!a && !b) {
409            return 0;
410        }
411        if (b == null) {
412            return -1;
413        }
414        if (a == null) {
415            return 1;
416        }
417        if (typeof a === 'string' || typeof b === 'string') {
418            return String(a).localeCompare(String(b));
419        }
420        return a - b;
421    }
422    /* String Utilities
423    ----------------------------------------------------------------------------------------------------------------------*/
424    function padStart(val, len) {
425        var s = String(val);
426        return '000'.substr(0, len - s.length) + s;
427    }
428    /* Number Utilities
429    ----------------------------------------------------------------------------------------------------------------------*/
430    function compareNumbers(a, b) {
431        return a - b;
432    }
433    function isInt(n) {
434        return n % 1 === 0;
435    }
436    /* FC-specific DOM dimension stuff
437    ----------------------------------------------------------------------------------------------------------------------*/
438    function computeSmallestCellWidth(cellEl) {
439        var allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame');
440        var contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion');
441        if (!allWidthEl) {
442            throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const
443        }
444        if (!contentWidthEl) {
445            throw new Error('needs fc-scrollgrid-shrink-cushion className');
446        }
447        return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border
448            contentWidthEl.getBoundingClientRect().width;
449    }
450
451    var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
452    // Adding
453    function addWeeks(m, n) {
454        var a = dateToUtcArray(m);
455        a[2] += n * 7;
456        return arrayToUtcDate(a);
457    }
458    function addDays(m, n) {
459        var a = dateToUtcArray(m);
460        a[2] += n;
461        return arrayToUtcDate(a);
462    }
463    function addMs(m, n) {
464        var a = dateToUtcArray(m);
465        a[6] += n;
466        return arrayToUtcDate(a);
467    }
468    // Diffing (all return floats)
469    // TODO: why not use ranges?
470    function diffWeeks(m0, m1) {
471        return diffDays(m0, m1) / 7;
472    }
473    function diffDays(m0, m1) {
474        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
475    }
476    function diffHours(m0, m1) {
477        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
478    }
479    function diffMinutes(m0, m1) {
480        return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
481    }
482    function diffSeconds(m0, m1) {
483        return (m1.valueOf() - m0.valueOf()) / 1000;
484    }
485    function diffDayAndTime(m0, m1) {
486        var m0day = startOfDay(m0);
487        var m1day = startOfDay(m1);
488        return {
489            years: 0,
490            months: 0,
491            days: Math.round(diffDays(m0day, m1day)),
492            milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()),
493        };
494    }
495    // Diffing Whole Units
496    function diffWholeWeeks(m0, m1) {
497        var d = diffWholeDays(m0, m1);
498        if (d !== null && d % 7 === 0) {
499            return d / 7;
500        }
501        return null;
502    }
503    function diffWholeDays(m0, m1) {
504        if (timeAsMs(m0) === timeAsMs(m1)) {
505            return Math.round(diffDays(m0, m1));
506        }
507        return null;
508    }
509    // Start-Of
510    function startOfDay(m) {
511        return arrayToUtcDate([
512            m.getUTCFullYear(),
513            m.getUTCMonth(),
514            m.getUTCDate(),
515        ]);
516    }
517    function startOfHour(m) {
518        return arrayToUtcDate([
519            m.getUTCFullYear(),
520            m.getUTCMonth(),
521            m.getUTCDate(),
522            m.getUTCHours(),
523        ]);
524    }
525    function startOfMinute(m) {
526        return arrayToUtcDate([
527            m.getUTCFullYear(),
528            m.getUTCMonth(),
529            m.getUTCDate(),
530            m.getUTCHours(),
531            m.getUTCMinutes(),
532        ]);
533    }
534    function startOfSecond(m) {
535        return arrayToUtcDate([
536            m.getUTCFullYear(),
537            m.getUTCMonth(),
538            m.getUTCDate(),
539            m.getUTCHours(),
540            m.getUTCMinutes(),
541            m.getUTCSeconds(),
542        ]);
543    }
544    // Week Computation
545    function weekOfYear(marker, dow, doy) {
546        var y = marker.getUTCFullYear();
547        var w = weekOfGivenYear(marker, y, dow, doy);
548        if (w < 1) {
549            return weekOfGivenYear(marker, y - 1, dow, doy);
550        }
551        var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
552        if (nextW >= 1) {
553            return Math.min(w, nextW);
554        }
555        return w;
556    }
557    function weekOfGivenYear(marker, year, dow, doy) {
558        var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
559        var dayStart = startOfDay(marker);
560        var days = Math.round(diffDays(firstWeekStart, dayStart));
561        return Math.floor(days / 7) + 1; // zero-indexed
562    }
563    // start-of-first-week - start-of-year
564    function firstWeekOffset(year, dow, doy) {
565        // first-week day -- which january is always in the first week (4 for iso, 1 for other)
566        var fwd = 7 + dow - doy;
567        // first-week day local weekday -- which local weekday is fwd
568        var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
569        return -fwdlw + fwd - 1;
570    }
571    // Array Conversion
572    function dateToLocalArray(date) {
573        return [
574            date.getFullYear(),
575            date.getMonth(),
576            date.getDate(),
577            date.getHours(),
578            date.getMinutes(),
579            date.getSeconds(),
580            date.getMilliseconds(),
581        ];
582    }
583    function arrayToLocalDate(a) {
584        return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
585        a[3] || 0, a[4] || 0, a[5] || 0);
586    }
587    function dateToUtcArray(date) {
588        return [
589            date.getUTCFullYear(),
590            date.getUTCMonth(),
591            date.getUTCDate(),
592            date.getUTCHours(),
593            date.getUTCMinutes(),
594            date.getUTCSeconds(),
595            date.getUTCMilliseconds(),
596        ];
597    }
598    function arrayToUtcDate(a) {
599        // according to web standards (and Safari), a month index is required.
600        // massage if only given a year.
601        if (a.length === 1) {
602            a = a.concat([0]);
603        }
604        return new Date(Date.UTC.apply(Date, a));
605    }
606    // Other Utils
607    function isValidDate(m) {
608        return !isNaN(m.valueOf());
609    }
610    function timeAsMs(m) {
611        return m.getUTCHours() * 1000 * 60 * 60 +
612            m.getUTCMinutes() * 1000 * 60 +
613            m.getUTCSeconds() * 1000 +
614            m.getUTCMilliseconds();
615    }
616
617    function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
618        return {
619            instanceId: guid(),
620            defId: defId,
621            range: range,
622            forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
623            forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo,
624        };
625    }
626
627    var hasOwnProperty = Object.prototype.hasOwnProperty;
628    // Merges an array of objects into a single object.
629    // The second argument allows for an array of property names who's object values will be merged together.
630    function mergeProps(propObjs, complexPropsMap) {
631        var dest = {};
632        if (complexPropsMap) {
633            for (var name_1 in complexPropsMap) {
634                var complexObjs = [];
635                // collect the trailing object values, stopping when a non-object is discovered
636                for (var i = propObjs.length - 1; i >= 0; i -= 1) {
637                    var val = propObjs[i][name_1];
638                    if (typeof val === 'object' && val) { // non-null object
639                        complexObjs.unshift(val);
640                    }
641                    else if (val !== undefined) {
642                        dest[name_1] = val; // if there were no objects, this value will be used
643                        break;
644                    }
645                }
646                // if the trailing values were objects, use the merged value
647                if (complexObjs.length) {
648                    dest[name_1] = mergeProps(complexObjs);
649                }
650            }
651        }
652        // copy values into the destination, going from last to first
653        for (var i = propObjs.length - 1; i >= 0; i -= 1) {
654            var props = propObjs[i];
655            for (var name_2 in props) {
656                if (!(name_2 in dest)) { // if already assigned by previous props or complex props, don't reassign
657                    dest[name_2] = props[name_2];
658                }
659            }
660        }
661        return dest;
662    }
663    function filterHash(hash, func) {
664        var filtered = {};
665        for (var key in hash) {
666            if (func(hash[key], key)) {
667                filtered[key] = hash[key];
668            }
669        }
670        return filtered;
671    }
672    function mapHash(hash, func) {
673        var newHash = {};
674        for (var key in hash) {
675            newHash[key] = func(hash[key], key);
676        }
677        return newHash;
678    }
679    function arrayToHash(a) {
680        var hash = {};
681        for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
682            var item = a_1[_i];
683            hash[item] = true;
684        }
685        return hash;
686    }
687    function buildHashFromArray(a, func) {
688        var hash = {};
689        for (var i = 0; i < a.length; i += 1) {
690            var tuple = func(a[i], i);
691            hash[tuple[0]] = tuple[1];
692        }
693        return hash;
694    }
695    function hashValuesToArray(obj) {
696        var a = [];
697        for (var key in obj) {
698            a.push(obj[key]);
699        }
700        return a;
701    }
702    function isPropsEqual(obj0, obj1) {
703        if (obj0 === obj1) {
704            return true;
705        }
706        for (var key in obj0) {
707            if (hasOwnProperty.call(obj0, key)) {
708                if (!(key in obj1)) {
709                    return false;
710                }
711            }
712        }
713        for (var key in obj1) {
714            if (hasOwnProperty.call(obj1, key)) {
715                if (obj0[key] !== obj1[key]) {
716                    return false;
717                }
718            }
719        }
720        return true;
721    }
722    function getUnequalProps(obj0, obj1) {
723        var keys = [];
724        for (var key in obj0) {
725            if (hasOwnProperty.call(obj0, key)) {
726                if (!(key in obj1)) {
727                    keys.push(key);
728                }
729            }
730        }
731        for (var key in obj1) {
732            if (hasOwnProperty.call(obj1, key)) {
733                if (obj0[key] !== obj1[key]) {
734                    keys.push(key);
735                }
736            }
737        }
738        return keys;
739    }
740    function compareObjs(oldProps, newProps, equalityFuncs) {
741        if (equalityFuncs === void 0) { equalityFuncs = {}; }
742        if (oldProps === newProps) {
743            return true;
744        }
745        for (var key in newProps) {
746            if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ;
747            else {
748                return false;
749            }
750        }
751        // check for props that were omitted in the new
752        for (var key in oldProps) {
753            if (!(key in newProps)) {
754                return false;
755            }
756        }
757        return true;
758    }
759    /*
760    assumed "true" equality for handler names like "onReceiveSomething"
761    */
762    function isObjValsEqual(val0, val1, comparator) {
763        if (val0 === val1 || comparator === true) {
764            return true;
765        }
766        if (comparator) {
767            return comparator(val0, val1);
768        }
769        return false;
770    }
771    function collectFromHash(hash, startIndex, endIndex, step) {
772        if (startIndex === void 0) { startIndex = 0; }
773        if (step === void 0) { step = 1; }
774        var res = [];
775        if (endIndex == null) {
776            endIndex = Object.keys(hash).length;
777        }
778        for (var i = startIndex; i < endIndex; i += step) {
779            var val = hash[i];
780            if (val !== undefined) { // will disregard undefined for sparse arrays
781                res.push(val);
782            }
783        }
784        return res;
785    }
786
787    function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) {
788        for (var i = 0; i < recurringTypes.length; i += 1) {
789            var parsed = recurringTypes[i].parse(refined, dateEnv);
790            if (parsed) {
791                var allDay = refined.allDay;
792                if (allDay == null) {
793                    allDay = defaultAllDay;
794                    if (allDay == null) {
795                        allDay = parsed.allDayGuess;
796                        if (allDay == null) {
797                            allDay = false;
798                        }
799                    }
800                }
801                return {
802                    allDay: allDay,
803                    duration: parsed.duration,
804                    typeData: parsed.typeData,
805                    typeId: i,
806                };
807            }
808        }
809        return null;
810    }
811    function expandRecurring(eventStore, framingRange, context) {
812        var dateEnv = context.dateEnv, pluginHooks = context.pluginHooks, options = context.options;
813        var defs = eventStore.defs, instances = eventStore.instances;
814        // remove existing recurring instances
815        // TODO: bad. always expand events as a second step
816        instances = filterHash(instances, function (instance) { return !defs[instance.defId].recurringDef; });
817        for (var defId in defs) {
818            var def = defs[defId];
819            if (def.recurringDef) {
820                var duration = def.recurringDef.duration;
821                if (!duration) {
822                    duration = def.allDay ?
823                        options.defaultAllDayEventDuration :
824                        options.defaultTimedEventDuration;
825                }
826                var starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes);
827                for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
828                    var start = starts_1[_i];
829                    var instance = createEventInstance(defId, {
830                        start: start,
831                        end: dateEnv.add(start, duration),
832                    });
833                    instances[instance.instanceId] = instance;
834                }
835            }
836        }
837        return { defs: defs, instances: instances };
838    }
839    /*
840    Event MUST have a recurringDef
841    */
842    function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
843        var typeDef = recurringTypes[eventDef.recurringDef.typeId];
844        var markers = typeDef.expand(eventDef.recurringDef.typeData, {
845            start: dateEnv.subtract(framingRange.start, duration),
846            end: framingRange.end,
847        }, dateEnv);
848        // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
849        if (eventDef.allDay) {
850            markers = markers.map(startOfDay);
851        }
852        return markers;
853    }
854
855    var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
vendor: 7,706 bytes, lines 856-1081
856    var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
857    // Parsing and Creation
858    function createDuration(input, unit) {
859        var _a;
860        if (typeof input === 'string') {
861            return parseString(input);
862        }
863        if (typeof input === 'object' && input) { // non-null object
864            return parseObject(input);
865        }
866        if (typeof input === 'number') {
867            return parseObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
868        }
869        return null;
870    }
871    function parseString(s) {
872        var m = PARSE_RE.exec(s);
873        if (m) {
874            var sign = m[1] ? -1 : 1;
875            return {
876                years: 0,
877                months: 0,
878                days: sign * (m[2] ? parseInt(m[2], 10) : 0),
879                milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
880                    (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
881                    (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
882                    (m[6] ? parseInt(m[6], 10) : 0) // ms
883                ),
884            };
885        }
886        return null;
887    }
888    function parseObject(obj) {
889        var duration = {
890            years: obj.years || obj.year || 0,
891            months: obj.months || obj.month || 0,
892            days: obj.days || obj.day || 0,
893            milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
894                (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
895                (obj.seconds || obj.second || 0) * 1000 + // seconds
896                (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms
897        };
898        var weeks = obj.weeks || obj.week;
899        if (weeks) {
900            duration.days += weeks * 7;
901            duration.specifiedWeeks = true;
902        }
903        return duration;
904    }
905    // Equality
906    function durationsEqual(d0, d1) {
907        return d0.years === d1.years &&
908            d0.months === d1.months &&
909            d0.days === d1.days &&
910            d0.milliseconds === d1.milliseconds;
911    }
912    function asCleanDays(dur) {
913        if (!dur.years && !dur.months && !dur.milliseconds) {
914            return dur.days;
915        }
916        return 0;
917    }
918    // Simple Math
919    function addDurations(d0, d1) {
920        return {
921            years: d0.years + d1.years,
922            months: d0.months + d1.months,
923            days: d0.days + d1.days,
924            milliseconds: d0.milliseconds + d1.milliseconds,
925        };
926    }
927    function subtractDurations(d1, d0) {
928        return {
929            years: d1.years - d0.years,
930            months: d1.months - d0.months,
931            days: d1.days - d0.days,
932            milliseconds: d1.milliseconds - d0.milliseconds,
933        };
934    }
935    function multiplyDuration(d, n) {
936        return {
937            years: d.years * n,
938            months: d.months * n,
939            days: d.days * n,
940            milliseconds: d.milliseconds * n,
941        };
942    }
943    // Conversions
944    // "Rough" because they are based on average-case Gregorian months/years
945    function asRoughYears(dur) {
946        return asRoughDays(dur) / 365;
947    }
948    function asRoughMonths(dur) {
949        return asRoughDays(dur) / 30;
950    }
951    function asRoughDays(dur) {
952        return asRoughMs(dur) / 864e5;
953    }
954    function asRoughMinutes(dur) {
955        return asRoughMs(dur) / (1000 * 60);
956    }
957    function asRoughSeconds(dur) {
958        return asRoughMs(dur) / 1000;
959    }
960    function asRoughMs(dur) {
961        return dur.years * (365 * 864e5) +
962            dur.months * (30 * 864e5) +
963            dur.days * 864e5 +
964            dur.milliseconds;
965    }
966    // Advanced Math
967    function wholeDivideDurations(numerator, denominator) {
968        var res = null;
969        for (var i = 0; i < INTERNAL_UNITS.length; i += 1) {
970            var unit = INTERNAL_UNITS[i];
971            if (denominator[unit]) {
972                var localRes = numerator[unit] / denominator[unit];
973                if (!isInt(localRes) || (res !== null && res !== localRes)) {
974                    return null;
975                }
976                res = localRes;
977            }
978            else if (numerator[unit]) {
979                // needs to divide by something but can't!
980                return null;
981            }
982        }
983        return res;
984    }
985    function greatestDurationDenominator(dur) {
986        var ms = dur.milliseconds;
987        if (ms) {
988            if (ms % 1000 !== 0) {
989                return { unit: 'millisecond', value: ms };
990            }
991            if (ms % (1000 * 60) !== 0) {
992                return { unit: 'second', value: ms / 1000 };
993            }
994            if (ms % (1000 * 60 * 60) !== 0) {
995                return { unit: 'minute', value: ms / (1000 * 60) };
996            }
997            if (ms) {
998                return { unit: 'hour', value: ms / (1000 * 60 * 60) };
999            }
1000        }
1001        if (dur.days) {
1002            if (dur.specifiedWeeks && dur.days % 7 === 0) {
1003                return { unit: 'week', value: dur.days / 7 };
1004            }
1005            return { unit: 'day', value: dur.days };
1006        }
1007        if (dur.months) {
1008            return { unit: 'month', value: dur.months };
1009        }
1010        if (dur.years) {
1011            return { unit: 'year', value: dur.years };
1012        }
1013        return { unit: 'millisecond', value: 0 };
1014    }
1015
1016    // timeZoneOffset is in minutes
1017    function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
1018        if (stripZeroTime === void 0) { stripZeroTime = false; }
1019        var s = marker.toISOString();
1020        s = s.replace('.000', '');
1021        if (stripZeroTime) {
1022            s = s.replace('T00:00:00Z', '');
1023        }
1024        if (s.length > 10) { // time part wasn't stripped, can add timezone info
1025            if (timeZoneOffset == null) {
1026                s = s.replace('Z', '');
1027            }
1028            else if (timeZoneOffset !== 0) {
1029                s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
1030            }
1031            // otherwise, its UTC-0 and we want to keep the Z
1032        }
1033        return s;
1034    }
1035    // formats the date, but with no time part
1036    // TODO: somehow merge with buildIsoString and stripZeroTime
1037    // TODO: rename. omit "string"
1038    function formatDayString(marker) {
1039        return marker.toISOString().replace(/T.*$/, '');
1040    }
1041    // TODO: use Date::toISOString and use everything after the T?
1042    function formatIsoTimeString(marker) {
1043        return padStart(marker.getUTCHours(), 2) + ':' +
1044            padStart(marker.getUTCMinutes(), 2) + ':' +
1045            padStart(marker.getUTCSeconds(), 2);
1046    }
1047    function formatTimeZoneOffset(minutes, doIso) {
1048        if (doIso === void 0) { doIso = false; }
1049        var sign = minutes < 0 ? '-' : '+';
1050        var abs = Math.abs(minutes);
1051        var hours = Math.floor(abs / 60);
1052        var mins = Math.round(abs % 60);
1053        if (doIso) {
1054            return sign + padStart(hours, 2) + ":" + padStart(mins, 2);
1055        }
1056        return "GMT" + sign + hours + (mins ? ":" + padStart(mins, 2) : '');
1057    }
1058
1059    // TODO: new util arrayify?
1060    function removeExact(array, exactVal) {
1061        var removeCnt = 0;
1062        var i = 0;
1063        while (i < array.length) {
1064            if (array[i] === exactVal) {
1065                array.splice(i, 1);
1066                removeCnt += 1;
1067            }
1068            else {
1069                i += 1;
1070            }
1071        }
1072        return removeCnt;
1073    }
1074    function isArraysEqual(a0, a1, equalityFunc) {
1075        if (a0 === a1) {
1076            return true;
1077        }
1078        var len = a0.length;
1079        var i;
1080        if (len !== a1.length) { // not array? or not same length?
1081            return false;
1082        }
1083        for (i = 0; i < len; i += 1) {
1084            if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) {
1085                return false;
1086            }
1087        }
1088        return true;
1089    }
1090
1091    function memoize(workerFunc, resEquality, teardownFunc) {
1092        var currentArgs;
1093        var currentRes;
1094        return function () {
1095            var newArgs = [];
1096            for (var _i = 0; _i < arguments.length; _i++) {
1097                newArgs[_i] = arguments[_i];
1098            }
1099            if (!currentArgs) {
1100                currentRes = workerFunc.apply(this, newArgs);
1101            }
1102            else if (!isArraysEqual(currentArgs, newArgs)) {
1103                if (teardownFunc) {
1104                    teardownFunc(currentRes);
1105                }
1106                var res = workerFunc.apply(this, newArgs);
1107                if (!resEquality || !resEquality(res, currentRes)) {
1108                    currentRes = res;
1109                }
1110            }
1111            currentArgs = newArgs;
1112            return currentRes;
1113        };
1114    }
1115    function memoizeObjArg(workerFunc, resEquality, teardownFunc) {
1116        var _this = this;
1117        var currentArg;
1118        var currentRes;
1119        return function (newArg) {
1120            if (!currentArg) {
1121                currentRes = workerFunc.call(_this, newArg);
1122            }
1123            else if (!isPropsEqual(currentArg, newArg)) {
1124                if (teardownFunc) {
1125                    teardownFunc(currentRes);
1126                }
1127                var res = workerFunc.call(_this, newArg);
1128                if (!resEquality || !resEquality(res, currentRes)) {
1129                    currentRes = res;
1130                }
1131            }
1132            currentArg = newArg;
1133            return currentRes;
1134        };
1135    }
1136    function memoizeArraylike(// used at all?
1137    workerFunc, resEquality, teardownFunc) {
1138        var _this = this;
1139        var currentArgSets = [];
1140        var currentResults = [];
1141        return function (newArgSets) {
1142            var currentLen = currentArgSets.length;
1143            var newLen = newArgSets.length;
1144            var i = 0;
1145            for (; i < currentLen; i += 1) {
1146                if (!newArgSets[i]) { // one of the old sets no longer exists
1147                    if (teardownFunc) {
1148                        teardownFunc(currentResults[i]);
1149                    }
1150                }
1151                else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) {
1152                    if (teardownFunc) {
1153                        teardownFunc(currentResults[i]);
1154                    }
1155                    var res = workerFunc.apply(_this, newArgSets[i]);
1156                    if (!resEquality || !resEquality(res, currentResults[i])) {
1157                        currentResults[i] = res;
1158                    }
1159                }
1160            }
1161            for (; i < newLen; i += 1) {
1162                currentResults[i] = workerFunc.apply(_this, newArgSets[i]);
1163            }
1164            currentArgSets = newArgSets;
1165            currentResults.splice(newLen); // remove excess
1166            return currentResults;
1167        };
1168    }
1169    function memoizeHashlike(// used?
1170    workerFunc, resEquality, teardownFunc) {
1171        var _this = this;
1172        var currentArgHash = {};
1173        var currentResHash = {};
1174        return function (newArgHash) {
1175            var newResHash = {};
1176            for (var key in newArgHash) {
1177                if (!currentResHash[key]) {
1178                    newResHash[key] = workerFunc.apply(_this, newArgHash[key]);
1179                }
1180                else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) {
1181                    if (teardownFunc) {
1182                        teardownFunc(currentResHash[key]);
1183                    }
1184                    var res = workerFunc.apply(_this, newArgHash[key]);
1185                    newResHash[key] = (resEquality && resEquality(res, currentResHash[key]))
1186                        ? currentResHash[key]
1187                        : res;
1188                }
1189                else {
1190                    newResHash[key] = currentResHash[key];
1191                }
1192            }
1193            currentArgHash = newArgHash;
1194            currentResHash = newResHash;
1195            return newResHash;
1196        };
1197    }
1198
1199    var EXTENDED_SETTINGS_AND_SEVERITIES = {
1200        week: 3,
1201        separator: 0,
1202        omitZeroMinute: 0,
1203        meridiem: 0,
1204        omitCommas: 0,
1205    };
1206    var STANDARD_DATE_PROP_SEVERITIES = {
1207        timeZoneName: 7,
1208        era: 6,
1209        year: 5,
1210        month: 4,
1211        day: 2,
1212        weekday: 2,
1213        hour: 1,
1214        minute: 1,
1215        second: 1,
1216    };
1217    var MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
1217 // eats up leading spaces too
1218    var COMMA_RE = /,/g; // we need re for globalness
1219    var MULTI_SPACE_RE = /\s+/g;
1220    var LTR_RE = /\u200e/g; // control character
1221    var UTC_RE = /UTC|GMT/;
1222    var NativeFormatter = /** @class */ (function () {
1223        function NativeFormatter(formatSettings) {
1224            var standardDateProps = {};
1225            var extendedSettings = {};
1226            var severity = 0;
1227            for (var name_1 in formatSettings) {
1228                if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
1229                    extendedSettings[name_1] = formatSettings[name_1];
1230                    severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
1231                }
1232                else {
1233                    standardDateProps[name_1] = formatSettings[name_1];
1234                    if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity
1235                        severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
1236                    }
1237                }
1238            }
1239            this.standardDateProps = standardDateProps;
1240            this.extendedSettings = extendedSettings;
1241            this.severity = severity;
1242            this.buildFormattingFunc = memoize(buildFormattingFunc);
1243        }
1244        NativeFormatter.prototype.format = function (date, context) {
1245            return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
1246        };
1247        NativeFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1248            var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
1249            var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
1250            if (!diffSeverity) {
1251                return this.format(start, context);
1252            }
1253            var biggestUnitForPartial = diffSeverity;
1254            if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
1255                (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
1256                (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
1257                (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
1258                biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
1259            }
1260            var full0 = this.format(start, context);
1261            var full1 = this.format(end, context);
1262            if (full0 === full1) {
1263                return full0;
1264            }
1265            var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
1266            var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
1267            var partial0 = partialFormattingFunc(start);
1268            var partial1 = partialFormattingFunc(end);
1269            var insertion = findCommonInsertion(full0, partial0, full1, partial1);
1270            var separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || '';
1271            if (insertion) {
1272                return insertion.before + partial0 + separator + partial1 + insertion.after;
1273            }
1274            return full0 + separator + full1;
1275        };
1276        NativeFormatter.prototype.getLargestUnit = function () {
1277            switch (this.severity) {
1278                case 7:
1279                case 6:
1280                case 5:
1281                    return 'year';
1282                case 4:
1283                    return 'month';
1284                case 3:
1285                    return 'week';
1286                case 2:
1287                    return 'day';
1288                default:
1289                    return 'time'; // really?
1290            }
1291        };
1292        return NativeFormatter;
1293    }());
1294    function buildFormattingFunc(standardDateProps, extendedSettings, context) {
1295        var standardDatePropCnt = Object.keys(standardDateProps).length;
1296        if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
1297            return function (date) { return (formatTimeZoneOffset(date.timeZoneOffset)); };
1298        }
1299        if (standardDatePropCnt === 0 && extendedSettings.week) {
1300            return function (date) { return (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.locale, extendedSettings.week)); };
1301        }
1302        return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
1303    }
1304    function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
1305        standardDateProps = __assign({}, standardDateProps); // copy
1306        extendedSettings = __assign({}, extendedSettings); // copy
1307        sanitizeSettings(standardDateProps, extendedSettings);
1308        standardDateProps.timeZone = 'UTC';
1308 // we leverage the only guaranteed timeZone for our UTC markers
1309        var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
1310        var zeroFormat; // needed?
1311        if (extendedSettings.omitZeroMinute) {
1312            var zeroProps = __assign({}, standardDateProps);
1313            delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
1314            zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
1315        }
1316        return function (date) {
1317            var marker = date.marker;
1318            var format;
1319            if (zeroFormat && !marker.getUTCMinutes()) {
1320                format = zeroFormat;
1321            }
1322            else {
1323                format = normalFormat;
1324            }
1325            var s = format.format(marker);
1326            return postProcess(s, date, standardDateProps, extendedSettings, context);
1327        };
1328    }
1329    function sanitizeSettings(standardDateProps, extendedSettings) {
1330        // deal with a browser inconsistency where formatting the timezone
1331        // requires that the hour/minute be present.
1332        if (standardDateProps.timeZoneName) {
1333            if (!standardDateProps.hour) {
1334                standardDateProps.hour = '2-digit';
1335            }
1336            if (!standardDateProps.minute) {
1337                standardDateProps.minute = '2-digit';
1338            }
1339        }
1340        // only support short timezone names
1341        if (standardDateProps.timeZoneName === 'long') {
1342            standardDateProps.timeZoneName = 'short';
1343        }
1344        // if requesting to display seconds, MUST display minutes
1345        if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
1346            delete extendedSettings.omitZeroMinute;
1347        }
1348    }
1349    function postProcess(s, date, standardDateProps, extendedSettings, context) {
1350        s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
1351        if (standardDateProps.timeZoneName === 'short') {
1352            s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
1353                'UTC' : // important to normalize for IE, which does "GMT"
1354                formatTimeZoneOffset(date.timeZoneOffset));
1355        }
1356        if (extendedSettings.omitCommas) {
1357            s = s.replace(COMMA_RE, '').trim();
1358        }
1359        if (extendedSettings.omitZeroMinute) {
1360            s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
1361        }
1362        // ^ do anything that might create adjacent spaces before this point,
1363        // because MERIDIEM_RE likes to eat up loading spaces
1364        if (extendedSettings.meridiem === false) {
1365            s = s.replace(MERIDIEM_RE, '').trim();
1366        }
1367        else if (extendedSettings.meridiem === 'narrow') { // a/p
1368            s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase(); });
1369        }
1370        else if (extendedSettings.meridiem === 'short') { // am/pm
1371            s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase() + "m"; });
1372        }
1373        else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
1374            s = s.replace(MERIDIEM_RE, function (m0) { return m0.toLocaleLowerCase(); });
1375        }
1376        s = s.replace(MULTI_SPACE_RE, ' ');
1377        s = s.trim();
1378        return s;
1379    }
1380    function injectTzoStr(s, tzoStr) {
1381        var replaced = false;
1382        s = s.replace(UTC_RE, function () {
1383            replaced = true;
1384            return tzoStr;
1385        });
1386        // IE11 doesn't include UTC/GMT in the original string, so append to end
1387        if (!replaced) {
1388            s += " " + tzoStr;
1389        }
1390        return s;
1391    }
1392    function formatWeekNumber(num, weekText, locale, display) {
1393        var parts = [];
1394        if (display === 'narrow') {
1395            parts.push(weekText);
1396        }
1397        else if (display === 'short') {
1398            parts.push(weekText, ' ');
1399        }
1400        // otherwise, considered 'numeric'
1401        parts.push(locale.simpleNumberFormat.format(num));
1402        if (locale.options.direction === 'rtl') { // TODO: use control characters instead?
1403            parts.reverse();
1404        }
1405        return parts.join('');
1406    }
1407    // Range Formatting Utils
1408    // 0 = exactly the same
1409    // 1 = different by time
1410    // and bigger
1411    function computeMarkerDiffSeverity(d0, d1, ca) {
1412        if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
1413            return 5;
1414        }
1415        if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
1416            return 4;
1417        }
1418        if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
1419            return 2;
1420        }
1421        if (timeAsMs(d0) !== timeAsMs(d1)) {
1422            return 1;
1423        }
1424        return 0;
1425    }
1426    function computePartialFormattingOptions(options, biggestUnit) {
1427        var partialOptions = {};
1428        for (var name_2 in options) {
1429            if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
1430                STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
1431                partialOptions[name_2] = options[name_2];
1432            }
1433        }
1434        return partialOptions;
1435    }
1436    function findCommonInsertion(full0, partial0, full1, partial1) {
1437        var i0 = 0;
1438        while (i0 < full0.length) {
1439            var found0 = full0.indexOf(partial0, i0);
1440            if (found0 === -1) {
1441                break;
1442            }
1443            var before0 = full0.substr(0, found0);
1444            i0 = found0 + partial0.length;
1445            var after0 = full0.substr(i0);
1446            var i1 = 0;
1447            while (i1 < full1.length) {
1448                var found1 = full1.indexOf(partial1, i1);
1449                if (found1 === -1) {
1450                    break;
1451                }
1452                var before1 = full1.substr(0, found1);
1453                i1 = found1 + partial1.length;
1454                var after1 = full1.substr(i1);
1455                if (before0 === before1 && after0 === after1) {
1456                    return {
1457                        before: before0,
1458                        after: after0,
1459                    };
1460                }
1461            }
1462        }
1463        return null;
1464    }
1465
1466    function expandZonedMarker(dateInfo, calendarSystem) {
1467        var a = calendarSystem.markerToArray(dateInfo.marker);
1468        return {
1469            marker: dateInfo.marker,
1470            timeZoneOffset: dateInfo.timeZoneOffset,
1471            array: a,
1472            year: a[0],
1473            month: a[1],
1474            day: a[2],
1475            hour: a[3],
1476            minute: a[4],
1477            second: a[5],
1478            millisecond: a[6],
1479        };
1480    }
1481
1482    function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
1483        var startInfo = expandZonedMarker(start, context.calendarSystem);
1484        var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
1485        return {
1486            date: startInfo,
1487            start: startInfo,
1488            end: endInfo,
1489            timeZone: context.timeZone,
1490            localeCodes: context.locale.codes,
1491            defaultSeparator: betterDefaultSeparator || context.defaultSeparator,
1492        };
1493    }
1494
1495    /*
1496    TODO: fix the terminology of "formatter" vs "formatting func"
1497    */
1498    /*
1499    At the time of instantiation, this object does not know which cmd-formatting system it will use.
1500    It receives this at the time of formatting, as a setting.
1501    */
1502    var CmdFormatter = /** @class */ (function () {
1503        function CmdFormatter(cmdStr) {
1504            this.cmdStr = cmdStr;
1505        }
1506        CmdFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
1507            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
1508        };
1509        CmdFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1510            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
1511        };
1512        return CmdFormatter;
1513    }());
1514
1515    var FuncFormatter = /** @class */ (function () {
1516        function FuncFormatter(func) {
1517            this.func = func;
1518        }
1519        FuncFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
1520            return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
1521        };
1522        FuncFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1523            return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
1524        };
1525        return FuncFormatter;
1526    }());
1527
1528    function createFormatter(input) {
1529        if (typeof input === 'object' && input) { // non-null object
1530            return new NativeFormatter(input);
1531        }
1532        if (typeof input === 'string') {
1533            return new CmdFormatter(input);
1534        }
1535        if (typeof input === 'function') {
1536            return new FuncFormatter(input);
1537        }
1538        return null;
1539    }
1540
1541    // base options
1542    // ------------
1543    var BASE_OPTION_REFINERS = {
1544        navLinkDayClick: identity,
1545        navLinkWeekClick: identity,
1546        duration: createDuration,
1547        bootstrapFontAwesome: identity,
1548        buttonIcons: identity,
1549        customButtons: identity,
1550        defaultAllDayEventDuration: createDuration,
1551        defaultTimedEventDuration: createDuration,
1552        nextDayThreshold: createDuration,
1553        scrollTime: createDuration,
1554        scrollTimeReset: Boolean,
1555        slotMinTime: createDuration,
1556        slotMaxTime: createDuration,
1557        dayPopoverFormat: createFormatter,
1558        slotDuration: createDuration,
1559        snapDuration: createDuration,
1560        headerToolbar: identity,
1561        footerToolbar: identity,
1562        defaultRangeSeparator: String,
1563        titleRangeSeparator: String,
1564        forceEventDuration: Boolean,
1565        dayHeaders: Boolean,
1566        dayHeaderFormat: createFormatter,
1567        dayHeaderClassNames: identity,
1568        dayHeaderContent: identity,
1569        dayHeaderDidMount: identity,
1570        dayHeaderWillUnmount: identity,
1571        dayCellClassNames: identity,
1572        dayCellContent: identity,
1573        dayCellDidMount: identity,
1574        dayCellWillUnmount: identity,
1575        initialView: String,
1576        aspectRatio: Number,
1577        weekends: Boolean,
1578        weekNumberCalculation: identity,
1579        weekNumbers: Boolean,
1580        weekNumberClassNames: identity,
1581        weekNumberContent: identity,
1582        weekNumberDidMount: identity,
1583        weekNumberWillUnmount: identity,
1584        editable: Boolean,
1585        viewClassNames: identity,
1586        viewDidMount: identity,
1587        viewWillUnmount: identity,
1588        nowIndicator: Boolean,
1589        nowIndicatorClassNames: identity,
1590        nowIndicatorContent: identity,
1591        nowIndicatorDidMount: identity,
1592        nowIndicatorWillUnmount: identity,
1593        showNonCurrentDates: Boolean,
1594        lazyFetching: Boolean,
1595        startParam: String,
1596        endParam: String,
1597        timeZoneParam: String,
1598        timeZone: String,
1599        locales: identity,
1600        locale: identity,
1601        themeSystem: String,
1602        dragRevertDuration: Number,
1603        dragScroll: Boolean,
1604        allDayMaintainDuration: Boolean,
1605        unselectAuto: Boolean,
1606        dropAccept: identity,
1607        eventOrder: parseFieldSpecs,
1608        eventOrderStrict: Boolean,
1609        handleWindowResize: Boolean,
1610        windowResizeDelay: Number,
1611        longPressDelay: Number,
1612        eventDragMinDistance: Number,
1613        expandRows: Boolean,
1614        height: identity,
1615        contentHeight: identity,
1616        direction: String,
1617        weekNumberFormat: createFormatter,
1618        eventResizableFromStart: Boolean,
1619        displayEventTime: Boolean,
1620        displayEventEnd: Boolean,
1621        weekText: String,
1622        progressiveEventRendering: Boolean,
1623        businessHours: identity,
1624        initialDate: identity,
1625        now: identity,
1626        eventDataTransform: identity,
1627        stickyHeaderDates: identity,
1628        stickyFooterScrollbar: identity,
1629        viewHeight: identity,
1630        defaultAllDay: Boolean,
1631        eventSourceFailure: identity,
1632        eventSourceSuccess: identity,
1633        eventDisplay: String,
1634        eventStartEditable: Boolean,
1635        eventDurationEditable: Boolean,
1636        eventOverlap: identity,
1637        eventConstraint: identity,
1638        eventAllow: identity,
1639        eventBackgroundColor: String,
1640        eventBorderColor: String,
1641        eventTextColor: String,
1642        eventColor: String,
1643        eventClassNames: identity,
1644        eventContent: identity,
1645        eventDidMount: identity,
1646        eventWillUnmount: identity,
1647        selectConstraint: identity,
1648        selectOverlap: identity,
1649        selectAllow: identity,
1650        droppable: Boolean,
1651        unselectCancel: String,
1652        slotLabelFormat: identity,
1653        slotLaneClassNames: identity,
1654        slotLaneContent: identity,
1655        slotLaneDidMount: identity,
1656        slotLaneWillUnmount: identity,
1657        slotLabelClassNames: identity,
1658        slotLabelContent: identity,
1659        slotLabelDidMount: identity,
1660        slotLabelWillUnmount: identity,
1661        dayMaxEvents: identity,
1662        dayMaxEventRows: identity,
1663        dayMinWidth: Number,
1664        slotLabelInterval: createDuration,
1665        allDayText: String,
1666        allDayClassNames: identity,
1667        allDayContent: identity,
1668        allDayDidMount: identity,
1669        allDayWillUnmount: identity,
1670        slotMinWidth: Number,
1671        navLinks: Boolean,
1672        eventTimeFormat: createFormatter,
1673        rerenderDelay: Number,
1674        moreLinkText: identity,
1675        selectMinDistance: Number,
1676        selectable: Boolean,
1677        selectLongPressDelay: Number,
1678        eventLongPressDelay: Number,
1679        selectMirror: Boolean,
1680        eventMaxStack: Number,
1681        eventMinHeight: Number,
1682        eventMinWidth: Number,
1683        eventShortHeight: Number,
1684        slotEventOverlap: Boolean,
1685        plugins: identity,
1686        firstDay: Number,
1687        dayCount: Number,
1688        dateAlignment: String,
1689        dateIncrement: createDuration,
1690        hiddenDays: identity,
1691        monthMode: Boolean,
1692        fixedWeekCount: Boolean,
1693        validRange: identity,
1694        visibleRange: identity,
1695        titleFormat: identity,
1696        // only used by list-view, but languages define the value, so we need it in base options
1697        noEventsText: String,
1698        moreLinkClick: identity,
1699        moreLinkClassNames: identity,
1700        moreLinkContent: identity,
1701        moreLinkDidMount: identity,
1702        moreLinkWillUnmount: identity,
1703    };
1704    // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results.
1705    // raw values.
1706    var BASE_OPTION_DEFAULTS = {
1707        eventDisplay: 'auto',
1708        defaultRangeSeparator: ' - ',
1709        titleRangeSeparator: ' \u2013 ',
1710        defaultTimedEventDuration: '01:00:00',
1711        defaultAllDayEventDuration: { day: 1 },
1712        forceEventDuration: false,
1713        nextDayThreshold: '00:00:00',
1714        dayHeaders: true,
1715        initialView: '',
1716        aspectRatio: 1.35,
1717        headerToolbar: {
1718            start: 'title',
1719            center: '',
1720            end: 'today prev,next',
1721        },
1722        weekends: true,
1723        weekNumbers: false,
1724        weekNumberCalculation: 'local',
1725        editable: false,
1726        nowIndicator: false,
1727        scrollTime: '06:00:00',
1728        scrollTimeReset: true,
1729        slotMinTime: '00:00:00',
1730        slotMaxTime: '24:00:00',
1731        showNonCurrentDates: true,
1732        lazyFetching: true,
1733        startParam: 'start',
1734        endParam: 'end',
1735        timeZoneParam: 'timeZone',
1736        timeZone: 'local',
1737        locales: [],
1738        locale: '',
1739        themeSystem: 'standard',
1740        dragRevertDuration: 500,
1741        dragScroll: true,
1742        allDayMaintainDuration: false,
1743        unselectAuto: true,
1744        dropAccept: '*',
1745        eventOrder: 'start,-duration,allDay,title',
1746        dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
1747        handleWindowResize: true,
1748        windowResizeDelay: 100,
1749        longPressDelay: 1000,
1750        eventDragMinDistance: 5,
1751        expandRows: false,
1752        navLinks: false,
1753        selectable: false,
1754        eventMinHeight: 15,
1755        eventMinWidth: 30,
1756        eventShortHeight: 30,
1757    };
1758    // calendar listeners
1759    // ------------------
1760    var CALENDAR_LISTENER_REFINERS = {
1761        datesSet: identity,
1762        eventsSet: identity,
1763        eventAdd: identity,
1764        eventChange: identity,
1765        eventRemove: identity,
1766        windowResize: identity,
1767        eventClick: identity,
1768        eventMouseEnter: identity,
1769        eventMouseLeave: identity,
1770        select: identity,
1771        unselect: identity,
1772        loading: identity,
1773        // internal
1774        _unmount: identity,
1775        _beforeprint: identity,
1776        _afterprint: identity,
1777        _noEventDrop: identity,
1778        _noEventResize: identity,
1779        _resize: identity,
1780        _scrollRequest: identity,
1781    };
1782    // calendar-specific options
1783    // -------------------------
1784    var CALENDAR_OPTION_REFINERS = {
1785        buttonText: identity,
1786        views: identity,
1787        plugins: identity,
1788        initialEvents: identity,
1789        events: identity,
1790        eventSources: identity,
1791    };
1792    var COMPLEX_OPTION_COMPARATORS = {
1793        headerToolbar: isBoolComplexEqual,
1794        footerToolbar: isBoolComplexEqual,
1795        buttonText: isBoolComplexEqual,
1796        buttonIcons: isBoolComplexEqual,
1797    };
1798    function isBoolComplexEqual(a, b) {
1799        if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects
1800            return isPropsEqual(a, b);
1801        }
1802        return a === b;
1803    }
1804    // view-specific options
1805    // ---------------------
1806    var VIEW_OPTION_REFINERS = {
1807        type: String,
1808        component: identity,
1809        buttonText: String,
1810        buttonTextKey: String,
1811        dateProfileGeneratorClass: identity,
1812        usesMinMaxTime: Boolean,
1813        classNames: identity,
1814        content: identity,
1815        didMount: identity,
1816        willUnmount: identity,
1817    };
1818    // util funcs
1819    // ----------------------------------------------------------------------------------------------------
1820    function mergeRawOptions(optionSets) {
1821        return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS);
1822    }
1823    function refineProps(input, refiners) {
1824        var refined = {};
1825        var extra = {};
1826        for (var propName in refiners) {
1827            if (propName in input) {
1828                refined[propName] = refiners[propName](input[propName]);
1829            }
1830        }
1831        for (var propName in input) {
1832            if (!(propName in refiners)) {
1833                extra[propName] = input[propName];
1834            }
1835        }
1836        return { refined: refined, extra: extra };
1837    }
1838    function identity(raw) {
1839        return raw;
1840    }
1841
1842    function parseEvents(rawEvents, eventSource, context, allowOpenRange) {
1843        var eventStore = createEmptyEventStore();
1844        var eventRefiners = buildEventRefiners(context);
1845        for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
1846            var rawEvent = rawEvents_1[_i];
1847            var tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners);
1848            if (tuple) {
1849                eventTupleToStore(tuple, eventStore);
1850            }
1851        }
1852        return eventStore;
1853    }
1854    function eventTupleToStore(tuple, eventStore) {
1855        if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
1856        eventStore.defs[tuple.def.defId] = tuple.def;
1857        if (tuple.instance) {
1858            eventStore.instances[tuple.instance.instanceId] = tuple.instance;
1859        }
1860        return eventStore;
1861    }
1862    // retrieves events that have the same groupId as the instance specified by `instanceId`
1863    // or they are the same as the instance.
1864    // why might instanceId not be in the store? an event from another calendar?
1865    function getRelevantEvents(eventStore, instanceId) {
1866        var instance = eventStore.instances[instanceId];
1867        if (instance) {
1868            var def_1 = eventStore.defs[instance.defId];
1869            // get events/instances with same group
1870            var newStore = filterEventStoreDefs(eventStore, function (lookDef) { return isEventDefsGrouped(def_1, lookDef); });
1871            // add the original
1872            // TODO: wish we could use eventTupleToStore or something like it
1873            newStore.defs[def_1.defId] = def_1;
1874            newStore.instances[instance.instanceId] = instance;
1875            return newStore;
1876        }
1877        return createEmptyEventStore();
1878    }
1879    function isEventDefsGrouped(def0, def1) {
1880        return Boolean(def0.groupId && def0.groupId === def1.groupId);
1881    }
1882    function createEmptyEventStore() {
1883        return { defs: {}, instances: {} };
1884    }
1885    function mergeEventStores(store0, store1) {
1886        return {
1887            defs: __assign(__assign({}, store0.defs), store1.defs),
1888            instances: __assign(__assign({}, store0.instances), store1.instances),
1889        };
1890    }
1891    function filterEventStoreDefs(eventStore, filterFunc) {
1892        var defs = filterHash(eventStore.defs, filterFunc);
1893        var instances = filterHash(eventStore.instances, function (instance) { return (defs[instance.defId] // still exists?
1894        ); });
1895        return { defs: defs, instances: instances };
1896    }
1897    function excludeSubEventStore(master, sub) {
1898        var defs = master.defs, instances = master.instances;
1899        var filteredDefs = {};
1900        var filteredInstances = {};
1901        for (var defId in defs) {
1902            if (!sub.defs[defId]) { // not explicitly excluded
vendor: 4,622 bytes, lines 1903-2021
1903                filteredDefs[defId] = defs[defId];
1904            }
1905        }
1906        for (var instanceId in instances) {
1907            if (!sub.instances[instanceId] && // not explicitly excluded
1908                filteredDefs[instances[instanceId].defId] // def wasn't filtered away
1909            ) {
1910                filteredInstances[instanceId] = instances[instanceId];
1911            }
1912        }
1913        return {
1914            defs: filteredDefs,
1915            instances: filteredInstances,
1916        };
1917    }
1918
1919    function normalizeConstraint(input, context) {
1920        if (Array.isArray(input)) {
1921            return parseEvents(input, null, context, true); // allowOpenRange=true
1922        }
1923        if (typeof input === 'object' && input) { // non-null object
1924            return parseEvents([input], null, context, true); // allowOpenRange=true
1925        }
1926        if (input != null) {
1927            return String(input);
1928        }
1929        return null;
1930    }
1931
1932    function parseClassNames(raw) {
1933        if (Array.isArray(raw)) {
1934            return raw;
1935        }
1936        if (typeof raw === 'string') {
1937            return raw.split(/\s+/);
1938        }
1939        return [];
1940    }
1941
1942    // TODO: better called "EventSettings" or "EventConfig"
1943    // TODO: move this file into structs
1944    // TODO: separate constraint/overlap/allow, because selection uses only that, not other props
1945    var EVENT_UI_REFINERS = {
1946        display: String,
1947        editable: Boolean,
1948        startEditable: Boolean,
1949        durationEditable: Boolean,
1950        constraint: identity,
1951        overlap: identity,
1952        allow: identity,
1953        className: parseClassNames,
1954        classNames: parseClassNames,
1955        color: String,
1956        backgroundColor: String,
1957        borderColor: String,
1958        textColor: String,
1959    };
1960    var EMPTY_EVENT_UI = {
1961        display: null,
1962        startEditable: null,
1963        durationEditable: null,
1964        constraints: [],
1965        overlap: null,
1966        allows: [],
1967        backgroundColor: '',
1968        borderColor: '',
1969        textColor: '',
1970        classNames: [],
1971    };
1972    function createEventUi(refined, context) {
1973        var constraint = normalizeConstraint(refined.constraint, context);
1974        return {
1975            display: refined.display || null,
1976            startEditable: refined.startEditable != null ? refined.startEditable : refined.editable,
1977            durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable,
1978            constraints: constraint != null ? [constraint] : [],
1979            overlap: refined.overlap != null ? refined.overlap : null,
1980            allows: refined.allow != null ? [refined.allow] : [],
1981            backgroundColor: refined.backgroundColor || refined.color || '',
1982            borderColor: refined.borderColor || refined.color || '',
1983            textColor: refined.textColor || '',
1984            classNames: (refined.className || []).concat(refined.classNames || []), // join singular and plural
1985        };
1986    }
1987    // TODO: prevent against problems with <2 args!
1988    function combineEventUis(uis) {
1989        return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
1990    }
1991    function combineTwoEventUis(item0, item1) {
1992        return {
1993            display: item1.display != null ? item1.display : item0.display,
1994            startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
1995            durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
1996            constraints: item0.constraints.concat(item1.constraints),
1997            overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
1998            allows: item0.allows.concat(item1.allows),
1999            backgroundColor: item1.backgroundColor || item0.backgroundColor,
2000            borderColor: item1.borderColor || item0.borderColor,
2001            textColor: item1.textColor || item0.textColor,
2002            classNames: item0.classNames.concat(item1.classNames),
2003        };
2004    }
2005
2006    var EVENT_NON_DATE_REFINERS = {
2007        id: String,
2008        groupId: String,
2009        title: String,
2010        url: String,
2011    };
2012    var EVENT_DATE_REFINERS = {
2013        start: identity,
2014        end: identity,
2015        date: identity,
2016        allDay: Boolean,
2017    };
2018    var EVENT_REFINERS = __assign(__assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity });
2019    function parseEvent(raw, eventSource, context, allowOpenRange, refiners) {
2020        if (refiners === void 0) { refiners = buildEventRefiners(context); }
2021        var _a = refineEventDef(raw, context, refiners), refined 
2021= _a.refined, extra = _a.extra;
2022        var defaultAllDay = computeIsDefaultAllDay(eventSource, context);
2023        var recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes);
2024        if (recurringRes) {
2025            var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context);
2026            def.recurringDef = {
2027                typeId: recurringRes.typeId,
2028                typeData: recurringRes.typeData,
2029                duration: recurringRes.duration,
2030            };
2031            return { def: def, instance: null };
2032        }
2033        var singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange);
2034        if (singleRes) {
2035            var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context);
2036            var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
2037            return { def: def, instance: instance };
2038        }
2039        return null;
2040    }
2041    function refineEventDef(raw, context, refiners) {
2042        if (refiners === void 0) { refiners = buildEventRefiners(context); }
2043        return refineProps(raw, refiners);
2044    }
2045    function buildEventRefiners(context) {
2046        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners);
2047    }
2048    /*
2049    Will NOT populate extendedProps with the leftover properties.
2050    Will NOT populate date-related props.
2051    */
2052    function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) {
2053        var def = {
2054            title: refined.title || '',
2055            groupId: refined.groupId || '',
2056            publicId: refined.id || '',
2057            url: refined.url || '',
2058            recurringDef: null,
2059            defId: guid(),
2060            sourceId: sourceId,
2061            allDay: allDay,
2062            hasEnd: hasEnd,
2063            ui: createEventUi(refined, context),
2064            extendedProps: __assign(__assign({}, (refined.extendedProps || {})), extra),
2065        };
2066        for (var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; _i < _a.length; _i++) {
2067            var memberAdder = _a[_i];
2068            __assign(def, memberAdder(refined));
2069        }
2070        // help out EventApi from having user modify props
2071        Object.freeze(def.ui.classNames);
2072        Object.freeze(def.extendedProps);
2073        return def;
2074    }
2075    function parseSingle(refined, defaultAllDay, context, allowOpenRange) {
2076        var allDay = refined.allDay;
2077        var startMeta;
2078        var startMarker = null;
2079        var hasEnd = false;
2080        var endMeta;
2081        var endMarker = null;
2082        var startInput = refined.start != null ? refined.start : refined.date;
2083        startMeta = context.dateEnv.createMarkerMeta(startInput);
2084        if (startMeta) {
2085            startMarker = startMeta.marker;
2086        }
2087        else if (!allowOpenRange) {
2088            return null;
2089        }
2090        if (refined.end != null) {
2091            endMeta = context.dateEnv.createMarkerMeta(refined.end);
2092        }
2093        if (allDay == null) {
2094            if (defaultAllDay != null) {
2095                allDay = defaultAllDay;
2096            }
2097            else {
2098                // fall back to the date props LAST
2099                allDay = (!startMeta || startMeta.isTimeUnspecified) &&
2100                    (!endMeta || endMeta.isTimeUnspecified);
2101            }
2102        }
2103        if (allDay && startMarker) {
2104            startMarker = startOfDay(startMarker);
2105        }
2106        if (endMeta) {
2107            endMarker = endMeta.marker;
2108            if (allDay) {
2109                endMarker = startOfDay(endMarker);
2110            }
2111            if (startMarker && endMarker <= startMarker) {
2112                endMarker = null;
2113            }
2114        }
2115        if (endMarker) {
2116            hasEnd = true;
2117        }
2118        else if (!allowOpenRange) {
2119            hasEnd = context.options.forceEventDuration || false;
2120            endMarker = context.dateEnv.add(startMarker, allDay ?
2121                context.options.defaultAllDayEventDuration :
2122                context.options.defaultTimedEventDuration);
2123        }
2124        return {
2125            allDay: allDay,
2126            hasEnd: hasEnd,
2127            range: { start: startMarker, end: endMarker },
2128            forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
2129            forcedEndTzo: endMeta ? endMeta.forcedTzo : null,
2130        };
2131    }
2132    function computeIsDefaultAllDay(eventSource, context) {
2133        var res = null;
2134        if (eventSource) {
2135            res = eventSource.defaultAllDay;
2136        }
2137        if (res == null) {
2138            res = context.options.defaultAllDay;
2139        }
2140        return res;
2141    }
2142
2143    /* Date stuff that doesn't belong in datelib core
2144    ----------------------------------------------------------------------------------------------------------------------*/
2145    // given a timed range, computes an all-day range that has the same exact duration,
2146    // but whose start time is aligned with the start of the day.
2147    function computeAlignedDayRange(timedRange) {
2148        var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
2149        var start = startOfDay(timedRange.start);
2150        var end = addDays(start, dayCnt);
2151        return { start: start, end: end };
2152    }
2153    // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
2154    // TODO: give nextDayThreshold a default arg
2155    function computeVisibleDayRange(timedRange, nextDayThreshold) {
2156        if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
2157        var startDay = null;
2158        var endDay = null;
2159        if (timedRange.end) {
2160            endDay = startOfDay(timedRange.end);
2161            var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
2162            // If the end time is actually inclusively part of the next day and is equal to or
vendor: 16,001 bytes, lines 2163-2544
2163            // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
2164            // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
2165            if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
2166                endDay = addDays(endDay, 1);
2167            }
2168        }
2169        if (timedRange.start) {
2170            startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
2171            // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
2172            if (endDay && endDay <= startDay) {
2173                endDay = addDays(startDay, 1);
2174            }
2175        }
2176        return { start: startDay, end: endDay };
2177    }
2178    // spans from one day into another?
2179    function isMultiDayRange(range) {
2180        var visibleRange = computeVisibleDayRange(range);
2181        return diffDays(visibleRange.start, visibleRange.end) > 1;
2182    }
2183    function diffDates(date0, date1, dateEnv, largeUnit) {
2184        if (largeUnit === 'year') {
2185            return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
2186        }
2187        if (largeUnit === 'month') {
2188            return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
2189        }
2190        return diffDayAndTime(date0, date1); // returns a duration
2191    }
2192
2193    function parseRange(input, dateEnv) {
2194        var start = null;
2195        var end = null;
2196        if (input.start) {
2197            start = dateEnv.createMarker(input.start);
2198        }
2199        if (input.end) {
2200            end = dateEnv.createMarker(input.end);
2201        }
2202        if (!start && !end) {
2203            return null;
2204        }
2205        if (start && end && end < start) {
2206            return null;
2207        }
2208        return { start: start, end: end };
2209    }
2210    // SIDE-EFFECT: will mutate ranges.
2211    // Will return a new array result.
2212    function invertRanges(ranges, constraintRange) {
2213        var invertedRanges = [];
2214        var start = constraintRange.start; // the end of the previous range. the start of the new range
2215        var i;
2216        var dateRange;
2217        // ranges need to be in order. required for our date-walking algorithm
2218        ranges.sort(compareRanges);
2219        for (i = 0; i < ranges.length; i += 1) {
2220            dateRange = ranges[i];
2221            // add the span of time before the event (if there is any)
2222            if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
2223                invertedRanges.push({ start: start, end: dateRange.start });
2224            }
2225            if (dateRange.end > start) {
2226                start = dateRange.end;
2227            }
2228        }
2229        // add the span of time after the last event (if there is any)
2230        if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
2231            invertedRanges.push({ start: start, end: constraintRange.end });
2232        }
2233        return invertedRanges;
2234    }
2235    function compareRanges(range0, range1) {
2236        return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
2237    }
2238    function intersectRanges(range0, range1) {
2239        var start = range0.start, end = range0.end;
2240        var newRange = null;
2241        if (range1.start !== null) {
2242            if (start === null) {
2243                start = range1.start;
2244            }
2245            else {
2246                start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
2247            }
2248        }
2249        if (range1.end != null) {
2250            if (end === null) {
2251                end = range1.end;
2252            }
2253            else {
2254                end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
2255            }
2256        }
2257        if (start === null || end === null || start < end) {
2258            newRange = { start: start, end: end };
2259        }
2260        return newRange;
2261    }
2262    function rangesEqual(range0, range1) {
2263        return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
2264            (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
2265    }
2266    function rangesIntersect(range0, range1) {
2267        return (range0.end === null || range1.start === null || range0.end > range1.start) &&
2268            (range0.start === null || range1.end === null || range0.start < range1.end);
2269    }
2270    function rangeContainsRange(outerRange, innerRange) {
2271        return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
2272            (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
2273    }
2274    function rangeContainsMarker(range, date) {
2275        return (range.start === null || date >= range.start) &&
2276            (range.end === null || date < range.end);
2277    }
2278    // If the given date is not within the given range, move it inside.
2279    // (If it's past the end, make it one millisecond before the end).
2280    function constrainMarkerToRange(date, range) {
2281        if (range.start != null && date < range.start) {
2282            return range.start;
2283        }
2284        if (range.end != null && date >= range.end) {
2285            return new Date(range.end.valueOf() - 1);
2286        }
2287        return date;
2288    }
2289
2290    /*
2291    Specifying nextDayThreshold signals that all-day ranges should be sliced.
2292    */
2293    function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
2294        var inverseBgByGroupId = {};
2295        var inverseBgByDefId = {};
2296        var defByGroupId = {};
2297        var bgRanges = [];
2298        var fgRanges = [];
2299        var eventUis = compileEventUis(eventStore.defs, eventUiBases);
2300        for (var defId in eventStore.defs) {
2301            var def = eventStore.defs[defId];
2302            var ui = eventUis[def.defId];
2303            if (ui.display === 'inverse-background') {
2304                if (def.groupId) {
2305                    inverseBgByGroupId[def.groupId] = [];
2306                    if (!defByGroupId[def.groupId]) {
2307                        defByGroupId[def.groupId] = def;
2308                    }
2309                }
2310                else {
2311                    inverseBgByDefId[defId] = [];
2312                }
2313            }
2314        }
2315        for (var instanceId in eventStore.instances) {
2316            var instance = eventStore.instances[instanceId];
2317            var def = eventStore.defs[instance.defId];
2318            var ui = eventUis[def.defId];
2319            var origRange = instance.range;
2320            var normalRange = (!def.allDay && nextDayThreshold) ?
2321                computeVisibleDayRange(origRange, nextDayThreshold) :
2322                origRange;
2323            var slicedRange = intersectRanges(normalRange, framingRange);
2324            if (slicedRange) {
2325                if (ui.display === 'inverse-background') {
2326                    if (def.groupId) {
2327                        inverseBgByGroupId[def.groupId].push(slicedRange);
2328                    }
2329                    else {
2330                        inverseBgByDefId[instance.defId].push(slicedRange);
2331                    }
2332                }
2333                else if (ui.display !== 'none') {
2334                    (ui.display === 'background' ? bgRanges : fgRanges).push({
2335                        def: def,
2336                        ui: ui,
2337                        instance: instance,
2338                        range: slicedRange,
2339                        isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
2340                        isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(),
2341                    });
2342                }
2343            }
2344        }
2345        for (var groupId in inverseBgByGroupId) { // BY GROUP
2346            var ranges = inverseBgByGroupId[groupId];
2347            var invertedRanges = invertRanges(ranges, framingRange);
2348            for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
2349                var invertedRange = invertedRanges_1[_i];
2350                var def = defByGroupId[groupId];
2351                var ui = eventUis[def.defId];
2352                bgRanges.push({
2353                    def: def,
2354                    ui: ui,
2355                    instance: null,
2356                    range: invertedRange,
2357                    isStart: false,
2358                    isEnd: false,
2359                });
2360            }
2361        }
2362        for (var defId in inverseBgByDefId) {
2363            var ranges = inverseBgByDefId[defId];
2364            var invertedRanges = invertRanges(ranges, framingRange);
2365            for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
2366                var invertedRange = invertedRanges_2[_a];
2367                bgRanges.push({
2368                    def: eventStore.defs[defId],
2369                    ui: eventUis[defId],
2370                    instance: null,
2371                    range: invertedRange,
2372                    isStart: false,
2373                    isEnd: false,
2374                });
2375            }
2376        }
2377        return { bg: bgRanges, fg: fgRanges };
2378    }
2379    function hasBgRendering(def) {
2380        return def.ui.display === 'background' || def.ui.display === 'inverse-background';
2381    }
2382    function setElSeg(el, seg) {
2383        el.fcSeg = seg;
2384    }
2385    function getElSeg(el) {
2386        return el.fcSeg ||
2387            el.parentNode.fcSeg || // for the harness
2388            null;
2389    }
2390    // event ui computation
2391    function compileEventUis(eventDefs, eventUiBases) {
2392        return mapHash(eventDefs, function (eventDef) { return compileEventUi(eventDef, eventUiBases); });
2393    }
2394    function compileEventUi(eventDef, eventUiBases) {
2395        var uis = [];
2396        if (eventUiBases['']) {
2397            uis.push(eventUiBases['']);
2398        }
2399        if (eventUiBases[eventDef.defId]) {
2400            uis.push(eventUiBases[eventDef.defId]);
2401        }
2402        uis.push(eventDef.ui);
2403        return combineEventUis(uis);
2404    }
2405    function sortEventSegs(segs, eventOrderSpecs) {
2406        var objs = segs.map(buildSegCompareObj);
2407        objs.sort(function (obj0, obj1) { return compareByFieldSpecs(obj0, obj1, eventOrderSpecs); });
2408        return objs.map(function (c) { return c._seg; });
2409    }
2410    // returns a object with all primitive props that can be compared
2411    function buildSegCompareObj(seg) {
2412        var eventRange = seg.eventRange;
2413        var eventDef = eventRange.def;
2414        var range = eventRange.instance ? eventRange.instance.range : eventRange.range;
2415        var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
2416        var end = range.end ? range.end.valueOf() : 0; // "
2417        return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start: start,
2418            end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg });
2419    }
2420    function computeSegDraggable(seg, context) {
2421        var pluginHooks = context.pluginHooks;
2422        var transformers = pluginHooks.isDraggableTransformers;
2423        var _a = seg.eventRange, def = _a.def, ui = _a.ui;
2424        var val = ui.startEditable;
2425        for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
2426            var transformer = transformers_1[_i];
2427            val = transformer(val, def, ui, context);
2428        }
2429        return val;
2430    }
2431    function computeSegStartResizable(seg, context) {
2432        return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart;
2433    }
2434    function computeSegEndResizable(seg, context) {
2435        return seg.isEnd && seg.eventRange.ui.durationEditable;
2436    }
2437    function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true
2438    defaultDisplayEventEnd, // defaults to true
2439    startOverride, endOverride) {
2440        var dateEnv = context.dateEnv, options = context.options;
2441        var displayEventTime = options.displayEventTime, displayEventEnd = options.displayEventEnd;
2442        var eventDef = seg.eventRange.def;
2443        var eventInstance = seg.eventRange.instance;
2444        if (displayEventTime == null) {
2445            displayEventTime = defaultDisplayEventTime !== false;
2446        }
2447        if (displayEventEnd == null) {
2448            displayEventEnd = defaultDisplayEventEnd !== false;
2449        }
2450        var wholeEventStart = eventInstance.range.start;
2451        var wholeEventEnd = eventInstance.range.end;
2452        var segStart = startOverride || seg.start || seg.eventRange.range.start;
2453        var segEnd = endOverride || seg.end || seg.eventRange.range.end;
2454        var isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf();
2455        var isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf();
2456        if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) {
2457            segStart = isStartDay ? wholeEventStart : segStart;
2458            segEnd = isEndDay ? wholeEventEnd : segEnd;
2459            if (displayEventEnd && eventDef.hasEnd) {
2460                return dateEnv.formatRange(segStart, segEnd, timeFormat, {
2461                    forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo,
2462                    forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo,
2463                });
2464            }
2465            return dateEnv.format(segStart, timeFormat, {
2466                forcedTzo: startOverride ? null : eventInstance.forcedStartTzo, // nooooo, same
2467            });
2468        }
2469        return '';
2470    }
2471    function getSegMeta(seg, todayRange, nowDate) {
2472        var segRange = seg.eventRange.range;
2473        return {
2474            isPast: segRange.end < (nowDate || todayRange.start),
2475            isFuture: segRange.start >= (nowDate || todayRange.end),
2476            isToday: todayRange && rangeContainsMarker(todayRange, segRange.start),
2477        };
2478    }
2479    function getEventClassNames(props) {
2480        var classNames = ['fc-event'];
2481        if (props.isMirror) {
2482            classNames.push('fc-event-mirror');
2483        }
2484        if (props.isDraggable) {
2485            classNames.push('fc-event-draggable');
2486        }
2487        if (props.isStartResizable || props.isEndResizable) {
2488            classNames.push('fc-event-resizable');
2489        }
2490        if (props.isDragging) {
2491            classNames.push('fc-event-dragging');
2492        }
2493        if (props.isResizing) {
2494            classNames.push('fc-event-resizing');
2495        }
2496        if (props.isSelected) {
2497            classNames.push('fc-event-selected');
2498        }
2499        if (props.isStart) {
2500            classNames.push('fc-event-start');
2501        }
2502        if (props.isEnd) {
2503            classNames.push('fc-event-end');
2504        }
2505        if (props.isPast) {
2506            classNames.push('fc-event-past');
2507        }
2508        if (props.isToday) {
2509            classNames.push('fc-event-today');
2510        }
2511        if (props.isFuture) {
2512            classNames.push('fc-event-future');
2513        }
2514        return classNames;
2515    }
2516    function buildEventRangeKey(eventRange) {
2517        return eventRange.instance
2518            ? eventRange.instance.instanceId
2519            : eventRange.def.defId + ":" + eventRange.range.start.toISOString();
2520        // inverse-background events don't have specific instances. TODO: better solution
2521    }
2522
2523    var STANDARD_PROPS = {
2524        start: identity,
2525        end: identity,
2526        allDay: Boolean,
2527    };
2528    function parseDateSpan(raw, dateEnv, defaultDuration) {
2529        var span = parseOpenDateSpan(raw, dateEnv);
2530        var range = span.range;
2531        if (!range.start) {
2532            return null;
2533        }
2534        if (!range.end) {
2535            if (defaultDuration == null) {
2536                return null;
2537            }
2538            range.end = dateEnv.add(range.start, defaultDuration);
2539        }
2540        return span;
2541    }
2542    /*
2543    TODO: somehow combine with parseRange?
2544    Will return null if the start/end props were present but parsed invali
2544dly.
2545    */
2546    function parseOpenDateSpan(raw, dateEnv) {
2547        var _a = refineProps(raw, STANDARD_PROPS), standardProps = _a.refined, extra = _a.extra;
2548        var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
2549        var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
2550        var allDay = standardProps.allDay;
2551        if (allDay == null) {
2552            allDay = (startMeta && startMeta.isTimeUnspecified) &&
2553                (!endMeta || endMeta.isTimeUnspecified);
2554        }
2555        return __assign({ range: {
2556                start: startMeta ? startMeta.marker : null,
2557                end: endMeta ? endMeta.marker : null,
2558            }, allDay: allDay }, extra);
2559    }
2560    function isDateSpansEqual(span0, span1) {
2561        return rangesEqual(span0.range, span1.range) &&
2562            span0.allDay === span1.allDay &&
2563            isSpanPropsEqual(span0, span1);
2564    }
2565    // the NON-DATE-RELATED props
2566    function isSpanPropsEqual(span0, span1) {
2567        for (var propName in span1) {
2568            if (propName !== 'range' && propName !== 'allDay') {
2569                if (span0[propName] !== span1[propName]) {
2570                    return false;
2571                }
2572            }
2573        }
2574        // are there any props that span0 has that span1 DOESN'T have?
2575        // both have range/allDay, so no need to special-case.
2576        for (var propName in span0) {
2577            if (!(propName in span1)) {
2578                return false;
2579            }
2580        }
2581        return true;
2582    }
2583    function buildDateSpanApi(span, dateEnv) {
2584        return __assign(__assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay });
2585    }
2586    function buildRangeApiWithTimeZone(range, dateEnv, omitTime) {
2587        return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone });
2588    }
2589    function buildRangeApi(range, dateEnv, omitTime) {
2590        return {
2591            start: dateEnv.toDate(range.start),
2592            end: dateEnv.toDate(range.end),
2593            startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }),
2594            endStr: dateEnv.formatIso(range.end, { omitTime: omitTime }),
2595        };
2596    }
2597    function fabricateEventRange(dateSpan, eventUiBases, context) {
2598        var res = refineEventDef({ editable: false }, context);
2599        var def = parseEventDef(res.refined, res.extra, '', // sourceId
2600        dateSpan.allDay, true, // hasEnd
2601        context);
2602        return {
2603            def: def,
2604            ui: compileEventUi(def, eventUiBases),
2605            instance: createEventInstance(def.defId, dateSpan.range),
2606            range: dateSpan.range,
2607            isStart: true,
2608            isEnd: true,
2609        };
2610    }
2611
2612    function triggerDateSelect(selection, pev, context) {
2613        context.emitter.trigger('select', __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view }));
2614    }
2615    function triggerDateUnselect(pev, context) {
2616        context.emitter.trigger('unselect', {
2617            jsEvent: pev ? pev.origEvent : null,
2618            view: context.viewApi || context.calendarApi.view,
2619        });
2620    }
2621    function buildDateSpanApiWithContext(dateSpan, context) {
2622        var props = {};
2623        for (var _i = 0, _a = context.pluginHooks.dateSpanTransforms; _i < _a.length; _i++) {
2624            var transform = _a[_i];
2625            __assign(props, transform(dateSpan, context));
2626        }
2627        __assign(props, buildDateSpanApi(dateSpan, context.dateEnv));
2628        return props;
2629    }
2630    // Given an event's allDay status and start date, return what its fallback end date should be.
2631    // TODO: rename to computeDefaultEventEnd
2632    function getDefaultEventEnd(allDay, marker, context) {
2633        var dateEnv = context.dateEnv, options = context.options;
2634        var end = marker;
2635        if (allDay) {
2636            end = startOfDay(end);
2637            end = dateEnv.add(end, options.defaultAllDayEventDuration);
2638        }
2639        else {
2640            end = dateEnv.add(end, options.defaultTimedEventDuration);
2641        }
2642        return end;
2643    }
2644
2645    // applies the mutation to ALL defs/instances within the event store
2646    function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) {
2647        var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
2648        var dest = createEmptyEventStore();
2649        for (var defId in eventStore.defs) {
2650            var def = eventStore.defs[defId];
2651            dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context);
2652        }
2653        for (var instanceId in eventStore.instances) {
2654            var instance = eventStore.instances[instanceId];
2655            var def = dest.defs[instance.defId]; // important to grab the newly modified def
2656            dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context);
2657        }
2658        return dest;
2659    }
2660    function applyMutationToEventDef(eventDef, eventConfig, mutation, context) {
2661        var standardProps = mutation.standardProps || {};
2662        // if hasEnd has not been specified, guess a good value based on deltas.
2663        // if duration will change, there's no way the default duration will persist,
2664        // and thus, we need to mark the event as having a real end
2665        if (standardProps.hasEnd == null &&
2666            eventConfig.durationEditable &&
2667            (mutation.startDelta || mutation.endDelta)) {
2668            standardProps.hasEnd = true; // TODO: is this mutation okay?
2669        }
2670        var copy = __assign(__assign(__assign({}, eventDef), standardProps), { ui: __assign(__assign({}, eventDef.ui), standardProps.ui) });
2671        if (mutation.extendedProps) {
2672            copy.extendedProps = __assign(__assign({}, copy.extendedProps), mutation.extendedProps);
2673        }
2674        for (var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; _i < _a.length; _i++) {
2675            var applier = _a[_i];
2676            applier(copy, mutation, context);
2677        }
2678        if (!copy.hasEnd && context.options.forceEventDuration) {
2679            copy.hasEnd = true;
2680        }
2681        return copy;
2682    }
2683    function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
2684    eventConfig, mutation, context) {
2685        var dateEnv = context.dateEnv;
2686        var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
2687        var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
2688        var copy = __assign({}, eventInstance);
2689        if (forceAllDay) {
2690            copy.range = computeAlignedDayRange(copy.range);
2691        }
2692        if (mutation.datesDelta && eventConfig.startEditable) {
2693            copy.range = {
2694                start: dateEnv.add(copy.range.start, mutation.datesDelta),
2695                end: dateEnv.add(copy.range.end, mutation.datesDelta),
2696            };
2697        }
2698        if (mutation.startDelta && eventConfig.durationEditable) {
2699            copy.range = {
2700                start: dateEnv.add(copy.range.start, mutation.startDelta),
2701                end: copy.range.end,
2702            };
2703        }
2704        if (mutation.endDelta && eventConfig.durationEditable) {
2705            copy.range = {
2706                start: copy.range.start,
2707                end: dateEnv.add(copy.range.end, mutation.endDelta),
2708            };
2709        }
2710        if (clearEnd) {
2711            copy.range = {
2712                start: copy.range.start,
2713                end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context),
2714            };
2715        }
2716        // in case event was all-day but the supplied deltas were not
2717        // better util for this?
2718        if (eventDef.allDay) {
2719            copy.range = {
2720                start: startOfDay(copy.range.start),
2721                end: startOfDay(copy.range.end),
2722            };
2723        }
2724        // handle invalid durations
2725        if (copy.range.end < copy.range.start) {
2726            copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context);
2727        }
2728        return copy;
2729    }
2730
2731    // no public types yet. when there are, export from:
2732    // import {} from './api-type-deps'
2733    var ViewApi = /** @class */ (function () {
2734        function ViewApi(type, getCurrentData, dateEnv) {
2735            this.type = type;
2736            this.getCurrentData = getCurrentData;
2737            this.dateEnv = dateEnv;
2738        }
2739        Object.defineProperty(ViewApi.prototype, "calendar", {
2740            get: function () {
2741                return this.getCurrentData().calendarApi;
2742            },
2743            enumerable: false,
2744            configurable: true
2745        });
2746        Object.defineProperty(ViewApi.prototype, "title", {
2747            get: function () {
2748                return this.getCurrentData().viewTitle;
2749            },
2750            enumerable: false,
2751            configurable: true
2752        });
2753        Object.defineProperty(ViewApi.prototype, "activeStart", {
2754            get: function () {
2755                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);
2756            },
2757            enumerable: false,
2758            configurable: true
2759        });
2760        Object.defineProperty(ViewApi.prototype, "activeEnd", {
2761            get: function () {
2762                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);
2763            },
2764            enumerable: false,
2765            configurable: true
2766        });
2767        Object.defineProperty(ViewApi.prototype, "currentStart", {
2768            get: function () {
2769                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);
2770            },
2771            enumerable: false,
2772            configurable: true
2773        });
2774        Object.defineProperty(ViewApi.prototype, "currentEnd", {
2775            get: function () {
2776                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);
2777            },
2778            enumerable: false,
2779            configurable: true
2780        });
2781        ViewApi.prototype.getOption = function (name) {
2782            return this.getCurrentData().options[name]; // are the view-specific options
2783        };
2784        return ViewApi;
2785    }());
2786
2787    var EVENT_SOURCE_REFINERS$1 = {
2788        id: String,
2789        defaultAllDay: Boolean,
2790        url: String,
2791        format: String,
2792        events: identity,
2793        eventDataTransform: identity,
2794        // for any network-related sources
2795        success: identity,
2796        failure: identity,
2797    };
2798    function parseEventSource(raw, context, refiners) {
2799        if (refiners === void 0) { refiners = buildEventSourceRefiners(context); }
2800        var rawObj;
2801        if (typeof raw === 'string') {
2802            rawObj = { url: raw };
2803        }
2804        else if (typeof raw === 'function' || Array.isArray(raw)) {
2805            rawObj = { events: raw };
2806        }
2807        else if (typeof raw === 'object' && raw) { // not null
2808            rawObj = raw;
2809        }
2810        if (rawObj) {
2811            var _a = refineProps(rawObj, refiners), refined = _a.refined, extra = _a.extra;
2812            var metaRes = buildEventSourceMeta(refined, context);
2813            if (metaRes) {
2814                return {
2815                    _raw: raw,
2816                    isFetching: false,
2817                    latestFetchId: '',
2818                    fetchRange: null,
2819                    defaultAllDay: refined.defaultAllDay,
2820                    eventDataTransform: refined.eventDataTransform,
2821                    success: refined.success,
2822                    failure: refined.failure,
2823                    publicId: refined.id || '',
2824                    sourceId: guid(),
2825                    sourceDefId: metaRes.sourceDefId,
2826                    meta: metaRes.meta,
2827                    ui: createEventUi(refined, context),
2828                    extendedProps: extra,
2829                };
2830            }
2831        }
2832        return null;
2833    }
2834    function buildEventSourceRefiners(context) {
2835        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS$1), context.pluginHooks.eventSourceRefiners);
2836    }
2837    function buildEventSourceMeta(raw, context) {
2838        var defs = context.pluginHooks.eventSourceDefs;
2839        for (var i = defs.length - 1; i >= 0; i -= 1) { // later-added plugins take precedence
2840            var def = defs[i];
2841            var meta = def.parseMeta(raw);
2842            if (meta) {
2843                return { sourceDefId: i, meta: meta };
2844            }
2845        }
2846        return null;
2847    }
2848
2849    function reduceCurrentDate(currentDate, action) {
2850        switch (action.type) {
2851            case 'CHANGE_DATE':
2852                return action.dateMarker;
2853            default:
2854                return currentDate;
2855        }
2856    }
2857    function getInitialDate(options, dateEnv) {
2858        var initialDateInput = options.initialDate;
2859        // compute the initial ambig-timezone date
2860        if (initialDateInput != null) {
2861            return dateEnv.createMarker(initialDateInput);
2862        }
2863        return getNow(options.now, dateEnv); // getNow already returns unzoned
2864    }
2865    function getNow(nowInput, dateEnv) {
2866        if (typeof nowInput === 'function') {
2867            nowInput = nowInput();
2868        }
2869        if (nowInput == null) {
2870            return dateEnv.createNowMarker();
2871        }
2872        return dateEnv.createMarker(nowInput);
2873    }
2874
2875    var CalendarApi = /** @class */ (function () {
2876        function CalendarApi() {
2877        }
2878        CalendarApi.prototype.getCurrentData = function () {
2879            return this.currentDataManager.getCurrentData();
2880        };
2881        CalendarApi.prototype.dispatch = function (action) {
2882            return this.currentDataManager.dispatch(action);
2883        };
2884        Object.defineProperty(CalendarApi.prototype, "view", {
2885            get: function () { return this.getCurrentData().viewApi; } // for public API
2886            ,
2887            enumerable: false,
2888            configurable: true
2889        });
2890        CalendarApi.prototype.batchRendering = function (callback) {
2891            callback();
2892        };
2893        CalendarApi.prototype.updateSize = function () {
2894            this.trigger('_resize', true);
2895        };
2896        // Options
2897        // -----------------------------------------------------------------------------------------------------------------
2898        CalendarApi.prototype.setOption = function (name, val) {
2899            this.dispatch({
2900                type: 'SET_OPTION',
2901                optionName: name,
2902                rawOptionValue: val,
2903            });
2904        };
2905        CalendarApi.prototype.getOption = function (name) {
2906            return this.currentDataManager.currentCalendarOptionsInput[name];
2907        };
2908        CalendarApi.prototype.getAvailableLocaleCodes = function () {
2909            return Object.keys(this.getCurrentData().availableRawLocales);
2910        };
2911        // Trigger
2912        // -----------------------------------------------------------------------------------------------------------------
2913        CalendarApi.prototype.on = function (handlerName, handler) {
2914            var currentDataManager = this.currentDataManager;
2915            if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) {
2916                currentDataManager.emitter.on(handlerName, handler);
2917            }
2918            else {
2919                console.warn("Unknown listener name '" + handlerName + "'");
2920            }
2921        };
2922        CalendarApi.prototype.off = function (handlerName, handler) {
2923            this.currentDataManager.emitter.off(handlerName, handler);
2924        };
2925        // not meant for public use
2926        CalendarApi.prototype.trigger = function (handlerName) {
2927            var _a;
2928            var args = [];
2929            for (var _i = 1; _i < arguments.length; _i++) {
2930                args[_i - 1] = arguments[_i];
2931            }
2932            (_a = this.currentDataManager.emitter).trigger.apply(_a, __spreadArray([handlerName], args));
2933        };
2934        // View
2935        // -----------------------------------------------------------------------------------------------------------------
2936        CalendarApi.prototype.changeView = function (viewType, dateOrRange) {
2937            var _this = this;
2938            this.batchRendering(function () {
2939                _this.unselect();
2940                if (dateOrRange) {
2941                    if (dateOrRange.start && dateOrRange.end) { // a range
2942                        _this.dispatch({
2943                            type: 'CHANGE_VIEW_TYPE',
2944                            viewType: viewType,
2945                        });
2946                        _this.dispatch({
2947                            type: 'SET_OPTION',
2948                            optionName: 'visibleRange',
2949                            rawOptionValue: dateOrRange,
2950                        });
2951                    }
2952                    else {
2953                        var dateEnv = _this.getCurrentData().dateEnv;
2954                        _this.dispatch({
2955                            type: 'CHANGE_VIEW_TYPE',
2956                            viewType: viewType,
2957                            dateMarker: dateEnv.createMarker(dateOrRange),
2958                        });
2959                    }
2960                }
2961                else {
2962                    _this.dispatch({
2963                        type: 'CHANGE_VIEW_TYPE',
2964                        viewType: viewType,
2965                    });
2966                }
2967            });
2968        };
2969        // Forces navigation to a view for the given date.
2970        // `viewType` can be a specific view name or a generic one like "week" or "day".
2971        // needs to change
2972        CalendarApi.prototype.zoomTo = function (dateMarker, viewType) {
2973            var state = this.getCurrentData();
2974            var spec;
2975            viewType = viewType || 'day'; // day is default zoom
2976            spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType);
2977            this.unselect();
2978            if (spec) {
2979                this.dispatch({
2980                    type: 'CHANGE_VIEW_TYPE',
2981                    viewType: spec.type,
2982                    dateMarker: dateMarker,
2983                });
2984            }
2985            else {
2986                this.dispatch({
2987                    type: 'CHANGE_DATE',
2988                    dateMarker: dateMarker,
2989                });
2990            }
2991        };
2992        // Given a duration singular unit, like "week" or "day", finds a matching view spec.
2993        // Preference is given to views that have corresponding buttons.
2994        CalendarApi.prototype.getUnitViewSpec = function (unit) {
2995            var _a = this.getCurrentData(), viewSpecs = _a.viewSpecs, toolbarConfig = _a.toolbarConfig;
2996            var viewTypes = [].concat(toolbarConfig.viewsWithButtons);
2997            var i;
2998            var spec;
2999            for (var viewType in viewSpecs) {
3000                viewTypes.push(viewType);
3001            }
3002            for (i = 0; i < viewTypes.length; i += 1) {
3003                spec = viewSpecs[viewTypes[i]];
3004                if (spec) {
3005                    if (spec.singleUnit === unit) {
3006                        return spec;
3007                    }
3008                }
3009            }
3010            return null;
3011        };
3012        // Current Date
3013        // -----------------------------------------------------------------------------------------------------------------
3014        CalendarApi.prototype.prev = function () {
3015            this.unselect();
3016            this.dispatch({ type: 'PREV' });
3017        };
3018        CalendarApi.prototype.next = function () {
3019            this.unselect();
3020            this.dispatch({ type: 'NEXT' });
3021        };
3022        CalendarApi.prototype.prevYear = function () {
3023            var state = this.getCurrentData();
3024            this.unselect();
3025            this.dispatch({
3026                type: 'CHANGE_DATE',
3027                dateMarker: state.dateEnv.addYears(state.currentDate, -1),
3028            });
3029        };
3030        CalendarApi.prototype.nextYear = function () {
3031            var state = this.getCurrentData();
3032            this.unselect();
3033            this.dispatch({
3034                type: 'CHANGE_DATE',
3035                dateMarker: state.dateEnv.addYears(state.currentDate, 1),
3036            });
3037        };
3038        CalendarApi.prototype.today = function () {
3039            var state = this.getCurrentData();
3040            this.unselect();
3041            this.dispatch({
3042                type: 'CHANGE_DATE',
3043                dateMarker: getNow(state.calendarOptions.now, state.dateEnv),
3044            });
3045        };
3046        CalendarApi.prototype.gotoDate = function (zonedDateInput) {
3047            var state = this.getCurrentData();
3048            this.unselect();
3049            this.dispatch({
3050                type: 'CHANGE_DATE',
3051                dateMarker: state.dateEnv.createMarker(zonedDateInput),
3052            });
3053        };
3054        CalendarApi.prototype.incrementDate = function (deltaInput) {
3055            var state = this.getCurrentData();
3056            var delta = createDuration(deltaInput);
3057            if (delta) { // else, warn about invalid input?
3058                this.unselect();
3059                this.dispatch({
3060                    type: 'CHANGE_DATE',
3061                    dateMarker: state.dateEnv.add(state.currentDate, delta),
3062                });
3063            }
3064        };
3065        // for external API
3066        CalendarApi.prototype.getDate = function () {
3067            var state = this.getCurrentData();
3068            return state.dateEnv.toDate(state.currentDate);
3069        };
3070        // Date Formatting Utils
3071        // -----------------------------------------------------------------------------------------------------------------
3072        CalendarApi.prototype.formatDate = function (d, formatter) {
3073            var dateEnv = this.getCurrentData().dateEnv;
3074            return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
3075        };
3076        // `settings` is for formatter AND isEndExclusive
3077        CalendarApi.prototype.formatRange = function (d0, d1, settings) {
3078            var dateEnv = this.getCurrentData().dateEnv;
3079            return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings);
3080        };
3081        CalendarApi.prototype.formatIso = function (d, omitTime) {
3082            var dateEnv = this.getCurrentData().dateEnv;
3083            return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
3084        };
3085        // Date Selection / Event Selection / DayClick
3086        // -----------------------------------------------------------------------------------------------------------------
3087        // this public method receives start/end dates in any format, with any timezone
3088        // NOTE: args were changed from v3
3089        CalendarApi.prototype.select = function (dateOrObj, endDate) {
3090            var selectionInput;
3091            if (endDate == null) {
3092                if (dateOrObj.start != null) {
3093                    selectionInput = dateOrObj;
3094                }
3095                else {
3096                    selectionInput = {
3097                        start: dateOrObj,
3098                        end: null,
3099                    };
3100                }
3101            }
3102            else {
3103                selectionInput = {
3104                    start: dateOrObj,
3105                    end: endDate,
3106                };
3107            }
3108            var state = this.getCurrentData();
3109            var selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 }));
3110            if (selection) { // throw parse error otherwise?
3111                this.dispatch({ type: 'SELECT_DATES', selection: selection });
3112                triggerDateSelect(selection, null, state);
3113            }
3114        };
3115        // public method
3116        CalendarApi.prototype.unselect = function (pev) {
3117            var state = this.getCurrentData();
3118            if (state.dateSelection) {
3119                this.dispatch({ type: 'UNSELECT_DATES' });
3120                triggerDateUnselect(pev, state);
3121            }
3122        };
3123        // Public Events API
3124        // -----------------------------------------------------------------------------------------------------------------
3125        CalendarApi.prototype.addEvent = function (eventInput, sourceIn
3125put) {
3126            if (eventInput instanceof EventApi) {
3127                var def = eventInput._def;
3128                var instance = eventInput._instance;
3129                var currentData = this.getCurrentData();
3130                // not already present? don't want to add an old snapshot
3131                if (!currentData.eventStore.defs[def.defId]) {
3132                    this.dispatch({
3133                        type: 'ADD_EVENTS',
3134                        eventStore: eventTupleToStore({ def: def, instance: instance }), // TODO: better util for two args?
3135                    });
3136                    this.triggerEventAdd(eventInput);
3137                }
3138                return eventInput;
3139            }
3140            var state = this.getCurrentData();
3141            var eventSource;
3142            if (sourceInput instanceof EventSourceApi) {
3143                eventSource = sourceInput.internalEventSource;
3144            }
3145            else if (typeof sourceInput === 'boolean') {
3146                if (sourceInput) { // true. part of the first event source
3147                    eventSource = hashValuesToArray(state.eventSources)[0];
3148                }
3149            }
3150            else if (sourceInput != null) { // an ID. accepts a number too
3151                var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
3152                if (!sourceApi) {
3153                    console.warn("Could not find an event source with ID \"" + sourceInput + "\""); // TODO: test
3154                    return null;
3155                }
3156                eventSource = sourceApi.internalEventSource;
3157            }
3158            var tuple = parseEvent(eventInput, eventSource, state, false);
3159            if (tuple) {
3160                var newEventApi = new EventApi(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
3161                this.dispatch({
3162                    type: 'ADD_EVENTS',
3163                    eventStore: eventTupleToStore(tuple),
3164                });
3165                this.triggerEventAdd(newEventApi);
3166                return newEventApi;
3167            }
3168            return null;
3169        };
3170        CalendarApi.prototype.triggerEventAdd = function (eventApi) {
3171            var _this = this;
3172            var emitter = this.getCurrentData().emitter;
3173            emitter.trigger('eventAdd', {
3174                event: eventApi,
3175                relatedEvents: [],
3176                revert: function () {
3177                    _this.dispatch({
3178                        type: 'REMOVE_EVENTS',
3179                        eventStore: eventApiToStore(eventApi),
3180                    });
3181                },
3182            });
3183        };
3184        // TODO: optimize
3185        CalendarApi.prototype.getEventById = function (id) {
3186            var state = this.getCurrentData();
3187            var _a = state.eventStore, defs = _a.defs, instances = _a.instances;
3188            id = String(id);
3189            for (var defId in defs) {
3190                var def = defs[defId];
3191                if (def.publicId === id) {
3192                    if (def.recurringDef) {
3193                        return new EventApi(state, def, null);
3194                    }
3195                    for (var instanceId in instances) {
3196                        var instance = instances[instanceId];
3197                        if (instance.defId === def.defId) {
3198                            return new EventApi(state, def, instance);
3199                        }
3200                    }
3201                }
3202            }
3203            return null;
3204        };
3205        CalendarApi.prototype.getEvents = function () {
3206            var currentData = this.getCurrentData();
3207            return buildEventApis(currentData.eventStore, currentData);
3208        };
3209        CalendarApi.prototype.removeAllEvents = function () {
3210            this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
3211        };
3212        // Public Event Sources API
3213        // -----------------------------------------------------------------------------------------------------------------
3214        CalendarApi.prototype.getEventSources = function () {
3215            var state = this.getCurrentData();
3216            var sourceHash = state.eventSources;
3217            var sourceApis = [];
3218            for (var internalId in sourceHash) {
3219                sourceApis.push(new EventSourceApi(state, sourceHash[internalId]));
3220            }
3221            return sourceApis;
3222        };
3223        CalendarApi.prototype.getEventSourceById = function (id) {
3224            var state = this.getCurrentData();
3225            var sourceHash = state.eventSources;
3226            id = String(id);
3227            for (var sourceId in sourceHash) {
3228                if (sourceHash[sourceId].publicId === id) {
3229                    return new EventSourceApi(state, sourceHash[sourceId]);
3230                }
3231            }
3232            return null;
3233        };
3234        CalendarApi.prototype.addEventSource = function (sourceInput) {
3235            var state = this.getCurrentData();
3236            if (sourceInput instanceof EventSourceApi) {
3237                // not already present? don't want to add an old snapshot
3238                if (!state.eventSources[sourceInput.internalEventSource.sourceId]) {
3239                    this.dispatch({
3240                        type: 'ADD_EVENT_SOURCES',
3241                        sources: [sourceInput.internalEventSource],
3242                    });
3243                }
3244                return sourceInput;
3245            }
3246            var eventSource = parseEventSource(sourceInput, state);
3247            if (eventSource) { // TODO: error otherwise?
3248                this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
3249                return new EventSourceApi(state, eventSource);
3250            }
3251            return null;
3252        };
3253        CalendarApi.prototype.removeAllEventSources = function () {
3254            this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
3255        };
3256        CalendarApi.prototype.refetchEvents = function () {
3257            this.dispatch({ type: 'FETCH_EVENT_SOURCES', isRefetch: true });
3258        };
3259        // Scroll
3260        // -----------------------------------------------------------------------------------------------------------------
3261        CalendarApi.prototype.scrollToTime = function (timeInput) {
3262            var time = createDuration(timeInput);
3263            if (time) {
3264                this.trigger('_scrollRequest', { time: time });
3265            }
3266        };
3267        return CalendarApi;
3268    }());
3269
3270    var EventApi = /** @class */ (function () {
3271        // instance will be null if expressing a recurring event that has no current instances,
3272        // OR if trying to validate an incoming external event that has no dates assigned
3273        function EventApi(context, def, instance) {
3274            this._context = context;
3275            this._def = def;
3276            this._instance = instance || null;
3277        }
3278        /*
3279        TODO: make event struct more responsible for this
3280        */
3281        EventApi.prototype.setProp = function (name, val) {
3282            var _a, _b;
3283            if (name in EVENT_DATE_REFINERS) {
3284                console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.');
3285                // TODO: make proper aliasing system?
3286            }
3287            else if (name === 'id') {
3288                val = EVENT_NON_DATE_REFINERS[name](val);
3289                this.mutate({
3290                    standardProps: { publicId: val }, // hardcoded internal name
3291                });
3292            }
3293            else if (name in EVENT_NON_DATE_REFINERS) {
3294                val = EVENT_NON_DATE_REFINERS[name](val);
3295                this.mutate({
3296                    standardProps: (_a = {}, _a[name] = val, _a),
3297                });
3298            }
3299            else if (name in EVENT_UI_REFINERS) {
3300                var ui = EVENT_UI_REFINERS[name](val);
3301                if (name === 'color') {
3302                    ui = { backgroundColor: val, borderColor: val };
3303                }
3304                else if (name === 'editable') {
3305                    ui = { startEditable: val, durationEditable: val };
3306                }
3307                else {
3308                    ui = (_b = {}, _b[name] = val, _b);
3309                }
3310                this.mutate({
3311                    standardProps: { ui: ui },
3312                });
3313            }
3314            else {
3315                console.warn("Could not set prop '" + name + "'. Use setExtendedProp instead.");
3316            }
3317        };
3318        EventApi.prototype.setExtendedProp = function (name, val) {
3319            var _a;
3320            this.mutate({
3321                extendedProps: (_a = {}, _a[name] = val, _a),
3322            });
3323        };
3324        EventApi.prototype.setStart = function (startInput, options) {
3325            if (options === void 0) { options = {}; }
3326            var dateEnv = this._context.dateEnv;
3327            var start = dateEnv.createMarker(startInput);
3328            if (start && this._instance) { // TODO: warning if parsed bad
3329                var instanceRange = this._instance.range;
3330                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
3331                if (options.maintainDuration) {
3332                    this.mutate({ datesDelta: startDelta });
3333                }
3334                else {
3335                    this.mutate({ startDelta: startDelta });
3336                }
3337            }
3338        };
3339        EventApi.prototype.setEnd = function (endInput, options) {
3340            if (options === void 0) { options = {}; }
3341            var dateEnv = this._context.dateEnv;
3342            var end;
3343            if (endInput != null) {
3344                end = dateEnv.createMarker(endInput);
3345                if (!end) {
3346                    return; // TODO: warning if parsed bad
3347                }
3348            }
3349            if (this._instance) {
3350                if (end) {
3351                    var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
3352                    this.mutate({ endDelta: endDelta });
3353                }
3354                else {
3355                    this.mutate({ standardProps: { hasEnd: false } });
3356                }
3357            }
3358        };
3359        EventApi.prototype.setDates = function (startInput, endInput, options) {
3360            if (options === void 0) { options = {}; }
3361            var dateEnv = this._context.dateEnv;
3362            var standardProps = { allDay: options.allDay };
3363            var start = dateEnv.createMarker(startInput);
3364            var end;
3365            if (!start) {
3366                return; // TODO: warning if parsed bad
3367            }
3368            if (endInput != null) {
3369                end = dateEnv.createMarker(endInput);
3370                if (!end) { // TODO: warning if parsed bad
3371                    return;
3372                }
3373            }
3374            if (this._instance) {
3375                var instanceRange = this._instance.range;
3376                // when computing the diff for an event being converted to all-day,
3377                // compute diff off of the all-day values the way event-mutation does.
3378                if (options.allDay === true) {
3379                    instanceRange = computeAlignedDayRange(instanceRange);
3380                }
3381                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
3382                if (end) {
3383                    var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
3384                    if (durationsEqual(startDelta, endDelta)) {
3385                        this.mutate({ datesDelta: startDelta, standardProps: standardProps });
3386                    }
3387                    else {
3388                        this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
3389                    }
3390                }
3391                else { // means "clear the end"
3392                    standardProps.hasEnd = false;
3393                    this.mutate({ datesDelta: startDelta, standardProps: standardProps });
3394                }
3395            }
3396        };
3397        EventApi.prototype.moveStart = function (deltaInput) {
3398            var delta = createDuration(deltaInput);
3399            if (delta) { // TODO: warning if parsed bad
3400                this.mutate({ startDelta: delta });
3401            }
3402        };
3403        EventApi.prototype.moveEnd = function (deltaInput) {
3404            var delta = createDuration(deltaInput);
3405            if (delta) { // TODO: warning if parsed bad
3406                this.mutate({ endDelta: delta });
3407            }
3408        };
3409        EventApi.prototype.moveDates = function (deltaInput) {
3410            var delta = createDuration(deltaInput);
3411            if (delta) { // TODO: warning if parsed bad
3412                this.mutate({ datesDelta: delta });
3413            }
3414        };
3415        EventApi.prototype.setAllDay = function (allDay, options) {
3416            if (options === void 0) { options = {}; }
3417            var standardProps = { allDay: allDay };
3418            var maintainDuration = options.maintainDuration;
3419            if (maintainDuration == null) {
3420                maintainDuration = this._context.options.allDayMaintainDuration;
3421            }
3422            if (this._def.allDay !== allDay) {
3423                standardProps.hasEnd = maintainDuration;
3424            }
3425            this.mutate({ standardProps: standardProps });
3426        };
3427        EventApi.prototype.formatRange = function (formatInput) {
3428            var dateEnv = this._context.dateEnv;
3429            var instance = this._instance;
3430            var formatter = createFormatter(formatInput);
3431            if (this._def.hasEnd) {
3432                return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
3433                    forcedStartTzo: instance.forcedStartTzo,
3434                    forcedEndTzo: instance.forcedEndTzo,
3435                });
3436            }
3437            return dateEnv.format(instance.range.start, formatter, {
3438                forcedTzo: instance.forcedStartTzo,
3439            });
3440        };
3441        EventApi.prototype.mutate = function (mutation) {
3442            var instance = this._instance;
3443            if (instance) {
3444                var def = this._def;
3445                var context_1 = this._context;
3446                var eventStore_1 = context_1.getCurrentData().eventStore;
3447                var relevantEvents = getRelevantEvents(eventStore_1, instance.instanceId);
3448                var eventConfigBase = {
3449                    '': {
3450                        display: '',
3451                        startEditable: true,
3452                        durationEditable: true,
3453                        constraints: [],
3454                        overlap: null,
3455                        allows: [],
3456                        backgroundColor: '',
3457                        borderColor: '',
3458                        textColor: '',
3459                        classNames: [],
3460                    },
3461                };
3462                relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context_1);
3463                var oldEvent = new EventApi(context_1, def, instance); // snapshot
3464                this._def = relevantEvents.defs[def.defId];
3465                this._instance = relevantEvents.instances[instance.instanceId];
3466                context_1.dispatch({
3467                    type: 'MERGE_EVENTS',
3468                    eventStore: relevantEvents,
3469                });
3470                context_1.emitter.trigger('eventChange', {
3471                    oldEvent: oldEvent,
3472                    event: this,
3473                    relatedEvents: buildEventApis(relevantEvents, context_1, instance),
3474                    revert: function () {
3475                        context_1.dispatch({
3476                            type: 'RESET_EVENTS',
3477                            eventStore: eventStore_1,
3478                        });
3479                    },
3480                });
3481            }
3482        };
3483        EventApi.prototype.remove = function () {
3484            var context = this._context;
3485            var asStore = eventApiToStore(this);
3486            context.dispatch({
3487                type: 'REMOVE_EVENTS',
3488                eventStore: asStore,
3489            });
3490            context.emitter.trigger('eventRemove', {
3491                event: this,
3492                relatedEvents: [],
3493                revert: function () {
3494                    context.dispatch({
3495                        type: 'MERGE_EVENTS',
3496                        eventStore: asStore,
3497                    });
3498                },
3499            });
3500        };
3501        Object.defineProperty(EventApi.prototype, "source", {
3502            get: function () {
3503                var sourceId = this._def.sourceId;
3504                if (sourceId) {
3505                    return new EventSourceApi(this._context, this._context.getCurrentData().eventSources[sourceId]);
3506                }
3507                return null;
3508            },
3509            enumerable: false,
3510            configurable: true
3511        });
3512        Object.defineProperty(EventApi.prototype, "start", {
3513            get: function () {
3514                return this._instance ?
3515                    this._context.dateEnv.toDate(this._instance.range.start) :
3516                    null;
3517            },
3518            enumerable: false,
3519            configurable: true
3520        });
3521        Object.defineProperty(EventApi.prototype, "end", {
3522            get: function () {
3523                return (this._instance && this._def.hasEnd) ?
3524                    this._context.dateEnv.toDate(this._instance.range.end) :
3525                    null;
3526            },
3527            enumerable: false,
3528            configurable: true
3529        });
3530        Object.defineProperty(EventApi.prototype, "startStr", {
3531            get: function () {
3532                var instance = this._instance;
3533                if (instance) {
3534                    return this._context.dateEnv.formatIso(instance.range.start, {
3535                        omitTime: this._def.allDay,
3536                        forcedTzo: instance.forcedStartTzo,
3537                    });
3538                }
3539                return '';
3540            },
3541            enumerable: false,
3542            configurable: true
3543        });
3544        Object.defineProperty(EventApi.prototype, "endStr", {
3545            get: function () {
3546                var instance = this._instance;
3547                if (instance && this._def.hasEnd) {
3548                    return this._context.dateEnv.formatIso(instance.range.end, {
3549                        omitTime: this._def.allDay,
3550                        forcedTzo: instance.forcedEndTzo,
3551                    });
3552                }
3553                return '';
3554            },
3555            enumerable: false,
3556            configurable: true
3557        });
3558        Object.defineProperty(EventApi.prototype, "id", {
3559            // computable props that all access the def
3560            // TODO: find a TypeScript-compatible way to do this at scale
3561            get: function () { return this._def.publicId; },
3562            enumerable: false,
3563            configurable: true
3564        });
3565        Object.defineProperty(EventApi.prototype, "groupId", {
3566            get: function () { return this._def.groupId; },
3567            enumerable: false,
3568            configurable: true
3569        });
3570        Object.defineProperty(EventApi.prototype, "allDay", {
3571            get: function () { return this._def.allDay; },
3572            enumerable: false,
3573            configurable: true
3574        });
3575        Object.defineProperty(EventApi.prototype, "title", {
3576            get: function () { return this._def.title; },
3577            enumerable: false,
3578            configurable: true
3579        });
3580        Object.defineProperty(EventApi.prototype, "url", {
3581            get: function () { return this._def.url; },
3582            enumerable: false,
3583            configurable: true
3584        });
3585        Object.defineProperty(EventApi.prototype, "display", {
3586            get: function () { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier
3587            ,
3588            enumerable: false,
3589            configurable: true
3590        });
3591        Object.defineProperty(EventApi.prototype, "startEditable", {
3592            get: function () { return this._def.ui.startEditable; },
3593            enumerable: false,
3594            configurable: true
3595        });
3596        Object.defineProperty(EventApi.prototype, "durationEditable", {
3597            get: function () { return this._def.ui.durationEditable; },
3598            enumerable: false,
3599            configurable: true
3600        });
3601        Object.defineProperty(EventApi.prototype, "constraint", {
3602            get: function () { return this._def.ui.constraints[0] || null; },
3603            enumerable: false,
3604            configurable: true
3605        });
3606        Object.defineProperty(EventApi.prototype, "overlap", {
3607            get: function () { return this._def.ui.overlap; },
3608            enumerable: false,
3609            configurable: true
3610        });
3611        Object.defineProperty(EventApi.prototype, "allow", {
3612            get: function () { return this._def.ui.allows[0] || null; },
3613            enumerable: false,
3614            configurable: true
3615        });
3616        Object.defineProperty(EventApi.prototype, "backgroundColor", {
3617            get: function () { return this._def.ui.backgroundColor; },
3618            enumerable: false,
3619            configurable: true
3620        });
3621        Object.defineProperty(EventApi.prototype, "borderColor", {
3622            get: function () { return this._def.ui.borderColor; },
3623            enumerable: false,
3624            configurable: true
3625        });
3626        Object.defineProperty(EventApi.prototype, "textColor", {
3627            get: function () { return this._def.ui.textColor; },
3628            enumerable: false,
3629            configurable: true
3630        });
3631        Object.defineProperty(EventApi.prototype, "classNames", {
3632            // NOTE: user can't modify these because Object.freeze was called in event-def parsing
3633            get: function () { return this._def.ui.classNames; },
3634            enumerable: false,
3635            configurable: true
3636        });
3637        Object.defineProperty(EventApi.prototype, "extendedProps", {
3638            get: function () { return this._def.extendedProps; },
3639            enumerable: false,
3640            configurable: true
3641        });
3642        EventApi.prototype.toPlainObject = function (settings) {
3643            if (settings === void 0) { settings = {}; }
3644            var def = this._def;
3645            var ui = def.ui;
3646            var _a = this, startStr = _a.startStr, endStr = _a.endStr;
3647            var res = {};
3648            if (def.title) {
3649                res.title = def.title;
3650            }
3651            if (startStr) {
3652                res.start = startStr;
3653            }
3654            if (endStr) {
3655                res.end = endStr;
3656            }
3657            if (def.publicId) {
3658                res.id = def.publicId;
3659            }
3660            if (def.groupId) {
3661                res.groupId = def.groupId;
3662            }
3663            if (def.url) {
3664                res.url = def.url;
3665            }
3666            if (ui.display && ui.display !== 'auto') {
3667                res.display = ui.display;
3668            }
3669            // TODO: what about recurring-event properties???
3670            // TODO: include startEditable/durationEditable/constraint/overlap/allow
3671            if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) {
3672                res.color = ui.backgroundColor;
3673            }
3674            else {
3675                if (ui.backgroundColor) {
3676                    res.backgroundColor = ui.backgroundColor;
3677                }
3678                if (ui.borderColor) {
3679                    res.borderColor = ui.borderColor;
3680                }
3681            }
3682            if (ui.textColor) {
3683                res.textColor = ui.textColor;
3684            }
3685            if (ui.classNames.length) {
3686                res.classNames = ui.classNames;
3687            }
3688            if (Object.keys(def.extendedProps).length) {
3689                if (settings.collapseExtendedProps) {
3690                    __assign(res, def.extendedProps);
3691                }
3692                else {
3693                    res.extendedProps = def.extendedProps;
3694                }
3695            }
3696            return res;
3697        };
3698        EventApi.prototype.toJSON = function () {
3699            return this.toPlainObject();
3700        };
3701        return EventApi;
3702    }());
3703    function eventApiToStore(eventApi) {
3704        var _a, _b;
3705        var def = eventApi._def;
3706        var instance = eventApi._instance;
3707        return {
3708            defs: (_a = {}, _a[def.defId] = def, _a),
3709            instances: instance
3710                ? (_b = {}, _b[instance.instanceId] = instance, _b) : {},
3711        };
3712    }
3713    function buildEventApis(eventStore, context, excludeInstance) {
3714        var defs = eventStore.defs, instances = eventStore.instances;
3715        var eventApis = [];
3716        var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : '';
3717        for (var id in instances) {
3718            var instance = instances[id];
3719            var def = defs[instance.defId];
3720            if (instance.instanceId !== excludeInstanceId) {
3721                eventApis.push(new EventApi(context, def, instance));
3722            }
3723        }
3724        return eventApis;
3725    }
3726
3727    var calendarSystemClassMap = {};
3728    function registerCalendarSystem(name, theClass) {
3729        calendarSystemClassMap[name] = theClass;
3730    }
3731    function createCalendarSystem(name) {
3732        return new calendarSystemClassMap[name]();
3733    }
3734    var GregorianCalendarSystem = /** @class */ (function () {
3735        function GregorianCalendarSystem() {
3736        }
3737        GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
3738            return d.getUTCFullYear();
3739        };
3740        GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
3741            return d.getUTCMonth();
3742        };
3743        GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
3744            return d.getUTCDate();
3745        };
3746        GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
3747            return arrayToUtcDate(arr);
3748        };
3749        GregorianCalendarSystem.prototype.markerToArray = function (marker) {
3750            return dateToUtcArray(marker);
3751        };
3752        return GregorianCalendarSystem;
3753    }());
3754    registerCalendarSystem('gregory', GregorianCalendarSystem);
3755
3756    var ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
3757    function parse(str) {
3758        var m = ISO_RE.exec(str);
3759        if (m) {
3760            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));
3761            if (isValidDate(marker)) {
3762                var timeZoneOffset = null;
3763                if (m[13]) {
3764                    timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
3765                        Number(m[18] || 0));
3766                }
3767                return {
3768                    marker: marker,
3769                    isTimeUnspecified: !m[6],
3770                    timeZoneOffset: timeZoneOffset,
3771                };
3772            }
3773        }
3774        return null;
3775    }
3776
3777    var DateEnv = /** @class */ (function () {
3778        function DateEnv(settings) {
3779            var timeZone = this.timeZone = settings.timeZone;
3780            var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
3781            if (settings.namedTimeZoneImpl && isNamedTimeZone) {
3782                this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
3783            }
3784            this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
3785            this.calendarSystem = createCalendarSystem(settings.calendarSystem);
3786            this.locale = settings.locale;
3787            this.weekDow = settings.locale.week.dow;
3788            this.weekDoy = settings.locale.week.doy;
3789            if (settings.weekNumberCalculation === 'ISO') {
3790                this.weekDow = 1;
3791                this.weekDoy = 4;
3792            }
3793            if (typeof settings.firstDay === 'number') {
3794                this.weekDow = settings.firstDay;
3795            }
3796            if (typeof settings.weekNumberCalculation === 'function') {
vendor: 16,384 bytes, lines 3797-4208
3797                this.weekNumberFunc = settings.weekNumberCalculation;
3798            }
3799            this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText;
3800            this.cmdFormatter = settings.cmdFormatter;
3801            this.defaultSeparator = settings.defaultSeparator;
3802        }
3803        // Creating / Parsing
3804        DateEnv.prototype.createMarker = function (input) {
3805            var meta = this.createMarkerMeta(input);
3806            if (meta === null) {
3807                return null;
3808            }
3809            return meta.marker;
3810        };
3811        DateEnv.prototype.createNowMarker = function () {
3812            if (this.canComputeOffset) {
3813                return this.timestampToMarker(new Date().valueOf());
3814            }
3815            // if we can't compute the current date val for a timezone,
3816            // better to give the current local date vals than UTC
3817            return arrayToUtcDate(dateToLocalArray(new Date()));
3818        };
3819        DateEnv.prototype.createMarkerMeta = function (input) {
3820            if (typeof input === 'string') {
3821                return this.parse(input);
3822            }
3823            var marker = null;
3824            if (typeof input === 'number') {
3825                marker = this.timestampToMarker(input);
3826            }
3827            else if (input instanceof Date) {
3828                input = input.valueOf();
3829                if (!isNaN(input)) {
3830                    marker = this.timestampToMarker(input);
3831                }
3832            }
3833            else if (Array.isArray(input)) {
3834                marker = arrayToUtcDate(input);
3835            }
3836            if (marker === null || !isValidDate(marker)) {
3837                return null;
3838            }
3839            return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
3840        };
3841        DateEnv.prototype.parse = function (s) {
3842            var parts = parse(s);
3843            if (parts === null) {
3844                return null;
3845            }
3846            var marker = parts.marker;
3847            var forcedTzo = null;
3848            if (parts.timeZoneOffset !== null) {
3849                if (this.canComputeOffset) {
3850                    marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
3851                }
3852                else {
3853                    forcedTzo = parts.timeZoneOffset;
3854                }
3855            }
3856            return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
3857        };
3858        // Accessors
3859        DateEnv.prototype.getYear = function (marker) {
3860            return this.calendarSystem.getMarkerYear(marker);
3861        };
3862        DateEnv.prototype.getMonth = function (marker) {
3863            return this.calendarSystem.getMarkerMonth(marker);
3864        };
3865        // Adding / Subtracting
3866        DateEnv.prototype.add = function (marker, dur) {
3867            var a = this.calendarSystem.markerToArray(marker);
3868            a[0] += dur.years;
3869            a[1] += dur.months;
3870            a[2] += dur.days;
3871            a[6] += dur.milliseconds;
3872            return this.calendarSystem.arrayToMarker(a);
3873        };
3874        DateEnv.prototype.subtract = function (marker, dur) {
3875            var a = this.calendarSystem.markerToArray(marker);
3876            a[0] -= dur.years;
3877            a[1] -= dur.months;
3878            a[2] -= dur.days;
3879            a[6] -= dur.milliseconds;
3880            return this.calendarSystem.arrayToMarker(a);
3881        };
3882        DateEnv.prototype.addYears = function (marker, n) {
3883            var a = this.calendarSystem.markerToArray(marker);
3884            a[0] += n;
3885            return this.calendarSystem.arrayToMarker(a);
3886        };
3887        DateEnv.prototype.addMonths = function (marker, n) {
3888            var a = this.calendarSystem.markerToArray(marker);
3889            a[1] += n;
3890            return this.calendarSystem.arrayToMarker(a);
3891        };
3892        // Diffing Whole Units
3893        DateEnv.prototype.diffWholeYears = function (m0, m1) {
3894            var calendarSystem = this.calendarSystem;
3895            if (timeAsMs(m0) === timeAsMs(m1) &&
3896                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
3897                calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
3898                return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
3899            }
3900            return null;
3901        };
3902        DateEnv.prototype.diffWholeMonths = function (m0, m1) {
3903            var calendarSystem = this.calendarSystem;
3904            if (timeAsMs(m0) === timeAsMs(m1) &&
3905                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
3906                return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
3907                    (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
3908            }
3909            return null;
3910        };
3911        // Range / Duration
3912        DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
3913            var n = this.diffWholeYears(m0, m1);
3914            if (n !== null) {
3915                return { unit: 'year', value: n };
3916            }
3917            n = this.diffWholeMonths(m0, m1);
3918            if (n !== null) {
3919                return { unit: 'month', value: n };
3920            }
3921            n = diffWholeWeeks(m0, m1);
3922            if (n !== null) {
3923                return { unit: 'week', value: n };
3924            }
3925            n = diffWholeDays(m0, m1);
3926            if (n !== null) {
3927                return { unit: 'day', value: n };
3928            }
3929            n = diffHours(m0, m1);
3930            if (isInt(n)) {
3931                return { unit: 'hour', value: n };
3932            }
3933            n = diffMinutes(m0, m1);
3934            if (isInt(n)) {
3935                return { unit: 'minute', value: n };
3936            }
3937            n = diffSeconds(m0, m1);
3938            if (isInt(n)) {
3939                return { unit: 'second', value: n };
3940            }
3941            return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
3942        };
3943        DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
3944            // TODO: can use greatestWholeUnit
3945            var diff;
3946            if (d.years) {
3947                diff = this.diffWholeYears(m0, m1);
3948                if (diff !== null) {
3949                    return diff / asRoughYears(d);
3950                }
3951            }
3952            if (d.months) {
3953                diff = this.diffWholeMonths(m0, m1);
3954                if (diff !== null) {
3955                    return diff / asRoughMonths(d);
3956                }
3957            }
3958            if (d.days) {
3959                diff = diffWholeDays(m0, m1);
3960                if (diff !== null) {
3961                    return diff / asRoughDays(d);
3962                }
3963            }
3964            return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
3965        };
3966        // Start-Of
3967        // these DON'T return zoned-dates. only UTC start-of dates
3968        DateEnv.prototype.startOf = function (m, unit) {
3969            if (unit === 'year') {
3970                return this.startOfYear(m);
3971            }
3972            if (unit === 'month') {
3973                return this.startOfMonth(m);
3974            }
3975            if (unit === 'week') {
3976                return this.startOfWeek(m);
3977            }
3978            if (unit === 'day') {
3979                return startOfDay(m);
3980            }
3981            if (unit === 'hour') {
3982                return startOfHour(m);
3983            }
3984            if (unit === 'minute') {
3985                return startOfMinute(m);
3986            }
3987            if (unit === 'second') {
3988                return startOfSecond(m);
3989            }
3990            return null;
3991        };
3992        DateEnv.prototype.startOfYear = function (m) {
3993            return this.calendarSystem.arrayToMarker([
3994                this.calendarSystem.getMarkerYear(m),
3995            ]);
3996        };
3997        DateEnv.prototype.startOfMonth = function (m) {
3998            return this.calendarSystem.arrayToMarker([
3999                this.calendarSystem.getMarkerYear(m),
4000                this.calendarSystem.getMarkerMonth(m),
4001            ]);
4002        };
4003        DateEnv.prototype.startOfWeek = function (m) {
4004            return this.calendarSystem.arrayToMarker([
4005                this.calendarSystem.getMarkerYear(m),
4006                this.calendarSystem.getMarkerMonth(m),
4007                m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7),
4008            ]);
4009        };
4010        // Week Number
4011        DateEnv.prototype.computeWeekNumber = function (marker) {
4012            if (this.weekNumberFunc) {
4013                return this.weekNumberFunc(this.toDate(marker));
4014            }
4015            return weekOfYear(marker, this.weekDow, this.weekDoy);
4016        };
4017        // TODO: choke on timeZoneName: long
4018        DateEnv.prototype.format = function (marker, formatter, dateOptions) {
4019            if (dateOptions === void 0) { dateOptions = {}; }
4020            return formatter.format({
4021                marker: marker,
4022                timeZoneOffset: dateOptions.forcedTzo != null ?
4023                    dateOptions.forcedTzo :
4024                    this.offsetForMarker(marker),
4025            }, this);
4026        };
4027        DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
4028            if (dateOptions === void 0) { dateOptions = {}; }
4029            if (dateOptions.isEndExclusive) {
4030                end = addMs(end, -1);
4031            }
4032            return formatter.formatRange({
4033                marker: start,
4034                timeZoneOffset: dateOptions.forcedStartTzo != null ?
4035                    dateOptions.forcedStartTzo :
4036                    this.offsetForMarker(start),
4037            }, {
4038                marker: end,
4039                timeZoneOffset: dateOptions.forcedEndTzo != null ?
4040                    dateOptions.forcedEndTzo :
4041                    this.offsetForMarker(end),
4042            }, this, dateOptions.defaultSeparator);
4043        };
4044        /*
4045        DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
4046        might as well use buildIsoString or some other util directly
4047        */
4048        DateEnv.prototype.formatIso = function (marker, extraOptions) {
4049            if (extraOptions === void 0) { extraOptions = {}; }
4050            var timeZoneOffset = null;
4051            if (!extraOptions.omitTimeZoneOffset) {
4052                if (extraOptions.forcedTzo != null) {
4053                    timeZoneOffset = extraOptions.forcedTzo;
4054                }
4055                else {
4056                    timeZoneOffset = this.offsetForMarker(marker);
4057                }
4058            }
4059            return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
4060        };
4061        // TimeZone
4062        DateEnv.prototype.timestampToMarker = function (ms) {
4063            if (this.timeZone === 'local') {
4064                return arrayToUtcDate(dateToLocalArray(new Date(ms)));
4065            }
4066            if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
4067                return new Date(ms);
4068            }
4069            return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
4070        };
4071        DateEnv.prototype.offsetForMarker = function (m) {
4072            if (this.timeZone === 'local') {
4073                return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
4074            }
4075            if (this.timeZone === 'UTC') {
4076                return 0;
4077            }
4078            if (this.namedTimeZoneImpl) {
4079                return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
4080            }
4081            return null;
4082        };
4083        // Conversion
4084        DateEnv.prototype.toDate = function (m, forcedTzo) {
4085            if (this.timeZone === 'local') {
4086                return arrayToLocalDate(dateToUtcArray(m));
4087            }
4088            if (this.timeZone === 'UTC') {
4089                return new Date(m.valueOf()); // make sure it's a copy
4090            }
4091            if (!this.namedTimeZoneImpl) {
4092                return new Date(m.valueOf() - (forcedTzo || 0));
4093            }
4094            return new Date(m.valueOf() -
4095                this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);
4096        };
4097        return DateEnv;
4098    }());
4099
4100    var globalLocales = [];
4101
4102    var RAW_EN_LOCALE = {
4103        code: 'en',
4104        week: {
4105            dow: 0,
4106            doy: 4, // 4 days need to be within the year to be considered the first week
4107        },
4108        direction: 'ltr',
4109        buttonText: {
4110            prev: 'prev',
4111            next: 'next',
4112            prevYear: 'prev year',
4113            nextYear: 'next year',
4114            year: 'year',
4115            today: 'today',
4116            month: 'month',
4117            week: 'week',
4118            day: 'day',
4119            list: 'list',
4120        },
4121        weekText: 'W',
4122        allDayText: 'all-day',
4123        moreLinkText: 'more',
4124        noEventsText: 'No events to display',
4125    };
4126    function organizeRawLocales(explicitRawLocales) {
4127        var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
4128        var allRawLocales = globalLocales.concat(explicitRawLocales);
4129        var rawLocaleMap = {
4130            en: RAW_EN_LOCALE, // necessary?
4131        };
4132        for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
4133            var rawLocale = allRawLocales_1[_i];
4134            rawLocaleMap[rawLocale.code] = rawLocale;
4135        }
4136        return {
4137            map: rawLocaleMap,
4138            defaultCode: defaultCode,
4139        };
4140    }
4141    function buildLocale(inputSingular, available) {
4142        if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
4143            return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
4144        }
4145        return queryLocale(inputSingular, available);
4146    }
4147    function queryLocale(codeArg, available) {
4148        var codes = [].concat(codeArg || []); // will convert to array
4149        var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
4150        return parseLocale(codeArg, codes, raw);
4151    }
4152    function queryRawLocale(codes, available) {
4153        for (var i = 0; i < codes.length; i += 1) {
4154            var parts = codes[i].toLocaleLowerCase().split('-');
4155            for (var j = parts.length; j > 0; j -= 1) {
4156                var simpleId = parts.slice(0, j).join('-');
4157                if (available[simpleId]) {
4158                    return available[simpleId];
4159                }
4160            }
4161        }
4162        return null;
4163    }
4164    function parseLocale(codeArg, codes, raw) {
4165        var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
4166        delete merged.code; // don't want this part of the options
4167        var week = merged.week;
4168        delete merged.week;
4169        return {
4170            codeArg: codeArg,
4171            codes: codes,
4172            week: week,
4173            simpleNumberFormat: new Intl.NumberFormat(codeArg),
4174            options: merged,
4175        };
4176    }
4177
4178    function formatDate(dateInput, options) {
4179        if (options === void 0) { options = {}; }
4180        var dateEnv = buildDateEnv$1(options);
4181        var formatter = createFormatter(options);
4182        var dateMeta = dateEnv.createMarkerMeta(dateInput);
4183        if (!dateMeta) { // TODO: warning?
4184            return '';
4185        }
4186        return dateEnv.format(dateMeta.marker, formatter, {
4187            forcedTzo: dateMeta.forcedTzo,
4188        });
4189    }
4190    function formatRange(startInput, endInput, options) {
4191        var dateEnv = buildDateEnv$1(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            defaultSeparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator,
4203        });
4204    }
4205    // TODO: more DRY and optimized
4206    function buildDateEnv$1(settings) {
4207        var locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
4208        r
4208eturn 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) { return rawDef.daysOfWeek; });
4233        }
4234        else if (typeof input === 'object' && input) { // non-null object
4235            rawDefs = [input];
4236        }
4237        else { // is probably false
4238            rawDefs = [];
4239        }
4240        rawDefs = rawDefs.map(function (rawDef) { return (__assign(__assign({}, DEF_DEFAULTS), rawDef)); });
4241        return rawDefs;
4242    }
4243
4244    function pointInsideRect(point, rect) {
4245        return point.left >= rect.left &&
4246            point.left < rect.right &&
4247            point.top >= rect.top &&
4248            point.top < rect.bottom;
4249    }
4250    // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
4251    function intersectRects(rect1, rect2) {
4252        var res = {
4253            left: Math.max(rect1.left, rect2.left),
4254            right: Math.min(rect1.right, rect2.right),
4255            top: Math.max(rect1.top, rect2.top),
4256            bottom: Math.min(rect1.bottom, rect2.bottom),
4257        };
4258        if (res.left < res.right && res.top < res.bottom) {
4259            return res;
4260        }
4261        return false;
4262    }
4263    function translateRect(rect, deltaX, deltaY) {
4264        return {
4265            left: rect.left + deltaX,
4266            right: rect.right + deltaX,
4267            top: rect.top + deltaY,
4268            bottom: rect.bottom + deltaY,
4269        };
4270    }
4271    // Returns a new point that will have been moved to reside within the given rectangle
4272    function constrainPoint(point, rect) {
4273        return {
4274            left: Math.min(Math.max(point.left, rect.left), rect.right),
4275            top: Math.min(Math.max(point.top, rect.top), rect.bottom),
4276        };
4277    }
4278    // Returns a point that is the center of the given rectangle
4279    function getRectCenter(rect) {
4280        return {
4281            left: (rect.left + rect.right) / 2,
4282            top: (rect.top + rect.bottom) / 2,
4283        };
4284    }
4285    // Subtracts point2's coordinates from point1's coordinates, returning a delta
4286    function diffPoints(point1, point2) {
4287        return {
4288            left: point1.left - point2.left,
4289            top: point1.top - point2.top,
4290        };
4291    }
4292
4293    var canVGrowWithinCell;
4294    function getCanVGrowWithinCell() {
4295        if (canVGrowWithinCell == null) {
4296            canVGrowWithinCell = computeCanVGrowWithinCell();
4297        }
4298        return canVGrowWithinCell;
4299    }
4300    function computeCanVGrowWithinCell() {
4301        // for SSR, because this function is call immediately at top-level
4302        // TODO: just make this logic execute top-level, immediately, instead of doing lazily
4303        if (typeof document === 'undefined') {
4304            return true;
4305        }
4306        var el = document.createElement('div');
4307        el.style.position = 'absolute';
4308        el.style.top = '0px';
4309        el.style.left = '0px';
4310        el.innerHTML = '<table><tr><td><div></div></td></tr></table>';
4311        el.querySelector('table').style.height = '100px';
4312        el.querySelector('div').style.height = '100%';
4313        document.body.appendChild(el);
4314        var div = el.querySelector('div');
4315        var possible = div.offsetHeight > 0;
4316        document.body.removeChild(el);
4317        return possible;
4318    }
4319
4320    var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
4321    var Splitter = /** @class */ (function () {
4322        function Splitter() {
4323            this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
4324            this.splitDateSelection = memoize(this._splitDateSpan);
4325            this.splitEventStore = memoize(this._splitEventStore);
4326            this.splitIndividualUi = memoize(this._splitIndividualUi);
4327            this.splitEventDrag = memoize(this._splitInteraction);
4328            this.splitEventResize = memoize(this._splitInteraction);
4329            this.eventUiBuilders = {}; // TODO: typescript protection
4330        }
4331        Splitter.prototype.splitProps = function (props) {
4332            var _this = this;
4333            var keyInfos = this.getKeyInfo(props);
4334            var defKeys = this.getKeysForEventDefs(props.eventStore);
4335            var dateSelections = this.splitDateSelection(props.dateSelection);
4336            var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
4337            var eventStores = this.splitEventStore(props.eventStore, defKeys);
4338            var eventDrags = this.splitEventDrag(props.eventDrag);
4339            var eventResizes = this.splitEventResize(props.eventResize);
4340            var splitProps = {};
4341            this.eventUiBuilders = mapHash(keyInfos, function (info, key) { return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); });
4342            for (var key in keyInfos) {
4343                var keyInfo = keyInfos[key];
4344                var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
4345                var buildEventUi = this.eventUiBuilders[key];
4346                splitProps[key] = {
4347                    businessHours: keyInfo.businessHours || props.businessHours,
4348                    dateSelection: dateSelections[key] || null,
4349                    eventStore: eventStore,
4350                    eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
4351                    eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
4352                    eventDrag: eventDrags[key] || null,
4353                    eventResize: eventResizes[key] || null,
4354                };
4355            }
4356            return splitProps;
4357        };
4358        Splitter.prototype._splitDateSpan = function (dateSpan) {
4359            var dateSpans = {};
4360            if (dateSpan) {
4361                var keys = this.getKeysForDateSpan(dateSpan);
4362                for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
4363                    var key = keys_1[_i];
4364                    dateSpans[key] = dateSpan;
4365                }
4366            }
4367            return dateSpans;
4368        };
4369        Splitter.prototype._getKeysForEventDefs = function (eventStore) {
4370            var _this = this;
4371            return mapHash(eventStore.defs, function (eventDef) { return _this.getKeysForEventDef(eventDef); });
4372        };
4373        Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
4374            var defs = eventStore.defs, instances = eventStore.instances;
4375            var splitStores = {};
4376            for (var defId in defs) {
4377                for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
4378                    var key = _a[_i];
4379                    if (!splitStores[key]) {
4380                        splitStores[key] = createEmptyEventStore();
4381                    }
4382                    splitStores[key].defs[defId] = defs[defId];
4383                }
4384            }
4385            for (var instanceId in instances) {
4386                var instance = instances[instanceId];
4387                for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
4388                    var key = _c[_b];
4389                    if (splitStores[key]) { // must have already been created
4390                        splitStores[key].instances[instanceId] = instance;
4391                    }
4392                }
4393            }
4394            return splitStores;
4395        };
4396        Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
4397            var splitHashes = {};
4398            for (var defId in eventUiBases) {
4399                if (defId) { // not the '' key
4400                    for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
4401                        var key = _a[_i];
4402                        if (!splitHashes[key]) {
4403                            splitHashes[key] = {};
4404                        }
4405                        splitHashes[key][defId] = eventUiBases[defId];
4406                    }
4407                }
4408            }
4409            return splitHashes;
4410        };
4411        Splitter.prototype._splitInteraction = function (interaction) {
4412            var splitStates = {};
4413            if (interaction) {
4414                var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeys
4414ForEventDefs(interaction.affectedEvents));
4415                // can't rely on defKeys because event data is mutated
4416                var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
4417                var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
4418                var populate = function (key) {
4419                    if (!splitStates[key]) {
4420                        splitStates[key] = {
4421                            affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
4422                            mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
4423                            isEvent: interaction.isEvent,
4424                        };
4425                    }
4426                };
4427                for (var key in affectedStores_1) {
4428                    populate(key);
4429                }
4430                for (var key in mutatedStores_1) {
4431                    populate(key);
4432                }
4433            }
4434            return splitStates;
4435        };
4436        return Splitter;
4437    }());
4438    function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
4439        var baseParts = [];
4440        if (allUi) {
4441            baseParts.push(allUi);
4442        }
4443        if (eventUiForKey) {
4444            baseParts.push(eventUiForKey);
4445        }
4446        var stuff = {
4447            '': combineEventUis(baseParts),
4448        };
4449        if (individualUi) {
4450            __assign(stuff, individualUi);
4451        }
4452        return stuff;
4453    }
4454
4455    function getDateMeta(date, todayRange, nowDate, dateProfile) {
4456        return {
4457            dow: date.getUTCDay(),
4458            isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)),
4459            isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),
4460            isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),
4461            isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false),
4462            isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false),
4463        };
4464    }
4465    function getDayClassNames(meta, theme) {
4466        var classNames = [
4467            'fc-day',
4468            "fc-day-" + DAY_IDS[meta.dow],
4469        ];
4470        if (meta.isDisabled) {
4471            classNames.push('fc-day-disabled');
4472        }
4473        else {
4474            if (meta.isToday) {
4475                classNames.push('fc-day-today');
4476                classNames.push(theme.getClass('today'));
4477            }
4478            if (meta.isPast) {
4479                classNames.push('fc-day-past');
4480            }
4481            if (meta.isFuture) {
4482                classNames.push('fc-day-future');
4483            }
4484            if (meta.isOther) {
4485                classNames.push('fc-day-other');
4486            }
4487        }
4488        return classNames;
4489    }
4490    function getSlotClassNames(meta, theme) {
4491        var classNames = [
4492            'fc-slot',
4493            "fc-slot-" + DAY_IDS[meta.dow],
4494        ];
4495        if (meta.isDisabled) {
4496            classNames.push('fc-slot-disabled');
4497        }
4498        else {
4499            if (meta.isToday) {
4500                classNames.push('fc-slot-today');
4501                classNames.push(theme.getClass('today'));
4502            }
4503            if (meta.isPast) {
4504                classNames.push('fc-slot-past');
4505            }
4506            if (meta.isFuture) {
4507                classNames.push('fc-slot-future');
4508            }
4509        }
4510        return classNames;
4511    }
4512
4513    function buildNavLinkData(date, type) {
4514        if (type === void 0) { type = 'day'; }
4515        return JSON.stringify({
4516            date: formatDayString(date),
4517            type: type,
4518        });
4519    }
4520
4521    var _isRtlScrollbarOnLeft = null;
4522    function getIsRtlScrollbarOnLeft() {
4523        if (_isRtlScrollbarOnLeft === null) {
4524            _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
4525        }
4526        return _isRtlScrollbarOnLeft;
4527    }
4528    function computeIsRtlScrollbarOnLeft() {
4529        var outerEl = document.createElement('div');
4530        applyStyle(outerEl, {
4531            position: 'absolute',
4532            top: -1000,
4533            left: 0,
4534            border: 0,
4535            padding: 0,
4536            overflow: 'scroll',
4537            direction: 'rtl',
4538        });
4539        outerEl.innerHTML = '<div></div>';
4540        document.body.appendChild(outerEl);
4541        var innerEl = outerEl.firstChild;
4542        var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
4543        removeElement(outerEl);
4544        return res;
4545    }
4546
4547    var _scrollbarWidths;
4548    function getScrollbarWidths() {
4549        if (!_scrollbarWidths) {
4550            _scrollbarWidths = computeScrollbarWidths();
4551        }
4552        return _scrollbarWidths;
4553    }
4554    function computeScrollbarWidths() {
4555        var el = document.createElement('div');
4556        el.style.overflow = 'scroll';
4557        el.style.position = 'absolute';
4558        el.style.top = '-9999px';
4559        el.style.left = '-9999px';
4560        document.body.appendChild(el);
4561        var res = computeScrollbarWidthsForEl(el);
4562        document.body.removeChild(el);
4563        return res;
4564    }
4565    // WARNING: will include border
4566    function computeScrollbarWidthsForEl(el) {
4567        return {
4568            x: el.offsetHeight - el.clientHeight,
4569            y: el.offsetWidth - el.clientWidth,
4570        };
4571    }
4572
4573    function computeEdges(el, getPadding) {
4574        if (getPadding === void 0) { getPadding = false; }
4575        var computedStyle = window.getComputedStyle(el);
4576        var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
4577        var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
4578        var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
4579        var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
4580        var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border!
4581        var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;
4582        var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;
4583        var res = {
4584            borderLeft: borderLeft,
4585            borderRight: borderRight,
4586            borderTop: borderTop,
4587            borderBottom: borderBottom,
4588            scrollbarBottom: scrollbarBottom,
4589            scrollbarLeft: 0,
4590            scrollbarRight: 0,
4591        };
4592        if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
4593            res.scrollbarLeft = scrollbarLeftRight;
4594        }
4595        else {
4596            res.scrollbarRight = scrollbarLeftRight;
4597        }
4598        if (getPadding) {
4599            res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
4600            res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
4601            res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
4602            res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
4603        }
4604        return res;
4605    }
4606    function computeInnerRect(el, goWithinPadding, doFromWindowViewport) {
4607        if (goWithinPadding === void 0) { goWithinPadding = false; }
4608        var outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);
4609        var edges = computeEdges(el, goWithinPadding);
4610        var res = {
4611            left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
4612            right: outerRect.right - edges.borderRight - edges.scrollbarRight,
4613            top: outerRect.top + edges.borderTop,
4614            bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom,
4615        };
4616        if (goWithinPadding) {
4617            res.left += edges.paddingLeft;
4618            res.right -= edges.paddingRight;
4619            res.top += edges.paddingTop;
4620            res.bottom -= edges.paddingBottom;
4621        }
4622        return res;
4623    }
4624    function computeRect(el) {
4625        var rect = el.getBoundingClientRect();
4626        return {
4627            left: rect.left + window.pageXOffset,
4628            top: rect.top + window.pageYOffset,
4629            right: rect.right + window.pageXOffset,
4630            bottom: rect.bottom + window.pageYOffset,
4631        };
4632    }
4633    function computeClippedClientRect(el) {
4634        var clippingParents = getClippingParents(el);
4635        var rect = el.getBoundingClientRect();
4636        for (var _i = 0, clippingParents_1 = clippingParents; _i < clippingParents_1.length; _i++) {
4637            var clippingParent = clippingParents_1[_i];
4638            var intersection = intersectRects(rect, clippingParent.getBoundingClientRect());
4639            if (intersection) {
4640                rect = intersection;
4641            }
4642            else {
4643                return null;
4644            }
4645        }
4646        return rect;
4647    }
4648    function computeHeightAndMargins(el) {
4649        return el.getBoundingClientRect().height + computeVMargins(el);
4650    }
4651    function computeVMargins(el) {
4652        var computed = window.getComputedStyle(el);
4653        return parseInt(computed.marginTop, 10) +
4654            parseInt(computed.marginBottom, 10);
4655    }
4656    // does not return window
4657    function getClippingParents(el) {
4658        var parents = [];
4659        while (el instanceof HTMLElement) { // will stop when gets to document or null
4660            var computedStyle = window.getComputedStyle(el);
4661            if (computedStyle.position === 'fixed') {
4662                break;
4663            }
4664            if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
4665                parents.push(el);
4666            }
4667            el = el.parentNode;
4668        }
4669        return parents;
4670    }
4671
4672    // given a function that resolves a result asynchronously.
4673    // the function can either call passed-in success and failure callbacks,
4674    // or it can return a promise.
4675    // if you need to pass additional params to func, bind them first.
4676    function unpromisify(func, success, failure) {
4677        // guard against success/failure callbacks being called more than once
4678        // and guard against a promise AND callback being used together.
4679        var isResolved = false;
4680        var wrappedSuccess = function () {
4681            if (!isResolved) {
4682                isResolved = true;
4683                success.apply(this, arguments); // eslint-disable-line prefer-rest-params
4684            }
4685        };
4686        var wrappedFailure = function () {
4687            if (!isResolved) {
4688                isResolved = true;
4689                if (failure) {
4690                    failure.apply(this, arguments); // eslint-disable-line prefer-rest-params
4691                }
4692            }
4693        };
4694        var res = func(wrappedSuccess, wrappedFailure);
4695        if (res && typeof res.then === 'function') {
4696            res.then(wrappedSuccess, wrappedFailure);
4697        }
4698    }
4699
4700    var Emitter = /** @class */ (function () {
4701        function Emitter() {
4702            this.handlers = {};
4703            this.thisContext = null;
4704        }
4705        Emitter.prototype.setThisContext = function (thisContext) {
4706            this.thisContext = thisContext;
4707        };
4708        Emitter.prototype.setOptions = function (options) {
4709            this.options = options;
4710        };
4711        Emitter.prototype.on = function (type, handler) {
4712            addToHash(this.handlers, type, handler);
4713        };
4714        Emitter.prototype.off = function (type, handler) {
4715            removeFromHash(this.handlers, type, handler);
4716        };
4717        Emitter.prototype.trigger = function (type) {
4718            var args = [];
4719            for (var _i = 1; _i < arguments.length; _i++) {
4720                args[_i - 1] = arguments[_i];
4721            }
4722            var attachedHandlers = this.handlers[type] || [];
4723            var optionHandler = this.options && this.options[type];
4724            var handlers = [].concat(optionHandler || [], attachedHandlers);
4725            for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) {
4726                var handler = handlers_1[_a];
4727                handler.apply(this.thisContext, args);
4728            }
4729        };
4730        Emitter.prototype.hasHandlers = function (type) {
4731            return (this.handlers[type] && this.handlers[type].length) ||
4732                (this.options && this.options[type]);
4733        };
4734        return Emitter;
4735    }());
4736    function addToHash(hash, type, handler) {
4737        (hash[type] || (hash[type] = []))
4738            .push(handler);
4739    }
4740    function removeFromHash(hash, type, handler) {
4741        if (handler) {
4742            if (hash[type]) {
4743                hash[type] = hash[type].filter(function (func) { return func !== handler; });
4744            }
4745        }
4746        else {
4747            delete hash[type]; // remove all handler funcs for this type
4748        }
4749    }
4750
4751    /*
4752    Records offset information for a set of elements, relative to an origin element.
4753    Can record the left/right OR the top/bottom OR both.
4754    Provides methods for querying the cache by position.
4755    */
4756    var PositionCache = /** @class */ (function () {
4757        function PositionCache(originEl, els, isHorizontal, isVertical) {
4758            this.els = els;
4759            var originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left
4760            if (isHorizontal) {
4761                this.buildElHorizontals(originClientRect.left);
4762            }
4763            if (isVertical) {
4764                this.buildElVerticals(originClientRect.top);
4765            }
4766        }
4767        // Populates the left/right internal coordinate arrays
4768        PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
4769            var lefts = [];
4770            var rights = [];
4771            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
4772                var el = _a[_i];
4773                var rect = el.getBoundingClientRect();
4774                lefts.push(rect.left - originClientLeft);
4775                rights.push(rect.right - originClientLeft);
4776            }
4777            this.lefts = lefts;
4778            this.rights = rights;
4779        };
4780        // Populates the top/bottom internal coordinate arrays
4781        PositionCache.prototype.buildElVerticals = function (originClientTop) {
4782            var tops = [];
4783            var bottoms = [];
4784            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
4785                var el = _a[_i];
4786                var rect = el.getBoundingClientRect();
4787                tops.push(rect.top - originClientTop);
4788                bottoms.push(rect.bottom - originClientTop);
4789            }
4790            this.tops = tops;
4791            this.bottoms = bottoms;
4792        };
4793        // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
4794        // If no intersection is made, returns undefined.
4795        PositionCache.prototype.leftToIndex = function (leftPosition) {
4796            var _a = this, lefts = _a.lefts, rights = _a.rights;
4797            var len = lefts.length;
4798            var i;
4799            for (i = 0; i < len; i += 1) {
4800                if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
4801                    return i;
4802                }
4803            }
4804            return undefined; // TODO: better
4805        };
4806        // Given a top offset (from document top), returns the index of the el that it vertically intersects.
4807        // If no intersection is made, returns undefined.
4808        PositionCache.prototype.topToIndex = function (topPosition) {
4809            var _a = this, tops = _a.tops, bottoms = _a.bottoms;
4810            var len = tops.length;
4811            var i;
4812            for (i = 0; i < len; i += 1) {
4813                if (topPosition >= tops[i] && topPosition < bottoms[i]) {
4814                    return i;
4815                }
4816            }
4817            return undefined; // TODO: better
4818        };
4819        // Gets the width of the element at the given index
4820        PositionCache.prototype.getWidth = function (leftIndex) {
4821            return this.rights[leftIndex] - this.lefts[leftIndex];
4822        };
4823        // Gets the height of the element at the given index
4824        PositionCache.prototype.getHeight = function (topIndex) {
4825            return this.bottoms[topIndex] - this.tops[topIndex];
4826        };
4827        return PositionCache;
4828    }());
4829
4830    /* eslint max-classes-per-file: "off" */
4831    /*
4832    An object for getting/setting scroll-related information for an element.
4833    Internally, this is done very differently for window versus DOM element,
4834    so this object serves as a common interface.
4835    */
4836    var ScrollController = /** @class */ (function () {
4837        function ScrollController() {
4838        }
4839        ScrollController.prototype.getMaxScrollTop = function () {
4840            return this.getScrollHeight() - this.getClientHeight();
4841        };
4842        ScrollController.prototype.getMaxScrollLeft = function () {
4843            return this.getScrollWidth() - this.getClientWidth();
4844        };
4845        ScrollController.prototype.canScrollVertically = function () {
4846            return this.getMaxScrollTop() > 0;
4847        };
4848        ScrollController.prototype.canScrollHorizontally = function () {
4849            return this.getMaxScrollLeft() > 0;
4850        };
4851        ScrollController.prototype.canScrollUp = function () {
4852            return this.getScrollTop() > 0;
4853        };
4854        ScrollController.prototype.canScrollDown = function () {
4855            return this.getScrollTop() < this.getMaxScrollTop();
4856        };
4857        ScrollController.prototype.canScrollLeft = function () {
4858            return this.getScrollLeft() > 0;
4859        };
4860        ScrollController.prototype.canScrollRight = function () {
4861            return this.getScrollLeft() < this.getMaxScrollLeft();
4862        };
4863        return ScrollController;
4864    }());
4865    var ElementScrollController = /** @class */ (function (_super) {
4866        __extends(ElementScrollController, _super);
4867        function ElementScrollController(el) {
4868            var _this = _super.call(this) || this;
4869            _this.el = el;
4870            return _this;
4871        }
4872        ElementScrollController.prototype.getScrollTop = function () {
4873            return this.el.scrollTop;
4874        };
4875        ElementScrollController.prototype.getScrollLeft = function () {
4876            return this.el.scrollLeft;
4877        };
4878        ElementScrollController.prototype.setScrollTop = function (top) {
4879            this.el.scrollTop = top;
4880        };
4881        ElementScrollController.prototype.setScrollLeft = function (left) {
4882            this.el.scrollLeft = left;
4883        };
4884        ElementScrollController.prototype.getScrollWidth = function () {
4885            return this.el.scrollWidth;
4886        };
4887        ElementScrollController.prototype.getScrollHeight = function () {
4888            return this.el.scrollHeight;
4889        };
4890        ElementScrollController.prototype.getClientHeight = function () {
4891            return this.el.clientHeight;
4892        };
4893        ElementScrollController.prototype.getClientWidth = function () {
4894            return this.el.clientWidth;
4895        };
4896        return ElementScrollController;
4897    }(ScrollController));
4898    var WindowScrollController = /** @class */ (function (_super) {
4899        __extends(WindowScrollController, _super);
4900        function WindowScrollController() {
4901            return _super !== null && _super.apply(this, arguments) || this;
4902        }
4903        WindowScrollController.prototype.getScrollTop = function () {
4904            return window.pageYOffset;
4905        };
4906        WindowScrollController.prototype.getScrollLeft = function () {
4907            return window.pageXOffset;
4908        };
4909        WindowScrollController.prototype.setScrollTop = function (n) {
4910            window.scroll(window.pageXOffset, n);
4911        };
4912        WindowScrollController.prototype.setScrollLeft = function (n) {
4913            window.scroll(n, window.pageYOffset);
4914        };
4915        WindowScrollController.prototype.getScrollWidth = function () {
4916            return document.documentElement.scrollWidth;
4917        };
4918        WindowScrollController.prototype.getScrollHeight = function () {
4919            return document.documentElement.scrollHeight;
4920        };
4921        WindowScrollController.prototype.getClientHeight = function () {
4922            return document.documentElement.clientHeight;
4923        };
4924        WindowScrollController.prototype.getClientWidth = function () {
4925            return document.documentElement.clientWidth;
4926        };
4927        return WindowScrollController;
4928    }(ScrollController));
4929
4930    var Theme = /** @class */ (function () {
4931        function Theme(calendarOptions) {
4932            if (this.iconOverrideOption) {
4933                this.setIconOverride(calendarOptions[this.iconOverrideOption]);
4934            }
4935        }
4936        Theme.prototype.setIconOverride = function (iconOverrideHash) {
4937            var iconClassesCopy;
4938            var buttonName;
4939            if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
4940                iconClassesCopy = __assign({}, this.iconClasses);
4941                for (buttonName in iconOverrideHash) {
4942                    iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
4943                }
4944                this.iconClasses = iconClassesCopy;
4945            }
4946            else if (iconOverrideHash === false) {
4947                this.iconClasses = {};
4948            }
4949        };
4950        Theme.prototype.applyIconOverridePrefix = function (className) {
4951            var prefix = this.iconOverridePrefix;
4952            if (prefix && className.indexOf(prefix) !== 0) { // if not already present
4953                className = prefix + className;
4954            }
4955            return className;
4956        };
4957        Theme.prototype.getClass = function (key) {
4958            return this.classes[key] || '';
4959        };
4960        Theme.prototype.getIconClass = function (buttonName, isRtl) {
4961            var className;
4962            if (isRtl && this.rtlIconClasses) {
4963                className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName];
4964            }
4965            else {
4966                className = this.iconClasses[buttonName];
4967            }
4968            if (className) {
4969                return this.baseIconClass + " " + className;
4970            }
4971            return '';
4972        };
4973        Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
4974            var className;
4975            if (this.iconOverrideCustomButtonOption) {
4976                className = customButtonProps[this.iconOverrideCustomButtonOption];
4977                if (className) {
4978                    return this.baseIconClass + " " + this.applyIconOverridePrefix(className);
4979                }
4980            }
4981            return '';
4982        };
4983        return Theme;
4984    }());
4985    Theme.prototype.classes = {};
4986    Theme.prototype.iconClasses = {};
4987    Theme.prototype.baseIconClass = '';
4988    Theme.prototype.iconOverridePrefix = '';
4989
4990    /// <reference types="@fullcalendar/core-preact" />
4991    if (typeof FullCalendarVDom === 'undefined') {
4992        throw new Error('Please import the top-level fullcalendar lib before attempting to import a plugin.');
4993    }
4994    var Component = FullCalendarVDom.Component;
4995    var createElement = FullCalendarVDom.createElement;
4996    var render = FullCalendarVDom.render;
4997    var createRef = FullCalendarVDom.createRef;
4998    var Fragment = FullCalendarVDom.Fragment;
4999    var createContext = FullCalendarVDom.createContext;
5000    var createPortal = FullCalendarVDom.createPortal;
5001    var flushToDom = FullCalendarVDom.flushToDom;
5002    var unmountComponentAtNode = FullCalendarVDom.unmountComponentAtNode;
5003    /* eslint-enable */
5004
5005    var ScrollResponder = /** @class */ (function () {
5006        function ScrollResponder(execFunc, emitter, scrollTime, scrollTimeReset) {
5007            var _this = this;
5008            this.execFunc = execFunc;
5009            this.emitter = emitter;
5010            this.scrollTime = scrollTime;
5011            this.scrollTimeReset = scrollTimeReset;
5012            this.handleScrollRequest = function (request) {
5013                _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request);
5014                _this.drain();
5015            };
5016            emitter.on('_scrollRequest', this.handleScrollRequest);
5017            this.fireInitialScroll();
5018        }
5019        ScrollResponder.prototype.detach = function () {
5020            this.emitter.off('_scrollRequest', this.handleScrollRequest);
5021        };
5022        ScrollResponder.prototype.update = function (isDatesNew) {
5023            if (isDatesNew && this.scrollTimeReset) {
5024                this.fireInitialScroll(); // will drain
5025            }
5026            else {
5027                this.drain();
5028            }
5029        };
5030        ScrollResponder.prototype.fireInitialScroll = function () {
5031            this.handleScrollRequest({
5032                time: this.scrollTime,
5033            });
5034        };
5035        ScrollResponder.prototype.drain = function () {
5036            if (this.queuedRequest && this.execFunc(this.queuedRequest)) {
5037                this.queuedRequest = null;
5038            }
5039        };
5040        return ScrollResponder;
5041    }());
5042
5043    var ViewContextType = createContext({}); // for Components
5044    function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
5045        return {
5046            dateEnv: dateEnv,
5047            options: viewOptions,
5048            pluginHooks: pluginHooks,
5049            emitter: emitter,
5050            dispatch: dispatch,
5051            getCurrentData: getCurrentData,
5052            calendarApi: calendarApi,
5053            viewSpec: viewSpec,
5054            viewApi: viewApi,
5055            dateProfileGenerator: dateProfileGenerator,
5056            theme: theme,
5057            isRtl: viewOptions.direction === 'rtl',
5058            addResizeHandler: function (handler) {
5059                emitter.on('_resize', handler);
5060            },
5061            removeResizeHandler: function (handler) {
5062                emitter.off('_resize', handler);
5063            },
5064            createScrollResponder: function (execFunc) {
5065                return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset);
5066            },
5067            registerInteractiveComponent: registerInteractiveComponent,
5068            unregisterInteractiveComponent: unregisterInteractiveComponent,
5069        };
5070    }
5071
5072    /* eslint max-classes-per-file: off */
5073    var PureComponent = /** @class */ (function (_super) {
5074        __extends(PureComponent, _super);
5075        function PureComponent() {
5076            return _super !== null && _super.apply(this, arguments) || this;
5077        }
5078        PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
5079            if (this.debug) {
5080                // eslint-disable-next-line no-console
5081                console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state));
5082            }
5083            return !compareObjs(this.props, nextProps, this.propEquality) ||
5084                !compareObjs(this.state, nextState, this.stateEquality);
5085        };
5086        PureComponent.addPropsEquality = addPropsEquality;
5087        PureComponent.addStateEquality = addStateEquality;
5088        PureComponent.contextType = ViewContextType;
5089        return PureComponent;
5090    }(Component));
5091    PureComponent.prototype.propEquality = {};
5092    PureComponent.prototype.stateEquality = {};
5093    var BaseComponent = /** @class */ (function (_super) {
5094        __extends(BaseComponent, _super);
5095        function BaseComponent() {
5096            return _super !== null && _super.apply(this, arguments) || this;
5097        }
5098        BaseComponent.contextType = ViewContextType;
5099        return BaseComponent;
5100    }(PureComponent));
5101    function addPropsEquality(propEquality) {
5102        var hash = Object.create(this.prototype.propEquality);
5103        __assign(hash, propEquality);
5104        this.prototype.propEquality = hash;
5105    }
5106    function addStateEquality(stateEquality) {
5107        var hash = Object.create(this.prototype.stateEquality);
5108        __assign(hash, stateEquality);
5109        this.prototype.stateEquality = hash;
5110    }
5111    // use other one
5112    function setRef(ref, current) {
5113        if (typeof ref === 'function') {
5114            ref(current);
5115        }
5116        else if (ref) {
5117            // see https://github.com/facebook/react/issues/13029
5118            ref.current = current;
5119        }
5120    }
5121
5122    /*
5123    an INTERACTABLE date component
5124
5125    PURPOSES:
5126    - hook up to fg, fill, and mirror renderers
5127    - interface for dragging and hits
5128    */
5129    var DateComponent = /** @class */ (function (_super) {
5130        __extends(DateComponent, _super);
5131        function DateComponent() {
5132            var _this = _super !== null && _super.apply(this, arguments) || this;
5133            _this.uid = guid();
5134            return _this;
5135        }
5136        // Hit System
5137        // -----------------------------------------------------------------------------------------------------------------
5138        DateComponent.prototype.prepareHits = function () {
5139        };
5140        DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
5141            return null; // this should be abstract
5142        };
5143        // Pointer Interaction Utils
5144        // -----------------------------------------------------------------------------------------------------------------
5145        DateComponent.prototype.isValidSegDownEl = function (el) {
5146            return !this.props.eventDrag && // HACK
5147                !this.props.eventResize && // HACK
5148                !elementClosest(el, '.fc-event-mirror');
5149        };
5150        DateComponent.prototype.isValidDateDownEl = function (el) {
5151            return !elementClosest(el, '.fc-event:not(.fc-bg-event)') &&
5152                !elementClosest(el, '.fc-more-link') && // a "more.." link
5153                !elementClosest(el, 'a[data-navlink]') && // a clickable nav link
5154                !elementClosest(el, '.fc-popover'); // hack
5155        };
5156        return DateComponent;
5157    }(BaseComponent));
5158
5159    // TODO: easier way to add new hooks? need to update a million things
5160    function createPlugin(input) {
5161        return {
5162            id: guid(),
5163            deps: input.deps || [],
5164            reducers: input.reducers || [],
5165            isLoadingFuncs: input.isLoadingFuncs || [],
5166            contextInit: [].concat(input.contextInit || []),
5167            eventRefiners: input.eventRefiners || {},
5168            eventDefMemberAdders: input.eventDefMemberAdders || [],
5169            eventSourceRefiners: input.eventSourceRefiners || {},
5170            isDraggableTransformers: input.isDraggableTransformers || [],
5171            eventDragMutationMassagers: input.eventDragMutationMassagers || [],
5172            eventDefMutationAppliers: input.eventDefMutationAppliers || [],
5173            dateSelectionTransformers: input.dateSelectionTransformers || [],
5174            datePointTransforms: input.datePointTransforms || [],
5175            dateSpanTransforms: input.dateSpanTransforms || [],
5176            views: input.views || {},
5177            viewPropsTransformers: input.viewPropsTransformers || [],
5178            isPropsValid: input.isPropsValid || null,
5179            externalDefTransforms: input.externalDefTransforms || [],
5180            viewContainerAppends: input.viewContainerAppends || [],
5181            eventDropTransformers: input.eventDropTransformers || [],
5182            componentInteractions: input.componentInteractions || [],
5183            calendarInteractions: input.calendarInteractions || [],
5184            themeClasses: input.themeClasses || {},
5185            eventSourceDefs: input.eventSourceDefs || [],
5186            cmdFormatter: input.cmdFormatter,
5187            recurringTypes: input.recurringTypes || [],
5188            namedTimeZonedImpl: input.namedTimeZonedImpl,
5189            initialView: input.initialView || '',
5190            elementDraggingImpl: input.elementDraggingImpl,
5191            optionChangeHandlers: input.optionChangeHandlers || {},
5192            scrollGridImpl: input.scrollGridImpl || null,
5193            contentTypeHandlers: input.contentTypeHandlers || {},
5194            listenerRefiners: input.listenerRefiners || {},
5195            optionRefiners: input.optionRefiners || {},
5196            propSetHandlers: input.propSetHandlers || {},
5197        };
5198    }
5199    function buildPluginHooks(pluginDefs, globalDefs) {
5200        var isAdded = {};
5201        var hooks = {
5202            reducers: [],
5203            isLoadingFuncs: [],
5204            contextInit: [],
5205            eventRefiners: {},
5206            eventDefMemberAdders: [],
5207            eventSourceRefiners: {},
5208            isDraggableTransformers: [],
5209            eventDragMutationMassagers: [],
5210            eventDefMutationAppliers: [],
5211            dateSelectionTransformers: [],
5212            datePointTransforms: [],
5213            dateSpanTransforms: [],
5214            views: {},
5215            viewPropsTransformers: [],
5216            isPropsValid: null,
5217            externalDefTransforms: [],
5218            viewContainerAppends: [],
5219            eventDropTransformers: [],
5220            componentInteractions: [],
5221            calendarInteractions: [],
5222            themeClasses: {},
5223            eventSourceDefs: [],
5224            cmdFormatter: null,
5225            recurringTypes: [],
5226            namedTimeZonedImpl: null,
5227            initialView: '',
5228            elementDraggingImpl: null,
5229            optionChangeHandlers: {},
5230            scrollGridImpl: null,
5231            contentTypeHandlers: {},
5232            listenerRefiners: {},
5233            optionRefiners: {},
5234            propSetHandlers: {},
5235        };
5236        function addDefs(defs) {
5237            for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) {
5238                var def = defs_1[_i];
5239                if (!isAdded[def.id]) {
5240                    isAdded[def.id] = true;
5241                    addDefs(def.deps);
5242                    hooks = combineHooks(hooks, def);
5243                }
5244            }
5245        }
5246        if (pluginDefs) {
5247            addDefs(pluginDefs);
5248        }
5249        addDefs(globalDefs);
5250        return hooks;
5251    }
5252    function buildBuildPluginHooks() {
5253        var currentOverrideDefs = [];
5254        var currentGlobalDefs = [];
5255        var currentHooks;
5256        return function (overrideDefs, globalDefs) {
5257            if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) {
5258                currentHooks = buildPluginHooks(overrideDefs, globalDefs);
5259            }
5260            currentOverrideDefs = overrideDefs;
5261            currentGlobalDefs = globalDefs;
5262            return currentHooks;
5263        };
5264    }
5265    function combineHooks(hooks0, hooks1) {
5266        return {
5267            reducers: hooks0.reducers.concat(hooks1.reducers),
5268            isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),
5269            contextInit: hooks0.contextInit.concat(hooks1.contextInit),
5270            eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners),
5271            eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),
5272            eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),
5273            isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
5274            eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
5275            eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
5276            dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
5277            datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
5278            dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
5279            views: __assign(__assign({}, hooks0.views), hooks1.views),
5280            viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
5281            isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
5282            externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
5283            viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),
5284            eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
5285            calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
5286            componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
5287            themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses),
5288            eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
5289            cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
5290            recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
5291            namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
5292            initialView: hooks0.initialView || hooks1.initialView,
5293            elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
5294            optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),
5295            scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,
5296            contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers),
5297            listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),
5298            optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners),
5299            propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers),
5300        };
5301    }
5302
5303    var StandardTheme = /** @class */ (function (_super) {
5304        __extends(StandardTheme, _super);
5305        function StandardTheme() {
5306            return _super !== null && _super.apply(this, arguments) || this;
5307        }
5308        return StandardTheme;
5309    }(Theme));
5310    StandardTheme.prototype.classes = {
5311        root: 'fc-theme-standard',
5312        tableCellShaded: 'fc-cell-shaded',
5313        buttonGroup: 'fc-button-group',
5314        button: 'fc-button fc-button-primary',
5315        buttonActive: 'fc-button-active',
5316    };
5317    StandardTheme.prototype.baseIconClass = 'fc-icon';
5318    StandardTheme.prototype.iconClasses = {
5319        close: 'fc-icon-x',
5320        prev: 'fc-icon-chevron-left',
5321        next: 'fc-icon-chevron-right',
5322        prevYear: 'fc-icon-chevrons-left',
5323        nextYear: 'fc-icon-chevrons-right',
5324    };
5325    StandardTheme.prototype.rtlIconClasses = {
5326        prev: 'fc-icon-chevron-right',
5327        next: 'fc-icon-chevron-left',
5328        prevYear: 'fc-icon-chevrons-right',
5329        nextYear: 'fc-icon-chevrons-left',
5330    };
5331    StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly
5332    StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
5333    StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
5334
5335    function compileViewDefs(defaultConfigs, overrideConfigs) {
5336        var hash = {};
5337        var viewType;
5338        for (viewType in defaultConfigs) {
5339            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5340        }
5341        for (viewType in overrideConfigs) {
5342            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5343        }
5344        return hash;
5345    }
5346    function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5347        if (hash[viewType]) {
5348            return hash[viewType];
5349        }
5350        var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5351        if (viewDef) {
5352            hash[viewType] = viewDef;
5353        }
5354        return viewDef;
5355    }
5356    function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5357        var defaultConfig = defaultConfigs[viewType];
5358        var overrideConfig = overrideConfigs[viewType];
5359        var queryProp = function (name) { return ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
5360            ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null)); };
5361        var theComponent = queryProp('component');
5362        var superType = queryProp('superType');
5363        var superDef = null;
5364        if (superType) {
5365            if (superType === viewType) {
5366                throw new Error('Can\'t have a custom view type that references itself');
5367            }
5368            superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
5369        }
5370        if (!theComponent && superDef) {
5371            theComponent = superDef.component;
5372        }
5373        if (!theComponent) {
5374            return null; // don't throw a warning, might be settings for a single-unit view
5375        }
5376        return {
5377            type: viewType,
5378            component: theComponent,
5379            defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),
5380            overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})),
5381        };
5382    }
5383
5384    /* eslint max-classes-per-file: off */
5385    // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any???
5386    var RenderHook = /** @class */ (function (_super) {
5387        __extends(RenderHook, _super);
5388        function RenderHook() {
5389            var _this = _super !== null && _super.apply(this, arguments) || this;
5390            _this.rootElRef = createRef();
5391            _this.handleRootEl = function (el) {
5392                setRef(_this.rootElRef, el);
5393                if (_this.props.elRef) {
5394                    setRef(_this.props.elRef, el);
5395                }
5396            };
5397            return _this;
5398        }
5399        RenderHook.prototype.render = function () {
5400            var _this = this;
5401            var props = this.props;
5402            var hookProps = props.hookProps;
5403            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); })); }));
5404        };
5405        return RenderHook;
5406    }(BaseComponent));
5407    // TODO: rename to be about function, not default. use in above type
5408    // for forcing rerender of components that use the ContentHook
5409    var CustomContentRenderContext = createContext(0);
5410    function ContentHook(props) {
5411        return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); }));
5412    }
5413    var ContentHookInner = /** @class */ (function (_super) {
5414        __extends(ContentHookInner, _super);
5415        function ContentHookInner() {
5416            var _this = _super !== null && _super.apply(this, arguments) || this;
5417            _this.innerElRef = createRef();
5418            return _this;
5419        }
5420        ContentHookInner.prototype.render = function () {
5421            return this.props.children(this.innerElRef, this.renderInnerContent());
5422        };
5423        ContentHookInner.prototype.componentDidMount = function () {
5424            this.updateCustomContent();
5425        };
5426        ContentHookInner.prototype.componentDidUpdate = function () {
5427            this.updateCustomContent();
5428        };
5429        ContentHookInner.prototype.componentWillUnmount = function () {
5430            if (this.customContentInfo && this.customContentInfo.destroy) {
5431                this.customContentInfo.destroy();
5432            }
5433        };
5434        ContentHookInner.prototype.renderInnerContent = function () {
5435            var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers;
5436            var _a = this, props = _a.props, customContentInfo = _a.customContentInfo;
5437            var rawVal = props.content;
5438            var innerContent = normalizeContent(rawVal, props.hookProps);
5439            var innerContentVDom = null;
5440            if (innerContent === undefined) { // use the default
5441                innerContent = normalizeContent(props.defaultContent, props.hookProps);
5442            }
5443            if (innerContent !== undefined) { // we allow custom content handlers to return nothing
5444                if (customContentInfo) {
5445                    customContentInfo.contentVal = innerContent[customContentInfo.contentKey];
5446                }
5447                else if (typeof innerContent === 'object') {
5448                    // look for a prop that would indicate a custom content handler is needed
5449                    for (var contentKey in contentTypeHandlers) {
5450                        if (innerContent[contentKey] !== undefined) {
5451                            var stuff = contentTypeHandlers[contentKey]();
5452                            customContentInfo = this.customContentInfo = __assign({ contentKey: contentKey, contentVal: innerContent[contentKey] }, stuff);
5453                            break;
5454                        }
5455                    }
5456                }
5457                if (customContentInfo) {
5458                    innerContentVDom = []; // signal that something was specified
5459                }
5460                else {
5461                    innerContentVDom = innerContent; // assume a [p]react vdom node. use it
5462                }
5463            }
5464            return innerContentVDom;
5465        };
5466        ContentHookInner.prototype.updateCustomContent = function () {
5467            if (this.customContentInfo) {
5468                this.customContentInfo.render(this.innerElRef.current || this.props.backupElRef.current, // the element to render into
5469                this.customContentInfo.contentVal);
5470            }
5471        };
5472        return ContentHookInner;
5473    }(BaseComponent));
5474    var MountHook = /** @class */ (function (_super) {
5475        __extends(MountHook, _super);
5476        function MountHook() {
5477            var _this = _super !== null && _super.apply(this, arguments) || this;
5478            _this.handleRootEl = function (rootEl) {
5479                _this.rootEl = rootEl;
5480                if (_this.props.elRef) {
5481                    setRef(_this.props.elRef, rootEl);
5482                }
5483            };
5484            return _this;
5485        }
5486        MountHook.prototype.render = function () {
5487            return this.props.children(this.handleRootEl);
5488        };
5489        MountHook.prototype.componentDidMount = function () {
5490            var callback = this.props.didMount;
5491            if (callback) {
5492                callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
5493            }
5494        };
5495        MountHook.prototype.componentWillUnmount = function () {
5496            var callback = this.props.willUnmount;
5497            if (callback) {
5498                callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
5499            }
5500        };
5501        return MountHook;
5502    }(BaseComponent));
5503    function buildClassNameNormalizer() {
5504        var currentGenerator;
5505        var currentHookProps;
5506        var currentClassNames = [];
5507        return function (generator, hookProps) {
5508            if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) {
5509                currentGenerator = generator;
5510                currentHookProps = hookProps;
5511                currentClassNames = normalizeClassNames(generator, hookProps);
5512            }
5513            return currentClassNames;
5514        };
5515    }
5516    function normalizeClassNames(classNames, hookProps) {
5517        if (typeof classNames === 'function') {
5518            classNames = classNames(hookProps);
5519        }
5520        return parseClassNames(classNames);
5521    }
5522    function normalizeContent(input, hookProps) {
5523        if (typeof input === 'function') {
5524            return input(hookProps, createElement); // give the function the vdom-creation func
5525        }
5526        return input;
5527    }
5528
5529    var ViewRoot = /** @class */ (function (_super) {
5530        __extends(ViewRoot, _super);
5531        function ViewRoot() {
5532            var _this = _super !== null && _super.apply(this, arguments) || this;
5533            _this.normalizeClassNames = buildClassNameNormalizer();
5534            return _this;
5535        }
5536        ViewRoot.prototype.render = function () {
5537            var _a = this, props = _a.props, context = _a.context;
5538            var options = context.options;
5539            var hookProps = { view: context.viewApi };
5540            var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps);
5541            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)); }));
5542        };
5543        return ViewRoot;
5544    }(BaseComponent));
5545
5546    function parseViewConfigs(inputs) {
5547        return mapHash(inputs, parseViewConfig);
5548    }
5549    function parseViewConfig(input) {
5550        var rawOptions = typeof input === 'function' ?
5551            { component: input } :
5552            input;
5553        var component = rawOptions.component;
5554        if (rawOptions.content) {
5555            component = createViewHookComponent(rawOptions);
5556            // TODO: remove content/classNames/didMount/etc from options?
5557        }
5558        return {
5559            superType: rawOptions.type,
5560            component: component,
5561            rawOptions: rawOptions,
5562        };
5563    }
5564    function createViewHookComponent(options) {
5565        return function (viewProps) { return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (viewElRef, viewClassNames) {
5566            var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold });
5567            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.classNames, content: options.content, didMount: options.didMount, willUnmount: options.willUnmount, elRef: viewElRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("div", { className: viewClassNames.c
5567oncat(customClassNames).join(' '), ref: rootElRef }, innerContent)); }));
5568        })); })); };
5569    }
5570
5571    function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
5572        var defaultConfigs = parseViewConfigs(defaultInputs);
5573        var overrideConfigs = parseViewConfigs(optionOverrides.views);
5574        var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
5575        return mapHash(viewDefs, function (viewDef) { return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults); });
5576    }
5577    function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
5578        var durationInput = viewDef.overrides.duration ||
5579            viewDef.defaults.duration ||
5580            dynamicOptionOverrides.duration ||
5581            optionOverrides.duration;
5582        var duration = null;
5583        var durationUnit = '';
5584        var singleUnit = '';
5585        var singleUnitOverrides = {};
5586        if (durationInput) {
5587            duration = createDurationCached(durationInput);
5588            if (duration) { // valid?
5589                var denom = greatestDurationDenominator(duration);
5590                durationUnit = denom.unit;
5591                if (denom.value === 1) {
5592                    singleUnit = durationUnit;
5593                    singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};
5594                }
5595            }
5596        }
5597        var queryButtonText = function (optionsSubset) {
5598            var buttonTextMap = optionsSubset.buttonText || {};
5599            var buttonTextKey = viewDef.defaults.buttonTextKey;
5600            if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
5601                return buttonTextMap[buttonTextKey];
5602            }
5603            if (buttonTextMap[viewDef.type] != null) {
5604                return buttonTextMap[viewDef.type];
5605            }
5606            if (buttonTextMap[singleUnit] != null) {
5607                return buttonTextMap[singleUnit];
5608            }
5609            return null;
5610        };
5611        return {
5612            type: viewDef.type,
5613            component: viewDef.component,
5614            duration: duration,
5615            durationUnit: durationUnit,
5616            singleUnit: singleUnit,
5617            optionDefaults: viewDef.defaults,
5618            optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides),
5619            buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||
5620                queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence
5621                viewDef.overrides.buttonText,
5622            buttonTextDefault: queryButtonText(localeDefaults) ||
5623                viewDef.defaults.buttonText ||
5624                queryButtonText(BASE_OPTION_DEFAULTS) ||
5625                viewDef.type, // fall back to given view name
5626        };
5627    }
5628    // hack to get memoization working
5629    var durationInputMap = {};
5630    function createDurationCached(durationInput) {
5631        var json = JSON.stringify(durationInput);
5632        var res = durationInputMap[json];
5633        if (res === undefined) {
5634            res = createDuration(durationInput);
5635            durationInputMap[json] = res;
5636        }
5637        return res;
5638    }
5639
5640    var DateProfileGenerator = /** @class */ (function () {
5641        function DateProfileGenerator(props) {
5642            this.props = props;
5643            this.nowDate = getNow(props.nowInput, props.dateEnv);
5644            this.initHiddenDays();
5645        }
5646        /* Date Range Computation
5647        ------------------------------------------------------------------------------------------------------------------*/
5648        // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5649        DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) {
5650            var dateEnv = this.props.dateEnv;
5651            var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5652            currentDateProfile.dateIncrement);
5653            return this.build(prevDate, -1, forceToValid);
5654        };
5655        // Builds a structure with info about what the dates/ranges will be for the "next" view.
5656        DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) {
5657            var dateEnv = this.props.dateEnv;
5658            var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5659            currentDateProfile.dateIncrement);
5660            return this.build(nextDate, 1, forceToValid);
5661        };
5662        // Builds a structure holding dates/ranges for rendering around the given date.
5663        // Optional direction param indicates whether the date is being incremented/decremented
5664        // from its previous value. decremented = -1, incremented = 1 (default).
5665        DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
5666            if (forceToValid === void 0) { forceToValid = true; }
5667            var props = this.props;
5668            var validRange;
5669            var currentInfo;
5670            var isRangeAllDay;
5671            var renderRange;
5672            var activeRange;
5673            var isValid;
5674            validRange = this.buildValidRange();
5675            validRange = this.trimHiddenDays(validRange);
5676            if (forceToValid) {
5677                currentDate = constrainMarkerToRange(currentDate, validRange);
5678            }
5679            currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
5680            isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5681            renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
5682            renderRange = this.trimHiddenDays(renderRange);
5683            activeRange = renderRange;
5684            if (!props.showNonCurrentDates) {
5685                activeRange = intersectRanges(activeRange, currentInfo.range);
5686            }
5687            activeRange = this.adjustActiveRange(activeRange);
5688            activeRange = intersectRanges(activeRange, validRange); // might return null
5689            // it's invalid if the originally requested date is not contained,
5690            // or if the range is completely outside of the valid range.
5691            isValid = rangesIntersect(currentInfo.range, validRange);
5692            return {
5693                // constraint for where prev/next operations can go and where events can be dragged/resized to.
5694                // an object with optional start and end properties.
5695                validRange: validRange,
5696                // range the view is formally responsible for.
5697                // for example, a month view might have 1st-31st, excluding padded dates
5698                currentRange: currentInfo.range,
5699                // name of largest unit being displayed, like "month" or "week"
5700                currentRangeUnit: currentInfo.unit,
5701                isRangeAllDay: isRangeAllDay,
5702                // dates that display events and accept drag-n-drop
5703                // will be `null` if no dates accept events
5704                activeRange: activeRange,
5705                // date range with a rendered skeleton
5706                // includes not-active days that need some sort of DOM
5707                renderRange: renderRange,
5708                // Duration object that denotes the first visible time of any given day
5709                slotMinTime: props.slotMinTime,
5710                // Duration object that denotes the exclusive visible end time of any given day
5711                slotMaxTime: props.slotMaxTime,
5712                isValid: isValid,
5713                // how far the current date will move for a prev/next operation
5714                dateIncrement: this.buildDateIncrement(currentInfo.duration),
5715                // pass a fallback (might be null) ^
5716            };
5717        };
5718        // Builds an object with optional start/end properties.
5719        // Indicates the minimum/maximum dates to display.
5720        // not responsible for trimming hidden days.
5721        DateProfileGenerator.prototype.buildValidRange = function () {
5722            var input = this.props.validRangeInput;
5723            var simpleInput = typeof input === 'function'
5724                ? input.call(this.props.calendarApi, this.nowDate)
5725                : input;
5726            return this.refineRange(simpleInput) ||
5727                { start: null, end: null }; // completely open-ended
5728        };
5729        // Builds a structure with info about the "current" range, the range that is
5730        // highlighted as being the current month for example.
5731        // See build() for a description of `direction`.
5732        // Guaranteed to have `range` and `unit` properties. `duration` is optional.
5733        DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
5734            var props = this.props;
5735            var duration = null;
5736            var unit = null;
5737            var range = null;
5738            var dayCount;
5739            if (props.duration) {
5740                duration = props.duration;
5741                unit = props.durationUnit;
5742                range = this.buildRangeFromDuration(date, direction, duration, unit);
5743            }
5744            else if ((dayCount = this.props.dayCount)) {
5745                unit = 'day';
5746                range = this.buildRangeFromDayCount(date, direction, dayCount);
5747            }
5748            else if ((range = this.buildCustomVisibleRange(date))) {
5749                unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit;
5750            }
5751            else {
5752                duration = this.getFallbackDuration();
5753                unit = greatestDurationDenominator(duration).unit;
5754                range = this.buildRangeFromDuration(date, direction, duration, unit);
5755            }
5756            return { duration: duration, unit: unit, range: range };
5757        };
5758        DateProfileGenerator.prototype.getFallbackDuration = function () {
5759            return createDuration({ day: 1 });
5760        };
5761        // Returns a new activeRange to have time values (un-ambiguate)
5762        // slotMinTime or slotMaxTime causes the range to expand.
5763        DateProfileGenerator.prototype.adjustActiveRange = function (range) {
5764            var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime;
5765            var start = range.start, end = range.end;
5766            if (usesMinMaxTime) {
5767                // expand active range if slotMinTime is negative (why not when positive?)
5768                if (asRoughDays(slotMinTime) < 0) {
5769                    start = startOfDay(start); // necessary?
5770                    start = dateEnv.add(start, slotMinTime);
5771                }
5772                // expand active range if slotMaxTime is beyond one day (why not when negative?)
5773                if (asRoughDays(slotMaxTime) > 1) {
5774                    end = startOfDay(end); // necessary?
5775                    end = addDays(end, -1);
5776                    end = dateEnv.add(end, slotMaxTime);
5777                }
5778            }
5779            return { start: start, end: end };
5780        };
5781        // Builds the "current" range when it is specified as an explicit duration.
5782        // `unit` is the already-computed greatestDurationDenominator unit of duration.
5783        DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
5784            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
5785            var start;
5786            var end;
5787            var res;
5788            // compute what the alignment should be
5789            if (!dateAlignment) {
5790                var dateIncrement = this.props.dateIncrement;
5791                if (dateIncrement) {
5792                    // use the smaller of the two units
5793                    if (asRoughMs(dateIncrement) < asRoughMs(duration)) {
5794                        dateAlignment = greatestDurationDenominator(dateIncrement).unit;
5795                    }
5796                    else {
5797                        dateAlignment = unit;
5798                    }
5799                }
5800                else {
5801                    dateAlignment = unit;
5802                }
5803            }
5804            // if the view displays a single day or smaller
5805            if (asRoughDays(duration) <= 1) {
5806                if (this.isHiddenDay(start)) {
5807                    start = this.skipHiddenDays(start, direction);
5808                    start = startOfDay(start);
5809                }
5810            }
5811            function computeRes() {
5812                start = dateEnv.startOf(date, dateAlignment);
5813                end = dateEnv.add(start, duration);
5814                res = { start: start, end: end };
5815            }
5816            computeRes();
5817            // if range is completely enveloped by hidden days, go past the hidden days
5818            if (!this.trimHiddenDays(res)) {
5819                date = this.skipHiddenDays(date, direction);
5820                computeRes();
5821            }
5822            return res;
5823        };
5824        // Builds the "current" range when a dayCount is specified.
5825        DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
5826            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
5827            var runningCount = 0;
5828            var start = date;
5829            var end;
5830            if (dateAlignment) {
5831                start = dateEnv.startOf(start, dateAlignment);
5832            }
5833            start = startOfDay(start);
5834            start = this.skipHiddenDays(start, direction);
5835            end = start;
5836            do {
5837                end = addDays(end, 1);
5838                if (!this.isHiddenDay(end)) {
5839                    runningCount += 1;
5840                }
5841            } while (runningCount < dayCount);
5842            return { start: start, end: end };
5843        };
5844        // Builds a normalized range object for the "visible" range,
5845        // which is a way to define the currentRange and activeRange at the same time.
5846        DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
5847            var props = this.props;
5848            var input = props.visibleRangeInput;
5849            var simpleInput = typeof input === 'function'
5850                ? input.call(props.calendarApi, props.dateEnv.toDate(date))
5851                : input;
5852            var range = this.refineRange(simpleInput);
5853            if (range && (range.start == null || range.end == null)) {
5854                return null;
5855            }
5856            return range;
5857        };
5858        // Computes the range that will represent the element/cells for *rendering*,
5859        // but which may have voided days/times.
5860        // not responsible for trimming hidden days.
5861        DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
5862            return currentRange;
5863        };
5864        // Compute the duration value that should be added/substracted to the current date
5865        // when a prev/next operation happens.
5866        DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
5867            var dateIncrement = this.props.dateIncrement;
5868            var customAlignment;
5869            if (dateIncrement) {
5870                return dateIncrement;
5871            }
5872            if ((customAlignment = this.props.dateAlignment)) {
5873                return createDuration(1, customAlignment);
5874            }
5875            if (fallback) {
5876                return fallback;
5877            }
5878            return createDuration({ days: 1 });
5879        };
5880        DateProfileGenerator.prototype.refineRange = function (rangeInput) {
5881            if (rangeInput) {
5882                var range = parseRange(rangeInput, this.props.dateEnv);
5883                if (range) {
5884                    range = computeVisibleDayRange(range);
5885                }
5886                return range;
5887            }
5888            return null;
5889        };
5890        /* Hidden Days
5891        ------------------------------------------------------------------------------------------------------------------*/
5892        // Initializes internal variables related to calculating hidden days-of-week
5893        DateProfileGenerator.prototype.initHiddenDays = function () {
5894            var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
5895            var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
5896            var dayCnt = 0;
5897            var i;
5898            if (this.props.weekends === false) {
5899                hiddenDays.push(0, 6); // 0=sunday, 6=saturday
5900            }
5901            for (i = 0; i < 7; i += 1) {
5902                if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
5903                    dayCnt += 1;
5904                }
5905            }
5906            if (!dayCnt) {
5907                throw new Error('invalid hiddenDays'); // all days were hidden? bad.
5908            }
5909            this.isHiddenDayHash = isHiddenDayHash;
5910        };
5911        // Remove days from the beginning and end of the range that are computed as hidden.
5912        // If the whole range is trimmed off, returns null
5913        DateProfileGenerator.prototype.trimHiddenDays = function (range) {
5914            var start = range.start, end = range.end;
5915            if (start) {
5916                start = this.skipHiddenDays(start);
5917            }
5918            if (end) {
5919                end = this.skipHiddenDays(end, -1, true);
5920            }
5921            if (start == null || end == null || start < end) {
5922                return { start: start, end: end };
5923            }
5924            return null;
5925        };
5926        // Is the current day hidden?
5927        // `day` is a day-of-week index (0-6), or a Date (used for UTC)
5928        DateProfileGenerator.prototype.isHiddenDay = function (day) {
5929            if (day instanceof Date) {
5930                day = day.getUTCDay();
5931            }
5932            return this.isHiddenDayHash[day];
5933        };
5934        // Incrementing the current day until it is no longer a hidden day, returning a copy.
5935        // DOES NOT CONSIDER validRange!
5936        // If the initial value of `date` is not a hidden day, don't do anything.
5937        // Pass `isExclusive` as `true` if you are dealing with an end date.
5938        // `inc` defaults to `1` (increment one day forward each time)
5939        DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
5940            if (inc === void 0) { inc = 1; }
5941            if (isExclusive === void 0) { isExclusive = false; }
5942            while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
5943                date = addDays(date, inc);
5944            }
5945            return date;
5946        };
5947        return DateProfileGenerator;
5948    }());
5949
5950    function reduceViewType(viewType, action) {
5951        switch (action.type) {
5952            case 'CHANGE_VIEW_TYPE':
5953                viewType = action.viewType;
5954        }
5955        return viewType;
5956    }
5957
5958    function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {
5959        var _a;
5960        switch (action.type) {
5961            case 'SET_OPTION':
5962                return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a));
5963            default:
5964                return dynamicOptionOverrides;
5965        }
5966    }
5967
5968    function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {
5969        var dp;
5970        switch (action.type) {
5971            case 'CHANGE_VIEW_TYPE':
5972                return dateProfileGenerator.build(action.dateMarker || currentDate);
5973            case 'CHANGE_DATE':
5974                if (!currentDateProfile.activeRange ||
5975                    !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker) // don't move if date already in view
5976                ) {
5977                    return dateProfileGenerator.build(action.dateMarker);
5978                }
5979                break;
5980            case 'PREV':
5981                dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);
5982                if (dp.isValid) {
5983                    return dp;
5984                }
5985                break;
5986            case 'NEXT':
5987                dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);
5988                if (dp.isValid) {
5989                    return dp;
5990                }
5991                break;
5992        }
5993        return currentDateProfile;
5994    }
5995
5996    function initEventSources(calendarOptions, dateProfile, context) {
5997        var activeRange = dateProfile ? dateProfile.activeRange : null;
5998        return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);
5999    }
6000    function reduceEventSources(eventSources, action, dateProfile, context) {
6001        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
6002        switch (action.type) {
6003            case 'ADD_EVENT_SOURCES': // already parsed
6004                return addSources(eventSources, action.sources, activeRange, context);
6005            case 'REMOVE_EVENT_SOURCE':
6006                return removeSource(eventSources, action.sourceId);
6007            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
6008            case 'NEXT':
6009            case 'CHANGE_DATE':
6010            case 'CHANGE_VIEW_TYPE':
6011                if (dateProfile) {
6012                    return fetchDirtySources(eventSources, activeRange, context);
6013                }
6014                return eventSources;
6015            case 'FETCH_EVENT_SOURCES':
6016                return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?
6017                    arrayToHash(action.sourceIds) :
6018                    excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context);
6019            case 'RECEIVE_EVENTS':
6020            case 'RECEIVE_EVENT_ERROR':
6021                return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
6022            case 'REMOVE_ALL_EVENT_SOURCES':
6023                return {};
6024            default:
6025                return eventSources;
6026        }
6027    }
6028    function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {
6029        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
6030        return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context);
6031    }
6032    function computeEventSourcesLoading(eventSources) {
6033        for (var sourceId in eventSources) {
6034            if (eventSources[sourceId].isFetching) {
6035                return true;
6036            }
6037        }
6038        return false;
6039    }
6040    function addSources(eventSourceHash, sources, fetchRange, context) {
6041        var hash = {};
6042        for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
6043            var source = sources_1[_i];
6044            hash[source.sourceId] = source;
6045        }
6046        if (fetchRange) {
6047            hash = fetchDirtySources(hash, fetchRange, context);
6048        }
6049        return __assign(__assign({}, eventSourceHash), hash);
6050    }
6051    function removeSource(eventSourceHash, sourceId) {
6052        return filterHash(eventSourceHash, function (eventSource) { return eventSource.sourceId !== sourceId; });
6053    }
6054    function fetchDirtySources(sourceHash, fetchRange, context) {
6055        return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { return isSourceDirty(eventSource, fetchRange, context); }), fetchRange, false, context);
6056    }
6057    function isSourceDirty(eventSource, fetchRange, context) {
6058        if (!doesSourceNeedRange(eventSource, context)) {
6059            return !eventSource.latestFetchId;
6060        }
6061        return !context.options.lazyFetching ||
6062            !eventSource.fetchRange ||
6063            eventSource.isFetching || // always cancel outdated in-progress fetches
6064            fetchRange.start < eventSource.fetchRange.start ||
6065            fetchRange.end > eventSource.fetchRange.end;
6066    }
6067    function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) {
6068        var nextSources = {};
6069        for (var sourceId in prevSources) {
6070            var source = prevSources[sourceId];
6071            if (sourceIdHash[sourceId]) {
6072                nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context);
6073            }
6074            else {
6075                nextSources[sourceId] = source;
6076            }
6077        }
6078        return nextSources;
6079    }
6080    function fetchSource(eventSource, fetchRange, isRefetch, context) {
6081        var options = context.options, calendarApi = context.calendarApi;
6082        var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];
6083        var fetchId = guid();
6084        sourceDef.fetch({
6085            eventSource: eventSource,
6086            range: fetchRange,
6087            isRefetch: isRefetch,
6088            context: context,
6089        }, function (res) {
6090            var rawEvents = res.rawEvents;
6091            if (options.eventSourceSuccess) {
6092                rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents;
6093            }
6094            if (eventSource.success) {
6095                rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents;
6096            }
6097            context.dispatch({
6098                type: 'RECEIVE_EVENTS',
6099                sourceId: eventSource.sourceId,
6100                fetchId: fetchId,
6101                fetchRange: fetchRange,
6102                rawEvents: rawEvents,
6103            });
6104        }, function (error) {
6105            console.warn(error.message, error);
6106            if (options.eventSourceFailure) {
6107                options.eventSourceFailure.call(calendarApi, error);
6108            }
6109            if (eventSource.failure) {
6110                eventSource.failure(error);
6111            }
6112            context.dispatch({
6113                type: 'RECEIVE_EVENT_ERROR',
6114                sourceId: eventSource.sourceId,
6115                fetchId: fetchId,
6116                fetchRange: fetchRange,
6117                error: error,
6118            });
6119        });
6120        return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });
6121    }
6122    function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
6123        var _a;
6124        var eventSource = sourceHash[sourceId];
6125        if (eventSource && // not already removed
6126            fetchId === eventSource.latestFetchId) {
6127            return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange }), _a));
6128        }
6129        return sourceHash;
6130    }
6131    function excludeStaticSources(eventSources, context) {
6132        return filterHash(eventSources, function (eventSource) { return doesSourceNeedRange(eventSource, context); });
6133    }
6134    function parseInitialSources(rawOptions, context) {
6135        var refiners = buildEventSourceRefiners(context);
6136        var rawSources = [].concat(rawOptions.eventSources || []);
6137        var sources = []; // parsed
6138        if (rawOptions.initialEvents) {
6139            rawSources.unshift(rawOptions.initialEvents);
6140        }
6141        if (rawOptions.events) {
6142            rawSources.unshift(rawOptions.events);
6143        }
6144        for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
6145            var rawSource = rawSources_1[_i];
6146            var source = parseEventSource(rawSource, context, refiners);
6147            if (source) {
6148                sources.push(source);
6149            }
6150        }
6151        return sources;
6152    }
6153    function doesSourceNeedRange(eventSource, context) {
6154        var defs = context.pluginHooks.eventSourceDefs;
6155        return !defs[eventSource.sourceDefId].ignoreRange;
6156    }
6157
6158    function reduceEventStore(eventStore, action, eventSources, dateProfile, context) {
6159        switch (action.type) {
6160            case 'RECEIVE_EVENTS': // raw
6161                return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context);
6162            case 'ADD_EVENTS': // already parsed, but not expanded
6163                return addEvent(eventStore, action.eventStore, // new ones
6164                dateProfile ? dateProfile.activeRange : null, context);
6165            case 'RESET_EVENTS':
6166                return action.eventStore;
6167            case 'MERGE_EVENTS': // already parsed and expanded
6168                return mergeEventStores(eventStore, action.eventStore);
6169            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
6170            case 'NEXT':
6171            case 'CHANGE_DATE':
6172            case 'CHANGE_VIEW_TYPE':
6173                if (dateProfile) {
6174                    return expandRecurring(eventStore, dateProfile.activeRange, context);
6175                }
6176                return eventStore;
6177            case 'REMOVE_EVENTS':
6178                return excludeSubEventStore(eventStore, action.eventStore);
6179            case 'REMOVE_EVENT_SOURCE':
6180                return excludeEventsBySourceId(eventStore, action.sourceId);
6181            case 'REMOVE_ALL_EVENT_SOURCES':
6182                return filterEventStoreDefs(eventStore, function (eventDef) { return (!eventDef.sourceId // only keep events with no source id
6183                ); });
6184            case 'REMOVE_ALL_EVENTS':
6185                return createEmptyEventStore();
6186            default:
6187                return eventStore;
6188        }
6189    }
6190    function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) {
6191        if (eventSource && // not already removed
6192            fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
6193        ) {
6194            var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context);
6195            if (fetchRange) {
6196                subset = expandRecurring(subset, fetchRange, context);
6197            }
6198            return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
6199        }
6200        return eventStore;
6201    }
6202    function transformRawEvents(rawEvents, eventSource, context) {
6203        var calEachTransform = context.options.eventDataTransform;
6204        var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
6205        if (sourceEachTransform) {
6206            rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
6207        }
6208        if (calEachTransform) {
6209            rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
6210        }
6211        return rawEvents;
6212    }
6213    function transformEachRawEvent(rawEvents, func) {
6214        var refinedEvents;
6215        if (!func) {
6216            refinedEvents = rawEvents;
6217        }
6218        else {
6219            refinedEvents = [];
6220            for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
6221                var rawEvent = rawEvents_1[_i];
6222                var refinedEvent = func(rawEvent);
6223                if (refinedEvent) {
6224                    refinedEvents.push(refinedEvent);
6225                }
6226                else if (refinedEvent == null) {
6227                    refinedEvents.push(rawEvent);
6228                } // if a different falsy value, do nothing
6229            }
6230        }
6231        return refinedEvents;
6232    }
6233    function addEvent(eventStore, subset, expandRange, context) {
6234        if (expandRange) {
6235            subset = expandRecurring(subset, expandRange, context);
6236        }
6237        return mergeEventStores(eventStore, subset);
6238    }
6239    function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) {
6240        var defs = eventStore.defs;
6241        var instances = mapHash(eventStore.instances, function (instance) {
6242            var def = defs[instance.defId];
6243            if (def.allDay || def.recurringDef) {
6244                return instance; // isn't dependent on timezone
6245            }
6246            return __assign(__assign({}, instance), { range: {
6247                    start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
6248                    end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)),
6249                }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
6250        });
6251        return { defs: defs, instances: instances };
6252    }
6253    function excludeEventsBySourceId(eventStore, sourceId) {
6254        return filterEventStoreDefs(eventStore, function (eventDef) { return eventDef.sourceId !== sourceId; });
6255    }
6256    // QUESTION: why not just return instances? do a general object-property-exclusion util
6257    function excludeInstances(eventStore, removals) {
6258        return {
6259            defs: eventStore.defs,
6260            instances: filterHash(eventStore.instances, function (instance) { return !removals[instance.instanceId]; }),
6261        };
6262    }
6263
6264    function reduceDateSelection(currentSelection, action) {
6265        switch (action.type) {
6266            case 'UNSELECT_DATES':
6267                return null;
6268            case 'SELECT_DATES':
6269                return action.selection;
6270            default:
6271                return currentSelection;
6272        }
6273    }
6274
6275    function reduceSelectedEvent(currentInstanceId, action) {
6276        switch (action.type) {
6277            case 'UNSELECT_EVENT':
6278                return '';
6279            case 'SELECT_EVENT':
6280                return action.eventInstanceId;
6281            default:
6282                return currentInstanceId;
6283        }
6284    }
6285
6286    function reduceEventDrag(currentDrag, action) {
6287        var newDrag;
6288        switch (action.type) {
6289            case 'UNSET_EVENT_DRAG':
6290                return null;
6291            case 'SET_EVENT_DRAG':
6292                newDrag = action.state;
6293                return {
6294                    affectedEvents: newDrag.affectedEvents,
6295                    mutatedEvents: newDrag.mutatedEvents,
6296                    isEvent: newDrag.isEvent,
6297                };
6298            default:
6299                return currentDrag;
6300        }
6301    }
6302
6303    function reduceEventResize(currentResize, action) {
6304        var newResize;
6305        switch (action.type) {
6306            case 'UNSET_EVENT_RESIZE':
6307                return null;
6308            case 'SET_EVENT_RESIZE':
6309                newResize = action.state;
6310                return {
6311                    affectedEvents: newResize.affectedEvents,
6312                    mutatedEvents: newResize.mutatedEvents,
6313                    isEvent: newResize.isEvent,
6314                };
6315            default:
6316                return currentResize;
6317        }
6318    }
6319
6320    function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
6321        var viewsWithButtons = [];
6322        var headerToolbar = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null;
6323        var footerToolbar = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null;
6324        return { headerToolbar: headerToolbar, footerToolbar: footerToolbar, viewsWithButtons: viewsWithButtons };
6325    }
6326    function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) {
6327        return mapHash(sectionStrHash, function (sectionStr) { return parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons); });
6328    }
6329    /*
6330    BAD: querying icons and text here. should be done at render time
6331    */
6332    function parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) {
6333        var isRtl = calendarOptions.direction === 'rtl';
6334        var calendarCustomButtons = calendarOptions.customButtons || {};
6335        var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};
6336        var calendarButtonText = calendarOptions.buttonText || {};
6337        var sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];
6338        return sectionSubstrs.map(function (buttonGroupStr) { return (buttonGroupStr.split(',').map(function (buttonName) {
6339            if (buttonName === 'title') {
6340                return { buttonName: buttonName };
6341            }
6342            var customButtonProps;
6343            var viewSpec;
6344            var buttonClick;
6345            var buttonIcon; // only one of these will be set
6346            var buttonText; // "
6347            if ((customButtonProps = calendarCustomButtons[buttonName])) {
6348                buttonClick = function (ev) {
6349                    if (customButtonProps.click) {
6350                        customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context?
6351                    }
6352                };
6353                (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
6354                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6355                    (buttonText = customButtonProps.text);
6356            }
6357            else if ((viewSpec = viewSpecs[buttonName])) {
6358                viewsWithButtons.push(buttonName);
6359                buttonClick = function () {
6360                    calendarApi.changeView(buttonName);
6361                };
6362                (buttonText = viewSpec.buttonTextOverride) ||
6363                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6364                    (buttonText = viewSpec.buttonTextDefault);
6365            }
6366            else if (calendarApi[buttonName]) { // a calendarApi method
6367                buttonClick = function () {
6368                    calendarApi[buttonName]();
6369                };
6370                (buttonText = calendarButtonTextOverrides[buttonName]) ||
6371                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6372                    (buttonText = calendarButtonText[buttonName]);
6373                //            ^ everything else is considered default
6374            }
6375            return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText };
6376        })); });
6377    }
6378
6379    var eventSourceDef$3 = {
6380        ignoreRange: true,
6381        parseMeta: function (refined) {
6382            if (Array.isArray(refined.events)) {
6383                return refined.events;
6384            }
6385            return null;
6386        },
6387        fetch: function (arg, success) {
6388            success({
6389                rawEvents: arg.eventSource.meta,
6390            });
6391        },
6392    };
6393    var arrayEventSourcePlugin = createPlugin({
6394        eventSourceDefs: [eventSourceDef$3],
6395    });
6396
6397    var eventSourceDef$2 = {
6398        parseMeta: function (refined) {
6399            if (typeof refined.events === 'function') {
6400                return refined.events;
6401            }
6402            return null;
6403        },
6404        fetch: function (arg, success, failure) {
6405            var dateEnv = arg.context.dateEnv;
6406            var func = arg.eventSource.meta;
6407            unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) {
6408                success({ rawEvents: rawEvents }); // needs an object response
6409            }, failure);
6410        },
6411    };
6412    var funcEventSourcePlugin = createPlugin({
6413        eventSourceDefs: [eventSourceDef$2],
6414    });
6415
6416    function requestJson(method, url, params, successCallback, failureCallback) {
6417        method = method.toUpperCase();
6418        var body = null;
6419        if (method === 'GET') {
6420            url = injectQueryStringParams(url, params);
6421        }
6422        else {
6423            body = encodeParams(params);
6424        }
6425        var xhr = new XMLHttpRequest();
6426        xhr.open(method, url, true);
6427        if (method !== 'GET') {
6428            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
6429            xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
6430        }
6431        xhr.onload = function () {
6432            if (xhr.status >= 200 && xhr.status < 400) {
6433                var parsed = false;
6434                var res = void 0;
6435                try {
6436                    res = JSON.parse(xhr.responseText);
6437                    parsed = true;
6438                }
6439                catch (err) {
6440                    // will handle parsed=false
6441                }
6442                if (parsed) {
6443                    successCallback(res, xhr);
6444                }
6445                else {
6446                    failureCallback('Failure parsing JSON', xhr);
6447                }
6448            }
6449            else {
6450                failureCallback('Request failed', xhr);
6451            }
6452        };
6453        xhr.onerror = function () {
6454            failureCallback('Request failed', xhr);
6455        };
6456        xhr.send(body);
6457    }
6458    function injectQueryStringParams(url, params) {
6459        return url +
6460            (url.indexOf('?') === -1 ? '?' : '&') +
6461            encodeParams(params);
6462    }
6463    function encodeParams(params) {
6464        var parts = [];
6465        for (var key in params) {
6466            parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
6467        }
6468        return parts.join('&');
6469    }
6470
6471    var JSON_FEED_EVENT_SOURCE_REFINERS = {
6472        method: String,
6473        extraParams: identity,
6474        startParam: String,
6475        endParam: String,
6476        timeZoneParam: String,
6477    };
6478
6479    var eventSourceDef$1 = {
6480        parseMeta: function (refined) {
6481            if (refined.url && (refined.format === 'json' || !refined.format)) {
6482                return {
6483                    url: refined.url,
6484                    format: 'json',
6485                    method: (refined.method || 'GET').toUpperCase(),
6486                    extraParams: refined.extraParams,
6487                    startParam: refined.startParam,
6488                    endParam: refined.endParam,
6489                    timeZoneParam: refined.timeZoneParam,
6490                };
6491            }
6492            return null;
6493        },
6494        fetch: function (arg, success, failure) {
6495            var meta = arg.eventSource.meta;
6496            var requestParams = buildRequestParams$1(meta, arg.range, arg.context);
6497            requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
6498                success({ rawEvents: rawEvents, xhr: xhr });
6499            }, function (errorMessage, xhr) {
6500                failure({ message: errorMessage, xhr: xhr });
6501            });
6502        },
6503    };
6504    var jsonFeedEventSourcePlugin = createPlugin({
6505        eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,
6506        eventSourceDefs: [eventSourceDef$1],
6507    });
6508    function buildRequestParams$1(meta, range, context) {
6509        var dateEnv = context.dateEnv, options = context.options;
6510        var startParam;
6511        var endParam;
6512        var timeZoneParam;
6513        var customRequestParams;
6514        var params = {};
6515        startParam = meta.startParam;
6516        if (startParam == null) {
6517            startParam = options.startParam;
6518        }
6519        endParam = meta.endParam;
6520        if (endParam == null) {
6521            endParam = options.endParam;
6522        }
6523        timeZoneParam = meta.timeZoneParam;
6524        if (timeZoneParam == null) {
6525            timeZoneParam = options.timeZoneParam;
6526        }
6527        // retrieve any outbound GET/POST data from the options
6528        if (typeof meta.extraParams === 'function') {
6529            // supplied as a function that returns a key/value object
6530            customRequestParams = meta.extraParams();
6531        }
6532        else {
6533            // probably supplied as a straight key/value object
6534            customRequestParams = meta.extraParams || {};
6535        }
6536        __assign(params, customRequestParams);
6537        params[startParam] = dateEnv.formatIso(range.start);
6538        params[endParam] = dateEnv.formatIso(range.end);
6539        if (dateEnv.timeZone !== 'local') {
6540            params[timeZoneParam] = dateEnv.timeZone;
6541        }
6542        return params;
6543    }
6544
6545    var SIMPLE_RECURRING_REFINERS = {
6546        daysOfWeek: identity,
6547        startTime: createDuration,
6548        endTime: createDuration,
6549        duration: createDuration,
6550        startRecur: identity,
6551        endRecur: identity,
6552    };
6553
6554    var recurring = {
6555        parse: function (refined, dateEnv) {
6556            if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {
6557                var recurringData = {
6558                    daysOfWeek: refined.daysOfWeek || null,
6559                    startTime: refined.startTime || null,
6560                    endTime: refined.endTime || null,
6561                    startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,
6562                    endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,
6563                };
6564                var duration = void 0;
6565                if (refined.duration) {
6566                    duration = refined.duration;
6567                }
6568                if (!duration && refined.startTime && refined.endTime) {
6569                    duration = subtractDurations(refined.endTime, refined.startTime);
6570                }
6571                return {
6572                    allDayGuess: Boolean(!refined.startTime && !refined.endTime),
6573                    duration: duration,
6574                    typeData: recurringData, // doesn't need endTime anymore but oh well
6575                };
6576            }
6577            return null;
6578        },
6579        expand: function (typeData, framingRange, dateEnv) {
6580            var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
6581            if (clippedFramingRange) {
6582                return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
6583            }
6584            return [];
6585        },
6586    };
6587    var simpleRecurringEventsPlugin = createPlugin({
6588        recurringTypes: [recurring],
6589        eventRefiners: SIMPLE_RECURRING_REFINERS,
6590    });
6591    function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
6592        var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
6593        var dayMarker = startOfDay(framingRange.start);
6594        var endMarker = framingRange.end;
6595        var instanceStarts = [];
6596        while (dayMarker < endMarker) {
6597            var instanceStart
6598            // if everyday, or this particular day-of-week
6599            = void 0;
6600            // if everyday, or this particular day-of-week
6601            if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
6602                if (startTime) {
6603                    instanceStart = dateEnv.add(dayMarker, startTime);
6604                }
6605                else {
6606                    instanceStart = dayMarker;
6607                }
6608                instanceStarts.push(instanceStart);
6609            }
6610            dayMarker = addDays(dayMarker, 1);
6611        }
6612        return instanceStarts;
6613    }
6614
6615    var changeHandlerPlugin = createPlugin({
6616        optionChangeHandlers: {
6617            events: function (events, context) {
6618                handleEventSources([events], context);
6619            },
6620            eventSources: handleEventSources,
6621        },
6622    });
6623    /*
6624    BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out
6625    */
6626    function handleEventSources(inputs, context) {
6627        var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources);
6628        var newInputs = [];
6629        for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
6630            var input = inputs_1[_i];
6631            var inputFound = false;
6632            for (var i = 0; i < unfoundSources.length; i += 1) {
6633                if (unfoundSources[i]._raw === input) {
6634                    unfoundSources.splice(i, 1); // delete
6635                    inputFound = true;
6636                    break;
6637                }
6638            }
6639            if (!inputFound) {
6640                newInputs.push(input);
6641            }
6642        }
6643        for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
6644            var unfoundSource = unfoundSources_1[_a];
6645            context.dispatch({
6646                type: 'REMOVE_EVENT_SOURCE',
6647                sourceId: unfoundSource.sourceId,
6648            });
6649        }
6650        for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
6651            var newInput = newInputs_1[_b];
6652            context.calendarApi.addEventSource(newInput);
6653        }
6654    }
6655
6656    function handleDateProfile(dateProfile, context) {
6657        context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));
6658    }
6659
6660    function handleEventStore(eventStore, context) {
6661        var emitter = context.emitter;
6662        if (emitter.hasHandlers('eventsSet')) {
6663            emitter.trigger('eventsSet', buildEventApis(eventStore, context));
6664        }
6665    }
6666
6667    /*
6668    this array is exposed on the root namespace so that UMD plugins can add to it.
6669    see the rollup-bundles script.
6670    */
6671    var globalPlugins = [
6672        arrayEventSourcePlugin,
6673        funcEventSourcePlugin,
6674        jsonFeedEventSourcePlugin,
6675        simpleRecurringEventsPlugin,
6676        changeHandlerPlugin,
6677        createPlugin({
6678            isLoadingFuncs: [
6679                function (state) { return computeEventSourcesLoading(state.eventSources); },
6680            ],
6681            contentTypeHandlers: {
6682                html: function () { return ({ render: injectHtml }); },
6683                domNodes: function () { return ({ render: injectDomNodes }); },
6684            },
6685            propSetHandlers: {
6686                dateProfile: handleDateProfile,
6687                eventStore: handleEventStore,
6688            },
6689        }),
6690    ];
6691    function injectHtml(el, html) {
6692        el.innerHTML = html;
6693    }
6694    function injectDomNodes(el, domNodes) {
6695        var oldNodes = Array.prototype.slice.call(el.childNodes); // TODO: use array util
6696        var newNodes = Array.prototype.slice.call(domNodes); // TODO: use array util
6697        if (!isArraysEqual(oldNodes, newNodes)) {
6698            for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) {
6699                var newNode = newNodes_1[_i];
6700                el.appendChild(newNode);
6701            }
6702            oldNodes.forEach(removeElement);
6703        }
6704    }
6705
6706    var DelayedRunner = /** @class */ (function () {
6707        function DelayedRunner(drainedOption) {
6708            this.drainedOption = drainedOption;
6709            this.isRunning = false;
6710            this.isDirty = false;
6711            this.pauseDepths = {};
6712            this.timeoutId = 0;
6713        }
6714        DelayedRunner.prototype.request = function (delay) {
6715            this.isDirty = true;
6716            if (!this.isPaused()) {
6717                this.clearTimeout();
6718                if (delay == null) {
6719                    this.tryDrain();
6720                }
6721                else {
6722                    this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce
6723                    this.tryDrain.bind(this), delay);
6724                }
6725            }
6726        };
6727        DelayedRunner.prototype.pause = function (scope) {
6728            if (scope === void 0) { scope = ''; }
6729            var pauseDepths = this.pauseDepths;
6730            pauseDepths[scope] = (pauseDepths[scope] || 0) + 1;
6731            this.clearTimeout();
6732        };
6733        DelayedRunner.prototype.resume = function (scope, force) {
6734            if (scope === void 0) { scope = ''; }
6735            var pauseDepths = this.pauseDepths;
6736            if (scope in pauseDepths) {
6737                if (force) {
6738                    delete pauseDepths[scope];
6739                }
6740                else {
6741                    pauseDepths[scope] -= 1;
6742                    var depth = pauseDepths[scope];
6743                    if (depth <= 0) {
6744                        delete pauseDepths[scope];
6745                    }
6746                }
6747                this.tryDrain();
6748            }
6749        };
6750        DelayedRunner.prototype.isPaused = function () {
6751            return Object.keys(this.pauseDepths).length;
6752        };
6753        DelayedRunner.prototype.tryDrain = function () {
6754            if (!this.isRunning && !this.isPaused()) {
6755                this.isRunning = true;
6756                while (this.isDirty) {
6757                    this.isDirty = false;
6758                    this.drained(); // might set isDirty to true again
6759                }
6760                this.isRunning = false;
6761            }
6762        };
6763        DelayedRunner.prototype.clear = function () {
6764            this.clearTimeout();
6765            this.isDirty = false;
6766            this.pauseDepths = {};
6767        };
6768        DelayedRunner.prototype.clearTimeout = function () {
6769            if (this.timeoutId) {
6770                clearTimeout(this.timeoutId);
6771                this.timeoutId = 0;
6772            }
6773        };
6774        DelayedRunner.prototype.drained = function () {
6775            if (this.drainedOption) {
6776                this.drainedOption();
6777            }
6778        };
6779        return DelayedRunner;
6780    }());
6781
6782    var TaskRunner = /** @class */ (function () {
6783        function TaskRunner(runTaskOption, drainedOption) {
6784            this.runTaskOption = runTaskOption;
6785            this.drainedOption = drainedOption;
6786            this.queue = [];
6787            this.delayedRunner = new DelayedRunner(this.drain.bind(this));
6788        }
6789        TaskRunner.prototype.request = function (task, delay) {
6790            this.queue.push(task);
6791            this.delayedRunner.request(delay);
6792        };
6793        TaskRunner.prototype.pause = function (scope) {
6794            this.delayedRunner.pause(scope);
6795        };
6796        TaskRunner.prototype.resume = function (scope, force) {
6797            this.delayedRunner.resume(scope, force);
6798        };
6799        TaskRunner.prototype.drain = function () {
6800            var queue = this.queue;
6801            while (queue.length) {
6802                var completedTasks = [];
6803                var task = void 0;
6804                while ((task = queue.shift())) {
6805                    this.runTask(task);
6806                    completedTasks.push(task);
6807                }
6808                this.drained(completedTasks);
6809            } // keep going, in case new tasks were added in the drained handler
6810        };
6811        TaskRunner.prototype.runTask = function (task) {
6812            if (this.runTaskOption) {
6813                this.runTaskOption(task);
6814            }
6815        };
6816        TaskRunner.prototype.drained = function (completedTasks) {
6817            if (this.drainedOption) {
6818                this.drainedOption(completedTasks);
6819            }
6820        };
6821        return TaskRunner;
6822    }());
6823
6824    // Computes what the title at the top of the calendarApi should be for this view
6825    function buildTitle(dateProfile, viewOptions, dateEnv) {
6826        var range;
6827        // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
6828        if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
6829            range = dateProfile.currentRange;
6830        }
6831        else { // for day units or smaller, use the actual day range
6832            range = dateProfile.activeRange;
6833        }
6834        return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {
6835            isEndExclusive: dateProfile.isRangeAllDay,
6836            defaultSeparator: viewOptions.titleRangeSeparator,
6837        });
6838    }
6839    // Generates the format string that should be used to generate the title for the current date range.
6840    // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
6841    function buildTitleFormat(dateProfile) {
6842        var currentRangeUnit = dateProfile.currentRangeUnit;
6843        if (currentRangeUnit === 'year') {
6844            return { year: 'numeric' };
6845        }
6846        if (currentRangeUnit === 'month') {
6847            return { year: 'numeric', month: 'long' }; // like "September 2014"
6848        }
6849        var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
6850        if (days !== null && days > 1) {
6851            // multi-day range. shorter, like "Sep 9 - 10 2014"
6852            return { year: 'numeric', month: 'short', day: 'numeric' };
6853        }
6854        // one day. longer, like "September 9 2014"
6855        return { year: 'numeric', month: 'long', day: 'numeric' };
6856    }
6857
6858    // in future refactor, do the redux-style function(state=initial) for initial-state
6859    // also, whatever is happening in constructor, have it happen in action queue too
6860    var CalendarDataManager = /** @class */ (function () {
6861        function CalendarDataManager(props) {
6862            var _this = this;
6863            this.computeOptionsData = memoize(this._computeOptionsData);
6864            this.computeCurrentViewData = memoize(this._computeCurrentViewData);
6865            this.organizeRawLocales = memoize(organizeRawLocales);
6866            this.buildLocale = memoize(buildLocale);
6867            this.buildPluginHooks = buildBuildPluginHooks();
6868            this.buildDateEnv = memoize(buildDateEnv);
6869            this.buildTheme = memoize(buildTheme);
6870            this.parseToolbars = memoize(parseToolbars);
6871            this.buildViewSpecs = memoize(buildViewSpecs);
6872            this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator);
6873            this.buildViewApi = memoize(buildViewApi);
6874            this.buildViewUiProps = memoizeObjArg(buildViewUiProps);
6875            this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual);
6876            this.buildEventUiBases = memoize(buildEventUiBases);
6877            this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours);
6878            this.buildTitle = memoize(buildTitle);
6879            this.emitter = new Emitter();
6880            this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));
6881            this.currentCalendarOptionsInput = {};
6882            this.currentCalendarOptionsRefined = {};
6883            this.currentViewOptionsInput = {};
6884            this.currentViewOptionsRefined = {};
6885            this.currentCalendarOptionsRefiners = {};
6886            this.getCurrentData = function () { return _this.data; };
6887            this.dispatch = function (action) {
6888                _this.actionRunner.request(action); // protects against recursive calls to _handleAction
6889            };
6890            this.props = props;
6891            this.actionRunner.pause();
6892            var dynamicOptionOverrides = {};
6893            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
6894            var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;
6895            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
6896            // wire things up
6897            // TODO: not DRY
6898            props.calendarApi.currentDataManager = this;
6899            this.emitter.setThisContext(props.calendarApi);
6900            this.emitter.setOptions(currentViewData.options);
6901            var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv);
6902            var dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
6903            if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) {
6904                currentDate = dateProfile.currentRange.start;
6905            }
6906            var calendarContext = {
6907                dateEnv: optionsData.dateEnv,
6908                options: optionsData.calendarOptions,
6909                pluginHooks: optionsData.pluginHooks,
6910                calendarApi: props.calendarApi,
6911                dispatch: this.dispatch,
6912                emitter: this.emitter,
6913                getCurrentData: this.getCurrentData,
6914            };
6915            // needs to be after setThisContext
6916            for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) {
6917                var callback = _a[_i];
6918                callback(calendarContext);
6919            }
6920            // NOT DRY
6921            var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);
6922            var initialState = {
6923                dynamicOptionOverrides: dynamicOptionOverrides,
6924                currentViewType: currentViewType,
6925                currentDate: currentDate,
6926                dateProfile: dateProfile,
6927                businessHours: this.parseContextBusinessHours(calendarContext),
6928                eventSources: eventSources,
6929                eventUiBases: {},
6930                eventStore: createEmptyEventStore(),
6931                renderableEventStore: createEmptyEventStore(),
6932                dateSelection: null,
6933                eventSelection: '',
6934                eventDrag: null,
6935                eventResize: null,
6936                selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig,
6937            };
6938            var contextAndState = __assign(__assign({}, calendarContext), initialState);
6939            for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) {
6940                var reducer = _c[_b];
6941                __assign(initialState, reducer(null, null, contextAndState));
6942            }
6943            if (computeIsLoading(initialState, calendarContext)) {
6944                this.emitter.trigger('loading', true); // NOT DRY
6945            }
6946            this.state = initialState;
6947            this.updateData();
6948            this.actionRunner.resume();
6949        }
6950        CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) {
6951            var props = this.props;
6952            props.optionOverrides = append
6953                ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides;
6954            this.actionRunner.request({
6955                type: 'NOTHING',
6956            });
6957        };
6958        CalendarDataManager.prototype._handleAction = function (action) {
6959            var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter;
6960            var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);
6961            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
6962            var currentViewType = reduceViewType(state.currentViewType, action);
6963            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
6964            // wire things up
6965            // TODO: not DRY
6966            props.calendarApi.currentDataManager = this;
6967            emitter.setThisContext(props.calendarApi);
6968            emitter.setOptions(currentViewData.options);
6969            var calendarContext = {
6970                dateEnv: optionsData.dateEnv,
6971                options: optionsData.calendarOptions,
6972                pluginHooks: optionsData.pluginHooks,
6973                calendarApi: props.calendarApi,
6974                dispatch: this.dispatch,
6975                emitter: emitter,
6976                getCurrentData: this.getCurrentData,
6977            };
6978            var currentDate = state.currentDate, dateProfile = state.dateProfile;
6979            if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack
6980                dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
6981            }
6982            currentDate = reduceCurrentDate(currentDate, action);
6983            dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);
6984            if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
6985                currentDate = dateProfile.currentRange.start;
6986            }
6987            var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);
6988            var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext);
6989            var isEventsLoading = computeEventSourcesLoading(eventSources);
6989 // BAD. also called in this func in computeIsLoading
6990            var renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?
6991                (state.renderableEventStore || eventStore) : // try from previous state
6992                eventStore;
6993            var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj
6994            var eventUiBySource = this.buildEventUiBySource(eventSources);
6995            var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
6996            var newState = {
6997                dynamicOptionOverrides: dynamicOptionOverrides,
6998                currentViewType: currentViewType,
6999                currentDate: currentDate,
7000                dateProfile: dateProfile,
7001                eventSources: eventSources,
7002                eventStore: eventStore,
7003                renderableEventStore: renderableEventStore,
7004                selectionConfig: selectionConfig,
7005                eventUiBases: eventUiBases,
7006                businessHours: this.parseContextBusinessHours(calendarContext),
7007                dateSelection: reduceDateSelection(state.dateSelection, action),
7008                eventSelection: reduceSelectedEvent(state.eventSelection, action),
7009                eventDrag: reduceEventDrag(state.eventDrag, action),
7010                eventResize: reduceEventResize(state.eventResize, action),
7011            };
7012            var contextAndState = __assign(__assign({}, calendarContext), newState);
7013            for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) {
7014                var reducer = _c[_i];
7015                __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value
7016            }
7017            var wasLoading = computeIsLoading(state, calendarContext);
7018            var isLoading = computeIsLoading(newState, calendarContext);
7019            // TODO: use propSetHandlers in plugin system
7020            if (!wasLoading && isLoading) {
7021                emitter.trigger('loading', true);
7022            }
7023            else if (wasLoading && !isLoading) {
7024                emitter.trigger('loading', false);
7025            }
7026            this.state = newState;
7027            if (props.onAction) {
7028                props.onAction(action);
7029            }
7030        };
7031        CalendarDataManager.prototype.updateData = function () {
7032            var _a = this, props = _a.props, state = _a.state;
7033            var oldData = this.data;
7034            var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);
7035            var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);
7036            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);
7037            var changeHandlers = optionsData.pluginHooks.optionChangeHandlers;
7038            var oldCalendarOptions = oldData && oldData.calendarOptions;
7039            var newCalendarOptions = optionsData.calendarOptions;
7040            if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {
7041                if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {
7042                    // hack
7043                    state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);
7044                    state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv);
7045                }
7046                for (var optionName in changeHandlers) {
7047                    if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {
7048                        changeHandlers[optionName](newCalendarOptions[optionName], data);
7049                    }
7050                }
7051            }
7052            if (props.onData) {
7053                props.onData(data);
7054            }
7055        };
7056        CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) {
7057            // TODO: blacklist options that are handled by optionChangeHandlers
7058            var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra;
7059            warnUnknownOptions(extra);
7060            var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);
7061            var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults);
7062            var theme = this.buildTheme(refinedOptions, pluginHooks);
7063            var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi);
7064            return {
7065                calendarOptions: refinedOptions,
7066                pluginHooks: pluginHooks,
7067                dateEnv: dateEnv,
7068                viewSpecs: viewSpecs,
7069                theme: theme,
7070                toolbarConfig: toolbarConfig,
7071                localeDefaults: localeDefaults,
7072                availableRawLocales: availableLocaleData.map,
7073            };
7074        };
7075        // always called from behind a memoizer
7076        CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) {
7077            var _a = mergeRawOptions([
7078                BASE_OPTION_DEFAULTS,
7079                optionOverrides,
7080                dynamicOptionOverrides,
7081            ]), locales = _a.locales, locale = _a.locale;
7082            var availableLocaleData = this.organizeRawLocales(locales);
7083            var availableRawLocales = availableLocaleData.map;
7084            var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;
7085            var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);
7086            var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7087            var extra = {};
7088            var raw = mergeRawOptions([
7089                BASE_OPTION_DEFAULTS,
7090                localeDefaults,
7091                optionOverrides,
7092                dynamicOptionOverrides,
7093            ]);
7094            var refined = {};
7095            var currentRaw = this.currentCalendarOptionsInput;
7096            var currentRefined = this.currentCalendarOptionsRefined;
7097            var anyChanges = false;
7098            for (var optionName in raw) {
7099                if (optionName !== 'plugins') { // because plugins is special-cased
7100                    if (raw[optionName] === currentRaw[optionName] ||
7101                        (COMPLEX_OPTION_COMPARATORS[optionName] &&
7102                            (optionName in currentRaw) &&
7103                            COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) {
7104                        refined[optionName] = currentRefined[optionName];
7105                    }
7106                    else if (refiners[optionName]) {
7107                        refined[optionName] = refiners[optionName](raw[optionName]);
7108                        anyChanges = true;
7109                    }
7110                    else {
7111                        extra[optionName] = currentRaw[optionName];
7112                    }
7113                }
7114            }
7115            if (anyChanges) {
7116                this.currentCalendarOptionsInput = raw;
7117                this.currentCalendarOptionsRefined = refined;
7118            }
7119            return {
7120                rawOptions: this.currentCalendarOptionsInput,
7121                refinedOptions: this.currentCalendarOptionsRefined,
7122                pluginHooks: pluginHooks,
7123                availableLocaleData: availableLocaleData,
7124                localeDefaults: localeDefaults,
7125                extra: extra,
7126            };
7127        };
7128        CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) {
7129            var viewSpec = optionsData.viewSpecs[viewType];
7130            if (!viewSpec) {
7131                throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins");
7132            }
7133            var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra;
7134            warnUnknownOptions(extra);
7135            var dateProfileGenerator = this.buildDateProfileGenerator({
7136                dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,
7137                duration: viewSpec.duration,
7138                durationUnit: viewSpec.durationUnit,
7139                usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,
7140                dateEnv: optionsData.dateEnv,
7141                calendarApi: this.props.calendarApi,
7142                slotMinTime: refinedOptions.slotMinTime,
7143                slotMaxTime: refinedOptions.slotMaxTime,
7144                showNonCurrentDates: refinedOptions.showNonCurrentDates,
7145                dayCount: refinedOptions.dayCount,
7146                dateAlignment: refinedOptions.dateAlignment,
7147                dateIncrement: refinedOptions.dateIncrement,
7148                hiddenDays: refinedOptions.hiddenDays,
7149                weekends: refinedOptions.weekends,
7150                nowInput: refinedOptions.now,
7151                validRangeInput: refinedOptions.validRange,
7152                visibleRangeInput: refinedOptions.visibleRange,
7153                monthMode: refinedOptions.monthMode,
7154                fixedWeekCount: refinedOptions.fixedWeekCount,
7155            });
7156            var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);
7157            return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi };
7158        };
7159        CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {
7160            var raw = mergeRawOptions([
7161                BASE_OPTION_DEFAULTS,
7162                viewSpec.optionDefaults,
7163                localeDefaults,
7164                optionOverrides,
7165                viewSpec.optionOverrides,
7166                dynamicOptionOverrides,
7167            ]);
7168            var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7169            var refined = {};
7170            var currentRaw = this.currentViewOptionsInput;
7171            var currentRefined = this.currentViewOptionsRefined;
7172            var anyChanges = false;
7173            var extra = {};
7174            for (var optionName in raw) {
7175                if (raw[optionName] === currentRaw[optionName]) {
7176                    refined[optionName] = currentRefined[optionName];
7177                }
7178                else {
7179                    if (raw[optionName] === this.currentCalendarOptionsInput[optionName]) {
7180                        if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop
7181                            refined[optionName] = this.currentCalendarOptionsRefined[optionName];
7182                        }
7183                    }
7184                    else if (refiners[optionName]) {
7185                        refined[optionName] = refiners[optionName](raw[optionName]);
7186                    }
7187                    else {
7188                        extra[optionName] = raw[optionName];
7189                    }
7190                    anyChanges = true;
7191                }
7192            }
7193            if (anyChanges) {
7194                this.currentViewOptionsInput = raw;
7195                this.currentViewOptionsRefined = refined;
7196            }
7197            return {
7198                rawOptions: this.currentViewOptionsInput,
7199                refinedOptions: this.currentViewOptionsRefined,
7200                extra: extra,
7201            };
7202        };
7203        return CalendarDataManager;
7204    }());
7205    function buildDateEnv(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {
7206        var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);
7207        return new DateEnv({
7208            calendarSystem: 'gregory',
7209            timeZone: timeZone,
7210            namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,
7211            locale: locale,
7212            weekNumberCalculation: weekNumberCalculation,
7213            firstDay: firstDay,
7214            weekText: weekText,
7215            cmdFormatter: pluginHooks.cmdFormatter,
7216            defaultSeparator: defaultSeparator,
7217        });
7218    }
7219    function buildTheme(options, pluginHooks) {
7220        var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;
7221        return new ThemeClass(options);
7222    }
7223    function buildDateProfileGenerator(props) {
7224        var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator;
7225        return new DateProfileGeneratorClass(props);
7226    }
7227    function buildViewApi(type, getCurrentData, dateEnv) {
7228        return new ViewApi(type, getCurrentData, dateEnv);
7229    }
7230    function buildEventUiBySource(eventSources) {
7231        return mapHash(eventSources, function (eventSource) { return eventSource.ui; });
7232    }
7233    function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
7234        var eventUiBases = { '': eventUiSingleBase };
7235        for (var defId in eventDefs) {
7236            var def = eventDefs[defId];
7237            if (def.sourceId && eventUiBySource[def.sourceId]) {
7238                eventUiBases[defId] = eventUiBySource[def.sourceId];
7239            }
7240        }
7241        return eventUiBases;
7242    }
7243    function buildViewUiProps(calendarContext) {
7244        var options = calendarContext.options;
7245        return {
7246            eventUiSingleBase: createEventUi({
7247                display: options.eventDisplay,
7248                editable: options.editable,
7249                startEditable: options.eventStartEditable,
7250                durationEditable: options.eventDurationEditable,
7251                constraint: options.eventConstraint,
7252                overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,
7253                allow: options.eventAllow,
7254                backgroundColor: options.eventBackgroundColor,
7255                borderColor: options.eventBorderColor,
7256                textColor: options.eventTextColor,
7257                color: options.eventColor,
7258                // classNames: options.eventClassNames // render hook will handle this
7259            }, calendarContext),
7260            selectionConfig: createEventUi({
7261                constraint: options.selectConstraint,
7262                overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,
7263                allow: options.selectAllow,
7264            }, calendarContext),
7265        };
7266    }
7267    function computeIsLoading(state, context) {
7268        for (var _i = 0, _a = context.pluginHooks.isLoadingFuncs; _i < _a.length; _i++) {
7269            var isLoadingFunc = _a[_i];
7270            if (isLoadingFunc(state)) {
7271                return true;
7272            }
7273        }
7274        return false;
7275    }
7276    function parseContextBusinessHours(calendarContext) {
7277        return parseBusinessHours(calendarContext.options.businessHours, calendarContext);
7278    }
7279    function warnUnknownOptions(options, viewName) {
7280        for (var optionName in options) {
7281            console.warn("Unknown option '" + optionName + "'" +
7282                (viewName ? " for view '" + viewName + "'" : ''));
7283        }
7284    }
7285
7286    // TODO: move this to react plugin?
7287    var CalendarDataProvider = /** @class */ (function (_super) {
7288        __extends(CalendarDataProvider, _super);
7289        function CalendarDataProvider(props) {
7290            var _this = _super.call(this, props) || this;
7291            _this.handleData = function (data) {
7292                if (!_this.dataManager) { // still within initial run, before assignment in constructor
7293                    // eslint-disable-next-line react/no-direct-mutation-state
7294                    _this.state = data; // can't use setState yet
7295                }
7296                else {
7297                    _this.setState(data);
7298                }
7299            };
7300            _this.dataManager = new CalendarDataManager({
7301                optionOverrides: props.optionOverrides,
7302                calendarApi: props.calendarApi,
7303                onData: _this.handleData,
7304            });
7305            return _this;
7306        }
7307        CalendarDataProvider.prototype.render = function () {
7308            return this.props.children(this.state);
7309        };
7310        CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) {
7311            var newOptionOverrides = this.props.optionOverrides;
7312            if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData
7313                this.dataManager.resetOptions(newOptionOverrides);
7314            }
7315        };
7316        return CalendarDataProvider;
7317    }(Component));
7318
7319    // HELPERS
7320    /*
7321    if nextDayThreshold is specified, slicing is done in an all-day fashion.
7322    you can get nextDayThreshold from context.nextDayThreshold
7323    */
7324    function sliceEvents(props, allDay) {
7325        return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;
7326    }
7327
7328    var NamedTimeZoneImpl = /** @class */ (function () {
7329        function NamedTimeZoneImpl(timeZoneName) {
7330            this.timeZoneName = timeZoneName;
7331        }
7332        return NamedTimeZoneImpl;
7333    }());
7334
7335    var SegHierarchy = /** @class */ (function () {
7336        function SegHierarchy() {
7337            // settings
7338            this.strictOrder = false;
7339            this.allowReslicing = false;
7340            this.maxCoord = -1; // -1 means no max
7341            this.maxStackCnt = -1; // -1 means no max
7342            this.levelCoords = []; // ordered
7343            this.entriesByLevel = []; // parallel with levelCoords
7344            this.stackCnts = {}; // TODO: use better technique!?
7345        }
7346        SegHierarchy.prototype.addSegs = function (segInputs) {
7347            var hiddenEntries = [];
7348            for (var _i = 0, segInputs_1 = segInputs; _i < segInputs_1.length; _i++) {
7349                var segInput = segInputs_1[_i];
7350                this.insertEntry({
7351                    segInput: segInput,
7352                    spanStart: segInput.spanStart,
7353                    spanEnd: segInput.spanEnd,
7354                    thickness: segInput.thickness,
7355                }, hiddenEntries);
7356            }
7357            return hiddenEntries;
7358        };
7359        SegHierarchy.prototype.insertEntry = function (entry, hiddenEntries) {
7360            var insertion = this.findInsertion(entry);
7361            if (this.isInsertionValid(insertion, entry)) {
7362                this.insertEntryAt(entry, insertion);
7363                return 1;
7364            }
7365            return this.handleInvalidInsertion(insertion, entry, hiddenEntries);
7366        };
7367        SegHierarchy.prototype.isInsertionValid = function (insertion, entry) {
7368            return (this.maxCoord === -1 || insertion.levelCoord + entry.thickness <= this.maxCoord) &&
7369                (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt);
7370        };
7371        SegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) {
7372            if (this.allowReslicing && insertion.touchingEntry) {
7373                return this.splitEntry(entry, insertion.touchingEntry, hiddenEntries);
7374            }
7375            hiddenEntries.push(entry);
7376            return 0;
7377        };
7378        SegHierarchy.prototype.splitEntry = function (entry, barrier, hiddenEntries) {
7379            var partCnt = 0;
7380            var splitHiddenEntries = [];
7381            if (entry.spanStart < barrier.spanStart) {
7382                partCnt += this.insertEntry(__assign(__assign({}, entry), { spanStart: entry.spanStart, spanEnd: barrier.spanStart }), splitHiddenEntries);
7383            }
7384            if (barrier.spanEnd < entry.spanEnd) {
7385                partCnt += this.insertEntry(__assign(__assign({}, entry), { spanStart: barrier.spanEnd, spanEnd: entry.spanEnd }), splitHiddenEntries);
7386            }
7387            if (partCnt) {
7388                hiddenEntries.push.apply(hiddenEntries, __spreadArray([__assign(__assign({}, entry), { spanStart: Math.max(barrier.spanStart, entry.spanStart), spanEnd: Math.min(barrier.spanEnd, entry.spanEnd) })], splitHiddenEntries));
7389                return partCnt;
7390            }
7391            hiddenEntries.push(entry);
7392            return 0;
7393        };
7394        SegHierarchy.prototype.insertEntryAt = function (entry, insertion) {
7395            var nextLevel = insertion.nextLevel;
7396            // create a new level
7397            if (!nextLevel || this.levelCoords[nextLevel - 1] < insertion.levelCoord) {
7398                insertAt(this.levelCoords, nextLevel, insertion.levelCoord);
7399                insertAt(this.entriesByLevel, nextLevel, [entry]);
7400                // insert into existing level
7401            }
7402            else {
7403                insertAt(this.entriesByLevel[nextLevel - 1], insertion.lateralEnd, entry);
7404            }
7405            this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt;
7406        };
7407        SegHierarchy.prototype.findInsertion = function (newEntry) {
7408            var _a = this, levelCoords = _a.levelCoords, entriesByLevel = _a.entriesByLevel, stackCnts = _a.stackCnts, strictOrder = _a.strictOrder;
7409            var levelCnt = levelCoords.length;
7410            var level; // running value while iterating all segs
7411            var levelCoord; // "
7412            var lateralStart = 0; // "
7413            var lateralEnd = 0; // "
7414            var resCoord = 0; // the levelCoord for newSeg
7415            var touchingEntry = null;
7416            for (level = 0; level < levelCnt; level += 1) {
7417                levelCoord = levelCoords[level];
7418                // if the current level is past the placed entry, we have found a good
7419                // empty space and can stop. only if not strict-ordering mode.
7420                if (!strictOrder && levelCoord >= resCoord + newEntry.thickness) {
7421                    break;
7422                }
7423                var entries = entriesByLevel[level];
7424                var entry = void 0;
7425                var searchRes = binarySearch(entries, newEntry.spanStart, getEntrySpanEnd);
7426                lateralStart = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one
7427                lateralEnd = lateralStart;
7428                while ( // loop through entries that horizontally intersect
7429                (entry = entries[lateralEnd]) && // but not past the whole entry list
7430                    entry.spanStart < newEntry.spanEnd) {
7431                    if (strictOrder ||
7432                        ( // vertically intersects?
7433                        resCoord < levelCoord + entry.thickness &&
7434                            resCoord + newEntry.thickness > levelCoord)) {
7435                        // push down the potential destination
7436                        touchingEntry = entry;
7437                        resCoord = levelCoord + entry.thickness; // move to bottom of colliding entry
7438                    }
7439                    lateralEnd += 1;
7440                }
7441            }
7442            return {
7443                levelCoord: resCoord,
7444                nextLevel: level,
7445                lateralStart: lateralStart,
7446                lateralEnd: lateralEnd,
7447                touchingEntry: touchingEntry,
7448                stackCnt: touchingEntry ? stackCnts[buildEntryKey(touchingEntry
7448)] + 1 : 0,
7449            };
7450        };
7451        // sorted by levelCoord (lowest to highest)
7452        SegHierarchy.prototype.toRects = function () {
7453            var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords;
7454            var levelCnt = entriesByLevel.length;
7455            var rects = [];
7456            for (var level = 0; level < levelCnt; level += 1) {
7457                var entries = entriesByLevel[level];
7458                var levelCoord = levelCoords[level];
7459                for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
7460                    var entry = entries_1[_i];
7461                    rects.push(__assign(__assign({}, entry), { levelCoord: levelCoord }));
7462                }
7463            }
7464            return rects;
7465        };
7466        return SegHierarchy;
7467    }());
7468    function getEntrySpanEnd(entry) {
7469        return entry.spanEnd;
7470    }
7471    function buildEntryKey(entry) {
7472        return entry.segInput.index + ':' + entry.spanStart;
7473    }
7474    // returns groups with entries sorted by input order
7475    function groupIntersectingEntries(entries) {
7476        var merges = [];
7477        for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) {
7478            var entry = entries_2[_i];
7479            var filteredMerges = [];
7480            var hungryMerge = {
7481                spanStart: entry.spanStart,
7482                spanEnd: entry.spanEnd,
7483                entries: [entry],
7484            };
7485            for (var _a = 0, merges_1 = merges; _a < merges_1.length; _a++) {
7486                var merge = merges_1[_a];
7487                if (merge.spanStart < hungryMerge.spanEnd && merge.spanEnd > hungryMerge.spanStart) { // collides?
7488                    hungryMerge = {
7489                        spanStart: Math.min(merge.spanStart, hungryMerge.spanStart),
7490                        spanEnd: Math.max(merge.spanEnd, hungryMerge.spanEnd),
7491                        entries: merge.entries.concat(hungryMerge.entries), // keep preexisting merge's items first. maintains order
7492                    };
7493                }
7494                else {
7495                    filteredMerges.push(merge);
7496                }
7497            }
7498            filteredMerges.push(hungryMerge);
7499            merges = filteredMerges;
7500        }
7501        return merges;
7502    }
7503    // general util
7504    // ---------------------------------------------------------------------------------------------------------------------
7505    function insertAt(arr, index, item) {
7506        arr.splice(index, 0, item);
7507    }
7508    function binarySearch(a, searchVal, getItemVal) {
7509        var startIndex = 0;
7510        var endIndex = a.length; // exclusive
7511        if (!endIndex || searchVal < getItemVal(a[startIndex])) { // no items OR before first item
7512            return [0, 0];
7513        }
7514        if (searchVal > getItemVal(a[endIndex - 1])) { // after last item
7515            return [endIndex, 0];
7516        }
7517        while (startIndex < endIndex) {
7518            var middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);
7519            var middleVal = getItemVal(a[middleIndex]);
7520            if (searchVal < middleVal) {
7521                endIndex = middleIndex;
7522            }
7523            else if (searchVal > middleVal) {
7524                startIndex = middleIndex + 1;
7525            }
7526            else { // equal!
7527                return [middleIndex, 1];
7528            }
7529        }
7530        return [startIndex, 0];
7531    }
7532
7533    var Interaction = /** @class */ (function () {
7534        function Interaction(settings) {
7535            this.component = settings.component;
7536            this.isHitComboAllowed = settings.isHitComboAllowed || null;
7537        }
7538        Interaction.prototype.destroy = function () {
7539        };
7540        return Interaction;
7541    }());
7542    function parseInteractionSettings(component, input) {
7543        return {
7544            component: component,
7545            el: input.el,
7546            useEventCenter: input.useEventCenter != null ? input.useEventCenter : true,
7547            isHitComboAllowed: input.isHitComboAllowed || null,
7548        };
7549    }
7550    function interactionSettingsToStore(settings) {
7551        var _a;
7552        return _a = {},
7553            _a[settings.component.uid] = settings,
7554            _a;
7555    }
7556    // global state
7557    var interactionSettingsStore = {};
7558
7559    /*
7560    An abstraction for a dragging interaction originating on an event.
7561    Does higher-level things than PointerDragger, such as possibly:
7562    - a "mirror" that moves with the pointer
7563    - a minimum number of pixels or other criteria for a true drag to begin
7564
7565    subclasses must emit:
7566    - pointerdown
7567    - dragstart
7568    - dragmove
7569    - pointerup
7570    - dragend
7571    */
7572    var ElementDragging = /** @class */ (function () {
7573        function ElementDragging(el, selector) {
7574            this.emitter = new Emitter();
7575        }
7576        ElementDragging.prototype.destroy = function () {
7577        };
7578        ElementDragging.prototype.setMirrorIsVisible = function (bool) {
7579            // optional if subclass doesn't want to support a mirror
7580        };
7581        ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
7582            // optional if subclass doesn't want to support a mirror
7583        };
7584        ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
7585            // optional
7586        };
7587        return ElementDragging;
7588    }());
7589
7590    // TODO: get rid of this in favor of options system,
7591    // tho it's really easy to access this globally rather than pass thru options.
7592    var config = {};
7593
7594    /*
7595    Information about what will happen when an external element is dragged-and-dropped
7596    onto a calendar. Contains information for creating an event.
7597    */
7598    var DRAG_META_REFINERS = {
7599        startTime: createDuration,
7600        duration: createDuration,
7601        create: Boolean,
7602        sourceId: String,
7603    };
7604    function parseDragMeta(raw) {
7605        var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra;
7606        return {
7607            startTime: refined.startTime || null,
7608            duration: refined.duration || null,
7609            create: refined.create != null ? refined.create : true,
7610            sourceId: refined.sourceId,
7611            leftoverProps: extra,
7612        };
7613    }
7614
7615    var ToolbarSection = /** @class */ (function (_super) {
7616        __extends(ToolbarSection, _super);
7617        function ToolbarSection() {
7618            return _super !== null && _super.apply(this, arguments) || this;
7619        }
7620        ToolbarSection.prototype.render = function () {
7621            var _this = this;
7622            var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); });
7623            return createElement.apply(void 0, __spreadArray(['div', { className: 'fc-toolbar-chunk' }], children));
7624        };
7625        ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) {
7626            var props = this.props;
7627            var theme = this.context.theme;
7628            var children = [];
7629            var isOnlyButtons = true;
7630            for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) {
7631                var widget = widgetGroup_1[_i];
7632                var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon;
7633                if (buttonName === 'title') {
7634                    isOnlyButtons = false;
7635                    children.push(createElement("h2", { className: "fc-toolbar-title" }, props.title));
7636                }
7637                else {
7638                    var ariaAttrs = buttonIcon ? { 'aria-label': buttonName } : {};
7639                    var buttonClasses = ["fc-" + buttonName + "-button", theme.getClass('button')];
7640                    if (buttonName === props.activeButton) {
7641                        buttonClasses.push(theme.getClass('buttonActive'));
7642                    }
7643                    var isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||
7644                        (!props.isPrevEnabled && buttonName === 'prev') ||
7645                        (!props.isNextEnabled && buttonName === 'next');
7646                    children.push(createElement("button", __assign({ disabled: isDisabled, className: buttonClasses.join(' '), onClick: buttonClick, type: "button" }, ariaAttrs), buttonText || (buttonIcon ? createElement("span", { className: buttonIcon }) : '')));
7647                }
7648            }
7649            if (children.length > 1) {
7650                var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || '';
7651                return createElement.apply(void 0, __spreadArray(['div', { className: groupClassName }], children));
7652            }
7653            return children[0];
7654        };
7655        return ToolbarSection;
7656    }(BaseComponent));
7657
7658    var Toolbar = /** @class */ (function (_super) {
7659        __extends(Toolbar, _super);
7660        function Toolbar() {
7661            return _super !== null && _super.apply(this, arguments) || this;
7662        }
7663        Toolbar.prototype.render = function () {
7664            var _a = this.props, model = _a.model, extraClassName = _a.extraClassName;
7665            var forceLtr = false;
7666            var startContent;
7667            var endContent;
7668            var centerContent = model.center;
7669            if (model.left) {
7670                forceLtr = true;
7671                startContent = model.left;
7672            }
7673            else {
7674                startContent = model.start;
7675            }
7676            if (model.right) {
7677                forceLtr = true;
7678                endContent = model.right;
7679            }
7680            else {
7681                endContent = model.end;
7682            }
7683            var classNames = [
7684                extraClassName || '',
7685                'fc-toolbar',
7686                forceLtr ? 'fc-toolbar-ltr' : '',
7687            ];
7688            return (createElement("div", { className: classNames.join(' ') },
7689                this.renderSection('start', startContent || []),
7690                this.renderSection('center', centerContent || []),
7691                this.renderSection('end', endContent || [])));
7692        };
7693        Toolbar.prototype.renderSection = function (key, widgetGroups) {
7694            var props = this.props;
7695            return (createElement(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled }));
7696        };
7697        return Toolbar;
7698    }(BaseComponent));
7699
7700    // TODO: do function component?
7701    var ViewContainer = /** @class */ (function (_super) {
7702        __extends(ViewContainer, _super);
7703        function ViewContainer() {
7704            var _this = _super !== null && _super.apply(this, arguments) || this;
7705            _this.state = {
7706                availableWidth: null,
7707            };
7708            _this.handleEl = function (el) {
7709                _this.el = el;
7710                setRef(_this.props.elRef, el);
7711                _this.updateAvailableWidth();
7712            };
7713            _this.handleResize = function () {
7714                _this.updateAvailableWidth();
7715            };
7716            return _this;
7717        }
7718        ViewContainer.prototype.render = function () {
7719            var _a = this, props = _a.props, state = _a.state;
7720            var aspectRatio = props.aspectRatio;
7721            var classNames = [
7722                'fc-view-harness',
7723                (aspectRatio || props.liquid || props.height)
7724                    ? 'fc-view-harness-active' // harness controls the height
7725                    : 'fc-view-harness-passive', // let the view do the height
7726            ];
7727            var height = '';
7728            var paddingBottom = '';
7729            if (aspectRatio) {
7730                if (state.availableWidth !== null) {
7731                    height = state.availableWidth / aspectRatio;
7732                }
7733                else {
7734                    // while waiting to know availableWidth, we can't set height to *zero*
7735                    // because will cause lots of unnecessary scrollbars within scrollgrid.
7736                    // BETTER: don't start rendering ANYTHING yet until we know container width
7737                    // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)
7738                    paddingBottom = (1 / aspectRatio) * 100 + "%";
7739                }
7740            }
7741            else {
7742                height = props.height || '';
7743            }
7744            return (createElement("div", { ref: this.handleEl, onClick: props.onClick, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children));
7745        };
7746        ViewContainer.prototype.componentDidMount = function () {
7747            this.context.addResizeHandler(this.handleResize);
7748        };
7749        ViewContainer.prototype.componentWillUnmount = function () {
7750            this.context.removeResizeHandler(this.handleResize);
7751        };
7752        ViewContainer.prototype.updateAvailableWidth = function () {
7753            if (this.el && // needed. but why?
7754                this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth
7755            ) {
7756                this.setState({ availableWidth: this.el.offsetWidth });
7757            }
7758        };
7759        return ViewContainer;
7760    }(BaseComponent));
7761
7762    /*
7763    Detects when the user clicks on an event within a DateComponent
7764    */
7765    var EventClicking = /** @class */ (function (_super) {
7766        __extends(EventClicking, _super);
7767        function EventClicking(settings) {
7768            var _this = _super.call(this, settings) || this;
7769            _this.handleSegClick = function (ev, segEl) {
7770                var component = _this.component;
7771                var context = component.context;
7772                var seg = getElSeg(segEl);
7773                if (seg && // might be the <div> surrounding the more link
7774                    component.isValidSegDownEl(ev.target)) {
7775                    // our way to simulate a link click for elements that can't be <a> tags
7776                    // grab before trigger fired in case trigger trashes DOM thru rerendering
7777                    var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url');
7778                    var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
7779                    context.emitter.trigger('eventClick', {
7780                        el: segEl,
7781                        event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance),
7782                        jsEvent: ev,
7783                        view: context.viewApi,
7784                    });
7785                    if (url && !ev.defaultPrevented) {
7786                        window.location.href = url;
7787                    }
7788                }
7789            };
7790            _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events
7791            _this.handleSegClick);
7792            return _this;
7793        }
7794        return EventClicking;
7795    }(Interaction));
7796
7797    /*
7798    Triggers events and adds/removes core classNames when the user's pointer
7799    enters/leaves event-elements of a component.
7800    */
7801    var EventHovering = /** @class */ (function (_super) {
7802        __extends(EventHovering, _super);
7803        function EventHovering(settings) {
7804            var _this = _super.call(this, settings) || this;
7805            // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
7806            _this.handleEventElRemove = function (el) {
7807                if (el === _this.currentSegEl) {
7808                    _this.handleSegLeave(null, _this.currentSegEl);
7809                }
7810            };
7811            _this.handleSegEnter = function (ev, segEl) {
7812                if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
7813                    _this.currentSegEl = segEl;
7814                    _this.triggerEvent('eventMouseEnter', ev, segEl);
7815                }
7816            };
7817            _this.handleSegLeave = function (ev, segEl) {
7818                if (_this.currentSegEl) {
7819                    _this.currentSegEl = null;
7820                    _this.triggerEvent('eventMouseLeave', ev, segEl);
7821                }
7822            };
7823            _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events
7824            _this.handleSegEnter, _this.handleSegLeave);
7825            return _this;
7826        }
7827        EventHovering.prototype.destroy = function () {
7828            this.removeHoverListeners();
7829        };
7830        EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
7831            var component = this.component;
7832            var context = component.context;
7833            var seg = getElSeg(segEl);
7834            if (!ev || component.isValidSegDownEl(ev.target)) {
7835                context.emitter.trigger(publicEvName, {
7836                    el: segEl,
7837                    event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance),
7838                    jsEvent: ev,
7839                    view: context.viewApi,
7840                });
7841            }
7842        };
7843        return EventHovering;
7844    }(Interaction));
7845
7846    var CalendarContent = /** @class */ (function (_super) {
7847        __extends(CalendarContent, _super);
7848        function CalendarContent() {
7849            var _this = _super !== null && _super.apply(this, arguments) || this;
7850            _this.buildViewContext = memoize(buildViewContext);
7851            _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
7852            _this.buildToolbarProps = memoize(buildToolbarProps);
7853            _this.handleNavLinkClick = buildDelegationHandler('a[data-navlink]', _this._handleNavLinkClick.bind(_this));
7854            _this.headerRef = createRef();
7855            _this.footerRef = createRef();
7856            _this.interactionsStore = {};
7857            // Component Registration
7858            // -----------------------------------------------------------------------------------------------------------------
7859            _this.registerInteractiveComponent = function (component, settingsInput) {
7860                var settings = parseInteractionSettings(component, settingsInput);
7861                var DEFAULT_INTERACTIONS = [
7862                    EventClicking,
7863                    EventHovering,
7864                ];
7865                var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions);
7866                var interactions = interactionClasses.map(function (TheInteractionClass) { return new TheInteractionClass(settings); });
7867                _this.interactionsStore[component.uid] = interactions;
7868                interactionSettingsStore[component.uid] = settings;
7869            };
7870            _this.unregisterInteractiveComponent = function (component) {
7871                for (var _i = 0, _a = _this.interactionsStore[component.uid]; _i < _a.length; _i++) {
7872                    var listener = _a[_i];
7873                    listener.destroy();
7874                }
7875                delete _this.interactionsStore[component.uid];
7876                delete interactionSettingsStore[component.uid];
7877            };
7878            // Resizing
7879            // -----------------------------------------------------------------------------------------------------------------
7880            _this.resizeRunner = new DelayedRunner(function () {
7881                _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ?
7882                _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi });
7883            });
7884            _this.handleWindowResize = function (ev) {
7885                var options = _this.props.options;
7886                if (options.handleWindowResize &&
7887                    ev.target === window // avoid jqui events
7888                ) {
7889                    _this.resizeRunner.request(options.windowResizeDelay);
7890                }
7891            };
7892            return _this;
7893        }
7894        /*
7895        renders INSIDE of an outer div
7896        */
7897        CalendarContent.prototype.render = function () {
7898            var props = this.props;
7899            var toolbarConfig = props.toolbarConfig, options = props.options;
7900            var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer????
7901            props.viewTitle);
7902            var viewVGrow = false;
7903            var viewHeight = '';
7904            var viewAspectRatio;
7905            if (props.isHeightAuto || props.forPrint) {
7906                viewHeight = '';
7907            }
7908            else if (options.height != null) {
7909                viewVGrow = true;
7910            }
7911            else if (options.contentHeight != null) {
7912                viewHeight = options.contentHeight;
7913            }
7914            else {
7915                viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall
7916            }
7917            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);
7918            return (createElement(ViewContextType.Provider, { value: viewContext },
7919                toolbarConfig.headerToolbar && (createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.headerToolbar }, toolbarProps))),
7920                createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, onClick: this.handleNavLinkClick },
7921                    this.renderView(props),
7922                    this.buildAppendContent()),
7923                toolbarConfig.footerToolbar && (createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footerToolbar }, toolbarProps)))));
7924        };
7925        CalendarContent.prototype.componentDidMount = function () {
7926            var props = this.props;
7927            this.calendarInteractions = props.pluginHooks.calendarInteractions
7928                .map(function (CalendarInteractionClass) { return new CalendarInteractionClass(props); });
7929            window.addEventListener('resize', this.handleWindowResize);
7930            var propSetHandlers = props.pluginHooks.propSetHandlers;
7931            for (var propName in propSetHandlers) {
7932                propSetHandlers[propName](props[propName], props);
7933            }
7934        };
7935        CalendarContent.prototype.componentDidUpdate = function (prevProps) {
7936            var props = this.props;
7937            var propSetHandlers = props.pluginHooks.propSetHandlers;
7938            for (var propName in propSetHandlers) {
7939                if (props[propName] !== prevProps[propName]) {
7940                    propSetHandlers[propName](props[propName], props);
7941                }
7942            }
7943        };
7944        CalendarContent.prototype.componentWillUnmount = function () {
7945            window.removeEventListener('resize', this.handleWindowResize);
7946            this.resizeRunner.clear();
7947            for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
7948                var interaction = _a[_i];
7949                interaction.destroy();
7950            }
7951            this.props.emitter.trigger('_unmount');
7952        };
7953        CalendarContent.prototype._handleNavLinkClick = function (ev, anchorEl) {
7954            var _a = this.props, dateEnv = _a.dateEnv, options = _a.options, calendarApi = _a.calendarApi;
7955            var navLinkOptions = anchorEl.getAttribute('data-navlink');
7956            navLinkOptions = navLinkOptions ? JSON.parse(navLinkOptions) : {};
7957            var dateMarker = dateEnv.createMarker(navLinkOptions.date);
7958            var viewType = navLinkOptions.type;
7959            var customAction = viewType === 'day' ? options.navLinkDayClick :
7960                viewType === 'week' ? options.navLinkWeekClick : null;
7961            if (typeof customAction === 'function') {
7962                customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev);
7963            }
7964            else {
7965                if (typeof customAction === 'string') {
7966                    viewType = customAction;
7967                }
7968                calendarApi.zoomTo(dateMarker, viewType);
7969            }
7970        };
7971        CalendarContent.prototype.buildAppendContent = function () {
7972            var props = this.props;
7973            var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); });
7974            return createElement.apply(void 0, __spreadArray([Fragment, {}], children));
7975        };
7976        CalendarContent.prototype.renderView = function (props) {
7977            var pluginHooks = props.pluginHooks;
7978            var viewSpec = props.viewSpec;
7979            var viewProps = {
7980                dateProfile: props.dateProfile,
7981                businessHours: props.businessHours,
7982                eventStore: props.renderableEventStore,
7983                eventUiBases: props.eventUiBases,
7984                dateSelection: props.dateSelection,
7985                eventSelection: props.eventSelection,
7986                eventDrag: props.eventDrag,
7987                eventResize: props.eventResize,
7988                isHeightAuto: props.isHeightAuto,
7989                forPrint: props.forPrint,
7990            };
7991            var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);
7992            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
7993                var transformer = transformers_1[_i];
7994                __assign(viewProps, transformer.transform(viewProps, props));
7995            }
7996            var ViewComponent = viewSpec.component;
7997            return (createElement(ViewComponent, __assign({}, viewProps)));
7998        };
7999        return CalendarContent;
8000    }(PureComponent));
8001    function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {
8002        // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid
8003        var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason
8004        var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);
8005        var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);
8006        return {
8007            title: title,
8008            activeButton: viewSpec.type,
8009            isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
8010            isPrevEnabled: prevInfo.isValid,
8011            isNextEnabled: nextInfo.isValid,
8012        };
8013    }
8014    // Plugin
8015    // -----------------------------------------------------------------------------------------------------------------
8016    function buildViewPropTransformers(theClasses) {
8017        return theClasses.map(function (TheClass) { return new TheClass(); });
8018    }
8019
8020    var CalendarRoot = /** @class */ (function (_super) {
8021        __extends(CalendarRoot, _super);
8022        function CalendarRoot() {
8023            var _this = _super !== null && _super.apply(this, arguments) || this;
8024            _this.state = {
8025                forPrint: false,
8026            };
8027            _this.handleBeforePrint = function () {
8028                _this.setState({ forPrint: true });
8029            };
8030            _this.handleAfterPrint = function () {
8031                _this.setState({ forPrint: false });
8032            };
8033            return _this;
8034        }
8035        CalendarRoot.prototype.render = function () {
8036            var props = this.props;
8037            var options = props.options;
8038            var forPrint = this.state.forPrint;
8039            var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto';
8040            var height = (!isHeightAuto && options.height != null) ? options.height : '';
8041            var classNames = [
8042                'fc',
8043                forPrint ? 'fc-media-print' : 'fc-media-screen',
8044                "fc-direction-" + options.direction,
8045                props.theme.getClass('root'),
8046            ];
8047            if (!getCanVGrowWithinCell()) {
8048                classNames.push('fc-liquid-hack');
8049            }
8050            return props.children(classNames, height, isHeightAuto, forPrint);
8051        };
8052        CalendarRoot.prototype.componentDidMount = function () {
8053            var emitter = this.props.emitter;
8054            emitter.on('_beforeprint', this.handleBeforePrint);
8055            emitter.on('_afterprint', this.handleAfterPrint);
8056        };
8057        CalendarRoot.prototype.componentWillUnmount = function () {
8058            var emitter = this.props.emitter;
8059            emitter.off('_beforeprint', this.handleBeforePrint);
8060            emitter.off('_afterprint', this.handleAfterPrint);
8061        };
8062        return CalendarRoot;
8063    }(BaseComponent));
8064
8065    // Computes a default column header formatting string if `colFormat` is not explicitly defined
8066    function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
8067        // if more than one week row, or if there are a lot of columns with not much space,
8068        // put just the day numbers will be in each cell
8069        if (!datesRepDistinctDays || dayCnt > 10) {
8070            return createFormatter({ weekday: 'short' }); // "Sat"
8071        }
8072        if (dayCnt > 1) {
8073            return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12"
8074        }
8075        return createFormatter({ weekday: 'long' }); // "Saturday"
8076    }
8077
8078    var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no
8079    function renderInner$1(hookProps) {
8080        return hookProps.text;
8081    }
8082
8083    var TableDateCell = /** @class */ (function (_super) {
8084        __extends(TableDateCell, _super);
8085        function TableDateCell() {
8086            return _super !== null && _super.apply(this, arguments) || this;
8087        }
8088        TableDateCell.prototype.render = function () {
8089            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi;
8090            var props = this.props;
8091            var date = props.date, dateProfile = props.dateProfile;
8092            var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile);
8093            var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme));
8094            var text = dateEnv.format(date, props.dayHeaderFormat);
8095            // if colCnt is 1, we are already in a day-view and don't need a navlink
8096            var navLinkAttrs = (options.navLinks && !dayMeta.isDisabled && props.colCnt > 1)
8097                ? { 'data-navlink': buildNavLinkData(date), tabIndex: 0 }
8098                : {};
8099            var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta);
8100            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, 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),
8101                createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement("a", __assign({ ref: innerElRef, className: [
8102                        'fc-col-header-cell-cushion',
8103                        props.isSticky ? 'fc-sticky' : '',
8104                    ].join(' ') }, navLinkAttrs), innerContent))))); }));
8105        };
8106        return TableDateCell;
8107    }(BaseComponent));
8108
8109    var TableDowCell = /** @class */ (function (_super) {
8110        __extends(TableDowCell, _super);
8111        function TableDowCell() {
8112            return _super !== null && _super.apply(this, arguments) || this;
8113        }
8114        TableDowCell.prototype.render = function () {
8115            var props = this.props;
8116            var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options;
8117            var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT
8118            var dateMeta = {
8119                dow: props.dow,
8120                isDisabled: false,
8121                isFuture: false,
8122                isPast: false,
8123                isToday: false,
8124                isOther: false,
8125            };
8126            var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []);
8127            var text = dateEnv.format(date, props.dayHeaderFormat);
8128            var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public?
8129                date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text });
8130            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, 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),
8131                createElement("div", { className: "fc-scrollgrid-sync-inner" },
8132                    createElement("a", { className: [
8133                            'fc-col-header-cell-cushion',
8134                            props.isSticky ? 'fc-sticky' : '',
8135                        ].join(' '), ref: innerElRef }, innerContent)))); }));
8136        };
8137        return TableDowCell;
8138    }(BaseComponent));
8139
8140    var NowTimer = /** @class */ (function (_super) {
8141        __extends(NowTimer, _super);
8142        function NowTimer(props, context) {
8143            var _this = _super.call(this, props, context) || this;
8144            _this.initialNowDate = getNow(context.options.now, context.dateEnv);
8145            _this.initialNowQueriedMs = new Date().valueOf();
8146            _this.state = _this.computeTiming().currentState;
8147            return _this;
8148        }
8149        NowTimer.prototype.render = function () {
8150            var _a = this, props = _a.props, state = _a.state;
8151            return props.children(state.nowDate, state.todayRange);
8152        };
8153        NowTimer.prototype.componentDidMount = function () {
8154            this.setTimeout();
8155        };
8156        NowTimer.prototype.componentDidUpdate = function (prevProps) {
8157            if (prevProps.unit !== this.props.unit) {
8158                this.clearTimeout();
8159                this.setTimeout();
8160            }
8161        };
8162        NowTimer.prototype.componentWillUnmount = function () {
8163            this.clearTimeout();
8164        };
8165        NowTimer.prototype.computeTiming = function () {
8166            var _a = this, props = _a.props, context = _a.context;
8167            var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs);
8168            var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);
8169            var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));
8170            var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
8171            // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342)
8172            // ensure no longer than a day
8173            waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);
8174            return {
8175                currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },
8176                nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) },
8177                waitMs: waitMs,
8178            };
8179        };
8180        NowTimer.prototype.setTimeout = function () {
8181            var _this = this;
8182            var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs;
8183            this.timeoutId = setTimeout(function () {
8184                _this.setState(nextState, function () {
8185                    _this.setTimeout();
8186                });
8187            }, waitMs);
8188        };
8189        NowTimer.prototype.clearTimeout = function () {
8190            if (this.timeoutId) {
8191                clearTimeout(this.timeoutId);
8192            }
8193        };
8194        NowTimer.contextType = ViewContextType;
8195        return NowTimer;
8196    }(Component));
8197    function buildDayRange(date) {
8198        var start = startOfDay(date);
8199        var end = addDays(start, 1);
8200        return { start: start, end: end };
8201    }
8202
8203    var DayHeader = /** @class */ (function (_super) {
8204        __extends(DayHeader, _super);
8205        function DayHeader() {
8206            var _this = _super !== null && _super.apply(this, arguments) || this;
8207            _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter);
8208            return _this;
8209        }
8210        DayHeader.prototype.render = function () {
8211            var context = this.context;
8212            var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro;
8213            var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length);
8214            return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement("tr", null,
8215                renderIntro && renderIntro('day'),
8216                dates.map(function (date) { return (datesRepDistinctDays ? (createElement(TableDateCell, { key: date.toISOString(), date: date, dateProfile: dateProfile, todayRange: todayRange, colCnt: dates.length, dayHeaderFormat: dayHeaderFormat })) : (createElement(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat: dayHeaderFormat }))); }))); }));
8217        };
8218        return DayHeader;
8219    }(BaseComponent));
8220    function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
8221        return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
8222    }
8223
8224    var DaySeriesModel = /** @class */ (function () {
8225        function DaySeriesModel(range, dateProfileGenerator) {
8226            var date = range.start;
8227            var end = range.end;
8228            var indices = [];
8229            var dates = [];
8230            var dayIndex = -1;
8231            while (date < end) { // loop each day from start to end
8232                if (dateProfileGenerator.isHiddenDay(date)) {
8233                    indices.push(dayIndex + 0.5); // mark that it's between indices
8234                }
8235                else {
8236                    dayIndex += 1;
8237                    indices.push(dayIndex);
8238                    dates.push(date);
8239                }
8240                date = addDays(date, 1);
8241            }
8242            this.dates = dates;
8243            this.indices = indices;
8244            this.cnt = dates.length;
8245        }
8246        DaySeriesModel.prototype.sliceRange = function (range) {
8247            var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
8248            var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
8249            var clippedFirstIndex = Math.max(0, firstIndex);
8250            var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
8251            // deal with in-between indices
8252            clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
8253            clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
8254            if (clippedFirstIndex <= clippedLastIndex) {
8255                return {
8256                    firstIndex: clippedFirstIndex,
8257                    lastIndex: clippedLastIndex,
8258                    isStart: firstIndex === clippedFirstIndex,
8259                    isEnd: lastIndex === clippedLastIndex,
8260                };
8261            }
8262            return null;
8263        };
8264        // Given a date, returns its chronolocial cell-index from the first cell of the grid.
8265        // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
8266        // If before the first offset, returns a negative number.
8267        // If after the last offset, returns an offset past the last cell offset.
8268        // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
8269        DaySeriesModel.prototype.getDateDayIndex = function (date) {
8270            var indices = this.indices;
8271            var dayOffset = Math.floor(diffDays(this.dates[0], date));
8272            if (dayOffset < 0) {
8273                return indices[0] - 1;
8274            }
8275            if (dayOffset >= indices.length) {
8276                return indices[indices.length - 1] + 1;
8277            }
8278            return indices[dayOffset];
8279        };
8280        return DaySeriesModel;
8281    }());
8282
8283    var DayTableModel = /** @class */ (function () {
8284        function DayTableModel(daySeries, breakOnWeeks) {
8285            var dates = daySeries.dates;
8286            var daysPerRow;
8287            var firstDay;
8288            var rowCnt;
8289            if (breakOnWeeks) {
8290                // count columns until the day-of-week repeats
8291                firstDay = dates[0].getUTCDay();
8292                for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) {
8293                    if (dates[daysPerRow].getUTCDay() === firstDay) {
8294                        break;
8295                    }
8296                }
8297                rowCnt = Math.ceil(dates.length / daysPerRow);
8298            }
8299            else {
8300                rowCnt = 1;
8301                daysPerRow = dates.length;
8302            }
8303            this.rowCnt = rowCnt;
8304            this.colCnt = daysPerRow;
8305            this.daySeries = daySeries;
8306            this.cells = this.buildCells();
8307            this.headerDates = this.buildHeaderDates();
8308        }
8309        DayTableModel.prototype.buildCells = function () {
8310            var rows = [];
8311            for (var row = 0; row < this.rowCnt; row += 1) {
8312                var cells = [];
8313                for (var col = 0; col < this.colCnt; col += 1) {
8314                    cells.push(this.buildCell(row, col));
8315                }
8316                rows.push(cells);
8317            }
8318            return rows;
8319        };
8320        DayTableModel.prototype.buildCell = function (row, col) {
8321            var date = this.daySeries.dates[row * this.colCnt + col];
8322            return {
8323                key: date.toISOString(),
8324                date: date,
8325            };
8326        };
8327        DayTableModel.prototype.buildHeaderDates = function () {
8328            var dates = [];
8329            for (var col = 0; col < this.colCnt; col += 1) {
8330                dates.push(this.cells[0][col].date);
8331            }
8332            return dates;
8333        };
8334        DayTableModel.prototype.sliceRange = function (range) {
8335            var colCnt = this.colCnt;
8336            var seriesSeg = this.daySeries.sliceRange(range);
8337            var segs = [];
8338            if (seriesSeg) {
8339                var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
8340                var index = firstIndex;
8341                while (index <= lastIndex) {
8342                    var row = Math.floor(index / colCnt);
8343                    var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
8344                    segs.push({
8345                        row: row,
8346                        firstCol: index % colCnt,
8347                        lastCol: (nextIndex - 1) % colCnt,
8348                        isStart: seriesSeg.isStart && index === firstIndex,
8349                        isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex,
8350                    });
8351                    index = nextIndex;
8352                }
8353            }
8354            return segs;
8355        };
8356        return DayTableModel;
8357    }());
8358
8359    var Slicer = /** @class */ (function () {
8360        function Slicer() {
8361            this.sliceBusinessHours = memoize(this._sliceBusinessHours);
8362            this.sliceDateSelection = memoize(this._sliceDateSpan);
8363            this.sliceEventStore = memoize(this._sliceEventStore);
8364            this.sliceEventDrag = memoize(this._sliceInteraction);
8365            this.sliceEventResize = memoize(this._sliceInteraction);
8366            this.forceDayIfListItem = false; // hack
8367        }
8368        Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) {
8369            var extraArgs = [];
8370            for (var _i = 4; _i < arguments.length; _i++) {
8371                extraArgs[_i - 4] = arguments[_i];
8372            }
8373            var eventUiBases = props.eventUiBases;
8374            var eventSegs = this.sliceEventStore.apply(this, __spreadArray([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs));
8375            return {
8376                dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArray([props.dateSelection, eventUiBases, context], extraArgs)),
8377                businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArray([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)),
8378                fgEventSegs: eventSegs.fg,
8379                bgEventSegs: eventSegs.bg,
8380                eventDrag: this.sliceEventDrag.apply(this, __spreadArray([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
8381                eventResize: this.sliceEventResize.apply(this, __spreadArray([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
8382                eventSelection: props.eventSelection,
8383            }; // TODO: give interactionSegs?
8384        };
8385        Slicer.prototype.sliceNowDate = function (// does not memoize
8386        date, context) {
8387            var extraArgs = [];
8388            for (var _i = 2; _i < arguments.length; _i++) {
8389                extraArgs[_i - 2] = arguments[_i];
8390            }
8391            return this._sliceDateSpan.apply(this, __spreadArray([{ range: { start: date, end: addMs(date, 1) }, allDay: false },
8392                {},
8393                context], extraArgs));
8394        };
8395        Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) {
8396            var extraArgs = [];
8397            for (var _i = 4; _i < arguments.length; _i++) {
8398                extraArgs[_i - 4] = arguments[_i];
8399            }
8400            if (!businessHours) {
8401                return [];
8402            }
8403            return this._sliceEventStore.apply(this, __spreadArray([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context),
8404                {},
8405                dateProfile,
8406                nextDayThreshold], extraArgs)).bg;
8407        };
8408        Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) {
8409            var extraArgs = [];
8410            for (var _i = 4; _i < arguments.length; _i++) {
8411                extraArgs[_i - 4] = arguments[_i];
8412            }
8413            if (eventStore) {
8414                var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8415                return {
8416                    bg: this.sliceEventRanges(rangeRes.bg, extraArgs),
8417                    fg: this.sliceEventRanges(rangeRes.fg, extraArgs),
8418                };
8419            }
8420            return { bg: [], fg: [] };
8421        };
8422        Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) {
8423            var extraArgs = [];
8424            for (var _i = 4; _i < arguments.length; _i++) {
8425                extraArgs[_i - 4] = arguments[_i];
8426            }
8427            if (!interaction) {
8428                return null;
8429            }
8430            var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8431            return {
8432                segs: this.sliceEventRanges(rangeRes.fg, extraArgs),
8433                affectedInstances: interaction.affectedEvents.instances,
8434                isEvent: interaction.isEvent,
8435            };
8436        };
8437        Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) {
8438            var extraArgs = [];
8439            for (var _i = 3; _i < arguments.length; _i++) {
8440                extraArgs[_i - 3] = arguments[_i];
8441            }
8442            if (!dateSpan) {
8443                return [];
8444            }
8445            var eventRange = fabricateEventRange(dateSpan, eventUiBases, context);
8446            var segs = this.sliceRange.apply(this, __spreadArray([dateSpan.range], extraArgs));
8447            for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
8448                var seg = segs_1[_a];
8449                seg.eventRange = eventRange;
8450            }
8451            return segs;
8452        };
8453        /*
8454        "complete" seg means it has component and eventRange
8455        */
8456        Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) {
8457            var segs = [];
8458            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
8459                var eventRange = eventRanges_1[_i];
8460                segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs));
8461            }
8462            return segs;
8463        };
8464        /*
8465        "complete" seg means it has component and eventRange
8466        */
8467        Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) {
8468            var dateRange = eventRange.range;
8469            // hack to make multi-day events that are being force-displayed as list-items to take up only one day
8470            if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') {
8471                dateRange = {
8472                    start: dateRange.start,
8473                    end: addDays(dateRange.start, 1),
8474                };
8475            }
8476            var segs = this.sliceRange.apply(this, __spreadArray([dateRange], extraArgs));
8477            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
8478                var seg = segs_2[_i];
8479                seg.eventRange = eventRange;
8480                seg.isStart = eventRange.isStart && seg.isStart;
8481                seg.isEnd = eventRange.isEnd && seg.isEnd;
8482            }
8483            return segs;
8484        };
8485        return Slicer;
8486    }());
8487    /*
8488    for incorporating slotMinTime/slotMaxTime if appropriate
8489    TODO: should be part of DateProfile!
8490    TimelineDateProfile already does this btw
8491    */
8492    function computeActiveRange(dateProfile, isComponentAllDay) {
8493        var range = dateProfile.activeRange;
8494        if (isComponentAllDay) {
8495            return range;
8496        }
8497        return {
8498            start: addMs(range.start, dateProfile.slotMinTime.milliseconds),
8499            end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day
8500        };
8501    }
8502
8503    // high-level segmenting-aware tester functions
8504    // ------------------------------------------------------------------------------------------------------------------------
8505    function isInteractionValid(interaction, dateProfile, context) {
8506        var instances = interaction.mutatedEvents.instances;
8507        for (var instanceId in instances) {
8508            if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
8509                return false;
8510            }
8511        }
8512        return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions
8513    }
8514    function isDateSelectionValid(dateSelection, dateProfile, context) {
8515        if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) {
8516            return false;
8517        }
8518        return isNewPropsValid({ dateSelection: dateSelection }, context);
8519    }
8520    function isNewPropsValid(newProps, context) {
8521        var calendarState = context.getCurrentData();
8522        var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
8523        return (context.pluginHooks.isPropsValid || isPropsValid)(props, context);
8524    }
8525    function isPropsValid(state, context, dateSpanMeta, filterConfig) {
8526        if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
8527        if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) {
8528            return false;
8529        }
8530        if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) {
8531            return false;
8532        }
8533        return true;
8534    }
8535    // Moving Event Validation
8536    // ------------------------------------------------------------------------------------------------------------------------
8537    function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) {
8538        var currentState = context.getCurrentData();
8539        var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
8540        var subjectEventStore = interaction.mutatedEvents;
8541        var subjectDefs = subjectEventStore.defs;
8542        var subjectInstances = subjectEventStore.instances;
8543        var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
8544            state.eventUiBases :
8545            { '': currentState.selectionConfig });
8546        if (filterConfig) {
8547            subjectConfigs = mapHash(subjectConfigs, filterConfig);
8548        }
8549        // exclude the subject events. TODO: exclude defs too?
8550        var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances);
8551        var otherDefs = otherEventStore.defs;
8552        var otherInstances = otherEventStore.instances;
8553        var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
8554        for (var subjectInstanceId in subjectInstances) {
8555            var subjectInstance = subjectInstances[subjectInstanceId];
8556            var subjectRange = subjectInstance.range;
8557            var subjectConfig = subjectConfigs[subjectInstance.defId];
8558            var subjectDef = subjectDefs[subjectInstance.defId];
8559            // constraint
8560            if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) {
8561                return false;
8562            }
8563            // overlap
8564            var eventOverlap = context.options.eventOverlap;
8565            var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null;
8566            for (var otherInstanceId in otherInstances) {
8567                var otherInstance = otherInstances[otherInstanceId];
8568                // intersect! evaluate
8569                if (rangesIntersect(subjectRange, otherInstance.range)) {
8570                    var otherOverlap = otherConfigs[otherInstance.defId].overlap;
8571                    // consider the other event's overlap. only do this if the subject event is a "real" event
8572                    if (otherOverlap === false && interaction.isEvent) {
8573                        return false;
8574                    }
8575                    if (subjectConfig.overlap === false) {
8576                        return false;
8577                    }
8578                    if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event
8579                    new EventApi(context, subjectDef, subjectInstance))) {
8580                        return false;
8581                    }
8582                }
8583            }
8584            // allow (a function)
8585            var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state
8586            for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
8587                var subjectAllow = _a[_i];
8588                var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay });
8589                var origDef = calendarEventStore.defs[subjectDef.defId];
8590                var origInstance = calendarEventStore.instances[subjectInstanceId];
8591                var eventApi = void 0;
8592                if (origDef) { // was previously in the calendar
8593                    eventApi = new EventApi(context, origDef, origInstance);
8594                }
8595                else { // was an external event
8596                    eventApi = new EventApi(context, subjectDef); // no instance, because had no dates
8597                }
8598                if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) {
8599                    return false;
8600                }
8601            }
8602        }
8603        return true;
8604    }
8605    // Date Selection Validation
8606    // ------------------------------------------------------------------------------------------------------------------------
8607    function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) {
8608        var relevantEventStore = state.eventStore;
8609        var relevantDefs = relevantEventStore.defs;
8610        var relevantInstances = relevantEventStore.instances;
8611        var selection = state.dateSelection;
8612        var selectionRange = selection.range;
8613        var selectionConfig = context.getCurrentData().selectionConfig;
8614        if (filterConfig) {
8615            selectionConfig = filterConfig(selectionConfig);
8616        }
8617        // constraint
8618        if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) {
8619            return false;
8620        }
8621        // overlap
8622        var selectOverlap = context.options.selectOverlap;
8623        var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null;
8624        for (var relevantInstanceId in relevantInstances) {
8625            var relevantInstance = relevantInstances[relevantInstanceId];
8626            // intersect! evaluate
8627            if (rangesIntersect(selectionRange, relevantInstance.range)) {
8628                if (selectionConfig.overlap === false) {
8629                    return false;
8630                }
8631                if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) {
8632                    return false;
8633                }
8634            }
8635        }
8636        // allow (a function)
8637        for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
8638            var selectionAllow = _a[_i];
8639            var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection);
8640            if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) {
8641                return false;
8642            }
8643        }
8644        return true;
8645    }
8646    // Constraint Utils
8647    // ------------------------------------------------------------------------------------------------------------------------
8648    function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) {
8649        for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
8650            var constraint = constraints_1[_i];
8651            if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) {
8652                return false;
8653            }
8654        }
8655        return true;
8656    }
8657    function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
8658    otherEventStore, // for if constraint is an even group ID
8659    businessHoursUnexpanded, // for if constraint is 'businessHours'
8660    context) {
8661        if (constraint === 'businessHours') {
8662            return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context));
8663        }
8664        if (typeof constraint === 'string') { // an group ID
8665            return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { return eventDef.groupId === constraint; }));
8666        }
8667        if (typeof constraint === 'object' && constraint) { // non-null object
8668            return eventStoreToRanges(expandRecurring(constraint, subjectRange, context));
8669        }
8670        return []; // if it's false
8671    }
8672    // TODO: move to event-store file?
8673    function eventStoreToRanges(eventStore) {
8674        var instances = eventStore.instances;
8675        var ranges = [];
8676        for (var instanceId in instances) {
8677            ranges.push(instances[instanceId].range);
8678        }
8679        return ranges;
8680    }
8681    // TODO: move to geom file?
8682    function anyRangesContainRange(outerRanges, innerRange) {
8683        for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
8684            var outerRange = outerRanges_1[_i];
8685            if (rangeContainsRange(outerRange, innerRange)) {
8686                return true;
8687            }
8688        }
8689        return false;
8690    }
8691
8692    var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/;
8693    var Scroller = /** @class */ (function (_super) {
8694        __extends(Scroller, _super);
8695        function Scroller() {
8696            var _this = _super !== null && _super.apply(this, arguments) || this;
8697            _this.handleEl = function (el) {
8698                _this.el = el;
8699                setRef(_this.props.elRef, el);
8700            };
8701            return _this;
8702        }
8703        Scroller.prototype.render = function () {
8704            var props = this.props;
8705            var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute;
8706            var isAbsolute = liquid && liquidIsAbsolute;
8707            var className = ['fc-scroller'];
8708            if (liquid) {
8709                if (liquidIsAbsolute) {
8710                    className.push('fc-scroller-liquid-absolute');
8711                }
8712                else {
8713                    className.push('fc-scroller-liquid');
8714                }
8715            }
8716            return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: {
8717                    overflowX: props.overflowX,
8718                    overflowY: props.overflowY,
8719                    left: (isAbsolute && -(props.overcomeLeft || 0)) || '',
8720                    right: (isAbsolute && -(props.overcomeRight || 0)) || '',
8721                    bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '',
8722                    marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '',
8723                    marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '',
8724                    marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '',
8725                    maxHeight: props.maxHeight || '',
8726                } }, props.children));
8727        };
8728        Scroller.prototype.needsXScrolling = function () {
8729            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
8730                return false;
8731            }
8732            // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers.
8733            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
8734            // inner-child margins and absolute positioning
8735            var el = this.el;
8736            var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth();
8737            var children = el.children;
8738            for (var i = 0; i < children.length; i += 1) {
8739                var childEl = children[i];
8740                if (childEl.getBoundingClientRect().width > realClientWidth) {
8741                    return true;
8742                }
8743            }
8744            return false;
8745        };
8746        Scroller.prototype.needsYScrolling = function () {
8747            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
8748                return false;
8749            }
8750            // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers.
8751            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
8752            // inner-child margins and absolute positioning
8753            var el = this.el;
8754            var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth();
8755            var children = el.children;
8756            for (var i = 0; i < children.length; i += 1) {
8757                var childEl = children[i];
8758                if (childEl.getBoundingClientRect().height > realClientHeight) {
8759                    return true;
8760                }
8761            }
8762            return false;
8763        };
8764        Scroller.prototype.getXScrollbarWidth = function () {
8765            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
8766                return 0;
8767            }
8768            return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important?
8769        };
8770        Scroller.prototype.getYScrollbarWidth = function () {
8771            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
8772                return 0;
8773            }
8774            return this.el.offsetWidth - this.el.clientWidth;
8774 // only works because we guarantee no borders. TODO: add to CSS with important?
8775        };
8776        return Scroller;
8777    }(BaseComponent));
8778
8779    /*
8780    TODO: somehow infer OtherArgs from masterCallback?
8781    TODO: infer RefType from masterCallback if provided
8782    */
8783    var RefMap = /** @class */ (function () {
8784        function RefMap(masterCallback) {
8785            var _this = this;
8786            this.masterCallback = masterCallback;
8787            this.currentMap = {};
8788            this.depths = {};
8789            this.callbackMap = {};
8790            this.handleValue = function (val, key) {
8791                var _a = _this, depths = _a.depths, currentMap = _a.currentMap;
8792                var removed = false;
8793                var added = false;
8794                if (val !== null) {
8795                    // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore
8796                    removed = (key in currentMap);
8797                    currentMap[key] = val;
8798                    depths[key] = (depths[key] || 0) + 1;
8799                    added = true;
8800                }
8801                else {
8802                    depths[key] -= 1;
8803                    if (!depths[key]) {
8804                        delete currentMap[key];
8805                        delete _this.callbackMap[key];
8806                        removed = true;
8807                    }
8808                }
8809                if (_this.masterCallback) {
8810                    if (removed) {
8811                        _this.masterCallback(null, String(key));
8812                    }
8813                    if (added) {
8814                        _this.masterCallback(val, String(key));
8815                    }
8816                }
8817            };
8818        }
8819        RefMap.prototype.createRef = function (key) {
8820            var _this = this;
8821            var refCallback = this.callbackMap[key];
8822            if (!refCallback) {
8823                refCallback = this.callbackMap[key] = function (val) {
8824                    _this.handleValue(val, String(key));
8825                };
8826            }
8827            return refCallback;
8828        };
8829        // TODO: check callers that don't care about order. should use getAll instead
8830        // NOTE: this method has become less valuable now that we are encouraged to map order by some other index
8831        // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect"
8832        RefMap.prototype.collect = function (startIndex, endIndex, step) {
8833            return collectFromHash(this.currentMap, startIndex, endIndex, step);
8834        };
8835        RefMap.prototype.getAll = function () {
8836            return hashValuesToArray(this.currentMap);
8837        };
8838        return RefMap;
8839    }());
8840
8841    function computeShrinkWidth(chunkEls) {
8842        var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink');
8843        var largestWidth = 0;
8844        for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) {
8845            var shrinkCell = shrinkCells_1[_i];
8846            largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell));
8847        }
8848        return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits
8849    }
8850    function getSectionHasLiquidHeight(props, sectionConfig) {
8851        return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well)
8852    }
8853    function getAllowYScrolling(props, sectionConfig) {
8854        return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars
8855            getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars
8856    }
8857    // TODO: ONLY use `arg`. force out internal function to use same API
8858    function renderChunkContent(sectionConfig, chunkConfig, arg) {
8859        var expandRows = arg.expandRows;
8860        var content = typeof chunkConfig.content === 'function' ?
8861            chunkConfig.content(arg) :
8862            createElement('table', {
8863                className: [
8864                    chunkConfig.tableClassName,
8865                    sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '',
8866                ].join(' '),
8867                style: {
8868                    minWidth: arg.tableMinWidth,
8869                    width: arg.clientWidth,
8870                    height: expandRows ? arg.clientHeight : '', // css `height` on a <table> serves as a min-height
8871                },
8872            }, arg.tableColGroupNode, createElement('tbody', {}, typeof chunkConfig.rowContent === 'function' ? chunkConfig.rowContent(arg) : chunkConfig.rowContent));
8873        return content;
8874    }
8875    function isColPropsEqual(cols0, cols1) {
8876        return isArraysEqual(cols0, cols1, isPropsEqual);
8877    }
8878    function renderMicroColGroup(cols, shrinkWidth) {
8879        var colNodes = [];
8880        /*
8881        for ColProps with spans, it would have been great to make a single <col span="">
8882        HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans.
8883        SOLUTION: making individual <col> elements makes Chrome behave.
8884        */
8885        for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) {
8886            var colProps = cols_1[_i];
8887            var span = colProps.span || 1;
8888            for (var i = 0; i < span; i += 1) {
8889                colNodes.push(createElement("col", { style: {
8890                        width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''),
8891                        minWidth: colProps.minWidth || '',
8892                    } }));
8893            }
8894        }
8895        return createElement.apply(void 0, __spreadArray(['colgroup', {}], colNodes));
8896    }
8897    function sanitizeShrinkWidth(shrinkWidth) {
8898        /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth
8899        4 accounts for 2 2-pixel borders. TODO: better solution? */
8900        return shrinkWidth == null ? 4 : shrinkWidth;
8901    }
8902    function hasShrinkWidth(cols) {
8903        for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) {
8904            var col = cols_2[_i];
8905            if (col.width === 'shrink') {
8906                return true;
8907            }
8908        }
8909        return false;
8910    }
8911    function getScrollGridClassNames(liquid, context) {
8912        var classNames = [
8913            'fc-scrollgrid',
8914            context.theme.getClass('table'),
8915        ];
8916        if (liquid) {
8917            classNames.push('fc-scrollgrid-liquid');
8918        }
8919        return classNames;
8920    }
8921    function getSectionClassNames(sectionConfig, wholeTableVGrow) {
8922        var classNames = [
8923            'fc-scrollgrid-section',
8924            "fc-scrollgrid-section-" + sectionConfig.type,
8925            sectionConfig.className, // used?
8926        ];
8927        if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) {
8928            classNames.push('fc-scrollgrid-section-liquid');
8929        }
8930        if (sectionConfig.isSticky) {
8931            classNames.push('fc-scrollgrid-section-sticky');
8932        }
8933        return classNames;
8934    }
8935    function renderScrollShim(arg) {
8936        return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: {
8937                width: arg.clientWidth,
8938                minWidth: arg.tableMinWidth,
8939            } }));
8940    }
8941    function getStickyHeaderDates(options) {
8942        var stickyHeaderDates = options.stickyHeaderDates;
8943        if (stickyHeaderDates == null || stickyHeaderDates === 'auto') {
8944            stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto';
8945        }
8946        return stickyHeaderDates;
8947    }
8948    function getStickyFooterScrollbar(options) {
8949        var stickyFooterScrollbar = options.stickyFooterScrollbar;
8950        if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') {
8951            stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto';
8952        }
8953        return stickyFooterScrollbar;
8954    }
8955
8956    var SimpleScrollGrid = /** @class */ (function (_super) {
8957        __extends(SimpleScrollGrid, _super);
8958        function SimpleScrollGrid() {
8959            var _this = _super !== null && _super.apply(this, arguments) || this;
8960            _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time
8961            // yucky to memoize VNodes, but much more efficient for consumers
8962            _this.renderMicroColGroup = memoize(renderMicroColGroup);
8963            _this.scrollerRefs = new RefMap();
8964            _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this));
8965            _this.state = {
8966                shrinkWidth: null,
8967                forceYScrollbars: false,
8968                scrollerClientWidths: {},
8969                scrollerClientHeights: {},
8970            };
8971            // TODO: can do a really simple print-view. dont need to join rows
8972            _this.handleSizing = function () {
8973                _this.setState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims()));
8974            };
8975            return _this;
8976        }
8977        SimpleScrollGrid.prototype.render = function () {
8978            var _a = this, props = _a.props, state = _a.state, context = _a.context;
8979            var sectionConfigs = props.sections || [];
8980            var cols = this.processCols(props.cols);
8981            var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth);
8982            var classNames = getScrollGridClassNames(props.liquid, context);
8983            if (props.collapsibleWidth) {
8984                classNames.push('fc-scrollgrid-collapsible');
8985            }
8986            // TODO: make DRY
8987            var configCnt = sectionConfigs.length;
8988            var configI = 0;
8989            var currentConfig;
8990            var headSectionNodes = [];
8991            var bodySectionNodes = [];
8992            var footSectionNodes = [];
8993            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {
8994                headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode));
8995                configI += 1;
8996            }
8997            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') {
8998                bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode));
8999                configI += 1;
9000            }
9001            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') {
9002                footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode));
9003                configI += 1;
9004            }
9005            // firefox bug: when setting height on table and there is a thead or tfoot,
9006            // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524)
9007            // use getCanVGrowWithinCell as a way to detect table-stupid firefox.
9008            // if so, use a simpler dom structure, jam everything into a lone tbody.
9009            var isBuggy = !getCanVGrowWithinCell();
9010            return createElement('table', {
9011                className: classNames.join(' '),
9012                style: { height: props.height },
9013            }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArray(['thead', {}
9013], headSectionNodes)), Boolean(!isBuggy && bodySectionNodes.length) && createElement.apply(void 0, __spreadArray(['tbody', {}], bodySectionNodes)), Boolean(!isBuggy && footSectionNodes.length) && createElement.apply(void 0, __spreadArray(['tfoot', {}], footSectionNodes)), isBuggy && createElement.apply(void 0, __spreadArray(__spreadArray(__spreadArray(['tbody', {}], headSectionNodes), bodySectionNodes), footSectionNodes)));
9014        };
9015        SimpleScrollGrid.prototype.renderSection = function (sectionConfig, microColGroupNode) {
9016            if ('outerContent' in sectionConfig) {
9017                return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent));
9018            }
9019            return (createElement("tr", { key: sectionConfig.key, className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk)));
9020        };
9021        SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, microColGroupNode, chunkConfig) {
9022            if ('outerContent' in chunkConfig) {
9023                return chunkConfig.outerContent;
9024            }
9025            var props = this.props;
9026            var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights;
9027            var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config?
9028            var isLiquid = getSectionHasLiquidHeight(props, sectionConfig);
9029            // for `!props.liquid` - is WHOLE scrollgrid natural height?
9030            // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars
9031            var overflowY = !props.liquid ? 'visible' :
9032                forceYScrollbars ? 'scroll' :
9033                    !needsYScrolling ? 'hidden' :
9034                        'auto';
9035            var sectionKey = sectionConfig.key;
9036            var content = renderChunkContent(sectionConfig, chunkConfig, {
9037                tableColGroupNode: microColGroupNode,
9038                tableMinWidth: '',
9039                clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null,
9040                clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null,
9041                expandRows: sectionConfig.expandRows,
9042                syncRowHeights: false,
9043                rowSyncHeights: [],
9044                reportRowHeightChange: function () { },
9045            });
9046            return (createElement("td", { ref: chunkConfig.elRef },
9047                createElement("div", { className: "fc-scroller-harness" + (isLiquid ? ' fc-scroller-harness-liquid' : '') },
9048                    createElement(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */, maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute // because its within a harness
9049                        : true }, content))));
9050        };
9051        SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) {
9052            var section = getSectionByKey(this.props.sections, key);
9053            if (section) {
9054                setRef(section.chunk.scrollerElRef, scrollerEl);
9055            }
9056        };
9057        SimpleScrollGrid.prototype.componentDidMount = function () {
9058            this.handleSizing();
9059            this.context.addResizeHandler(this.handleSizing);
9060        };
9061        SimpleScrollGrid.prototype.componentDidUpdate = function () {
9062            // TODO: need better solution when state contains non-sizing things
9063            this.handleSizing();
9064        };
9065        SimpleScrollGrid.prototype.componentWillUnmount = function () {
9066            this.context.removeResizeHandler(this.handleSizing);
9067        };
9068        SimpleScrollGrid.prototype.computeShrinkWidth = function () {
9069            return hasShrinkWidth(this.props.cols)
9070                ? computeShrinkWidth(this.scrollerElRefs.getAll())
9071                : 0;
9072        };
9073        SimpleScrollGrid.prototype.computeScrollerDims = function () {
9074            var scrollbarWidth = getScrollbarWidths();
9075            var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs;
9076            var forceYScrollbars = false;
9077            var scrollerClientWidths = {};
9078            var scrollerClientHeights = {};
9079            for (var sectionKey in scrollerRefs.currentMap) {
9080                var scroller = scrollerRefs.currentMap[sectionKey];
9081                if (scroller && scroller.needsYScrolling()) {
9082                    forceYScrollbars = true;
9083                    break;
9084                }
9085            }
9086            for (var _i = 0, _b = this.props.sections; _i < _b.length; _i++) {
9087                var section = _b[_i];
9088                var sectionKey = section.key;
9089                var scrollerEl = scrollerElRefs.currentMap[sectionKey];
9090                if (scrollerEl) {
9091                    var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders
9092                    scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars
9093                        ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future
9094                        : 0));
9095                    scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height);
9096                }
9097            }
9098            return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights };
9099        };
9100        return SimpleScrollGrid;
9101    }(BaseComponent));
9102    SimpleScrollGrid.addStateEquality({
9103        scrollerClientWidths: isPropsEqual,
9104        scrollerClientHeights: isPropsEqual,
9105    });
9106    function getSectionByKey(sections, key) {
9107        for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) {
9108            var section = sections_1[_i];
9109            if (section.key === key) {
9110                return section;
9111            }
9112        }
9113        return null;
9114    }
9115
9116    var EventRoot = /** @class */ (function (_super) {
9117        __extends(EventRoot, _super);
9118        function EventRoot() {
9119            var _this = _super !== null && _super.apply(this, arguments) || this;
9120            _this.elRef = createRef();
9121            return _this;
9122        }
9123        EventRoot.prototype.render = function () {
9124            var _a = this, props = _a.props, context = _a.context;
9125            var options = context.options;
9126            var seg = props.seg;
9127            var eventRange = seg.eventRange;
9128            var ui = eventRange.ui;
9129            var hookProps = {
9130                event: new EventApi(context, eventRange.def, eventRange.instance),
9131                view: context.viewApi,
9132                timeText: props.timeText,
9133                textColor: ui.textColor,
9134                backgroundColor: ui.backgroundColor,
9135                borderColor: ui.borderColor,
9136                isDraggable: !props.disableDragging && computeSegDraggable(seg, context),
9137                isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context),
9138                isEndResizable: !props.disableResizing && computeSegEndResizable(seg),
9139                isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),
9140                isStart: Boolean(seg.isStart),
9141                isEnd: Boolean(seg.isEnd),
9142                isPast: Boolean(props.isPast),
9143                isFuture: Boolean(props.isFuture),
9144                isToday: Boolean(props.isToday),
9145                isSelected: Boolean(props.isSelected),
9146                isDragging: Boolean(props.isDragging),
9147                isResizing: Boolean(props.isResizing),
9148            };
9149            var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames);
9150            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); }));
9151        };
9152        EventRoot.prototype.componentDidMount = function () {
9153            setElSeg(this.elRef.current, this.props.seg);
9154        };
9155        /*
9156        need to re-assign seg to the element if seg changes, even if the element is the same
9157        */
9158        EventRoot.prototype.componentDidUpdate = function (prevProps) {
9159            var seg = this.props.seg;
9160            if (seg !== prevProps.seg) {
9161                setElSeg(this.elRef.current, seg);
9162            }
9163        };
9164        return EventRoot;
9165    }(BaseComponent));
9166
9167    // should not be a purecomponent
9168    var StandardEvent = /** @class */ (function (_super) {
9169        __extends(StandardEvent, _super);
9170        function StandardEvent() {
9171            return _super !== null && _super.apply(this, arguments) || this;
9172        }
9173        StandardEvent.prototype.render = function () {
9174            var _a = this, props = _a.props, context = _a.context;
9175            var seg = props.seg;
9176            var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat;
9177            var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd);
9178            return (createElement(EventRoot, { seg: seg, timeText: timeText, disableDragging: props.disableDragging, disableResizing: props.disableResizing, defaultContent: props.defaultContent || renderInnerContent$4, 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
9178oncat(classNames).join(' '), style: {
9179                    borderColor: hookProps.borderColor,
9180                    backgroundColor: hookProps.backgroundColor,
9181                }, ref: rootElRef }, getSegAnchorAttrs$1(seg)),
9182                createElement("div", { className: "fc-event-main", ref: innerElRef, style: { color: hookProps.textColor } }, innerContent),
9183                hookProps.isStartResizable &&
9184                    createElement("div", { className: "fc-event-resizer fc-event-resizer-start" }),
9185                hookProps.isEndResizable &&
9186                    createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))); }));
9187        };
9188        return StandardEvent;
9189    }(BaseComponent));
9190    function renderInnerContent$4(innerProps) {
9191        return (createElement("div", { className: "fc-event-main-frame" },
9192            innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)),
9193            createElement("div", { className: "fc-event-title-container" },
9194                createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))));
9195    }
9196    function getSegAnchorAttrs$1(seg) {
9197        var url = seg.eventRange.def.url;
9198        return url ? { href: url } : {};
9199    }
9200
9201    var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
9202        var options = context.options;
9203        var hookProps = {
9204            isAxis: props.isAxis,
9205            date: context.dateEnv.toDate(props.date),
9206            view: context.viewApi,
9207        };
9208        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children));
9209    })); };
9210
9211    var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' });
9212    var DayCellContent = /** @class */ (function (_super) {
9213        __extends(DayCellContent, _super);
9214        function DayCellContent() {
9215            return _super !== null && _super.apply(this, arguments) || this;
9216        }
9217        DayCellContent.prototype.render = function () {
9218            var _a = this, props = _a.props, context = _a.context;
9219            var options = context.options;
9220            var hookProps = refineDayCellHookProps({
9221                date: props.date,
9222                dateProfile: props.dateProfile,
9223                todayRange: props.todayRange,
9224                showDayNumber: props.showDayNumber,
9225                extraProps: props.extraHookProps,
9226                viewApi: context.viewApi,
9227                dateEnv: context.dateEnv,
9228            });
9229            return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children));
9230        };
9231        return DayCellContent;
9232    }(BaseComponent));
9233    function refineDayCellHookProps(raw) {
9234        var date = raw.date, dateEnv = raw.dateEnv;
9235        var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile);
9236        return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraProps);
9237    }
9238
9239    var DayCellRoot = /** @class */ (function (_super) {
9240        __extends(DayCellRoot, _super);
9241        function DayCellRoot() {
9242            var _this = _super !== null && _super.apply(this, arguments) || this;
9243            _this.refineHookProps = memoizeObjArg(refineDayCellHookProps);
9244            _this.normalizeClassNames = buildClassNameNormalizer();
9245            return _this;
9246        }
9247        DayCellRoot.prototype.render = function () {
9248            var _a = this, props = _a.props, context = _a.context;
9249            var options = context.options;
9250            var hookProps = this.refineHookProps({
9251                date: props.date,
9252                dateProfile: props.dateProfile,
9253                todayRange: props.todayRange,
9254                showDayNumber: props.showDayNumber,
9255                extraProps: props.extraHookProps,
9256                viewApi: context.viewApi,
9257                dateEnv: context.dateEnv,
9258            });
9259            var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled
9260                ? [] // don't use custom classNames if disabled
9261                : this.normalizeClassNames(options.dayCellClassNames, hookProps));
9262            var dataAttrs = hookProps.isDisabled ? {} : {
9263                'data-date': formatDayString(props.date),
9264            };
9265            return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); }));
9266        };
9267        return DayCellRoot;
9268    }(BaseComponent));
9269
9270    function renderFill(fillType) {
9271        return (createElement("div", { className: "fc-" + fillType }));
9272    }
9273    var BgEvent = function (props) { return (createElement(EventRoot, { defaultContent: renderInnerContent$3, seg: props.seg /* uselesss i think */, timeText: "", 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: {
9274            backgroundColor: hookProps.backgroundColor,
9275        } }, innerContent)); })); };
9276    function renderInnerContent$3(props) {
9277        var title = props.event.title;
9278        return title && (createElement("div", { className: "fc-event-title" }, props.event.title));
9279    }
9280
9281    var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
9282        var dateEnv = context.dateEnv, options = context.options;
9283        var date = props.date;
9284        var format = options.weekNumberFormat || props.defaultFormat;
9285        var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well?
9286        var text = dateEnv.format(date, format);
9287        var hookProps = { num: num, text: text, date: date };
9288        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children));
9289    })); };
9290    function renderInner(innerProps) {
9291        return innerProps.text;
9292    }
9293
9294    var PADDING_FROM_VIEWPORT = 10;
9295    var Popover = /** @class */ (function (_super) {
9296        __extends(Popover, _super);
9297        function Popover() {
9298            var _this = _super !== null && _super.apply(this, arguments) || this;
9299            _this.handleRootEl = function (el) {
9300                _this.rootEl = el;
9301                if (_this.props.elRef) {
9302                    setRef(_this.props.elRef, el);
9303                }
9304            };
9305            // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
9306            _this.handleDocumentMousedown = function (ev) {
9307                // only hide the popover if the click happened outside the popover
9308                var target = getEventTargetViaRoot(ev);
9309                if (!_this.rootEl.contains(target)) {
9310                    _this.handleCloseClick();
9311                }
9312            };
9313            _this.handleCloseClick = function () {
9314                var onClose = _this.props.onClose;
9315                if (onClose) {
9316                    onClose();
9317                }
9318            };
9319            return _this;
9320        }
9321        Popover.prototype.render = function () {
9322            var theme = this.context.theme;
9323            var props = this.props;
9324            var classNames = [
9325                'fc-popover',
9326                theme.getClass('popover'),
9327            ].concat(props.extraClassNames || []);
9328            return createPortal(createElement("div", __assign({ className: classNames.join(' ') }, props.extraAttrs, { ref: this.handleRootEl }),
9329                createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') },
9330                    createElement("span", { className: "fc-popover-title" }, props.title),
9331                    createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), onClick: this.handleCloseClick })),
9332                createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl);
9333        };
9334        Popover.prototype.componentDidMount = function () {
9335            document.addEventListener('mousedown', this.handleDocumentMousedown);
9336            this.updateSize();
9337        };
9338        Popover.prototype.componentWillUnmount = function () {
9339            document.removeEventListener('mousedown', this.handleDocumentMousedown);
9340        };
9341        Popover.prototype.updateSize = function () {
9342            var isRtl = this.context.isRtl;
9343            var _a = this.props, alignmentEl = _a.alignmentEl, alignGridTop = _a.alignGridTop;
9344            var rootEl = this.rootEl;
9345            var alignmentRect = computeClippedClientRect(alignmentEl);
9346            if (alignmentRect) {
9347                var popoverDims = rootEl.getBoundingClientRect();
9348                // position relative to viewport
9349                var popoverTop = alignGridTop
9350                    ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top
9351                    : alignmentRect.top;
9352                var popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left;
9353                // constrain
9354                popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT);
9355                popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width);
9356                popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT);
9357                var origin_1 = rootEl.offsetParent.getBoundingClientRect();
9358                applyStyle(rootEl, {
9359                    top: popoverTop - origin_1.top,
9360                    left: popoverLeft - origin_1.left,
9361                });
9362            }
9363        };
9364        return Popover;
9365    }(BaseComponent));
9366
9367    var MorePopover = /** @class */ (function (_super) {
9368        __extends(MorePopover, _super);
9369        function MorePopover() {
9370            var _this = _super !== null && _super.apply(this, arguments) || this;
9371            _this.handleRootEl = function (rootEl) {
9372                _this.rootEl = rootEl;
9373                if (rootEl) {
9374                    _this.context.registerInteractiveComponent(_this, {
9375                        el: rootEl,
9376                        useEventCenter: false,
9377                    });
9378                }
9379                else {
9380                    _this.context.unregisterInteractiveComponent(_this);
9381                }
9382            };
9383            return _this;
9384        }
9385        MorePopover.prototype.render = function () {
9386            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv;
9387            var props = this.props;
9388            var startDate = props.startDate, todayRange = props.todayRange, dateProfile = props.dateProfile;
9389            var title = dateEnv.format(startDate, options.dayPopoverFormat);
9390            return (createElement(DayCellRoot, { date: startDate, dateProfile: dateProfile, todayRange: todayRange, elRef: this.handleRootEl }, function (rootElRef, dayClassNames, dataAttrs) { return (createElement(Popover, { elRef: rootElRef, title: title, extraClassNames: ['fc-more-popover'].concat(dayClassNames), extraAttrs: dataAttrs /* TODO: make these time-based when not whole-day? */, parentEl: props.parentEl, alignmentEl: props.alignmentEl, alignGridTop: props.alignGridTop, onClose: props.onClose },
9391                createElement(DayCellContent, { date: startDate, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent &&
9392                    createElement("div", { className: "fc-more-popover-misc", ref: innerElRef }, innerContent)); }),
9393                props.children)); }));
9394        };
9395        MorePopover.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
9396            var _a = this, rootEl = _a.rootEl, props = _a.props;
9397            if (positionLeft >= 0 && positionLeft < elWidth &&
9398                positionTop >= 0 && positionTop < elHeight) {
9399                return {
9400                    dateProfile: props.dateProfile,
9401                    dateSpan: __assign({ allDay: true, range: {
9402                            start: props.startDate,
9403                            end: props.endDate,
9404                        } }, props.extraDateSpan),
9405                    dayEl: rootEl,
9406                    rect: {
9407                        left: 0,
9408                        top: 0,
9409                        right: elWidth,
9410                        bottom: elHeight,
9411                    },
9412                    layer: 1, // important when comparing with hits from other components
9413                };
9414            }
9415            return null;
9416        };
9417        return MorePopover;
9418    }(DateComponent));
9419
9420    var MoreLinkRoot = /** @class */ (function (_super) {
9421        __extends(MoreLinkRoot, _super);
9422        function MoreLinkRoot() {
9423            var _this = _super !== null && _super.apply(this, arguments) || this;
9424            _this.linkElRef = createRef();
9425            _this.state = {
9426                isPopoverOpen: false,
9427            };
9428            _this.handleClick = function (ev) {
9429                var _a = _this, props = _a.props, context = _a.context;
9430                var moreLinkClick = context.options.moreLinkClick;
9431                var date = computeRange(props).start;
9432                function buildPublicSeg(seg) {
9433                    var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range;
9434                    return {
9435                        event: new EventApi(context, def, instance),
9436                        start: context.dateEnv.toDate(range.start),
9437                        end: context.dateEnv.toDate(range.end),
9438                        isStart: seg.isStart,
9439                        isEnd: seg.isEnd,
9440                    };
9441                }
9442                if (typeof moreLinkClick === 'function') {
9443                    moreLinkClick = moreLinkClick({
9444                        date: date,
9445                        allDay: Boolean(props.allDayDate),
9446                        allSegs: props.allSegs.map(buildPublicSeg),
9447                        hiddenSegs: props.hiddenSegs.map(buildPublicSeg),
9448                        jsEvent: ev,
9449                        view: context.viewApi,
9450                    });
9451                }
9452                if (!moreLinkClick || moreLinkClick === 'popover') {
9453                    _this.setState({ isPopoverOpen: true });
9454                }
9455                else if (typeof moreLinkClick === 'string') { // a view n
9455ame
9456                    context.calendarApi.zoomTo(date, moreLinkClick);
9457                }
9458            };
9459            _this.handlePopoverClose = function () {
9460                _this.setState({ isPopoverOpen: false });
9461            };
9462            return _this;
9463        }
9464        MoreLinkRoot.prototype.render = function () {
9465            var _this = this;
9466            var props = this.props;
9467            return (createElement(ViewContextType.Consumer, null, function (context) {
9468                var viewApi = context.viewApi, options = context.options, calendarApi = context.calendarApi;
9469                var moreLinkText = options.moreLinkText;
9470                var moreCnt = props.moreCnt;
9471                var range = computeRange(props);
9472                var hookProps = {
9473                    num: moreCnt,
9474                    shortText: "+" + moreCnt,
9475                    text: typeof moreLinkText === 'function'
9476                        ? moreLinkText.call(calendarApi, moreCnt)
9477                        : "+" + moreCnt + " " + moreLinkText,
9478                    view: viewApi,
9479                };
9480                return (createElement(Fragment, null,
9481                    Boolean(props.moreCnt) && (createElement(RenderHook, { elRef: _this.linkElRef, hookProps: hookProps, classNames: options.moreLinkClassNames, content: options.moreLinkContent, defaultContent: props.defaultContent || renderMoreLinkInner$1, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, ['fc-more-link'].concat(customClassNames), innerElRef, innerContent, _this.handleClick); })),
9482                    _this.state.isPopoverOpen && (createElement(MorePopover, { startDate: range.start, endDate: range.end, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: props.extraDateSpan, parentEl: _this.parentEl, alignmentEl: props.alignmentElRef.current, alignGridTop: props.alignGridTop, onClose: _this.handlePopoverClose }, props.popoverContent()))));
9483            }));
9484        };
9485        MoreLinkRoot.prototype.componentDidMount = function () {
9486            this.updateParentEl();
9487        };
9488        MoreLinkRoot.prototype.componentDidUpdate = function () {
9489            this.updateParentEl();
9490        };
9491        MoreLinkRoot.prototype.updateParentEl = function () {
9492            if (this.linkElRef.current) {
9493                this.parentEl = elementClosest(this.linkElRef.current, '.fc-view-harness');
9494            }
9495        };
9496        return MoreLinkRoot;
9497    }(BaseComponent));
9498    function renderMoreLinkInner$1(props) {
9499        return props.text;
9500    }
9501    function computeRange(props) {
9502        if (props.allDayDate) {
9503            return {
9504                start: props.allDayDate,
9505                end: addDays(props.allDayDate, 1),
9506            };
9507        }
9508        var hiddenSegs = props.hiddenSegs;
9509        return {
9510            start: computeEarliestSegStart(hiddenSegs),
9511            end: computeLatestSegEnd(hiddenSegs),
9512        };
9513    }
9514    function computeEarliestSegStart(segs) {
9515        return segs.reduce(pickEarliestStart).eventRange.range.start;
9516    }
9517    function pickEarliestStart(seg0, seg1) {
9518        return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1;
9519    }
9520    function computeLatestSegEnd(segs) {
9521        return segs.reduce(pickLatestEnd).eventRange.range.end;
9522    }
9523    function pickLatestEnd(seg0, seg1) {
9524        return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1;
9525    }
9526
9527    // exports
9528    // --------------------------------------------------------------------------------------------------
9529    var version = '5.7.2'; // important to type it, so .d.ts has generic string
9530
9531    var Calendar = /** @class */ (function (_super) {
9532        __extends(Calendar, _super);
9533        function Calendar(el, optionOverrides) {
9534            if (optionOverrides === void 0) { optionOverrides = {}; }
9535            var _this = _super.call(this) || this;
9536            _this.isRendering = false;
9537            _this.isRendered = false;
9538            _this.currentClassNames = [];
9539            _this.customContentRenderId = 0; // will affect custom generated classNames?
9540            _this.handleAction = function (action) {
9541                // actions we know we want to render immediately
9542                switch (action.type) {
9543                    case 'SET_EVENT_DRAG':
9544                    case 'SET_EVENT_RESIZE':
9545                        _this.renderRunner.tryDrain();
9546                }
9547            };
9548            _this.handleData = function (data) {
9549                _this.currentData = data;
9550                _this.renderRunner.request(data.calendarOptions.rerenderDelay);
9551            };
9552            _this.handleRenderRequest = function () {
9553                if (_this.isRendering) {
9554                    _this.isRendered = true;
9555                    var currentData_1 = _this.currentData;
9556                    render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) {
9557                        _this.setClassNames(classNames);
9558                        _this.setHeight(height);
9559                        return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId },
9560                            createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1))));
9561                    }), _this.el);
9562                }
9563                else if (_this.isRendered) {
9564                    _this.isRendered = false;
9565                    unmountComponentAtNode(_this.el);
9566                    _this.setClassNames([]);
9567                    _this.setHeight('');
9568                }
9569                flushToDom();
9570            };
9571            _this.el = el;
9572            _this.renderRunner = new DelayedRunner(_this.handleRenderRequest);
9573            new CalendarDataManager({
9574                optionOverrides: optionOverrides,
9575                calendarApi: _this,
9576                onAction: _this.handleAction,
9577                onData: _this.handleData,
9578            });
9579            return _this;
9580        }
9581        Object.defineProperty(Calendar.prototype, "view", {
9582            get: function () { return this.currentData.viewApi; } // for public API
9583            ,
9584            enumerable: false,
9585            configurable: true
9586        });
9587        Calendar.prototype.render = function () {
9588            var wasRendering = this.isRendering;
9589            if (!wasRendering) {
9590                this.isRendering = true;
9591            }
9592            else {
9593                this.customContentRenderId += 1;
9594            }
9595            this.renderRunner.request();
9596            if (wasRendering) {
9597                this.updateSize();
9598            }
9599        };
9600        Calendar.prototype.destroy = function () {
9601            if (this.isRendering) {
9602                this.isRendering = false;
9603                this.renderRunner.request();
9604            }
9605        };
9606        Calendar.prototype.updateSize = function () {
9607            _super.prototype.updateSize.call(this);
9608            flushToDom();
9609        };
9610        Calendar.prototype.batchRendering = function (func) {
9611            this.renderRunner.pause('batchRendering');
9612            func();
9613            this.renderRunner.resume('batchRendering');
9614        };
9615        Calendar.prototype.pauseRendering = function () {
9616            this.renderRunner.pause('pauseRendering');
9617        };
9618        Calendar.prototype.resumeRendering = function () {
9619            this.renderRunner.resume('pauseRendering', true);
9620        };
9621        Calendar.prototype.resetOptions = function (optionOverrides, append) {
9622            this.currentDataManager.resetOptions(optionOverrides, append);
9623        };
9624        Calendar.prototype.setClassNames = function (classNames) {
9625            if (!isArraysEqual(classNames, this.currentClassNames)) {
9626                var classList = this.el.classList;
9627                for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) {
9628                    var className = _a[_i];
9629                    classList.remove(className);
9630                }
9631                for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) {
9632                    var className = classNames_1[_b];
9633                    classList.add(className);
9634                }
9635                this.currentClassNames = classNames;
9636            }
9637        };
9638        Calendar.prototype.setHeight = function (height) {
9639            applyStyleProp(this.el, 'height', height);
9640        };
9641        return Calendar;
9642    }(CalendarApi));
9643
9644    config.touchMouseIgnoreWait = 500;
9645    var ignoreMouseDepth = 0;
9646    var listenerCnt = 0;
9647    var isWindowTouchMoveCancelled = false;
9648    /*
9649    Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
9650    Tracks when the pointer "drags" on a certain element, meaning down+move+up.
9651
9652    Also, tracks if there was touch-scrolling.
9653    Also, can prevent touch-scrolling from happening.
9654    Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
9655
9656    emits:
9657    - pointerdown
9658    - pointermove
9659    - pointerup
9660    */
9661    var PointerDragging = /** @class */ (function () {
9662        function PointerDragging(containerEl) {
9663            var _this = this;
9664            this.subjectEl = null;
9665            // options that can be directly assigned by caller
9666            this.selector = ''; // will cause subjectEl in all emitted events to be this element
9667            this.handleSelector = '';
9668            this.shouldIgnoreMove = false;
9669            this.shouldWatchScroll = true; // for simulating pointermove on scroll
9670            // internal states
9671            this.isDragging = false;
9672            this.isTouchDragging = false;
9673            this.wasTouchScroll = false;
9674            // Mouse
9675            // ----------------------------------------------------------------------------------------------------
9676            this.handleMouseDown = function (ev) {
9677                if (!_this.shouldIgnoreMouse() &&
9678                    isPrimaryMouseButton(ev) &&
9679                    _this.tryStart(ev)) {
9680                    var pev = _this.createEventFromMouse(ev, true);
9681                    _this.emitter.trigger('pointerdown', pev);
9682                    _this.initScrollWatch(pev);
9683                    if (!_this.shouldIgnoreMove) {
9684                        document.addEventListener('mousemove', _this.handleMouseMove);
9685                    }
9686                    document.addEventListener('mouseup', _this.handleMouseUp);
9687                }
9688            };
9689            this.handleMouseMove = function (ev) {
9690                var pev = _this.createEventFromMouse(ev);
9691                _this.recordCoords(pev);
9692                _this.emitter.trigger('pointermove', pev);
9693            };
9694            this.handleMouseUp = function (ev) {
9695                document.removeEventListener('mousemove', _this.handleMouseMove);
9696                document.removeEventListener('mouseup', _this.handleMouseUp);
9697                _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
9698                _this.cleanup(); // call last so that pointerup has access to props
9699            };
9700            // Touch
9701            // ----------------------------------------------------------------------------------------------------
9702            this.handleTouchStart = function (ev) {
9703                if (_this.tryStart(ev)) {
9704                    _this.isTouchDragging = true;
9705                    var pev = _this.createEventFromTouch(ev, true);
9706                    _this.emitter.trigger('pointerdown', pev);
9707                    _this.initScrollWatch(pev);
9708                    // unlike mouse, need to attach to target, not document
9709                    // https://stackoverflow.com/a/45760014
9710                    var targetEl = ev.target;
9711                    if (!_this.shouldIgnoreMove) {
9712                        targetEl.addEventListener('touchmove', _this.handleTouchMove);
9713                    }
9714                    targetEl.addEventListener('touchend', _this.handleTouchEnd);
9715                    targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
9716                    // attach a handler to get called when ANY scroll action happens on the page.
9717                    // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
9718                    // http://stackoverflow.com/a/32954565/96342
9719                    window.addEventListener('scroll', _this.handleTouchScroll, true);
9720                }
9721            };
9722            this.handleTouchMove = function (ev) {
9723                var pev = _this.createEventFromTouch(ev);
9724                _this.recordCoords(pev);
9725                _this.emitter.trigger('pointermove', pev);
9726            };
9727            this.handleTouchEnd = function (ev) {
9728                if (_this.isDragging) { // done to guard against touchend followed by touchcancel
9729                    var targetEl = ev.target;
9730                    targetEl.removeEventListener('touchmove', _this.handleTouchMove);
9731                    targetEl.removeEventListener('touchend', _this.handleTouchEnd);
9732                    targetEl.removeEventListener('touchcancel', _this.handleTouchEnd);
9733                    window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
9734                    _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
9735                    _this.cleanup(); // call last so that pointerup has access to props
9736                    _this.isTouchDragging = false;
9737                    startIgnoringMouse();
9738                }
9739            };
9740            this.handleTouchScroll = function () {
9741                _this.wasTouchScroll = true;
9742            };
9743            this.handleScroll = function (ev) {
9744                if (!_this.shouldIgnoreMove) {
9745                    var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
9746                    var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
9747                    _this.emitter.trigger('pointermove', {
9748                        origEvent: ev,
9749                        isTouch: _this.isTouchDragging,
9750                        subjectEl: _this.subjectEl,
9751                        pageX: pageX,
9752                        pageY: pageY,
9753                        deltaX: pageX - _this.origPageX,
9754                        deltaY: pageY - _this.origPageY,
9755                    });
9756                }
9757            };
9758            this.containerEl = containerEl;
9759            this.emitter = new Emitter();
9760            containerEl.addEventListener('mousedown', this.handleMouseDown);
9761            containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
9762            listenerCreated();
9763        }
9764        PointerDragging.prototype.destroy = function () {
9765            this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
9766            this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
9767            listenerDestroyed();
9768        };
9769        PointerDragging.prototype.tryStart = function (ev) {
9770            var subjectEl = this.querySubjectEl(ev);
9771            var downEl = ev.target;
9772            if (subjectEl &&
9773                (!this.handleSelector || elementClosest(downEl, this.handleSelector))) {
9774                this.subjectEl = subjectEl;
9775                this.isDragging = true; // do this first so cancelTouchScroll will work
9776                this.wasTouchScroll = false;
9777                return true;
9778            }
9779            return false;
9780        };
9781        PointerDragging.prototype.cleanup = function () {
9782            isWindowTouchMoveCancelled = false;
9783            this.isDragging = false;
9784            this.subjectEl = null;
9785            // keep wasTouchScroll around for later access
9786            this.destroyScrollWatch();
9787        };
9788        PointerDragging.prototype.querySubjectEl = function (ev) {
9789            if (this.selector) {
9790                return elementClosest(ev.target, this.selector);
9791            }
9792            return this.containerEl;
9793        };
9794        PointerDragging.prototype.shouldIgnoreMouse = function () {
9795            return ignoreMouseDepth || this.isTouchDragging;
9796        };
9797        // can be called by user of this class, to cancel touch-based scrolling for the current drag
9798        PointerDragging.prototype.cancelTouchScroll = function () {
9799            if (this.isDragging) {
9800                isWindowTouchMoveCancelled = true;
9801            }
9802        };
9803        // Scrolling that simulates pointermoves
9804        // ----------------------------------------------------------------------------------------------------
9805        PointerDragging.prototype.initScrollWatch = function (ev) {
9806            if (this.shouldWatchScroll) {
9807                this.recordCoords(ev);
9808                window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
9809            }
9810        };
9811        PointerDragging.prototype.recordCoords = function (ev) {
9812            if (this.shouldWatchScroll) {
9813                this.prevPageX = ev.pageX;
9814                this.prevPageY = ev.pageY;
9815                this.prevScrollX = window.pageXOffset;
9816                this.prevScrollY = window.pageYOffset;
9817            }
9818        };
9819        PointerDragging.prototype.destroyScrollWatch = function () {
9820            if (this.shouldWatchScroll) {
9821                window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
9822            }
9823        };
9824        // Event Normalization
9825        // ----------------------------------------------------------------------------------------------------
9826        PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
9827            var deltaX = 0;
9828            var deltaY = 0;
9829            // TODO: repeat code
9830            if (isFirst) {
9831                this.origPageX = ev.pageX;
9832                this.origPageY = ev.pageY;
9833            }
9834            else {
9835                deltaX = ev.pageX - this.origPageX;
9836                deltaY = ev.pageY - this.origPageY;
9837            }
9838            return {
9839                origEvent: ev,
9840                isTouch: false,
9841                subjectEl: this.subjectEl,
9842                pageX: ev.pageX,
9843                pageY: ev.pageY,
9844                deltaX: deltaX,
9845                deltaY: deltaY,
9846            };
9847        };
9848        PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
9849            var touches = ev.touches;
9850            var pageX;
9851            var pageY;
9852            var deltaX = 0;
9853            var deltaY = 0;
9854            // if touch coords available, prefer,
9855            // because FF would give bad ev.pageX ev.pageY
9856            if (touches && touches.length) {
9857                pageX = touches[0].pageX;
9858                pageY = touches[0].pageY;
9859            }
9860            else {
9861                pageX = ev.pageX;
9862                pageY = ev.pageY;
9863            }
9864            // TODO: repeat code
9865            if (isFirst) {
9866                this.origPageX = pageX;
9867                this.origPageY = pageY;
9868            }
9869            else {
9870                deltaX = pageX - this.origPageX;
9871                deltaY = pageY - this.origPageY;
9872            }
9873            return {
9874                origEvent: ev,
9875                isTouch: true,
9876                subjectEl: this.subjectEl,
9877                pageX: pageX,
9878                pageY: pageY,
9879                deltaX: deltaX,
9880                deltaY: deltaY,
9881            };
9882        };
9883        return PointerDragging;
9884    }());
9885    // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
9886    function isPrimaryMouseButton(ev) {
9887        return ev.button === 0 && !ev.ctrlKey;
9888    }
9889    // Ignoring fake mouse events generated by touch
9890    // ----------------------------------------------------------------------------------------------------
9891    function startIgnoringMouse() {
9892        ignoreMouseDepth += 1;
9893        setTimeout(function () {
9894            ignoreMouseDepth -= 1;
9895        }, config.touchMouseIgnoreWait);
9896    }
9897    // We want to attach touchmove as early as possible for Safari
9898    // ----------------------------------------------------------------------------------------------------
9899    function listenerCreated() {
9900        listenerCnt += 1;
9901        if (listenerCnt === 1) {
9902            window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
9903        }
9904    }
9905    function listenerDestroyed() {
9906        listenerCnt -= 1;
9907        if (!listenerCnt) {
9908            window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
9909        }
9910    }
9911    function onWindowTouchMove(ev) {
9912        if (isWindowTouchMoveCancelled) {
9913            ev.preventDefault();
9914        }
9915    }
9916
9917    /*
9918    An effect in which an element follows the movement of a pointer across the screen.
9919    The moving element is a clone of some other element.
9920    Must call start + handleMove + stop.
9921    */
9922    var ElementMirror = /** @class */ (function () {
9923        function ElementMirror() {
9924            this.isVisible = false; // must be explicitly enabled
9925            this.sourceEl = null;
9926            this.mirrorEl = null;
9927            this.sourceElRect = null; // screen coords relative to viewport
9928            // options that can be set directly by caller
9929            this.parentNode = document.body;
9930            this.zIndex = 9999;
9931            this.revertDuration = 0;
9932        }
9933        ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
9934            this.sourceEl = sourceEl;
9935            this.sourceElRect = this.sourceEl.getBoundingClientRect();
9936            this.origScreenX = pageX - window.pageXOffset;
9937            this.origScreenY = pageY - window.pageYOffset;
9938            this.deltaX = 0;
9939            this.deltaY = 0;
9940            this.updateElPosition();
9941        };
9942        ElementMirror.prototype.handleMove = function (pageX, pageY) {
9943            this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
9944            this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
9945            this.updateElPosition();
9946        };
9947        // can be called before start
9948        ElementMirror.prototype.setIsVisible = function (bool) {
9949            if (bool) {
9950                if (!this.isVisible) {
9951                    if (this.mirrorEl) {
9952                        this.mirrorEl.style.display = '';
9953                    }
9954                    this.isVisible = bool; // needs to happen before updateElPosition
9955                    this.updateElPosition(); // because was not updating the position while invisible
9956                }
9957            }
9958            else if (this.isVisible) {
9959                if (this.mirrorEl) {
9960                    this.mirrorEl.style.display = 'none';
9961                }
9962                this.isVisible = bool;
9963            }
9964        };
9965        // always async
9966        ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
9967            var _this = this;
9968            var done = function () {
9969                _this.cleanup();
9970                callback();
9971            };
9972            if (needsRevertAnimation &&
9973                this.mirrorEl &&
9974                this.isVisible &&
9975                this.revertDuration && // if 0, transition won't work
9976                (this.deltaX || this.deltaY) // if same coords, transition won't work
9977            ) {
9978                this.doRevertAnimation(done, this.revertDuration);
9979            }
9980            else {
9981                setTimeout(done, 0);
9982            }
9983        };
9984        ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
9985            var mirrorEl = this.mirrorEl;
9986            var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
9987            mirrorEl.style.transition =
9988                'top ' + revertDuration + 'ms,' +
9989                    'left ' + revertDuration + 'ms';
9990            applyStyle(mirrorEl, {
9991                left: finalSourceElRect.left,
9992                top: finalSourceElRect.top,
9993            });
9994            whenTransitionDone(mirrorEl, function () {
9995                mirrorEl.style.transition = '';
9996                callback();
9997            });
9998        };
9999        ElementMirror.prototype.cleanup = function () {
10000            if (this.mirrorEl) {
10001                removeElement(this.mirrorEl);
10002                this.mirrorEl = null;
10003            }
10004            this.sourceEl = null;
10005        };
10006        ElementMirror.prototype.updateElPosition = function () {
10007            if (this.sourceEl && this.isVisible) {
10008                applyStyle(this.getMirrorEl(), {
10009                    left: this.sourceElRect.left + this.deltaX,
10010                    top: this.sourceElRect.top + this.deltaY,
10011                });
10012            }
10013        };
10014        ElementMirror.prototype.getMirrorEl = function () {
10015            var sourceElRect = this.sourceElRect;
10016            var mirrorEl = this.mirrorEl;
10017            if (!mirrorEl) {
10018                mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
10019                // we don't want long taps or any mouse interaction causing selection/menus.
10020                // would use preventSelection(), but that prevents selectstart, causing problems.
10021                mirrorEl.classList.add('fc-unselectable');
10022                mirrorEl.classList.add('fc-event-dragging');
10023                applyStyle(mirrorEl, {
10024                    position: 'fixed',
10025                    zIndex: this.zIndex,
10026                    visibility: '',
10027                    boxSizing: 'border-box',
10028                    width: sourceElRect.right - sourceElRect.left,
10029                    height: sourceElRect.bottom - sourceElRect.top,
10030                    right: 'auto',
10031                    bottom: 'auto',
10032                    margin: 0,
10033                });
10034                this.parentNode.appendChild(mirrorEl);
10035            }
10036            return mirrorEl;
10037        };
10038        return ElementMirror;
10039    }());
10040
10041    /*
10042    Is a cache for a given element's scroll information (all the info that ScrollController stores)
10043    in addition the "client rectangle" of the element.. the area within the scrollbars.
10044
10045    The cache can be in one of two modes:
10046    - doesListening:false - ignores when the container is scrolled by someone else
10047    - doesListening:true - watch for scrolling and update the cache
10048    */
10049    var ScrollGeomCache = /** @class */ (function (_super) {
10050        __extends(ScrollGeomCache, _super);
10051        function ScrollGeomCache(scrollController, doesListening) {
10052            var _this = _super.call(this) || this;
10053            _this.handleScroll = function () {
10054                _this.scrollTop = _this.scrollController.getScrollTop();
10055                _this.scrollLeft = _this.scrollController.getScrollLeft();
10056                _this.handleScrollChange();
10057            };
10058            _this.scrollController = scrollController;
10059            _this.doesListening = doesListening;
10060            _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
10061            _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
10062            _this.scrollWidth = scrollController.getScrollWidth();
10063            _this.scrollHeight = scrollController.getScrollHeight();
10064            _this.clientWidth = scrollController.getClientWidth();
10065            _this.clientHeight = scrollController.getClientHeight();
10066            _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
10067            if (_this.doesListening) {
10068                _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
10069            }
10070            return _this;
10071        }
10072        ScrollGeomCache.prototype.destroy = function () {
10073            if (this.doesListening) {
10074                this.getEventTarget().removeEventListener('scroll', this.handleScroll);
10075            }
10076        };
10077        ScrollGeomCache.prototype.getScrollTop = function () {
10078            return this.scrollTop;
10079        };
10080        ScrollGeomCache.prototype.getScrollLeft = function () {
10081            return this.scrollLeft;
10082        };
10083        ScrollGeomCache.prototype.setScrollTop = function (top) {
10084            this.scrollController.setScrollTop(top);
10085            if (!this.doesListening) {
10086                // we are not relying on the element to normalize out-of-bounds scroll values
10087                // so we need to sanitize ourselves
10088                this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
10089                this.handleScrollChange();
10090            }
10091        };
10092        ScrollGeomCache.prototype.setScrollLeft = function (top) {
10093            this.scrollController.setScrollLeft(top);
10094            if (!this.doesListening) {
10095                // we are not relying on the element to normalize out-of-bounds scroll values
10096                // so we need to sanitize ourselves
10097                this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
10098                this.handleScrollChange();
10099            }
10100        };
10101        ScrollGeomCache.prototype.getClientWidth = function () {
10102            return this.clientWidth;
10103        };
10104        ScrollGeomCache.prototype.getClientHeight = function () {
10105            return this.clientHeight;
10106        };
10107        ScrollGeomCache.prototype.getScrollWidth = function () {
10108            return this.scrollWidth;
10109        };
10110        ScrollGeomCache.prototype.getScrollHeight = function () {
10111            return this.scrollHeight;
10112        };
10113        ScrollGeomCache.prototype.handleScrollChange = function () {
10114        };
10115        return ScrollGeomCache;
10116    }(ScrollController));
10117
10118    var ElementScrollGeomCache = /** @class */ (function (_super) {
10119        __extends(ElementScrollGeomCache, _super);
10120        function ElementScrollGeomCache(el, doesListening) {
10121            return _super.call(this, new ElementScrollController(el), doesListening) || this;
10122        }
10123        ElementScrollGeomCache.prototype.getEventTarget = function () {
10124            return this.scrollController.el;
10125        };
10126        ElementScrollGeomCache.prototype.computeClientRect = function () {
10127            return computeInnerRect(this.scrollController.el);
10128        };
10129        return ElementScrollGeomCache;
10130    }(ScrollGeomCache));
10131
10132    var WindowScrollGeomCache = /** @class */ (function (_super) {
10133        __extends(WindowScrollGeomCache, _super);
10134        function WindowScrollGeomCache(doesListening) {
10135            return _super.call(this, new WindowScrollController(), doesListening) || this;
10136        }
10137        WindowScrollGeomCache.prototype.getEventTarget = function () {
10138            return window;
10139        };
10140        WindowScrollGeomCache.prototype.computeClientRect = function () {
10141            return {
10142                left: this.scrollLeft,
10143                right: this.scrollLeft + this.clientWidth,
10144                top: this.scrollTop,
10145                bottom: this.scrollTop + this.clientHeight,
10146            };
10147        };
10148        // the window is the only scroll object that changes it's rectangle relative
10149        // to the document's topleft as it scrolls
10150        WindowScrollGeomCache.prototype.handleScrollChange = function () {
10151            this.clientRect = this.computeClientRect();
10152        };
10153        return WindowScrollGeomCache;
10154    }(ScrollGeomCache));
10155
10156    // If available we are using native "performance" API instead of "Date"
10157    // Read more about it on MDN:
10158    // https://developer.mozilla.org/en-US/docs/Web/API/Performance
10159    var getTime = typeof performance === 'function' ? performance.now : Date.now;
10160    /*
10161    For a pointer interaction, automatically scrolls certain scroll containers when the pointer
10162    approaches the edge.
10163
10164    The caller must call start + handleMove + stop.
10165    */
10166    var AutoScroller = /** @class */ (function () {
10167        function AutoScroller() {
10168            var _this = this;
10169            // options that can be set by caller
10170            this.isEnabled = true;
10171            this.scrollQuery = [window, '.fc-scroller'];
10172            this.edgeThreshold = 50; // pixels
10173            this.maxVelocity = 300; // pixels per second
10174            // internal state
10175            this.pointerScreenX = null;
10176            this.pointerScreenY = null;
10177            this.isAnimating = false;
10178            this.scrollCaches = null;
10179            // protect against the initial pointerdown being too close to an edge and starting the scroll
10180            this.everMovedUp = false;
10181            this.everMovedDown = false;
10182            this.everMovedLeft = false;
10183            this.everMovedRight = false;
10184            this.animate = function () {
10185                if (_this.isAnimating) { // wasn't cancelled between animation calls
10186                    var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
10187                    if (edge) {
10188                        var now = getTime();
10189                        _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
10190                        _this.requestAnimation(now);
10191                    }
10192                    else {
10193                        _this.isAnimating = false; // will stop animation
10194                    }
10195                }
10196            };
10197        }
10198        AutoScroller.prototype.start = function (pageX, pageY) {
10199            if (this.isEnabled) {
10200                this.scrollCaches = this.buildCaches();
10201                this.pointerScreenX = null;
10202                this.pointerScreenY = null;
10203                this.everMovedUp = false;
10204                this.everMovedDown = false;
10205                this.everMovedLeft = false;
10206                this.everMovedRight = false;
10207                this.handleMove(pageX, pageY);
10208            }
10209        };
10210        AutoScroller.prototype.handleMove = function (pageX, pageY) {
10211            if (this.isEnabled) {
10212                var pointerScreenX = pageX - window.pageXOffset;
10213                var pointerScreenY = pageY - window.pageYOffset;
10214                var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
10215                var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
10216                if (yDelta < 0) {
10217                    this.everMovedUp = true;
10218                }
10219                else if (yDelta > 0) {
10220                    this.everMovedDown = true;
10221                }
10222                if (xDelta < 0) {
10223                    this.everMovedLeft = true;
10224                }
10225                else if (xDelta > 0) {
10226                    this.everMovedRight = true;
10227                }
10228                this.pointerScreenX = pointerScreenX;
10229                this.pointerScreenY = pointerScreenY;
10230                if (!this.isAnimating) {
10231                    this.isAnimating = true;
10232                    this.requestAnimation(getTime());
10233                }
10234            }
10235        };
10236        AutoScroller.prototype.stop = function () {
10237            if (this.isEnabled) {
10238                this.isAnimating = false; // will stop animation
10239                for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10240                    var scrollCache = _a[_i];
10241                    scrollCache.destroy();
10242                }
10243                this.scrollCaches = null;
10244            }
10245        };
10246        AutoScroller.prototype.requestAnimation = function (now) {
10247            this.msSinceRequest = now;
10248            requestAnimationFrame(this.animate);
10249        };
10250        AutoScroller.prototype.handleSide = function (edge, seconds) {
10251            var scrollCache = edge.scrollCache;
10252            var edgeThreshold = this.edgeThreshold;
10253            var invDistance = edgeThreshold - edge.distance;
10254            var velocity = // the closer to the edge, the faster we scroll
10255             ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic
10256                this.maxVelocity * seconds;
10257            var sign = 1;
10258            switch (edge.name) {
10259                case 'left':
10260                    sign = -1;
10261                // falls through
10262                case 'right':
10263                    scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
10264                    break;
10265                case 'top':
10266                    sign = -1;
10267                // falls through
10268                case 'bottom':
10269                    scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
10270                    break;
10271            }
10272        };
10273        // left/top are relative to document topleft
10274        AutoScroller.prototype.computeBestEdge = function (left, top) {
10275            var edgeThreshold = this.edgeThreshold;
10276            var bestSide = null;
10277            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10278                var scrollCache = _a[_i];
10279                var rect = scrollCache.clientRect;
10280                var leftDist = left - rect.left;
10281                var rightDist = rect.right - left;
10282                var topDist = top - rect.top;
10283                var bottomDist = rect.bottom - top;
10284                // completely within the rect?
10285                if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
10286                    if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
10287                        (!bestSide || bestSide.distance > topDist)) {
10288                        bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
10289                    }
10290                    if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
10291                        (!bestSide || bestSide.distance > bottomDist)) {
10292                        bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
10293                    }
10294                    if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
10295                        (!bestSide || bestSide.distance > leftDist)) {
10296                        bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
10297                    }
10298                    if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
10299                        (!bestSide || bestSide.distance > rightDist)) {
10300                        bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
10301                    }
10302                }
10303            }
10304            return bestSide;
10305        };
10306        AutoScroller.prototype.buildCaches = function () {
10307            return this.queryScrollEls().map(function (el) {
10308                if (el === window) {
10309                    return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
10310                }
10311                return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
10312            });
10313        };
10314        AutoScroller.prototype.queryScrollEls = function () {
10315            var els = [];
10316            for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
10317                var query = _a[_i];
10318                if (typeof query === 'object') {
10319                    els.push(query);
10320                }
10321                else {
10322                    els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query)));
10323                }
10324            }
10325            return els;
10326        };
10327        return AutoScroller;
10328    }());
10329
10330    /*
10331    Monitors dragging on an element. Has a number of high-level features:
10332    - minimum distance required before dragging
10333    - minimum wait time ("delay") before dragging
10334    - a mirror element that follows the pointer
10335    */
10336    var FeaturefulElementDragging = /** @class */ (function (_super) {
10337        __extends(FeaturefulElementDragging, _super);
10338        function FeaturefulElementDragging(containerEl, selector) {
10339            var _this = _super.call(this, containerEl) || this;
10340            // options that can be directly set by caller
10341            // the caller can also set the PointerDragging's options as well
10342            _this.delay = null;
10343            _this.minDistance = 0;
10344            _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
10345            _this.mirrorNeedsRevert = false;
10346            _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
10347            _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
10348            _this.isDelayEnded = false;
10349            _this.isDistanceSurpassed = false;
10350            _this.delayTimeoutId = null;
10351            _this.onPointerDown = function (ev) {
10352                if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
10353                    _this.isInteracting = true;
10354                    _this.isDelayEnded = false;
10355                    _this.isDistanceSurpassed = false;
10356                    preventSelection(document.body);
10357                    preventContextMenu(document.body);
10358                    // prevent links from being visited if there's an eventual drag.
10359                    // also prevents selection in older browsers (maybe?).
10360                    // not necessary for touch, besides, browser would complain about passiveness.
10361                    if (!ev.isTouch) {
10362                        ev.origEvent.preventDefault();
10363                    }
10364                    _this.emitter.trigger('pointerdown', ev);
10365                    if (_this.isInteracting && // not destroyed via pointerdown handler
10366                        !_this.pointer.shouldIgnoreMove) {
10367                        // actions related to initiating dragstart+dragmove+dragend...
10368                        _this.mirror.setIsVisible(false); // reset. caller must set-visible
10369                        _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
10370                        _this.startDelay(ev);
10371                        if (!_this.minDistance) {
10372                            _this.handleDistanceSurpassed(ev);
10373                        }
10374                    }
10375                }
10376            };
10377            _this.onPointerMove = function (ev) {
10378                if (_this.isInteracting) {
10379                    _this.emitter.trigger('pointermove', ev);
10380                    if (!_this.isDistanceSurpassed) {
10381                        var minDistance = _this.minDistance;
10382                        var distanceSq = void 0; // current distance from the origin, squared
10383                        var deltaX = ev.deltaX, deltaY = ev.deltaY;
10384                        distanceSq = deltaX * deltaX + deltaY * deltaY;
10385                        if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
10386                            _this.handleDistanceSurpassed(ev);
10387                        }
10388                    }
10389                    if (_this.isDragging) {
10390                        // a real pointer move? (not one simulated by scrolling)
10391                        if (ev.origEvent.type !== 'scroll') {
10392                            _this.mirror.handleMove(ev.pageX, ev.pageY);
10393                            _this.autoScroller.handleMove(ev.pageX, ev.pageY);
10394                        }
10395                        _this.emitter.trigger('dragmove', ev);
10396                    }
10397                }
10398            };
10399            _this.onPointerUp = function (ev) {
10400                if (_this.isInteracting) {
10401                    _this.isInteracting = false;
10402                    allowSelection(document.body);
10403                    allowContextMenu(document.body);
10404                    _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
10405                    if (_this.isDragging) {
10406                        _this.autoScroller.stop();
10407                        _this.tryStopDrag(ev); // which will stop the mirror
10408                    }
10409                    if (_this.delayTimeoutId) {
10410                        clearTimeout(_this.delayTimeoutId);
10411                        _this.delayTimeoutId = null;
10412                    }
10413                }
10414            };
10415            var pointer = _this.pointer = new PointerDragging(containerEl);
10416            pointer.emitter.on('pointerdown', _this.onPointerDown);
10417            pointer.emitter.on('pointermove', _this.onPointerMove);
10418            pointer.emitter.on('pointerup', _this.onPointerUp);
10419            if (selector) {
10420                pointer.selector = selector;
10421            }
10422            _this.mirror = new ElementMirror();
10423            _this.autoScroller = new AutoScroller();
10424            return _this;
10425        }
10426        FeaturefulElementDragging.prototype.destroy = function () {
10427            this.pointer.destroy();
10428            // HACK: simulate a pointer-up to end the current drag
10429            // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire)
10430            this.onPointerUp({});
10431        };
10432        FeaturefulElementDragging.prototype.startDelay = function (ev) {
10433            var _this = this;
10434            if (typeof this.delay === 'number') {
10435                this.delayTimeoutId = setTimeout(function () {
10436                    _this.delayTimeoutId = null;
10437                    _this.handleDelayEnd(ev);
10438                }, this.delay); // not assignable to number!
10439            }
10440            else {
10441                this.handleDelayEnd(ev);
10442            }
10443        };
10444        FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
10445            this.isDelayEnded = true;
10446            this.tryStartDrag(ev);
10447        };
10448        FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
10449            this.isDistanceSurpassed = true;
10450            this.tryStartDrag(ev);
10451        };
10452        FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
10453            if (this.isDelayEnded && this.isDistanceSurpassed) {
10454                if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
10455                    this.isDragging = true;
10456                    this.mirrorNeedsRevert = false;
10457                    this.autoScroller.start(ev.pageX, ev.pageY);
10458                    this.emitter.trigger('dragstart', ev);
10459                    if (this.touchScrollAllowed === false) {
10460                        this.pointer.cancelTouchScroll();
10461                    }
10462                }
10463            }
10464        };
10465        FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
10466            // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
10467            // that come from the document to fire beforehand. much more convenient this way.
10468            this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev));
10469        };
10470        FeaturefulElementDragging.prototype.stopDrag = function (ev) {
10471            this.isDragging = false;
10472            this.emitter.trigger('dragend', ev);
10473        };
10474        // fill in the implementations...
10475        FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
10476            this.pointer.shouldIgnoreMove = bool;
10477        };
10478        FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
10479            this.mirror.setIsVisible(bool);
10480        };
10481        FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
10482            this.mirrorNeedsRevert = bool;
10483        };
10484        FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
10485            this.autoScroller.isEnabled = bool;
10486        };
10487        return FeaturefulElementDragging;
10488    }(ElementDragging));
10489
10490    /*
10491    When this class is instantiated, it records the offset of an element (relative to the document topleft),
10492    and continues to monitor scrolling, updating the cached coordinates if it needs to.
10493    Does not access the DOM after instantiation, so highly performant.
10494
10495    Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
10496    and an determine if a given point is inside the combined clipping rectangle.
10497    */
10498    var OffsetTracker = /** @class */ (function () {
10499        function OffsetTracker(el) {
10500            this.origRect = computeRect(el);
10501            // will work fine for divs that have overflow:hidden
10502            this.scrollCaches = getClippingParents(el).map(function (scrollEl) { return new ElementScrollGeomCache(scrollEl, true); });
10503        }
10504        OffsetTracker.prototype.destroy = function () {
10505            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10506                var scrollCache = _a[_i];
10507                scrollCache.destroy();
10508            }
10509        };
10510        OffsetTracker.prototype.computeLeft = function () {
10511            var left = this.origRect.left;
10512            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10513                var scrollCache = _a[_i];
10514                left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
10515            }
10516            return left;
10517        };
10518        OffsetTracker.prototype.computeTop = function () {
10519            var top = this.origRect.top;
10520            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10521                var scrollCache = _a[_i];
10522                top += scrollCache.origScrollTop - scrollCache.getScrollTop();
10523            }
10524            return top;
10525        };
10526        OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
10527            var point = { left: pageX, top: pageY };
10528            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10529                var scrollCache = _a[_i];
10530                if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
10531                    !pointInsideRect(point, scrollCache.clientRect)) {
10532                    return false;
10533                }
10534            }
10535            return true;
10536        };
10537        return OffsetTracker;
10538    }());
10539    // certain clipping containers should never constrain interactions, like <html> and <body>
10540    // https://github.com/fullcalendar/fullcalendar/issues/3615
10541    function isIgnoredClipping(node) {
10542        var tagName = node.tagName;
10543        return tagName === 'HTML' || tagName === 'BODY';
10544    }
10545
10546    /*
10547    Tracks movement over multiple droppable areas (aka "hits")
10548    that exist in one or more DateComponents.
10549    Relies on an existing draggable.
10550
10551    emits:
10552    - pointerdown
10553    - dragstart
10554    - hitchange - fires initially, even if not over a hit
10555    - pointerup
10556    - (hitchange - again, to null, if ended over a hit)
10557    - dragend
10558    */
10559    var HitDragging = /** @class */ (function () {
10560        function HitDragging(dragging, droppableStore) {
10561            var _this = this;
10562            // options that can be set by caller
10563            this.useSubjectCenter = false;
10564            this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
10565            this.initialHit = null;
10566            this.movingHit = null;
10567            this.finalHit = null; // won't ever be populated if shouldIgnoreMove
10568            this.handlePointerDown = function (ev) {
10569                var dragging = _this.dragging;
10570                _this.initialHit = null;
10571                _this.movingHit = null;
10572                _this.finalHit = null;
10573                _this.prepareHits();
10574                _this.processFirstCoord(ev);
10575                if (_this.initialHit || !_this.requireInitial) {
10576                    dragging.setIgnoreMove(false);
10577                    // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
10578                    _this.emitter.trigger('pointerdown', ev);
10579                }
10580                else {
10581                    dragging.setIgnoreMove(true);
10582                }
10583            };
10584            this.handleDragStart = function (ev) {
10585                _this.emitter.trigger('dragstart', ev);
10586                _this.handleMove(ev, true); // force = fire even if initially null
10587            };
10588            this.handleDragMove = function (ev) {
10589                _this.emitter.trigger('dragmove', ev);
10590                _this.handleMove(ev);
10591            };
10592            this.handlePointerUp = function (ev) {
10593                _this.releaseHits();
10594                _this.emitter.trigger('pointerup', ev);
10595            };
10596            this.handleDragEnd = function (ev) {
10597                if (_this.movingHit) {
10598                    _this.emitter.trigger('hitupdate', null, true, ev);
10599                }
10600                _this.finalHit = _this.movingHit;
10601                _this.movingHit = null;
10602                _this.emitter.trigger('dragend', ev);
10603            };
10604            this.droppableStore = droppableStore;
10605            dragging.emitter.on('pointerdown', this.handlePointerDown);
10606            dragging.emitter.on('dragstart', this.handleDragStart);
10607            dragging.emitter.on('dragmove', this.handleDragMove);
10608            dragging.emitter.on('pointerup', this.handlePointerUp);
10609            dragging.emitter.on('dragend', this.handleDragEnd);
10610            this.dragging = dragging;
10611            this.emitter = new Emitter();
10612        }
10613        // sets initialHit
10614        // sets coordAdjust
10615        HitDragging.prototype.processFirstCoord = function (ev) {
10616            var origPoint = { left: ev.pageX, top: ev.pageY };
10617            var adjustedPoint = origPoint;
10618            var subjectEl = ev.subjectEl;
10619            var subjectRect;
10620            if (subjectEl !== document) {
10621                subjectRect = computeRect(subjectEl);
10622                adjustedPoint = constrainPoint(adjustedPoint, subjectRect);
10623            }
10624            var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
10625            if (initialHit) {
10626                if (this.useSubjectCenter && subjectRect) {
10627                    var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect);
10628                    if (slicedSubjectRect) {
10629                        adjustedPoint = getRectCenter(slicedSubjectRect);
10630                    }
10631                }
10632                this.coordAdjust = diffPoints(adjustedPoint, origPoint);
10633            }
10634            else {
10635                this.coordAdjust = { left: 0, top: 0 };
10636            }
10637        };
10638        HitDragging.prototype.handleMove = function (ev, forceHandle) {
10639            var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
10640            if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
10641                this.movingHit = hit;
10642                this.emitter.trigger('hitupdate', hit, false, ev);
10643            }
10644        };
10645        HitDragging.prototype.prepareHits = function () {
10646            this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) {
10647                interactionSettings.component.prepareHits();
10648                return new OffsetTracker(interactionSettings.el);
10649            });
10650        };
10651        HitDragging.prototype.releaseHits = function () {
10652            var offsetTrackers = this.offsetTrackers;
10653            for (var id in offsetTrackers) {
10654                offsetTrackers[id].destroy();
10655            }
10656            this.offsetTrackers = {};
10657        };
10658        HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
10659            var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
10660            var bestHit = null;
10661            for (var id in droppableStore) {
10662                var component = droppableStore[id].component;
10663                var offsetTracker = offsetTrackers[id];
10664                if (offsetTracker && // wasn't destroyed mid-drag
10665                    offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
10666                    var originLeft = offsetTracker.computeLeft();
10667                    var originTop = offsetTracker.computeTop();
10668                    var positionLeft = offsetLeft - originLeft;
10669                    var positionTop = offsetTop - originTop;
10670                    var origRect = offsetTracker.origRect;
10671                    var width = origRect.right - origRect.left;
10672                    var height = origRect.bottom - origRect.top;
10673                    if (
10674                    // must be within the element's bounds
10675                    positionLeft >= 0 && positionLeft < width &&
10676                        positionTop >= 0 && positionTop < height) {
10677                        var hit = component.queryHit(positionLeft, positionTop, width, height);
10678                        if (hit && (
10679                        // make sure the hit is within activeRange, meaning it's not a dead cell
10680                        rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range)) &&
10681                            (!bestHit || hit.layer > bestHit.layer)) {
10682                            hit.componentId = id;
10683                            hit.context = component.context;
10684                            // TODO: better way to re-orient rectangle
10685                            hit.rect.left += originLeft;
10686                            hit.rect.right += originLeft;
10687                            hit.rect.top += originTop;
10688                            hit.rect.bottom += originTop;
10689                            bestHit = hit;
10690                        }
10691                    }
10692                }
10693            }
10694            return bestHit;
10695        };
10696        return HitDragging;
10697    }());
10698    function isHitsEqual(hit0, hit1) {
10699        if (!hit0 && !hit1) {
10700            return true;
10701        }
10702        if (Boolean(hit0) !== Boolean(hit1)) {
10703            return false;
10704        }
10705        return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
10706    }
10707
10708    function buildDatePointApiWithContext(dateSpan, context) {
10709        var props = {};
10710        for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) {
10711            var transform = _a[_i];
10712            __assign(props, transform(dateSpan, context));
10713        }
10714        __assign(props, buildDatePointApi(dateSpan, context.dateEnv));
10715        return props;
10716    }
10717    function buildDatePointApi(span, dateEnv) {
10718        return {
10719            date: dateEnv.toDate(span.range.start),
10720            dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
10721            allDay: span.allDay,
10722        };
10723    }
10724
10725    /*
10726    Monitors when the user clicks on a specific date/time of a component.
10727    A pointerdown+pointerup on the same "hit" constitutes a click.
10728    */
10729    var DateClicking = /** @class */ (function (_super) {
10730        __extends(DateClicking, _super);
10731        function DateClicking(settings) {
10732            var _this = _super.call(this, settings) || this;
10733            _this.handlePointerDown = function (pev) {
10734                var dragging = _this.dragging;
10735                var downEl = pev.origEvent.target;
10736                // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
10737                dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl));
10738            };
10739            // won't even fire if moving was ignored
10740            _this.handleDragEnd = function (ev) {
10741                var component = _this.component;
10742                var pointer = _this.dragging.pointer;
10743                if (!pointer.wasTouchScroll) {
10744                    var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
10745                    if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
10746                        var context = component.context;
10747                        var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view });
10748                        context.emitter.trigger('dateClick', arg);
10749                    }
10750                }
10751            };
10752            // we DO want to watch pointer moves because otherwise finalHit won't get populated
10753            _this.dragging = new FeaturefulElementDragging(settings.el);
10754            _this.dragging.autoScroller.isEnabled = false;
10755            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10756            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10757            hitDragging.emitter.on('dragend', _this.handleDragEnd);
10758            return _this;
10759        }
10760        DateClicking.prototype.destroy = function () {
10761            this.dragging.destroy();
10762        };
10763        return DateClicking;
10764    }(Interaction));
10765
10766    /*
10767    Tracks when the user selects a portion of time of a component,
10768    constituted by a drag over date cells, with a possible delay at the beginning of the drag.
10769    */
10770    var DateSelecting = /** @class */ (function (_super) {
10771        __extends(DateSelecting, _super);
10772        function DateSelecting(settings) {
10773            var _this = _super.call(this, settings) || this;
10774            _this.dragSelection = null;
10775            _this.handlePointerDown = function (ev) {
10776                var _a = _this, component = _a.component, dragging = _a.dragging;
10777                var options = component.context.options;
10778                var canSelect = options.selectable &&
10779                    component.isValidDateDownEl(ev.origEvent.target);
10780                // don't bother to watch expensive moves if component won't do selection
10781                dragging.setIgnoreMove(!canSelect);
10782                // if touch, require user to hold down
10783                dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null;
10784            };
10785            _this.handleDragStart = function (ev) {
10786                _this.component.context.calendarApi.unselect(ev); // unselect previous selections
10787            };
10788            _this.handleHitUpdate = function (hit, isFinal) {
10789                var context = _this.component.context;
10790                var dragSelection = null;
10791                var isInvalid = false;
10792                if (hit) {
10793                    var initialHit = _this.hitDragging.initialHit;
10794                    var disallowed = hit.componentId === initialHit.componentId
10795                        && _this.isHitComboAllowed
10796                        && !_this.isHitComboAllowed(initialHit, hit);
10797                    if (!disallowed) {
10798                        dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers);
10799                    }
10800                    if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) {
10801                        isInvalid = true;
10802                        dragSelection = null;
10803                    }
10804                }
10805                if (dragSelection) {
10806                    context.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
10807                }
10808                else if (!isFinal) { // only unselect if moved away while dragging
10809                    context.dispatch({ type: 'UNSELECT_DATES' });
10810                }
10811                if (!isInvalid) {
10812                    enableCursor();
10813                }
10814                else {
10815                    disableCursor();
10816                }
10817                if (!isFinal) {
10818                    _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
10819                }
10820            };
10821            _this.handlePointerUp = function (pev) {
10822                if (_this.dragSelection) {
10823                    // selection is already rendered, so just need to report selection
10824                    triggerDateSelect(_this.dragSelection, pev, _this.component.context);
10825                    _this.dragSelection = null;
10826                }
10827            };
10828            var component = settings.component;
10829            var options = component.context.options;
10830            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
10831            dragging.touchScrollAllowed = false;
10832            dragging.minDistance = options.selectMinDistance || 0;
10833            dragging.autoScroller.isEnabled = options.dragScroll;
10834            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10835            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10836            hitDragging.emitter.on('dragstart', _this.handleDragStart);
10837            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
10838            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
10839            return _this;
10840        }
10841        DateSelecting.prototype.destroy = function () {
10842            this.dragging.destroy();
10843        };
10844        return DateSelecting;
10845    }(Interaction));
10846    function getComponentTouchDelay$1(component) {
10847        var options = component.context.options;
10848        var delay = options.selectLongPressDelay;
10849        if (delay == null) {
10850            delay = options.longPressDelay;
10851        }
10852        return delay;
10853    }
10854    function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
10855        var dateSpan0 = hit0.dateSpan;
10856        var dateSpan1 = hit1.dateSpan;
10857        var ms = [
10858            dateSpan0.range.start,
10859            dateSpan0.range.end,
10860            dateSpan1.range.start,
10861            dateSpan1.range.end,
10862        ];
10863        ms.sort(compareNumbers);
10864        var props = {};
10865        for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
10866            var transformer = dateSelectionTransformers_1[_i];
10867            var res = transformer(hit0, hit1);
10868            if (res === false) {
10869                return null;
10870            }
10871            if (res) {
10872                __assign(props, res);
10873            }
10874        }
10875        props.range = { start: ms[0], end: ms[3] };
10876        props.allDay = dateSpan0.allDay;
10877        return props;
10878    }
10879
10880    var EventDragging = /** @class */ (function (_super) {
10881        __extends(EventDragging, _super);
10882        function EventDragging(settings) {
10883            var _this = _super.call(this, settings) || this;
10884            // internal state
10885            _this.subjectEl = null;
10886            _this.subjectSeg = null; // the seg being selected/dragged
10887            _this.isDragging = false;
10888            _this.eventRange = null;
10889            _this.relevantEvents = null; // the events being dragged
10890            _this.receivingContext = null;
10891            _this.validMutation = null;
10892            _this.mutatedRelevantEvents = null;
10893            _this.handlePointerDown = function (ev) {
10894                var origTarget = ev.origEvent.target;
10895                var _a = _this, component = _a.component, dragging = _a.dragging;
10896                var mirror = dragging.mirror;
10897                var options = component.context.options;
10898                var initialContext = component.context;
10899                _this.subjectEl = ev.subjectEl;
10900                var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl);
10901                var eventRange = _this.eventRange = subjectSeg.eventRange;
10902                var eventInstanceId = eventRange.instance.instanceId;
10903                _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId);
10904                dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance;
10905                dragging.delay =
10906                    // only do a touch delay if touch and this event hasn't been selected yet
10907                    (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
10908                        getComponentTouchDelay(component) :
10909                        null;
10910                if (options.fixedMirrorParent) {
10911                    mirror.parentNode = options.fixedMirrorParent;
10912                }
10913                else {
10914                    mirror.parentNode = elementClosest(origTarget, '.fc');
10915                }
10916                mirror.revertDuration = options.dragRevertDuration;
10917                var isValid = component.isValidSegDownEl(origTarget) &&
10918                    !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer
10919                dragging.setIgnoreMove(!isValid);
10920                // disable dragging for elements that are resizable (ie, selectable)
10921                // but are not draggable
10922                _this.isDragging = isValid &&
10923                    ev.subjectEl.classList.contains('fc-event-draggable');
10924            };
10925            _this.handleDragStart = function (ev) {
10926                var initialContext = _this.component.context;
10927                var eventRange = _this.eventRange;
10928                var eventInstanceId = eventRange.instance.instanceId;
10929                if (ev.isTouch) {
10930                    // need to select a different event?
10931                    if (eventInstanceId !== _this.component.props.eventSelection) {
10932                        initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
10933                    }
10934                }
10935                else {
10936                    // if now using mouse, but was previous touch interaction, clear selected event
10937                    initialContext.dispatch({ type: 'UNSELECT_EVENT' });
10938                }
10939                if (_this.isDragging) {
10940                    initialContext.calendarApi.unselect(ev); // unselect *date* selection
10941                    initialContext.emitter.trigger('eventDragStart', {
10942                        el: _this.subjectEl,
10943                        event: new EventApi(initialContext, eventRange.def, eventRange.instance),
10944                        jsEvent: ev.origEvent,
10945                        view: initialContext.viewApi,
10946                    });
10947                }
10948            };
10949            _this.handleHitUpdate = function (hit, isFinal) {
10950                if (!_this.isDragging) {
10951                    return;
10952                }
10953                var relevantEvents = _this.relevantEvents;
10954                var initialHit = _this.hitDragging.initialHit;
10955                var initialContext = _this.component.context;
10956                // states based on new hit
10957                var receivingContext = null;
10958                var mutation = null;
10959                var mutatedRelevantEvents = null;
10960                var isInvalid = false;
10961                var interaction = {
10962                    affectedEvents: relevantEvents,
10963                    mutatedEvents: createEmptyEventStore(),
10964                    isEvent: true,
10965                };
10966                if (hit) {
10967                    receivingContext = hit.context;
10968                    var receivingOptions = receivingContext.options;
10969                    if (initialContext === receivingContext ||
10970                        (receivingOptions.editable && receivingOptions.droppable)) {
10971                        mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers);
10972                        if (mutation) {
10973                            mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext);
10974                            interaction.mutatedEvents = mutatedRelevantEvents;
10975                            if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) {
10976                                isInvalid = true;
10977                                mutation = null;
10978                                mutatedRelevantEvents = null;
10979                                interaction.mutatedEvents = createEmptyEventStore();
10980                            }
10981                        }
10982                    }
10983                    else {
10984                        receivingContext = null;
10985                    }
10986                }
10987                _this.displayDrag(receivingContext, interaction);
10988                if (!isInvalid) {
10989                    enableCursor();
10990                }
10991                else {
10992                    disableCursor();
10993                }
10994                if (!isFinal) {
10995                    if (initialContext === receivingContext && // TODO: write test for this
10996                        isHitsEqual(initialHit, hit)) {
10997                        mutation = null;
10998                    }
10999                    _this.dragging.setMirrorNeedsRevert(!mutation);
11000                    // render the mirror if no already-rendered mirror
11001                    // TODO: wish we could somehow wait for dispatch to guarantee render
11002                    _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-event-mirror'));
11003                    // assign states based on new hit
11004                    _this.receivingContext = receivingContext;
11005                    _this.validMutation = mutation;
11006                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
11007                }
11008            };
11009            _this.handlePointerUp = function () {
11010                if (!_this.isDragging) {
11011                    _this.cleanup(); // because handleDragEnd won't fire
11012                }
11013            };
11014            _this.handleDragEnd = function (ev) {
11015                if (_this.isDragging) {
11016                    var initialContext_1 = _this.component.context;
11017                    var initialView = initialContext_1.viewApi;
11018                    var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation;
11019                    var eventDef = _this.eventRange.def;
11020                    var eventInstance = _this.eventRange.instance;
11021                    var eventApi = new EventApi(initialContext_1, eventDef, eventInstance);
11022                    var relevantEvents_1 = _this.relevantEvents;
11023                    var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents;
11024                    var finalHit = _this.hitDragging.finalHit;
11025                    _this.clearDrag(); // must happen after revert animation
11026                    initialContext_1.emitter.trigger('eventDragStop', {
11027                        el: _this.subjectEl,
11028                        event: eventApi,
11029                        jsEvent: ev.origEvent,
11030                        view: initialView,
11031                    });
11032                    if (validMutation) {
11033                        // dropped within same calendar
11034                        if (receivingContext_1 === initialContext_1) {
11035                            var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null);
11036                            initialContext_1.dispatch({
11037                                type: 'MERGE_EVENTS',
11038                                eventStore: mutatedRelevantEvents_1,
11039                            });
11040                            var eventChangeArg = {
11041                                oldEvent: eventApi,
11042                                event: updatedEventApi,
11043                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance),
11044                                revert: function () {
11045                                    initialContext_1.dispatch({
11046                                        type: 'MERGE_EVENTS',
11047                                        eventStore: relevantEvents_1, // the pre-change data
11048                                    });
11049                                },
11050                            };
11051                            var transformed = {};
11052                            for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) {
11053                                var transformer = _b[_i];
11054                                __assign(transformed, transformer(validMutation, initialContext_1));
11055                            }
11056                            initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView }));
11057                            initialContext_1.emitter.trigger('eventChange', eventChangeArg);
11058                            // dropped in different calendar
11059                        }
11060                        else if (receivingContext_1) {
11061                            var eventRemoveArg = {
11062                                event: eventApi,
11063                                relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance),
11064                                revert: function () {
11065                                    initialContext_1.dispatch({
11066                                        type: 'MERGE_EVENTS',
11067                                        eventStore: relevantEvents_1,
11068                                    });
11069                                },
11070                            };
11071                            initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView }));
11072                            initialContext_1.dispatch({
11073                                type: 'REMOVE_EVENTS',
11074                                eventStore: relevantEvents_1,
11075                            });
11076                            initialContext_1.emitter.trigger('eventRemove', eventRemoveArg);
11077                            var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId];
11078                            var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId];
11079                            var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance);
11080                            receivingContext_1.dispatch({
11081                                type: 'MERGE_EVENTS',
11082                                eventStore: mutatedRelevantEvents_1,
11083                            });
11084                            var eventAddArg = {
11085                                event: addedEventApi,
11086                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance),
11087                                revert: function () {
11088                                    receivingContext_1.dispatch({
11089                                        type: 'REMOVE_EVENTS',
11090                                        eventStore: mutatedRelevantEvents_1,
11091                                    });
11092                                },
11093                            };
11094                            receivingContext_1.emitter.trigger('eventAdd', eventAddArg);
11095                            if (ev.isTouch) {
11096                                receivingContext_1.dispatch({
11097                                    type: 'SELECT_EVENT',
11098                                    eventInstanceId: eventInstance.instanceId,
11099                                });
11100                            }
11101                            receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi }));
11102                            receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi }));
11103                        }
11104                    }
11105                    else {
11106                        initialContext_1.emitter.trigger('_noEventDrop');
11107                    }
11108                }
11109                _this.cleanup();
11110            };
11111            var component = _this.component;
11112            var options = component.context.options;
11113            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
11114            dragging.pointer.selector = EventDragging.SELECTOR;
11115            dragging.touchScrollAllowed = false;
11116            dragging.autoScroller.isEnabled = options.dragScroll;
11117            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore);
11118            hitDragging.useSubjectCenter = settings.useEventCenter;
11119            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
11120            hitDragging.emitter.on('dragstart', _this.handleDragStart);
11121            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
11122            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
11123            hitDragging.emitter.on('dragend', _this.handleDragEnd);
11124            return _this;
11125        }
11126        EventDragging.prototype.destroy = function () {
11127            this.dragging.destroy();
11128        };
11129        // render a drag state on the next receivingCalendar
11130        EventDragging.prototype.displayDrag = function (nextContext, state) {
11131            var initialContext = this.component.context;
11132            var prevContext = this.receivingContext;
11133            // does the previous calendar need to be cleared?
11134            if (prevContext && prevContext !== nextContext) {
11135                // does the initial calendar need to be cleared?
11136                // if so, don't clear all the way. we still need to to hide the affectedEvents
11137                if (prevContext === initialContext) {
11138                    prevContext.dispatch({
11139                        type: 'SET_EVENT_DRAG',
11140                        state: {
11141                            affectedEvents: state.affectedEvents,
11142                            mutatedEvents: createEmptyEventStore(),
11143                            isEvent: true,
11144                        },
11145                    });
11146                    // completely clear the old calendar if it wasn't the initial
11147                }
11148                else {
11149                    prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11150                }
11151            }
11152            if (nextContext) {
11153                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
11154            }
11155        };
11156        EventDragging.prototype.clearDrag = function () {
11157            var initialCalendar = this.component.context;
11158            var receivingContext = this.receivingContext;
11159            if (receivingContext) {
11160                receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11161            }
11162            // the initial calendar might have an dummy drag state from displayDrag
11163            if (initialCalendar !== receivingContext) {
11164                initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
11165            }
11166        };
11167        EventDragging.prototype.cleanup = function () {
11168            this.subjectSeg = null;
11169            this.isDragging = false;
11170            this.eventRange = null;
11171            this.relevantEvents = null;
11172            this.receivingContext = null;
11173            this.validMutation = null;
11174            this.mutatedRelevantEvents = null;
11175        };
11176        // TODO: test this in IE11
11177        // QUESTION: why do we need it on the resizable???
11178        EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable';
11179        return EventDragging;
11180    }(Interaction));
11181    function computeEventMutation(hit0, hit1, massagers) {
11182        var dateSpan0 = hit0.dateSpan;
11183        var dateSpan1 = hit1.dateSpan;
11184        var date0 = dateSpan0.range.start;
11185        var date1 = dateSpan1.range.start;
11186        var standardProps = {};
11187        if (dateSpan0.allDay !== dateSpan1.allDay) {
11188            standardProps.allDay = dateSpan1.allDay;
11189            standardProps.hasEnd = hit1.context.options.allDayMaintainDuration;
11190            if (dateSpan1.allDay) {
11191                // means date1 is already start-of-day,
11192                // but date0 needs to be converted
11193                date0 = startOfDay(date0);
11194            }
11195        }
11196        var delta = diffDates(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ?
11197            hit0.largeUnit :
11198            null);
11199        if (delta.milliseconds) { // has hours/minutes/seconds
11200            standardProps.allDay = false;
11201        }
11202        var mutation = {
11203            datesDelta: delta,
11204            standardProps: standardProps,
11205        };
11206        for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
11207            var massager = massagers_1[_i];
11208            massager(mutation, hit0, hit1);
11209        }
11210        return mutation;
11211    }
11212    function getComponentTouchDelay(component) {
11213        var options = component.context.options;
11214        var delay = options.eventLongPressDelay;
11215        if (delay == null) {
11216            delay = options.longPressDelay;
11217        }
11218        return delay;
11219    }
11220
11221    var EventResizing = /** @class */ (function (_super) {
11222        __extends(EventResizing, _super);
11223        function EventResizing(settings) {
11224            var _this = _super.call(this, settings) || this;
11225            // internal state
11226            _this.draggingSegEl = null;
11227            _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
11228            _this.eventRange = null;
11229            _this.relevantEvents = null;
11230            _this.validMutation = null;
11231            _this.mutatedRelevantEvents = null;
11232            _this.handlePointerDown = function (ev) {
11233                var component = _this.component;
11234                var segEl = _this.querySegEl(ev);
11235                var seg = getElSeg(segEl);
11236                var eventRange = _this.eventRange = seg.eventRange;
11237                _this.dragging.minDistance = component.context.options.eventDragMinDistance;
11238                // if touch, need to be working with a selected event
11239                _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
11240                    (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
11241            };
11242            _this.handleDragStart = function (ev) {
11243                var context = _this.component.context;
11244                var eventRange = _this.eventRange;
11245                _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId);
11246                var segEl = _this.querySegEl(ev);
11247                _this.draggingSegEl = segEl;
11248                _this.draggingSeg = getElSeg(segEl);
11249                context.calendarApi.unselect();
11250                context.emitter.trigger('eventResizeStart', {
11251                    el: segEl,
11252                    event: new EventApi(context, eventRange.def, eventRange.instance),
11253                    jsEvent: ev.origEvent,
11254                    view: context.viewApi,
11255                });
11256            };
11257            _this.handleHitUpdate = function (hit, isFinal, ev) {
11258                var context = _this.component.context;
11259                var relevantEvents = _this.relevantEvents;
11260                var initialHit = _this.hitDragging.initialHit;
11261                var eventInstance = _this.eventRange.instance;
11262                var mutation = null;
11263                var mutatedRelevantEvents = null;
11264                var isInvalid = false;
11265                var interaction = {
11266                    affectedEvents: relevantEvents,
11267                    mutatedEvents: createEmptyEventStore(),
11268                    isEvent: true,
11269                };
11270                if (hit) {
11271                    var disallowed = hit.componentId === initialHit.componentId
11272                        && _this.isHitComboAllowed
11273                        && !_this.isHitComboAllowed(initialHit, hit);
11274                    if (!disallowed) {
11275                        mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range);
11276                    }
11277                }
11278                if (mutation) {
11279                    mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context);
11280                    interaction.mutatedEvents = mutatedRelevantEvents;
11281                    if (!isInteractionValid(interaction, hit.dateProfile, context)) {
11282                        isInvalid = true;
11283                        mutation = null;
11284                        mutatedRelevantEvents = null;
11285                        interaction.mutatedEvents = null;
11286                    }
11287                }
11288                if (mutatedRelevantEvents) {
11289                    context.dispatch({
11290                        type: 'SET_EVENT_RESIZE',
11291                        state: interaction,
11292                    });
11293                }
11294                else {
11295                    context.dispatch({ type: 'UNSET_EVENT_RESIZE' });
11296                }
11297                if (!isInvalid) {
11298                    enableCursor();
11299                }
11300                else {
11301                    disableCursor();
11302                }
11303                if (!isFinal) {
11304                    if (mutation && isHitsEqual(initialHit, hit)) {
11305                        mutation = null;
11306                    }
11307                    _this.validMutation = mutation;
11308                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
11309                }
11310            };
11311            _this.handleDragEnd = function (ev) {
11312                var context = _this.component.context;
11313                var eventDef = _this.eventRange.def;
11314                var eventInstance = _this.eventRange.instance;
11315                var eventApi = new EventApi(context, eventDef, eventInstance);
11316                var relevantEvents = _this.relevantEvents;
11317                var mutatedRelevantEvents = _this.mutatedRelevantEvents;
11318                context.emitter.trigger('eventResizeStop', {
11319                    el: _this.draggingSegEl,
11320                    event: eventApi,
11321                    jsEvent: ev.origEvent,
11322                    view: context.viewApi,
11323                });
11324                if (_this.validMutation) {
11325                    var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
11326                    context.dispatch({
11327                        type: 'MERGE_EVENTS',
11328                        eventStore: mutatedRelevantEvents,
11329                    });
11330                    var eventChangeArg = {
11331                        oldEvent: eventApi,
11332                        event: updatedEventApi,
11333                        relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance),
11334                        revert: function () {
11335                            context.dispatch({
11336                                type: 'MERGE_EVENTS',
11337                                eventStore: relevantEvents, // the pre-change events
11338                            });
11339                        },
11340                    };
11341                    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 }));
11342                    context.emitter.trigger('eventChange', eventChangeArg);
11343                }
11344                else {
11345                    context.emitter.trigger('_noEventResize');
11346                }
11347                // reset all internal state
11348                _this.draggingSeg = null;
11349                _this.relevantEvents = null;
11350                _this.validMutation = null;
11351                // okay to keep eventInstance around. useful to set it in handlePointerDown
11352            };
11353            var component = settings.component;
11354            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
11355            dragging.pointer.selector = '.fc-event-resizer';
11356            dragging.touchScrollAllowed = false;
11357            dragging.autoScroller.isEnabled = component.context.options.dragScroll;
11358            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
11359            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
11360            hitDragging.emitter.on('dragstart', _this.handleDragStart);
11361            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
11362            hitDragging.emitter.on('dragend', _this.handleDragEnd);
11363            return _this;
11364        }
11365        EventResizing.prototype.destroy = function () {
11366            this.dragging.destroy();
11367        };
11368        EventResizing.prototype.querySegEl = function (ev) {
11369            return elementClosest(ev.subjectEl, '.fc-event');
11370        };
11371        return EventResizing;
11372    }(Interaction));
11373    function computeMutation(hit0, hit1, isFromStart, instanceRange) {
11374        var dateEnv = hit0.context.dateEnv;
11375        var date0 = hit0.dateSpan.range.start;
11376        var date1 = hit1.dateSpan.range.start;
11377        var delta = diffDates(date0, date1, dateEnv, hit0.largeUnit);
11378        if (isFromStart) {
11379            if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
11380                return { startDelta: delta };
11381            }
11382        }
11383        else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
11384            return { endDelta: delta };
11385        }
11386        return null;
11387    }
11388
11389    var UnselectAuto = /** @class */ (function () {
11390        function UnselectAuto(context) {
11391            var _this = this;
11392            this.context = context;
11393            this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
11394            this.matchesCancel = false;
11395            this.matchesEvent = false;
11396            this.onSelect = function (selectInfo) {
11397                if (selectInfo.jsEvent) {
11398                    _this.isRecentPointerDateSelect = true;
11399                }
11400            };
11401            this.onDocumentPointerDown = function (pev) {
11402                var unselectCancel = _this.context.options.unselectCancel;
11403                var downEl = pev.origEvent.target;
11404                _this.matchesCancel = !!elementClosest(downEl, unselectCancel);
11405                _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event?
11406            };
11407            this.onDocumentPointerUp = function (pev) {
11408                var context = _this.context;
11409                var documentPointer = _this.documentPointer;
11410                var calendarState = context.getCurrentData();
11411                // touch-scrolling should never unfocus any type of selection
11412                if (!documentPointer.wasTouchScroll) {
11413                    if (calendarState.dateSelection && // an existing date selection?
11414                        !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
11415                    ) {
11416                        var unselectAuto = context.options.unselectAuto;
11417                        if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) {
11418                            context.calendarApi.unselect(pev);
11419                        }
11420                    }
11421                    if (calendarState.eventSelection && // an existing event selected?
11422                        !_this.matchesEvent // interaction DIDN'T start on an event
11423                    ) {
11424                        context.dispatch({ type: 'UNSELECT_EVENT' });
11425                    }
11426                }
11427                _this.isRecentPointerDateSelect = false;
11428            };
11429            var documentPointer = this.documentPointer = new PointerDragging(document);
11430            documentPointer.shouldIgnoreMove = true;
11431            documentPointer.shouldWatchScroll = false;
11432            documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);
11433            documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
11434            /*
11435            TODO: better way to know about whether there was a selection with the pointer
11436            */
11437            context.emitter.on('select', this.onSelect);
11438        }
11439        UnselectAuto.prototype.destroy = function () {
11440            this.context.emitter.off('select', this.onSelect);
11441            this.documentPointer.destroy();
11442        };
11443        return UnselectAuto;
11444    }());
11445
11446    var OPTION_REFINERS$3 = {
11447        fixedMirrorParent: identity,
11448    };
11449    var LISTENER_REFINERS = {
11450        dateClick: identity,
11451        eventDragStart: identity,
11452        eventDragStop: identity,
11453        eventDrop: identity,
11454        eventResizeStart: identity,
11455        eventResizeStop: identity,
11456        eventResize: identity,
11457        drop: identity,
11458        eventReceive: identity,
11459        eventLeave: identity,
11460    };
11461
11462    /*
11463    Given an already instantiated draggable object for one-or-more elements,
11464    Interprets any dragging as an attempt to drag an events that lives outside
11465    of a calendar onto a calendar.
11466    */
11467    var ExternalElementDragging = /** @class */ (function () {
11468        function ExternalElementDragging(dragging, suppliedDragMeta) {
11469            var _this = this;
11470            this.receivingContext = null;
11471            this.droppableEvent = null; // will exist for all drags, even if create:false
11472            this.suppliedDragMeta = null;
11473            this.dragMeta = null;
11474            this.handleDragStart = function (ev) {
11475                _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
11476            };
11477            this.handleHitUpdate = function (hit, isFinal, ev) {
11478                var dragging = _this.hitDragging.dragging;
11479                var receivingContext = null;
11480                var droppableEvent = null;
11481                var isInvalid = false;
11482                var interaction = {
11483                    affectedEvents: createEmptyEventStore(),
11484                    mutatedEvents: createEmptyEventStore(),
11485                    isEvent: _this.dragMeta.create,
11486                };
11487                if (hit) {
11488                    receivingContext = hit.context;
11489                    if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) {
11490                        droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext);
11491                        interaction.mutatedEvents = eventTupleToStore(droppableEvent);
11492                        isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext);
11493                        if (isInvalid) {
11494                            interaction.mutatedEvents = createEmptyEventStore();
11495                            droppableEvent = null;
11496                        }
11497                    }
11498                }
11499                _this.displayDrag(receivingContext, interaction);
11500                // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
11501                // TODO: wish we could somehow wait for dispatch to guarantee render
11502                dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror'));
11503                if (!isInvalid) {
11504                    enableCursor();
11505                }
11506                else {
11507                    disableCursor();
11508                }
11509                if (!isFinal) {
11510                    dragging.setMirrorNeedsRevert(!droppableEvent);
11511                    _this.receivingContext = receivingContext;
11512                    _this.droppableEvent = droppableEvent;
11513                }
11514            };
11515            this.handleDragEnd = function (pev) {
11516                var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent;
11517                _this.clearDrag();
11518                if (receivingContext && droppableEvent) {
11519                    var finalHit = _this.hitDragging.finalHit;
11520                    var finalView = finalHit.context.viewApi;
11521                    var dragMeta = _this.dragMeta;
11522                    receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView }));
11523                    if (dragMeta.create) {
11524                        var addingEvents_1 = eventTupleToStore(droppableEvent);
11525                        receivingContext.dispatch({
11526                            type: 'MERGE_EVENTS',
11527                            eventStore: addingEvents_1,
11528                        });
11529                        if (pev.isTouch) {
11530                            receivingContext.dispatch({
11531                                type: 'SELECT_EVENT',
11532                                eventInstanceId: droppableEvent.instance.instanceId,
11533                            });
11534                        }
11535                        // signal that an external event landed
11536                        receivingContext.emitter.trigger('eventReceive', {
11537                            event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance),
11538                            relatedEvents: [],
11539                            revert: function () {
11540                                receivingContext.dispatch({
11541                                    type: 'REMOVE_EVENTS',
11542                                    eventStore: addingEvents_1,
11543                                });
11544                            },
11545                            draggedEl: pev.subjectEl,
11546                            view: finalView,
11547                        });
11548                    }
11549                }
11550                _this.receivingContext = null;
11551                _this.droppableEvent = null;
11552            };
11553            var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore);
11554            hitDragging.requireInitial = false; // will start outside of a component
11555            hitDragging.emitter.on('dragstart', this.handleDragStart);
11556            hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
11557            hitDragging.emitter.on('dragend', this.handleDragEnd);
11558            this.suppliedDragMeta = suppliedDragMeta;
11559        }
11560        ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) {
11561            if (typeof this.suppliedDragMeta === 'object') {
11562                return parseDragMeta(this.suppliedDragMeta);
11563            }
11564            if (typeof this.suppliedDragMeta === 'function') {
11565                return parseDragMeta(this.suppliedDragMeta(subjectEl));
11566            }
11567            return getDragMetaFromEl(subjectEl);
11568        };
11569        ExternalElementDragging.prototype.displayDrag = function (nextContext, state) {
11570            var prevContext = this.receivingContext;
11571            if (prevContext && prevContext !== nextContext) {
11572                prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11573            }
11574            if (nextContext) {
11575                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
11576            }
11577        };
11578        ExternalElementDragging.prototype.clearDrag = function () {
11579            if (this.receivingContext) {
11580                this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11581            }
11582        };
11583        ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) {
11584            var dropAccept = receivingContext.options.dropAccept;
11585            if (typeof dropAccept === 'function') {
11586                return dropAccept.call(receivingContext.calendarApi, el);
11587            }
11588            if (typeof dropAccept === 'string' && dropAccept) {
11589                return Boolean(elementMatches(el, dropAccept));
11590            }
11591            return true;
11592        };
11593        return ExternalElementDragging;
11594    }());
11595    // Utils for computing event store from the DragMeta
11596    // ----------------------------------------------------------------------------------------------------
11597    function computeEventForDateSpan(dateSpan, dragMeta, context) {
11598        var defProps = __assign({}, dragMeta.leftoverProps);
11599        for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) {
11600            var transform = _a[_i];
11601            __assign(defProps, transform(dateSpan, dragMeta));
11602        }
11603        var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra;
11604        var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd
11605        context);
11606        var start = dateSpan.range.start;
11607        // only rely on time info if drop zone is all-day,
11608        // otherwise, we already know the time
11609        if (dateSpan.allDay && dragMeta.startTime) {
11610            start = context.dateEnv.add(start, dragMeta.startTime);
11611        }
11612        var end = dragMeta.duration ?
11613            context.dateEnv.add(start, dragMeta.duration) :
11614            getDefaultEventEnd(dateSpan.allDay, start, context);
11615        var instance = createEventInstance(def.defId, { start: start, end: end });
11616        return { def: def, instance: instance };
11617    }
11618    // Utils for extracting data from element
11619    // ----------------------------------------------------------------------------------------------------
11620    function getDragMetaFromEl(el) {
11621        var str = getEmbeddedElData(el, 'event');
11622        var obj = str ?
11623            JSON.parse(str) :
11624            { create: false }; // if no embedded data, assume no event creation
11625        return parseDragMeta(obj);
11626    }
11627    config.dataAttrPrefix = '';
11628    function getEmbeddedElData(el, name) {
11629        var prefix = config.dataAttrPrefix;
11630        var prefixedName = (prefix ? prefix + '-' : '') + name;
11631        return el.getAttribute('data-' + prefixedName) || '';
11632    }
11633
11634    /*
11635    Makes an element (that is *external* to any calendar) draggable.
11636    Can pass in data that determines how an event will be created when dropped onto a calendar.
11637    Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
11638    */
11639    var ExternalDraggable = /** @class */ (function () {
11640        function ExternalDraggable(el, settings) {
11641            var _this = this;
11642            if (settings === void 0) { settings = {}; }
11643            this.handlePointerDown = function (ev) {
11644                var dragging = _this.dragging;
11645                var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
11646                dragging.minDistance =
11647                    minDistance != null ?
11648                        minDistance :
11649                        (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance);
11650                dragging.delay =
11651                    ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
11652                        (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) :
11653                        0;
11654            };
11655            this.handleDragStart = function (ev) {
11656                if (ev.isTouch &&
11657                    _this.dragging.delay &&
11658                    ev.subjectEl.classList.contains('fc-event')) {
11659                    _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected');
11660                }
11661            };
11662            this.settings = settings;
11663            var dragging = this.dragging = new FeaturefulElementDragging(el);
11664            dragging.touchScrollAllowed = false;
11665            if (settings.itemSelector != null) {
11666                dragging.pointer.selector = settings.itemSelector;
11667            }
11668            if (settings.appendTo != null) {
11669                dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
11670            }
11671            dragging.emitter.on('pointerdown', this.handlePointerDown);
11672            dragging.emitter.on('dragstart', this.handleDragStart);
11673            new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new
11674        }
11675        ExternalDraggable.prototype.destroy = function () {
11676            this.dragging.destroy();
11677        };
11678        return ExternalDraggable;
11679    }());
11680
11681    /*
11682    Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
11683    The third-party system is responsible for drawing the visuals effects of the drag.
11684    This class simply monitors for pointer movements and fires events.
11685    It also has the ability to hide the moving element (the "mirror") during the drag.
11686    */
11687    var InferredElementDragging = /** @class */ (function (_super) {
11688        __extends(InferredElementDragging, _super);
11689        function InferredElementDragging(containerEl) {
11690            var _this = _super.call(this, containerEl) || this;
11691            _this.shouldIgnoreMove = false;
11692            _this.mirrorSelector = '';
11693            _this.currentMirrorEl = null;
11694            _this.handlePointerDown = function (ev) {
11695                _this.emitter.trigger('pointerdown', ev);
11696                if (!_this.shouldIgnoreMove) {
11697                    // fire dragstart right away. does not support delay or min-distance
11698                    _this.emitter.trigger('dragstart', ev);
11699                }
11700            };
11701            _this.handlePointerMove = function (ev) {
11702                if (!_this.shouldIgnoreMove) {
11703                    _this.emitter.trigger('dragmove', ev);
11704                }
11705            };
11706            _this.handlePointerUp = function (ev) {
11707                _this.emitter.trigger('pointerup', ev);
11708                if (!_this.shouldIgnoreMove) {
11709                    // fire dragend right away. does not support a revert animation
11710                    _this.emitter.trigger('dragend', ev);
11711                }
11712            };
11713            var pointer = _this.pointer = new PointerDragging(containerEl);
11714            pointer.emitter.on('pointerdown', _this.handlePointerDown);
11715            pointer.emitter.on('pointermove', _this.handlePointerMove);
11716            pointer.emitter.on('pointerup', _this.handlePointerUp);
11717            return _this;
11718        }
11719        InferredElementDragging.prototype.destroy = function () {
11720            this.pointer.destroy();
11721        };
11722        InferredElementDragging.prototype.setIgnoreMove = function (bool) {
11723            this.shouldIgnoreMove = bool;
11724        };
11725        InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
11726            if (bool) {
11727                // restore a previously hidden element.
11728                // use the reference in case the selector class has already been removed.
11729                if (this.currentMirrorEl) {
11730                    this.currentMirrorEl.style.visibility = '';
11731                    this.currentMirrorEl = null;
11732                }
11733            }
11734            else {
11735                var mirrorEl = this.mirrorSelector ?
11736                    document.querySelector(this.mirrorSelector) :
11737                    null;
11738                if (mirrorEl) {
11739                    this.currentMirrorEl = mirrorEl;
11740                    mirrorEl.style.visibility = 'hidden';
11741                }
11742            }
11743        };
11744        return InferredElementDragging;
11745    }(ElementDragging));
11746
11747    /*
11748    Bridges third-party drag-n-drop systems with FullCalendar.
11749    Must be instantiated and destroyed by caller.
11750    */
11751    var ThirdPartyDraggable = /** @class */ (function () {
11752        function ThirdPartyDraggable(containerOrSettings, settings) {
11753            var containerEl = document;
11754            if (
11755            // wish we could just test instanceof EventTarget, but doesn't work in IE11
11756            containerOrSettings === document ||
11757                containerOrSettings instanceof Element) {
11758                containerEl = containerOrSettings;
11759                settings = settings || {};
11760            }
11761            else {
11762                settings = (containerOrSettings || {});
11763            }
11764            var dragging = this.dragging = new InferredElementDragging(containerEl);
11765            if (typeof settings.itemSelector === 'string') {
11766                dragging.pointer.selector = settings.itemSelector;
11767            }
11768            else if (containerEl === document) {
11769                dragging.pointer.selector = '[data-event]';
11770            }
11771            if (typeof settings.mirrorSelector === 'string') {
11772                dragging.mirrorSelector = settings.mirrorSelector;
11773            }
11774            new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new
11775        }
11776        ThirdPartyDraggable.prototype.destroy = function () {
11777            this.dragging.destroy();
11778        };
11779        return ThirdPartyDraggable;
11780    }());
11781
11782    var interactionPlugin = createPlugin({
11783        componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing],
11784        calendarInteractions: [UnselectAuto],
11785        elementDraggingImpl: FeaturefulElementDragging,
11786        optionRefiners: OPTION_REFINERS$3,
11787        listenerRefiners: LISTENER_REFINERS,
11788    });
11789
11790    /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
11791    ----------------------------------------------------------------------------------------------------------------------*/
11792    // It is a manager for a Table subcomponent, which does most of the heavy lifting.
11793    // It is responsible for managing width/height.
11794    var TableView = /** @class */ (function (_super) {
11795        __extends(TableView, _super);
11796        function TableView() {
11797            var _this = _super !== null && _super.apply(this, arguments) || this;
11798            _this.headerElRef = createRef();
11799            return _this;
11800        }
11801        TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) {
11802            var _a = this, props = _a.props, context = _a.context;
11803            var sections = [];
11804            var stickyHeaderDates = getStickyHeaderDates(context.options);
11805            if (headerRowContent) {
11806                sections.push({
11807                    type: 'header',
11808                    key: 'header',
11809                    isSticky: stickyHeaderDates,
11810                    chunk: {
11811                        elRef: this.headerElRef,
11812                        tableClassName: 'fc-col-header',
11813                        rowContent: headerRowContent,
11814                    },
11815                });
11816            }
11817            sections.push({
11818                type: 'body',
11819                key: 'body',
11820                liquid: true,
11821                chunk: { content: bodyContent },
11822            });
11823            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygri
11823d'].concat(classNames).join(' ') },
11824                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); }));
11825        };
11826        TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) {
11827            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
11828            if (!ScrollGrid) {
11829                throw new Error('No ScrollGrid implementation');
11830            }
11831            var _a = this, props = _a.props, context = _a.context;
11832            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
11833            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
11834            var sections = [];
11835            if (headerRowContent) {
11836                sections.push({
11837                    type: 'header',
11838                    key: 'header',
11839                    isSticky: stickyHeaderDates,
11840                    chunks: [{
11841                            key: 'main',
11842                            elRef: this.headerElRef,
11843                            tableClassName: 'fc-col-header',
11844                            rowContent: headerRowContent,
11845                        }],
11846                });
11847            }
11848            sections.push({
11849                type: 'body',
11850                key: 'body',
11851                liquid: true,
11852                chunks: [{
11853                        key: 'main',
11854                        content: bodyContent,
11855                    }],
11856            });
11857            if (stickyFooterScrollbar) {
11858                sections.push({
11859                    type: 'footer',
11860                    key: 'footer',
11861                    isSticky: true,
11862                    chunks: [{
11863                            key: 'main',
11864                            content: renderScrollShim,
11865                        }],
11866                });
11867            }
11868            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') },
11869                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); }));
11870        };
11871        return TableView;
11872    }(DateComponent));
11873
11874    function splitSegsByRow(segs, rowCnt) {
11875        var byRow = [];
11876        for (var i = 0; i < rowCnt; i += 1) {
11877            byRow[i] = [];
11878        }
11879        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
11880            var seg = segs_1[_i];
11881            byRow[seg.row].push(seg);
11882        }
11883        return byRow;
11884    }
11885    function splitSegsByFirstCol(segs, colCnt) {
11886        var byCol = [];
11887        for (var i = 0; i < colCnt; i += 1) {
11888            byCol[i] = [];
11889        }
11890        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
11891            var seg = segs_2[_i];
11892            byCol[seg.firstCol].push(seg);
11893        }
11894        return byCol;
11895    }
11896    function splitInteractionByRow(ui, rowCnt) {
11897        var byRow = [];
11898        if (!ui) {
11899            for (var i = 0; i < rowCnt; i += 1) {
11900                byRow[i] = null;
11901            }
11902        }
11903        else {
11904            for (var i = 0; i < rowCnt; i += 1) {
11905                byRow[i] = {
11906                    affectedInstances: ui.affectedInstances,
11907                    isEvent: ui.isEvent,
11908                    segs: [],
11909                };
11910            }
11911            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
11912                var seg = _a[_i];
11913                byRow[seg.row].segs.push(seg);
11914            }
11915        }
11916        return byRow;
11917    }
11918
11919    var TableCellTop = /** @class */ (function (_super) {
11920        __extends(TableCellTop, _super);
11921        function TableCellTop() {
11922            return _super !== null && _super.apply(this, arguments) || this;
11923        }
11924        TableCellTop.prototype.render = function () {
11925            var props = this.props;
11926            var navLinkAttrs = this.context.options.navLinks
11927                ? { 'data-navlink': buildNavLinkData(props.date), tabIndex: 0 }
11928                : {};
11929            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) && (createElement("div", { className: "fc-daygri
11929d-day-top", ref: innerElRef },
11930                createElement("a", __assign({ className: "fc-daygrid-day-number" }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0"))))); }));
11931        };
11932        return TableCellTop;
11933    }(BaseComponent));
11934    function renderTopInner(props) {
11935        return props.dayNumberText;
11936    }
11937
11938    var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({
11939        hour: 'numeric',
11940        minute: '2-digit',
11941        omitZeroMinute: true,
11942        meridiem: 'narrow',
11943    });
11944    function hasListItemDisplay(seg) {
11945        var display = seg.eventRange.ui.display;
11946        return display === 'list-item' || (display === 'auto' &&
11947            !seg.eventRange.def.allDay &&
11948            seg.firstCol === seg.lastCol && // can't be multi-day
11949            seg.isStart && // "
11950            seg.isEnd // "
11951        );
11952    }
11953
11954    var TableBlockEvent = /** @class */ (function (_super) {
11955        __extends(TableBlockEvent, _super);
11956        function TableBlockEvent() {
11957            return _super !== null && _super.apply(this, arguments) || this;
11958        }
11959        TableBlockEvent.prototype.render = function () {
11960            var props = this.props;
11961            return (createElement(StandardEvent, __assign({}
11961, 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 })));
11962        };
11963        return TableBlockEvent;
11964    }(BaseComponent));
11965
11966    var TableListItemEvent = /** @class */ (function (_super) {
11967        __extends(TableListItemEvent, _super);
11968        function TableListItemEvent() {
11969            return _super !== null && _super.apply(this, arguments) || this;
11970        }
11971        TableListItemEvent.prototype.render = function () {
11972            var _a = this, props = _a.props, context = _a.context;
11973            var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT;
11974            var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd);
11975            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!
11976            createElement("a", __assign({ className: ['fc-daygrid-event', 'fc-daygri
11976d-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs(props.seg)), innerContent)); }));
11977        };
11978        return TableListItemEvent;
11979    }(BaseComponent));
11980    function renderInnerContent$2(innerProps) {
11981        return (createElement(Fragment, null,
11982            createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }),
11983            innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)),
11984            createElement("div", { className: "fc-event-title" }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))));
11985    }
11986    function getSegAnchorAttrs(seg) {
11987        var url = seg.eventRange.def.url;
11988        return url ? { href: url } : {};
11989    }
11990
11991    var TableCellMoreLink = /** @class */ (function (_super) {
11992        __extends(TableCellMoreLink, _super);
11993        function TableCellMoreLink() {
11994            var _this = _super !== null && _super.apply(this, arguments) || this;
11995            _this.compileSegs = memoize(compileSegs);
11996            return _this;
11997        }
11998        TableCellMoreLink.prototype.render = function () {
11999            var props = this.props;
12000            var _a = this.compileSegs(props.singlePlacements), allSegs = _a.allSegs, invisibleSegs = _a.invisibleSegs;
12001            return (createElement(MoreLinkRoot, { dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, moreCnt: props.moreCnt, allSegs: allSegs, hiddenSegs: invisibleSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: function () {
12002                    var isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) ||
12003                        (props.eventResize ? props.eventResize.affectedInstances : null) ||
12004                        {};
12005                    return (createElement(Fragment, null, allSegs.map(function (seg) {
12006                        var instanceId = seg.eventRange.instance.instanceId;
12007                        return (createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: {
12008                                visibility: isForcedInvisible[instanceId] ? 'hidden' : '',
12009                            } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange))))));
12010                    })));
12011                } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick) { return (createElement("a", { ref: rootElRef, className: ['fc-daygrid-more-link'].concat(classNames).join(' '), onClick: handleClick }, innerContent)); }));
12012        };
12013        return TableCellMoreLink;
12014    }(BaseComponent));
12015    function compileSegs(singlePlacements) {
12016        var allSegs = [];
12017        var invisibleSegs = [];
12018        for (var _i = 0, singlePlacements_1 = singlePlacements; _i < singlePlacements_1.length; _i++) {
12019            var placement = singlePlacements_1[_i];
12020            allSegs.push(placement.seg);
12021            if (!placement.isVisible) {
12022                invisibleSegs.push(placement.seg);
12023            }
12024        }
12025        return { allSegs: allSegs, invisibleSegs: invisibleSegs };
12026    }
12027
12028    var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'narrow' });
12029    var TableCell = /** @class */ (function (_super) {
12030        __extends(TableCell, _super);
12031        function TableCell() {
12032            var _this = _super !== null && _super.apply(this, arguments) || this;
12033            _this.rootElRef = createRef();
12034            _this.handleRootEl = function (el) {
12035                setRef(_this.rootElRef, el);
12036                setRef(_this.props.elRef, el);
12037            };
12038            return _this;
12039        }
12040        TableCell.prototype.render = function () {
12041            var _a = this, props = _a.props, context = _a.context, rootElRef = _a.rootElRef;
12042            var options = context.options;
12043            var date = props.date, dateProfile = props.dateProfile;
12044            var navLinkAttrs = options.navLinks
12045                ? { 'data-navlink': buildNavLinkData(date, 'week'), tabIndex: 0 }
12046                : {};
12047            return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, elRef: this.handleRootEl }, function (dayElRef, dayClassNames, rootDataAttrs, isDisabled) { return (createElement("td", __assign({ ref: dayElRef, className: ['fc-daygri
12047d-day'].concat(dayClassNames, props.extraClassNames || []).join(' ') }, rootDataAttrs, props.extraDataAttrs),
12048                createElement("div", { className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", ref: props.innerElRef /* different from hook system! RENAME */ },
12049                    props.showWeekNumber && (createElement(WeekNumberRoot, { date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }, function (weekElRef, weekClassNames, innerElRef, innerContent) { return (createElement("a", __assign({ ref: weekElRef, className: ['fc-daygrid-week-number'].concat(weekClassNames).join(' ') }, navLinkAttrs), innerContent)); })),
12050                    !isDisabled && (createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps })),
12051                    createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef },
12052                        props.fgContent,
12053                        createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } },
12054                            createElement(TableCellMoreLink, { allDayDate: date, singlePlacements: props.singlePlacements, moreCnt: props.moreCnt, alignmentElRef: rootElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }))),
12055                    createElement("div", { className: "fc-daygrid-day-bg" }, props.bgContent)))); }));
12056        };
12057        return TableCell;
12058    }(DateComponent));
12059
12060    function computeFgSegPlacement(segs, // assumed already sorted
12061    dayMaxEvents, dayMaxEventRows, strictOrder, eventInstanceHeights, maxContentHeight, cells) {
12062        var hierarchy = new DayGridSegHierarchy();
12063        hierarchy.allowReslicing = true;
12064        hierarchy.strictOrder = strictOrder;
12065        if (dayMaxEvents === true || dayMaxEventRows === true) {
12066            hierarchy.maxCoord = maxContentHeight;
12067            hierarchy.hiddenConsumes = true;
12068        }
12069        else if (typeof dayMaxEvents === 'number') {
12070            hierarchy.maxStackCnt = dayMaxEvents;
12071        }
12072        else if (typeof dayMaxEventRows === 'number') {
12073            hierarchy.maxStackCnt = dayMaxEventRows;
12074            hierarchy.hiddenConsumes = true;
12075        }
12076        // create segInputs only for segs with known heights
12077        var segInputs = [];
12078        var unknownHeightSegs = [];
12079        for (var i = 0; i < segs.length; i += 1) {
12080            var seg = segs[i];
12081            var instanceId = seg.eventRange.instance.instanceId;
12082            var eventHeight = eventInstanceHeights[instanceId];
12083            if (eventHeight != null) {
12084                segInputs.push({
12085                    index: i,
12086                    spanStart: seg.firstCol,
12087                    spanEnd: seg.lastCol + 1,
12088                    thickness: eventHeight,
12089                });
12090            }
12091            else {
12092                unknownHeightSegs.push(seg);
12093            }
12094        }
12095        var hiddenEntries = hierarchy.addSegs(segInputs);
12096        var segRects = hierarchy.toRects();
12097        var _a = placeRects(segRects, segs, cells), singleColPlacements = _a.singleColPlacements, multiColPlacements = _a.multiColPlacements, leftoverMargins = _a.leftoverMargins;
12098        var moreCnts = [];
12099        var moreMarginTops = [];
12100        // add segs with unknown heights
12101        for (var _i = 0, unknownHeightSegs_1 = unknownHeightSegs; _i < unknownHeightSegs_1.length; _i++) {
12102            var seg = unknownHeightSegs_1[_i];
12103            multiColPlacements[seg.firstCol].push({
12104                seg: seg,
12105                isVisible: false,
12106                isAbsolute: true,
12107                absoluteTop: 0,
12108                marginTop: 0,
12109            });
12110            for (var col = seg.firstCol; col <= seg.lastCol; col += 1) {
12111                singleColPlacements[col].push({
12112                    seg: resliceSeg(seg, col, col + 1, cells),
12113                    isVisible: false,
12114                    isAbsolute: false,
12115                    absoluteTop: 0,
12116                    marginTop: 0,
12117                });
12118            }
12119        }
12120        // add the hidden entries
12121        for (var col = 0; col < cells.length; col += 1) {
12122            moreCnts.push(0);
12123        }
12124        for (var _b = 0, hiddenEntries_1 = hiddenEntries; _b < hiddenEntries_1.length; _b++) {
12125            var hiddenEntry = hiddenEntries_1[_b];
12126            var seg = segs[hiddenEntry.segInput.index];
12127            multiColPlacements[hiddenEntry.spanStart].push({
12128                seg: seg,
12129                isVisible: false,
12130                isAbsolute: true,
12131                absoluteTop: 0,
12132                marginTop: 0,
12133            });
12134            for (var col = hiddenEntry.spanStart; col < hiddenEntry.spanEnd; col += 1) {
12135                moreCnts[col] += 1;
12136                singleColPlacements[col].push({
12137                    seg: resliceSeg(seg, col, col + 1, cells),
12138                    isVisible: false,
12139                    isAbsolute: false,
12140                    absoluteTop: 0,
12141                    marginTop: 0,
12142                });
12143            }
12144        }
12145        // deal with leftover margins
12146        for (var col = 0; col < cells.length; col += 1) {
12147            moreMarginTops.push(leftoverMargins[col]);
12148        }
12149        return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, moreCnts: moreCnts, moreMarginTops: moreMarginTops };
12150    }
12151    // rects ordered by top coord, then left
12152    function placeRects(allRects, segs, cells) {
12153        var rectsByEachCol = groupRectsByEachCol(allRects, cells.length);
12154        var singleColPlacements = [];
12155        var multiColPlacements = [];
12156        var leftoverMargins = [];
12157        for (var col = 0; col < cells.length; col += 1) {
12158            var rects = rectsByEachCol[col];
12159            // compute all static segs in singlePlacements
12160            var singlePlacements = [];
12161            var currentHeight = 0;
12162            var currentMarginTop = 0;
12163            for (var _i = 0, rects_1 = rects; _i < rects_1.length; _i++) {
12164                var rect = rects_1[_i];
12165                var seg = segs[rect.segInput.index];
12166                singlePlacements.push({
12167                    seg: resliceSeg(seg, col, col + 1, cells),
12168                    isVisible: true,
12169                    isAbsolute: false,
12170                    absoluteTop: 0,
12171                    marginTop: rect.levelCoord - currentHeight,
12172                });
12173                currentHeight = rect.levelCoord + rect.thickness;
12174            }
12175            // compute mixed static/absolute segs in multiPlacements
12176            var multiPlacements = [];
12177            currentHeight = 0;
12178            currentMarginTop = 0;
12179            for (var _a = 0, rects_2 = rects; _a < rects_2.length; _a++) {
12180                var rect = rects_2[_a];
12181                var seg = segs[rect.segInput.index];
12182                var isAbsolute = rect.spanEnd - rect.spanStart > 1; // multi-column?
12183                var isFirstCol = rect.spanStart === col;
12184                currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg
12185                currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg
12186                if (isAbsolute) {
12187                    currentMarginTop += rect.thickness;
12188                    if (isFirstCol) {
12189                        multiPlacements.push({
12190                            seg: resliceSeg(seg, rect.spanStart, rect.spanEnd, cells),
12191                            isVisible: true,
12192                            isAbsolute: true,
12193                            absoluteTop: rect.levelCoord,
12194                            marginTop: 0,
12195                        });
12196                    }
12197                }
12198                else if (isFirstCol) {
12199                    multiPlacements.push({
12200                        seg: resliceSeg(seg, rect.spanStart, rect.spanEnd, cells),
12201                        isVisible: true,
12202                        isAbsolute: false,
12203                        absoluteTop: 0,
12204                        marginTop: currentMarginTop, // claim the margin
12205                    });
12206                    currentMarginTop = 0;
12207                }
12208            }
12209            singleColPlacements.push(singlePlacements);
12210            multiColPlacements.push(multiPlacements);
12211            leftoverMargins.push(currentMarginTop);
12212        }
12213        return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, leftoverMargins: leftoverMargins };
12214    }
12215    function groupRectsByEachCol(rects, colCnt) {
12216        var rectsByEachCol = [];
12217        for (var col = 0; col < colCnt; col += 1) {
12218            rectsByEachCol.push([]);
12219        }
12220        for (var _i = 0, rects_3 = rects; _i < rects_3.length; _i++) {
12221            var rect = rects_3[_i];
12222            for (var col = rect.spanStart; col < rect.spanEnd; col += 1) {
12223                rectsByEachCol[col].push(rect);
12224            }
12225        }
12226        return rectsByEachCol;
12227    }
12228    function resliceSeg(seg, spanStart, spanEnd, cells) {
12229        if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) {
12230            return seg;
12231        }
12232        var eventRange = seg.eventRange;
12233        var origRange = eventRange.range;
12234        var slicedRange = intersectRanges(origRange, {
12235            start: cells[spanStart].date,
12236            end: addDays(cells[spanEnd - 1].date, 1),
12237        });
12238        return __assign(__assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: {
12239                def: eventRange.def,
12240                ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }),
12241                instance: eventRange.instance,
12242                range: slicedRange,
12243            }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() });
12244    }
12245    var DayGridSegHierarchy = /** @class */ (function (_super) {
12246        __extends(DayGridSegHierarchy, _super);
12247        function DayGridSegHierarchy() {
12248            var _this = _super !== null && _super.apply(this, arguments) || this;
12249            // config
12250            _this.hiddenConsumes = false;
12251            // allows us to keep hidden entries in the hierarchy so they take up space
12252            _this.forceHidden = {};
12253            return _this;
12254        }
12255        DayGridSegHierarchy.prototype.addSegs = function (segInputs) {
12256            var _this = this;
12257            var hiddenSegs = _super.prototype.addSegs.call(this, segInputs);
12258            var entriesByLevel = this.entriesByLevel;
12259            var excludeHidden = function (entry) { return !_this.forceHidden[buildEntryKey(entry)]; };
12260            // remove the forced-hidden segs
12261            for (var level = 0; level < entriesByLevel.length; level += 1) {
12262                entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden);
12263            }
12264            return hiddenSegs;
12265        };
12266        DayGridSegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) {
12267            var _a = this, entriesByLevel = _a.entriesByLevel, forceHidden = _a.forceHidden;
12268            var level = insertion.nextLevel - 1;
12269            if (this.hiddenConsumes && level >= 0) {
12270                for (var lateral = insertion.lateralStart; lateral < insertion.lateralEnd; lateral += 1) {
12271                    var leadingEntry = entriesByLevel[level][lateral];
12272                    if (this.allowReslicing) {
12273                        var placeholderEntry = __assign(__assign({}, leadingEntry), { spanStart: Math.max(leadingEntry.spanStart, entry.spanStart), spanEnd: Math.min(leadingEntry.spanEnd, entry.spanEnd) });
12274                        var placeholderEntryId = buildEntryKey(placeholderEntry);
12275                        if (!forceHidden[placeholderEntryId]) {
12276                            forceHidden[placeholderEntryId] = true;
12277                            entriesByLevel[level][lateral] = placeholderEntry;
12278                            this.splitEntry(leadingEntry, entry, hiddenEntries); // split up the leadingEntry
12279                        }
12280                    }
12281                    else {
12282                        var placeholderEntryId = buildEntryKey(leadingEntry);
12283                        if (!forceHidden[placeholderEntryId]) {
12284                            forceHidden[placeholderEntryId] = true;
12285                            hiddenEntries.push(leadingEntry);
12286                        }
12287                    }
12288                }
12289            }
12290            return _super.prototype.handleInvalidInsertion.call(this, insertion, entry, hiddenEntries);
12291        };
12292        return DayGridSegHierarchy;
12293    }(SegHierarchy));
12294
12295    var TableRow = /** @class */ (function (_super) {
12296        __extends(TableRow, _super);
12297        function TableRow() {
12298            var _this = _super !== null && _super.apply(this, arguments) || this;
12299            _this.cellElRefs = new RefMap(); // the <td>
12300            _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame
12301            _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events
12302            _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol"
12303            _this.rootElRef = createRef();
12304            _this.state = {
12305                framePositions: null,
12306                maxContentHeight: null,
12307                eventInstanceHeights: {},
12308            };
12309            return _this;
12310        }
12311        TableRow.prototype.render = function () {
12312            var _this = this;
12313            var _a = this, props = _a.props, state = _a.state, context = _a.context;
12314            var options = context.options;
12315            var colCnt = props.cells.length;
12316            var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt);
12317            var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt);
12318            var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt);
12319            var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt);
12320            var _b = computeFgSegPlacement(sortEventSegs(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.eventInstanceHeights, state.maxContentHeight, props.cells), singleColPlacements = _b.singleColPlacements, multiColPlacements = _b.multiColPlacements, moreCnts = _b.moreCnts, moreMarginTops = _b.moreMarginTops;
12321            var isForcedInvisible = // TODO: messy way to compute this
12322             (props.eventDrag && props.eventDrag.affectedInstances) ||
12323                (props.eventResize && props.eventResize.affectedInstances) ||
12324                {};
12325            return (createElement("tr", { ref: this.rootElRef },
12326                props.renderIntro && props.renderIntro(),
12327                props.cells.map(function (cell, col) {
12328                    var normalFgNodes = _this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible);
12329                    var mirrorFgNodes = _this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false);
12330                    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, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, moreCnt: moreCnts[col], moreMarginTop: moreMarginTops[col], singlePlacements: singleColPlacements[col], fgContentElRef: _this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys
12331                        createElement(Fragment, null,
12332                            createElement(Fragment, null, normalFgNodes),
12333                            createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys
12334                        createElement(Fragment, null,
12335                            _this.renderFillSegs(highlightSegsByCol[col], 'highlight'),
12336                            _this.renderFillSegs(businessHoursByCol[col], 'non-business'),
12337                            _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) }));
12338                })));
12339        };
12340        TableRow.prototype.componentDidMount = function () {
12341            this.updateSizing(true);
12342        };
12343        TableRow.prototype.componentDidUpdate = function (prevProps, prevState) {
12344            var currentProps = this.props;
12345            this.updateSizing(!isPropsEqual(prevProps, currentProps));
12346        };
12347        TableRow.prototype.getHighlightSegs = function () {
12348            var props = this.props;
12349            if (props.eventDrag && props.eventDrag.segs.length) { // messy check
12350                return props.eventDrag.segs;
12351            }
12352            if (props.eventResize && props.eventResize.segs.length) { // messy check
12353                return props.eventResize.segs;
12354            }
12355            return props.dateSelectionSegs;
12356        };
12357        TableRow.prototype.getMirrorSegs = function () {
12358            var props = this.props;
12359            if (props.eventResize && props.eventResize.segs.length) { // messy check
12360                return props.eventResize.segs;
12361            }
12362            return [];
12363        };
12364        TableRow.prototype.renderFgSegs = function (col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) {
12365            var context = this.context;
12366            var eventSelection = this.props.eventSelection;
12367            var framePositions = this.state.framePositions;
12368            var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1
12369            var isMirror = isDragging || isResizing || isDateSelecting;
12370            var nodes = [];
12371            if (framePositions) {
12372                for (var _i = 0, segPlacements_1 = segPlacements; _i < segPlacements_1.length; _i++) {
12373                    var placement = segPlacements_1[_i];
12374                    var seg = placement.seg;
12375                    var instanceId = seg.eventRange.instance.instanceId;
12376                    var key = instanceId + ':' + col;
12377                    var isVisible = placement.isVisible && !isForcedInvisible[instanceId];
12378                    var isAbsolute = placement.isAbsolute;
12379                    var left = '';
12380                    var right = '';
12381                    if (isAbsolute) {
12382                        if (context.isRtl) {
12383                            right = 0;
12384                            left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol];
12385                        }
12386                        else {
12387                            left = 0;
12388                            right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol];
12389                        }
12390                    }
12391                    /*
12392                    known bug: events that are force to be list-item but span multiple days still take up space in later columns
12393                    todo: in print view, for multi-day events, don't display title within non-start/end segs
12394                    */
12395                    nodes.push(createElement("div", { className: 'fc-daygrid-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: key, ref: isMirror ? null : this.segHarnessRefs.createRef(key), style: {
12396                            visibility: isVisible ? '' : 'hidden',
12397                            marginTop: isAbsolute ? '' : placement.marginTop,
12398                            top: isAbsolute ? placement.absoluteTop : '',
12399                            left: left,
12400                            right: right,
12401                        } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange))))));
12402                }
12403            }
12404            return nodes;
12405        };
12406        TableRow.prototype.renderFillSegs = function (segs, fillType) {
12407            var isRtl = this.context.isRtl;
12408            var todayRange = this.props.todayRange;
12409            var framePositions = this.state.framePositions;
12410            var nodes = [];
12411            if (framePositions) {
12412                for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
12413                    var seg = segs_1[_i];
12414                    var leftRightCss = isRtl ? {
12415                        right: 0,
12416                        left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol],
12417                    } : {
12418                        left: 0,
12419                        right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol],
12420                    };
12421                    nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ?
12422                        createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) :
12423                        renderFill(fillType)));
12424                }
12425            }
12426            return createElement.apply(void 0, __spreadArray([Fragment, {}], nodes));
12427        };
12428        TableRow.prototype.updateSizing = function (isExternalSizingChange) {
12429            var _a = this, props = _a.props, frameElRefs = _a.frameElRefs;
12430            if (!props.forPrint &&
12431                props.clientWidth !== null // positioning ready?
12432            ) {
12433                if (isExternalSizingChange) {
12434                    var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; });
12435                    if (frameEls.length) {
12436                        var originEl = this.rootElRef.current;
12437                        this.setState({
12438                            framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal
12439                            false),
12440                        });
12441                    }
12442                }
12443                var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
12444                this.setState({
12445                    eventInstanceHeights: this.queryEventInstanceHeights(),
12446                    maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null,
12447                });
12448            }
12449        };
12450        TableRow.prototype.queryEventInstanceHeights = function () {
12451            var segElMap = this.segHarnessRefs.currentMap;
12452            var eventInstanceHeights = {};
12453            // get the max height amongst instance segs
12454            for (var key in segElMap) {
12455                var height = Math.round(segElMap[key].getBoundingClientRect().height);
12456                var instanceId = key.split(':')[0]; // deconstruct how renderFgSegs makes the key
12457                eventInstanceHeights[instanceId] = Math.max(eventInstanceHeights[instanceId] || 0, height);
12458            }
12459            return eventInstanceHeights;
12460        };
12461        TableRow.prototype.computeMaxContentHeight = function () {
12462            var firstKey = this.props.cells[0].key;
12463            var cellEl = this.cellElRefs.currentMap[firstKey];
12464            var fcContainerEl = this.fgElRefs.currentMap[firstKey];
12465            return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top;
12466        };
12467        TableRow.prototype.getCellEls = function () {
12468            var elMap = this.cellElRefs.currentMap;
12469            return this.props.cells.map(function (cell) { return elMap[cell.key]; });
12470        };
12471        return TableRow;
12472    }(DateComponent));
12473    TableRow.addStateEquality({
12474        eventInstanceHeights: isPropsEqual,
12475    });
12476    function buildMirrorPlacements(mirrorSegs, colPlacements) {
12477        if (!mirrorSegs.length) {
12478            return [];
12479        }
12480        var topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render?
12481        return mirrorSegs.map(function (seg) { return ({
12482            seg: seg,
12483            isVisible: true,
12484            isAbsolute: true,
12485            absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId],
12486            marginTop: 0,
12487        }); });
12488    }
12489    function buildAbsoluteTopHash(colPlacements) {
12490        var topsByInstanceId = {};
12491        for (var _i = 0, colPlacements_1 = colPlacements; _i < colPlacements_1.length; _i++) {
12492            var placements = colPlacements_1[_i];
12493            for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) {
12494                var placement = placements_1[_a];
12495                topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop;
12496            }
12497        }
12498        return colPlacements;
12499    }
12500
12501    var Table = /** @class */ (function (_super) {
12502        __extends(Table, _super);
12503        function Table() {
12504            var _this = _super !== null && _super.apply(this, arguments) || this;
12505            _this.splitBusinessHourSegs = memoize(splitSegsByRow);
12506            _this.splitBgEventSegs = memoize(splitSegsByRow);
12507            _this.splitFgEventSegs = memoize(splitSegsByRow);
12508            _this.splitDateSelectionSegs = memoize(splitSegsByRow);
12509            _this.splitEventDrag = memoize(splitInteractionByRow);
12510            _this.splitEventResize = memoize(splitInteractionByRow);
12511            _this.rowRefs = new RefMap();
12512            _this.handleRootEl = function (rootEl) {
12513                _this.rootEl = rootEl;
12514                if (rootEl) {
12515                    _this.context.registerInteractiveComponent(_this, {
12516                        el: rootEl,
12517                        isHitComboAllowed: _this.props.isHitComboAllowed,
12518                    });
12519                }
12520                else {
12521                    _this.context.unregisterInteractiveComponent(_this);
12522                }
12523            };
12524            return _this;
12525        }
12526        Table.prototype.render = function () {
12527            var _this = this;
12528            var props = this.props;
12529            var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows;
12530            var rowCnt = props.cells.length;
12531            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
12532            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
12533            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);
12534            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);
12535            var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);
12536            var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
12537            var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true;
12538            // if rows can't expand to fill fixed height, can't do balanced-height event limit
12539            // TODO: best place to normalize these options?
12540            if (limitViaBalanced && !expandRows) {
12541                limitViaBalanced = false;
12542                dayMaxEventRows = null;
12543                dayMaxEvents = null;
12544            }
12545            var classNames = [
12546                'fc-daygrid-body',
12547                limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced',
12548                expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others?
12549            ];
12550            return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: {
12551                    // these props are important to give this wrapper correct dimensions for interactions
12552                    // TODO: if we set it here, can we avoid giving to inner tables?
12553                    width: props.clientWidth,
12554                    minWidth: props.tableMinWidth,
12555                } },
12556                createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement(Fragment, null,
12557                    createElement("table", { className: "fc-scrollgrid-sync-table", style: {
12558                            width: props.clientWidth,
12559                            minWidth: props.tableMinWidth,
12560                            height: expandRows ? props.clientHeight : '',
12561                        } },
12562                        props.colGroupNode,
12563                        createElement("tbody", null, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length
12564                                ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */
12565                                : row // in case there are no cells (like when resource view is loading)
12566                            , 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, forPrint: props.forPrint })); }))))); })));
12567        };
12568        // Hit System
12569        // ----------------------------------------------------------------------------------------------------
12570        Table.prototype.prepareHits = function () {
12571            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
12572            false, true);
12573            this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row
12574            true, // horizontal
12575            false);
12576        };
12577        Table.prototype.queryHit = function (positionLeft, positionTop) {
12578            var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
12579            var col = colPositions.leftToIndex(positionLeft);
12580            var row = rowPositions.topToIndex(positionTop);
12581            if (row != null && col != null) {
12582                var cell = this.props.cells[row][col];
12583                return {
12584                    dateProfile: this.props.dateProfile,
12585                    dateSpan: __assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan),
12586                    dayEl: this.getCellEl(row, col),
12587                    rect: {
12588                        left: colPositions.lefts[col],
12589                        right: colPositions.rights[col],
12590                        top: rowPositions.tops[row],
12591                        bottom: rowPositions.bottoms[row],
12592                    },
12593                    layer: 0,
12594                };
12595            }
12596            return null;
12597        };
12598        Table.prototype.getCellEl = function (row, col) {
12599            return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal
12600        };
12601        Table.prototype.getCellRange = function (row, col) {
12602            var start = this.props.cells[row][col].date;
12603            var end = addDays(start, 1);
12604            return { start: start, end: end };
12605        };
12606        return Table;
12607    }(DateComponent));
12608    function isSegAllDay(seg) {
12609        return seg.eventRange.def.allDay;
12610    }
12611
12612    var DayTableSlicer = /** @class */ (function (_super) {
12613        __extends(DayTableSlicer, _super);
12614        function DayTableSlicer() {
12615            var _this = _super !== null && _super.apply(this, arguments) || this;
12616            _this.forceDayIfListItem = true;
12617            return _this;
12618        }
12619        DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) {
12620            return dayTableModel.sliceRange(dateRange);
12621        };
12622        return DayTableSlicer;
12623    }(Slicer));
12624
12625    var DayTable = /** @class */ (function (_super) {
12626        __extends(DayTable, _super);
12627        function DayTable() {
12628            var _this = _super !== null && _super.apply(this, arguments) || this;
12629            _this.slicer = new DayTableSlicer();
12630            _this.tableRef = createRef();
12631            return _this;
12632        }
12633        DayTable.prototype.render = function () {
12634            var _a = this, props = _a.props, context = _a.context;
12635            return (createElement(Table, __assign({ ref: this.tableRef }, 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 })));
12636        };
12637        return DayTable;
12638    }(DateComponent));
12639
12640    var DayTableView = /** @class */ (function (_super) {
12641        __extends(DayTableView, _super);
12642        function DayTableView() {
12643            var _this = _super !== null && _super.apply(this, arguments) || this;
12644            _this.buildDayTableModel = memoize(buildDayTableModel);
12645            _this.headerRef = createRef();
12646            _this.tableRef = createRef();
12647            return _this;
12648        }
12649        DayTableView.prototype.render = function () {
12650            var _this = this;
12651            var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator;
12652            var props = this.props;
12653            var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator);
12654            var headerContent = options.dayHeaders && (createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 }));
12655            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 })); };
12656            return options.dayMinWidth
12657                ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth)
12658                : this.renderSimpleLayout(headerContent, bodyContent);
12659        };
12660        return DayTableView;
12661    }(TableView));
12662    function buildDayTableModel(dateProfile, dateProfileGenerator) {
12663        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
12664        return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
12665    }
12666
12667    var TableDateProfileGenerator = /** @class */ (function (_super) {
12668        __extends(TableDateProfileGenerator, _super);
12669        function TableDateProfileGenerator() {
12670            return _super !== null && _super.apply(this, arguments) || this;
12671        }
12672        // Computes the date range that will be rendered.
12673        TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
12674            var dateEnv = this.props.dateEnv;
12675            var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
12676            var start = renderRange.start;
12677            var end = renderRange.end;
12678            var endOfWeek;
12679            // year and month views should be aligned with weeks. this is already done for week
12680            if (/^(year|month)$/.test(currentRangeUnit)) {
12681                start = dateEnv.startOfWeek(start);
12682                // make end-of-week if not already
12683                endOfWeek = dateEnv.startOfWeek(end);
12684                if (endOfWeek.valueOf() !== end.valueOf()) {
12685                    end = addWeeks(endOfWeek, 1);
12686                }
12687            }
12688            // ensure 6 weeks
12689            if (this.props.monthMode &&
12690                this.props.fixedWeekCount) {
12691                var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
12692                diffWeeks(start, end));
12693                end = addWeeks(end, 6 - rowCnt);
12694            }
12695            return { start: start, end: end };
12696        };
12697        return TableDateProfileGenerator;
12698    }(DateProfileGenerator));
12699
12700    var dayGridPlugin = createPlugin({
12701        initialView: 'dayGridMonth',
12702        views: {
12703            dayGrid: {
12704                component: DayTableView,
12705                dateProfileGeneratorClass: TableDateProfileGenerator,
12706            },
12707            dayGridDay: {
12708                type: 'dayGrid',
12709                duration: { days: 1 },
12710            },
12711            dayGridWeek: {
12712                type: 'dayGrid',
12713                duration: { weeks: 1 },
12714            },
12715            dayGridMonth: {
12716                type: 'dayGrid',
12717                duration: { months: 1 },
12718                monthMode: true,
12719                fixedWeekCount: true,
12720            },
12721        },
12722    });
12723
12724    var AllDaySplitter = /** @class */ (function (_super) {
12725        __extends(AllDaySplitter, _super);
12726        function AllDaySplitter() {
12727            return _super !== null && _super.apply(this, arguments) || this;
12728        }
12729        AllDaySplitter.prototype.getKeyInfo = function () {
12730            return {
12731                allDay: {},
12732                timed: {},
12733            };
12734        };
12735        AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
12736            if (dateSpan.allDay) {
12737                return ['allDay'];
12738            }
12739            return ['timed'];
12740        };
12741        AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
12742            if (!eventDef.allDay) {
12743                return ['timed'];
12744            }
12745            if (hasBgRendering(eventDef)) {
12746                return ['timed', 'allDay'];
12747            }
12748            return ['allDay'];
12749        };
12750        return AllDaySplitter;
12751    }(Splitter));
12752
12753    var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({
12754        hour: 'numeric',
12755        minute: '2-digit',
12756        omitZeroMinute: true,
12757        meridiem: 'short',
12758    });
12759    function TimeColsAxisCell(props) {
12760        var classNames = [
12761            'fc-timegrid-slot',
12762            'fc-timegrid-slot-label',
12763            props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor',
12764        ];
12765        return (createElement(ViewContextType.Consumer, null, function (context) {
12766            if (!props.isLabeled) {
12767                return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr }));
12768            }
12769            var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi;
12770            var labelFormat = // TODO: fully pre-parse
12771             options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :
12772                Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) :
12773                    createFormatter(options.slotLabelFormat);
12774            var hookProps = {
12775                level: 0,
12776                time: props.time,
12777                date: dateEnv.toDate(props.date),
12778                view: viewApi,
12779                text: dateEnv.format(props.date, labelFormat),
12780            };
12781            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent$1, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
12781oncat(customClassNames).join(' '), "data-time": props.isoTimeStr },
12782                createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" },
12783                    createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); }));
12784        }));
12785    }
12786    function renderInnerContent$1(props) {
12787        return props.text;
12788    }
12789
12790    var TimeBodyAxis = /** @class */ (function (_super) {
12791        __extends(TimeBodyAxis, _super);
12792        function TimeBodyAxis() {
12793            return _super !== null && _super.apply(this, arguments) || this;
12794        }
12795        TimeBodyAxis.prototype.render = function () {
12796            return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key },
12797                createElement(TimeColsAxisCell, __assign({}, slatMeta)))); });
12798        };
12799        return TimeBodyAxis;
12800    }(BaseComponent));
12801
12802    var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'short' });
12803    var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;
12804    var TimeColsView = /** @class */ (function (_super) {
12805        __extends(TimeColsView, _super);
12806        function TimeColsView() {
12807            var _this = _super !== null && _super.apply(this, arguments) || this;
12808            _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses
12809            _this.headerElRef = createRef();
12810            _this.rootElRef = createRef();
12811            _this.scrollerElRef = createRef();
12812            _this.state = {
12813                slatCoords: null,
12814            };
12815            _this.handleScrollTopRequest = function (scrollTop) {
12816                var scrollerEl = _this.scrollerElRef.current;
12817                if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer
12818                    scrollerEl.scrollTop = scrollTop;
12819                }
12820            };
12821            /* Header Render Methods
12822            ------------------------------------------------------------------------------------------------------------------*/
12823            _this.renderHeadAxis = function (rowKey, frameHeight) {
12824                if (frameHeight === void 0) { frameHeight = ''; }
12825                var options = _this.context.options;
12826                var dateProfile = _this.props.dateProfile;
12827                var range = dateProfile.renderRange;
12828                var dayCnt = diffDays(range.start, range.end);
12829                var navLinkAttrs = (options.navLinks && dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it)
12830                    ? { 'data-navlink': buildNavLinkData(range.start, 'week'), tabIndex: 0 }
12831                    : {};
12832                if (options.weekNumbers && rowKey === 'day') {
12833                    return (createElement(WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("th", { ref: rootElRef, className: [
12834                            'fc-timegrid-axis',
12835                            'fc-scrollgrid-shrink',
12836                        ].concat(classNames).join(' ') },
12837                        createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } },
12838                            createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); }));
12839                }
12840                return (createElement("th", { className: "fc-timegrid-axis" },
12841                    createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } })));
12842            };
12843            /* Table Component Render Methods
12844            ------------------------------------------------------------------------------------------------------------------*/
12845            // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,
12846            // but DayGrid still needs to have classNames on inner elements in order to measure.
12847            _this.renderTableRowAxis = function (rowHeight) {
12848                var _a = _this.context, options = _a.options, viewApi = _a.viewApi;
12849                var hookProps = {
12850                    text: options.allDayText,
12851                    view: viewApi,
12852                };
12853                return (
12854                // TODO: make reusable hook. used in list view too
12855                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", { ref: rootElRef, className: [
12856                        'fc-timegrid-axis',
12857                        'fc-scrollgrid-shrink',
12858                    ].concat(classNames).join(' ') },
12859                    createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } },
12860                        createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); }));
12861            };
12862            _this.handleSlatCoords = function (slatCoords) {
12863                _this.setState({ slatCoords: slatCoords });
12864            };
12865            return _this;
12866        }
12867        // rendering
12868        // ----------------------------------------------------------------------------------------------------
12869        TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) {
12870            var _a = this, context = _a.context, props = _a.props;
12871            var sections = [];
12872            var stickyHeaderDates = getStickyHeaderDates(context.options);
12873            if (headerRowContent) {
12874                sections.push({
12875                    type: 'header',
12876                    key: 'header',
12877                    isSticky: stickyHeaderDates,
12878                    chunk: {
12879                        elRef: this.headerElRef,
12880                        tableClassName: 'fc-col-header',
12881                        rowContent: headerRowContent,
12882                    },
12883                });
12884            }
12885            if (allDayContent) {
12886                sections.push({
12887                    type: 'body',
12888                    key: 'all-day',
12889                    chunk: { content: allDayContent },
12890                });
12891                sections.push({
12892                    type: 'body',
12893                    key: 'all-day-divider',
12894                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
12895                    createElement("tr", { className: "fc-scrollgrid-section" },
12896                        createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
12897                });
12898            }
12899            sections.push({
12900                type: 'body',
12901                key: 'body',
12902                liquid: true,
12903                expandRows: Boolean(context.options.expandRows),
12904                chunk: {
12905                    scrollerElRef: this.scrollerElRef,
12906                    content: timeContent,
12907                },
12908            });
12909            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
12910                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); }));
12911        };
12912        TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) {
12913            var _this = this;
12914            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
12915            if (!ScrollGrid) {
12916                throw new Error('No ScrollGrid implementation');
12917            }
12918            var _a = this, context = _a.context, props = _a.props;
12919            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
12920            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
12921            var sections = [];
12922            if (headerRowContent) {
12923                sections.push({
12924                    type: 'header',
12925                    key: 'header',
12926                    isSticky: stickyHeaderDates,
12927                    syncRowHeights: true,
12928                    chunks: [
12929                        {
12930                            key: 'axis',
12931                            rowContent: function (arg) { return (createElement("tr", null, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); },
12932                        },
12933                        {
12934                            key: 'cols',
12935                            elRef: this.headerElRef,
12936                            tableClassName: 'fc-col-header',
12937                            rowContent: headerRowContent,
12938                        },
12939                    ],
12940                });
12941            }
12942            if (allDayContent) {
12943                sections.push({
12944                    type: 'body',
12945                    key: 'all-day',
12946                    syncRowHeights: true,
12947                    chunks: [
12948                        {
12949                            key: 'axis',
12950                            rowContent: function (contentArg) { return (createElement("tr", null, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); },
12951                        },
12952                        {
12953                            key: 'cols',
12954                            content: allDayContent,
12955                        },
12956                    ],
12957                });
12958                sections.push({
12959                    key: 'all-day-divider',
12960                    type: 'body',
12961                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
12962                    createElement("tr", { className: "fc-scrollgrid-section" },
12963                        createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
12964                });
12965            }
12966            var isNowIndicator = context.options.nowIndicator;
12967            sections.push({
12968                type: 'body',
12969                key: 'body',
12970                liquid: true,
12971                expandRows: Boolean(context.options.expandRows),
12972                chunks: [
12973                    {
12974                        key: 'axis',
12975                        content: function (arg) { return (
12976                        // TODO: make this now-indicator arrow more DRY with TimeColsContent
12977                        createElement("div", { className: "fc-timegrid-axis-chunk" },
12978                            createElement("table", { style: { height: arg.expandRows ? arg.clientHeight : '' } },
12979                                arg.tableColGroupNode,
12980                                createElement("tbody", null,
12981                                    createElement(TimeBodyAxis, { slatMetas: slatMetas }))),
12982                            createElement("div", { className: "fc-timegrid-now-indicator-container" },
12983                                createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) {
12984                                    var nowIndicatorTop = isNowIndicator &&
12985                                        slatCoords &&
12986                                        slatCoords.safeComputeTop(nowDate); // might return void
12987                                    if (typeof nowIndicatorTop === 'number') {
12988                                        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)); }));
12989                                    }
12990                                    return null;
12991                                })))); },
12992                    },
12993                    {
12994                        key: 'cols',
12995                        scrollerElRef: this.scrollerElRef,
12996                        content: timeContent,
12997                    },
12998                ],
12999            });
13000            if (stickyFooterScrollbar) {
13001                sections.push({
13002                    key: 'footer',
13003                    type: 'footer',
13004                    isSticky: true,
13005                    chunks: [
13006                        {
13007                            key: 'axis',
13008                            content: renderScrollShim,
13009                        },
13010                        {
13011                            key: 'cols',
13012                            content: renderScrollShim,
13013                        },
13014                    ],
13015                });
13016            }
13017            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].
13017concat(classNames).join(' '), ref: rootElRef },
13018                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [
13019                        { width: 'shrink', cols: [{ width: 'shrink' }] },
13020                        { cols: [{ span: colCnt, minWidth: dayMinWidth }] },
13021                    ], sections: sections }))); }));
13022        };
13023        /* Dimensions
13024        ------------------------------------------------------------------------------------------------------------------*/
13025        TimeColsView.prototype.getAllDayMaxEventProps = function () {
13026            var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows;
13027            if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?
13028                dayMaxEvents = undefined;
13029                dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number
13030            }
13031            return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows };
13032        };
13033        return TimeColsView;
13034    }(DateComponent));
13035    function renderAllDayInner$1(hookProps) {
13036        return hookProps.text;
13037    }
13038
13039    var TimeColsSlatsCoords = /** @class */ (function () {
13040        function TimeColsSlatsCoords(positions, dateProfile, slotDuration) {
13041            this.positions = positions;
13042            this.dateProfile = dateProfile;
13043            this.slotDuration = slotDuration;
13044        }
13045        TimeColsSlatsCoords.prototype.safeComputeTop = function (date) {
13046            var dateProfile = this.dateProfile;
13047            if (rangeContainsMarker(dateProfile.currentRange, date)) {
13048                var startOfDayDate = startOfDay(date);
13049                var timeMs = date.valueOf() - startOfDayDate.valueOf();
13050                if (timeMs >= asRoughMs(dateProfile.slotMinTime) &&
13051                    timeMs < asRoughMs(dateProfile.slotMaxTime)) {
13052                    return this.computeTimeTop(createDuration(timeMs));
13053                }
13054            }
13055            return null;
13056        };
13057        // Computes the top coordinate, relative to the bounds of the grid, of the given date.
13058        // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
13059        TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) {
13060            if (!startOfDayDate) {
13061                startOfDayDate = startOfDay(when);
13062            }
13063            return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf()));
13064        };
13065        // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
13066        // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.
13067        // Eventually allow computation with arbirary slat dates.
13068        TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) {
13069            var _a = this, positions = _a.positions, dateProfile = _a.dateProfile;
13070            var len = positions.els.length;
13071            // floating-point value of # of slots covered
13072            var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration);
13073            var slatIndex;
13074            var slatRemainder;
13075            // compute a floating-point number for how many slats should be progressed through.
13076            // from 0 to number of slats (inclusive)
13077            // constrained because slotMinTime/slotMaxTime might be customized.
13078            slatCoverage = Math.max(0, slatCoverage);
13079            slatCoverage = Math.min(len, slatCoverage);
13080            // an integer index of the furthest whole slat
13081            // from 0 to number slats (*exclusive*, so len-1)
13082            slatIndex = Math.floor(slatCoverage);
13083            slatIndex = Math.min(slatIndex, len - 1);
13084            // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
13085            // could be 1.0 if slatCoverage is covering *all* the slots
13086            slatRemainder = slatCoverage - slatIndex;
13087            return positions.tops[slatIndex] +
13088                positions.getHeight(slatIndex) * slatRemainder;
13089        };
13090        return TimeColsSlatsCoords;
13091    }());
13092
13093    var TimeColsSlatsBody = /** @class */ (function (_super) {
13094        __extends(TimeColsSlatsBody, _super);
13095        function TimeColsSlatsBody() {
13096            return _super !== null && _super.apply(this, arguments) || this;
13097        }
13098        TimeColsSlatsBody.prototype.render = function () {
13099            var _a = this, props = _a.props, context = _a.context;
13100            var options = context.options;
13101            var slatElRefs = props.slatElRefs;
13102            return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) {
13103                var hookProps = {
13104                    time: slatMeta.time,
13105                    date: context.dateEnv.toDate(slatMeta.date),
13106                    view: context.viewApi,
13107                };
13108                var classNames = [
13109                    'fc-timegrid-slot',
13110                    'fc-timegrid-slot-lane',
13111                    slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor',
13112                ];
13113                return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },
13114                    props.axis && (createElement(TimeColsAxisCell, __assign({}, slatMeta))),
13115                    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.c
13115oncat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); })));
13116            })));
13117        };
13118        return TimeColsSlatsBody;
13119    }(BaseComponent));
13120
13121    /*
13122    for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
13123    */
13124    var TimeColsSlats = /** @class */ (function (_super) {
13125        __extends(TimeColsSlats, _super);
13126        function TimeColsSlats() {
13127            var _this = _super !== null && _super.apply(this, arguments) || this;
13128            _this.rootElRef = createRef();
13129            _this.slatElRefs = new RefMap();
13130            return _this;
13131        }
13132        TimeColsSlats.prototype.render = function () {
13133            var _a = this, props = _a.props, context = _a.context;
13134            return (createElement("div", { className: "fc-timegrid-slots", ref: this.rootElRef },
13135                createElement("table", { className: context.theme.getClass('table'), style: {
13136                        minWidth: props.tableMinWidth,
13137                        width: props.clientWidth,
13138                        height: props.minHeight,
13139                    } },
13140                    props.tableColGroupNode /* relies on there only being a single <col> for the axis */,
13141                    createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));
13142        };
13143        TimeColsSlats.prototype.componentDidMount = function () {
13144            this.updateSizing();
13145        };
13146        TimeColsSlats.prototype.componentDidUpdate = function () {
13147            this.updateSizing();
13148        };
13149        TimeColsSlats.prototype.componentWillUnmount = function () {
13150            if (this.props.onCoords) {
13151                this.props.onCoords(null);
13152            }
13153        };
13154        TimeColsSlats.prototype.updateSizing = function () {
13155            var _a = this, context = _a.context, props = _a.props;
13156            if (props.onCoords &&
13157                props.clientWidth !== null // means sizing has stabilized
13158            ) {
13159                var rootEl = this.rootElRef.current;
13160                if (rootEl.offsetHeight) { // not hidden by css
13161                    props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration));
13162                }
13163            }
13164        };
13165        return TimeColsSlats;
13166    }(BaseComponent));
13167    function collectSlatEls(elMap, slatMetas) {
13168        return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; });
13169    }
13170
13171    function splitSegsByCol(segs, colCnt) {
13172        var segsByCol = [];
13173        var i;
13174        for (i = 0; i < colCnt; i += 1) {
13175            segsByCol.push([]);
13176        }
13177        if (segs) {
13178            for (i = 0; i < segs.length; i += 1) {
13179                segsByCol[segs[i].col].push(segs[i]);
13180            }
13181        }
13182        return segsByCol;
13183    }
13184    function splitInteractionByCol(ui, colCnt) {
13185        var byRow = [];
13186        if (!ui) {
13187            for (var i = 0; i < colCnt; i += 1) {
13188                byRow[i] = null;
13189            }
13190        }
13191        else {
13192            for (var i = 0; i < colCnt; i += 1) {
13193                byRow[i] = {
13194                    affectedInstances: ui.affectedInstances,
13195                    isEvent: ui.isEvent,
13196                    segs: [],
13197                };
13198            }
13199            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
13200                var seg = _a[_i];
13201                byRow[seg.col].segs.push(seg);
13202            }
13203        }
13204        return byRow;
13205    }
13206
13207    var TimeColMoreLink = /** @class */ (function (_super) {
13208        __extends(TimeColMoreLink, _super);
13209        function TimeColMoreLink() {
13210            var _this = _super !== null && _super.apply(this, arguments) || this;
13211            _this.rootElRef = createRef();
13212            return _this;
13213        }
13214        TimeColMoreLink.prototype.render = function () {
13215            var _this = this;
13216            var props = this.props;
13217            return (createElement(MoreLinkRoot, { allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, al
13217ignmentElRef: this.rootElRef, defaultContent: renderMoreLinkInner, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: function () { return renderPlainFgSegs(props.hiddenSegs, props); } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick) { return (createElement("a", { ref: function (el) {
13218                    setRef(rootElRef, el);
13219                    setRef(_this.rootElRef, el);
13220                }, className: ['fc-timegrid-more-link'].concat(classNames).join(' '), style: { top: props.top, bottom: props.bottom }, onClick: handleClick },
13221                createElement("div", { ref: innerElRef, className: "fc-timegrid-more-link-inner fc-sticky" }, innerContent))); }));
13222        };
13223        return TimeColMoreLink;
13224    }(BaseComponent));
13225    function renderMoreLinkInner(props) {
13226        return props.shortText;
13227    }
13228
13229    // segInputs assumed sorted
13230    function computeFgSegPlacements(segInputs, strictOrder, maxStackCnt) {
13231        var hierarchy = new SegHierarchy();
13232        if (strictOrder != null) {
13233            hierarchy.strictOrder = strictOrder;
13234        }
13235        if (maxStackCnt != null) {
13236            hierarchy.maxStackCnt = maxStackCnt;
13237        }
13238        var hiddenEntries = hierarchy.addSegs(segInputs);
13239        var hiddenGroups = groupIntersectingEntries(hiddenEntries);
13240        var web = buildWeb(hierarchy);
13241        web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0
13242        var segRects = webToRects(web);
13243        return { segRects: segRects, hiddenGroups: hiddenGroups };
13244    }
13245    function buildWeb(hierarchy) {
13246        var entriesByLevel = hierarchy.entriesByLevel;
13247        var buildNode = cacheable(function (level, lateral) { return level + ':' + lateral; }, function (level, lateral) {
13248            var siblingRange = findNextLevelSegs(hierarchy, level, lateral);
13249            var nextLevelRes = buildNodes(siblingRange, buildNode);
13250            var entry = entriesByLevel[level][lateral];
13251            return [
13252                __assign(__assign({}, entry), { nextLevelNodes: nextLevelRes[0] }),
13253                entry.thickness + nextLevelRes[1], // the pressure builds
13254            ];
13255        });
13256        return buildNodes(entriesByLevel.length
13257            ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length }
13258            : null, buildNode)[0];
13259    }
13260    function buildNodes(siblingRange, buildNode) {
13261        if (!siblingRange) {
13262            return [[], 0];
13263        }
13264        var level = siblingRange.level, lateralStart = siblingRange.lateralStart, lateralEnd = siblingRange.lateralEnd;
13265        var lateral = lateralStart;
13266        var pairs = [];
13267        while (lateral < lateralEnd) {
13268            pairs.push(buildNode(level, lateral));
13269            lateral += 1;
13270        }
13271        pairs.sort(cmpDescPressures);
13272        return [
13273            pairs.map(extractNode),
13274            pairs[0][1], // first item's pressure
13275        ];
13276    }
13277    function cmpDescPressures(a, b) {
13278        return b[1] - a[1];
13279    }
13280    function extractNode(a) {
13281        return a[0];
13282    }
13283    function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) {
13284        var levelCoords = hierarchy.levelCoords, entriesByLevel = hierarchy.entriesByLevel;
13285        var subjectEntry = entriesByLevel[subjectLevel][subjectLateral];
13286        var afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness;
13287        var levelCnt = levelCoords.length;
13288        var level = subjectLevel;
13289        // skip past levels that are too high up
13290        for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1)
13291            ; // do nothing
13292        for (; level < levelCnt; level += 1) {
13293            var entries = entriesByLevel[level];
13294            var entry = void 0;
13295            var searchIndex = binarySearch(entries, subjectEntry.spanStart, getEntrySpanEnd);
13296            var lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one
13297            var lateralEnd = lateralStart;
13298            while ( // loop through entries that horizontally intersect
13299            (entry = entries[lateralEnd]) && // but not past the whole seg list
13300                entry.spanStart < subjectEntry.spanEnd) {
13301                lateralEnd += 1;
13302            }
13303            if (lateralStart < lateralEnd) {
13304                return { level: level, lateralStart: lateralStart, lateralEnd: lateralEnd };
13305            }
13306        }
13307        return null;
13308    }
13309    function stretchWeb(topLevelNodes, totalThickness) {
13310        var stretchNode = cacheable(function (node, startCoord, prevThickness) { return buildEntryKey(node); }, function (node, startCoord, prevThickness) {
13311            var nextLevelNodes = node.nextLevelNodes, thickness = node.thickness;
13312            var allThickness = thickness + prevThickness;
13313            var thicknessFraction = thickness / allThickness;
13314            var endCoord;
13315            var newChildren = [];
13316            if (!nextLevelNodes.length) {
13317                endCoord = totalThickness;
13318            }
13319            else {
13320                for (var _i = 0, nextLevelNodes_1 = nextLevelNodes; _i < nextLevelNodes_1.length; _i++) {
13321                    var childNode = nextLevelNodes_1[_i];
13322                    if (endCoord === undefined) {
13323                        var res = stretchNode(childNode, startCoord, allThickness);
13324                        endCoord = res[0];
13325                        newChildren.push(res[1]);
13326                    }
13327                    else {
13328                        var res = stretchNode(childNode, endCoord, 0);
13329                        newChildren.push(res[1]);
13330                    }
13331                }
13332            }
13333            var newThickness = (endCoord - startCoord) * thicknessFraction;
13334            return [endCoord - newThickness, __assign(__assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })];
13335        });
13336        return topLevelNodes.map(function (node) { return stretchNode(node, 
133360, 0)[1]; });
13337    }
13338    // not sorted in any particular order
13339    function webToRects(topLevelNodes) {
13340        var rects = [];
13341        var processNode = cacheable(function (node, levelCoord, stackDepth) { return buildEntryKey(node); }, function (node, levelCoord, stackDepth) {
13342            var rect = __assign(__assign({}, node), { levelCoord: levelCoord,
13343                stackDepth: stackDepth, stackForward: 0 });
13344            rects.push(rect);
13345            return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1);
13346        });
13347        function processNodes(nodes, levelCoord, stackDepth) {
13348            var stackForward = 0;
13349            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
13350                var node = nodes_1[_i];
13351                stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward);
13352            }
13353            return stackForward;
13354        }
13355        processNodes(topLevelNodes, 0, 0);
13356        return rects; // TODO: sort rects by levelCoord to be consistent with toRects?
13357    }
13358    // TODO: move to general util
13359    function cacheable(keyFunc, workFunc) {
13360        var cache = {};
13361        return function () {
13362            var args = [];
13363            for (var _i = 0; _i < arguments.length; _i++) {
13364                args[_i] = arguments[_i];
13365            }
13366            var key = keyFunc.apply(void 0, args);
13367            return (key in cache)
13368                ? cache[key]
13369                : (cache[key] = workFunc.apply(void 0, args));
13370        };
13371    }
13372
13373    var DEFAULT_TIME_FORMAT$1 = createFormatter({
13374        hour: 'numeric',
13375        minute: '2-digit',
13376        meridiem: false,
13377    });
13378    var TimeColEvent = /** @class */ (function (_super) {
13379        __extends(TimeColEvent, _super);
13380        function TimeColEvent() {
13381            return _super !== null && _super.apply(this, arguments) || this;
13382        }
13383        TimeColEvent.prototype.render = function () {
13384            var classNames = [
13385                'fc-timegrid-event',
13386                'fc-v-event',
13387            ];
13388            if (this.props.isShort) {
13389                classNames.push('fc-timegrid-event-short');
13390            }
13391            return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT$1, extraClassNames: classNames })));
13392        };
13393        return TimeColEvent;
13394    }(BaseComponent));
13395
13396    var TimeColMisc = /** @class */ (function (_super) {
13397        __extends(TimeColMisc, _super);
13398        function TimeColMisc() {
13399            return _super !== null && _super.apply(this, arguments) || this;
13400        }
13401        TimeColMisc.prototype.render = function () {
13402            var props = this.props;
13403            return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent &&
13404                createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); }));
13405        };
13406        return TimeColMisc;
13407    }(BaseComponent));
13408
13409    var TimeCol = /** @class */ (function (_super) {
13410        __extends(TimeCol, _super);
13411        function TimeCol() {
13412            var _this = _super !== null && _super.apply(this, arguments) || this;
13413            _this.sortEventSegs = memoize(sortEventSegs);
13414            _this.computeFgSegPlacements = memoize(computeFgSegPlacements); // only for non-print, non-mirror
13415            return _this;
13416        }
13417        TimeCol.prototype.render = function () {
13418            var _this = this;
13419            var _a = this, props = _a.props, context = _a.context;
13420            var isSelectMirror = context.options.selectMirror;
13421            var mirrorSegs = (props.eventDrag && props.eventDrag.segs) ||
13422                (props.eventResize && props.eventResize.segs) ||
13423                (isSelectMirror && props.dateSelectionSegs) ||
13424                [];
13425            var interactionAffectedInstances = // TODO: messy way to compute this
13426             (props.eventDrag && props.eventDrag.affectedInstances) ||
13427                (props.eventResize && props.eventResize.affectedInstances) ||
13428                {};
13429            var sortedFgSegs = this.sortEventSegs(props.fgEventSegs, context.options.eventOrder);
13430            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),
13431                createElement("div", { className: "fc-timegrid-col-frame" },
13432                    createElement("div", { className: "fc-timegrid-col-bg" },
13433                        _this.renderFillSegs(props.businessHourSegs, 'non-business'),
13434                        _this.renderFillSegs(props.bgEventSegs, 'bg-event'),
13435                        _this.renderFillSegs(props.dateSelectionSegs, 'highlight')),
13436                    createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(sortedFgSegs, interactionAffectedInstances)),
13437                    createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))),
13438                    createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)),
13439                    createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); }));
13440        };
13441        TimeCol.prototype.renderFgSegs = function (sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
13442            var props = this.props;
13443            if (props.forPrint) {
13444                return renderPlainFgSegs(sortedFgSegs, props);
13445            }
13446            if (props.slatCoords) {
13447                return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting);
13448            }
13449            return null;
13450        };
13451        TimeCol.prototype.renderPositionedFgSegs = function (segs, // if not mirror, needs to be sorted
13452        segIsInvisible, isDragging, isResizing, isDateSelecting) {
13453            var _this = this;
13454            var _a = this.context.options, eventMaxStack = _a.eventMaxStack, eventShortHeight = _a.eventShortHeight, eventOrderStrict = _a.eventOrderStrict;
13455            var _b = this.props, eventSelection = _b.eventSelection, todayRange = _b.todayRange, nowDate = _b.nowDate;
13456            var isMirror = isDragging || isResizing || isDateSelecting;
13457            var segInputs = this.buildSegInputs(segs);
13458            var _c = isMirror ? computeFgSegPlacements(segInputs) : // don't use memoized
13459                this.computeFgSegPlacements(segInputs, eventOrderStrict, eventMaxStack), segRects = _c.segRects, hiddenGroups = _c.hiddenGroups;
13460            return (createElement(Fragment, null,
13461                this.renderHiddenGroups(hiddenGroups, segs),
13462                segRects.map(function (segRect) {
13463                    var seg = segs[segRect.segInput.index];
13464                    var instanceId = seg.eventRange.instance.instanceId;
13465                    var positionCss = __assign(__assign({}
13465, _this.computeSegTopBottomCss(segRect.segInput)), (isMirror ? { left: 0, right: 0 } : _this.computeSegLeftRightCss(segRect)));
13466                    return (createElement("div", { className: 'fc-timegrid-event-harness' + (segRect.stackForward > 0 ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign({ visibility: segIsInvisible[instanceId] ? 'hidden' : '' }, positionCss) },
13467                        createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: (segRect.spanEnd - segRect.spanStart) < eventShortHeight }, getSegMeta(seg, todayRange, nowDate)))));
13468                })));
13469        };
13470        // will already have eventMinHeight applied because segInputs already had it
13471        TimeCol.prototype.renderHiddenGroups = function (hiddenGroups, segs) {
13472            var _this = this;
13473            var _a = this.props, extraDateSpan = _a.extraDateSpan, dateProfile = _a.dateProfile, todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize;
13474            return (createElement(Fragment, null, hiddenGroups.map(function (hiddenGroup) {
13475                var positionCss = _this.computeSegTopBottomCss(hiddenGroup);
13476                var hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs);
13477                return (createElement(TimeColMoreLink, { key: buildIsoString(computeEarliestSegStart(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: nowDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize }));
13478            })));
13479        };
13480        TimeCol.prototype.buildSegInputs = function (segs) {
13481            var _a = this.props, date = _a.date, slatCoords = _a.slatCoords;
13482            var eventMinHeight = this.context.options.eventMinHeight;
13483            var segInputs = [];
13484            for (var i = 0; i < segs.length; i += 1) {
13485                var seg = segs[i];
13486                var spanStart = slatCoords.computeDateTop(seg.start, date);
13487                var spanEnd = Math.max(spanStart + (eventMinHeight || 0), // yuck
13488                slatCoords.computeDateTop(seg.end, date));
13489                segInputs.push({
13490                    index: i,
13491                    spanStart: Math.round(spanStart),
13492                    spanEnd: Math.round(spanEnd),
13493                    thickness: 1,
13494                });
13495            }
13496            return segInputs;
13497        };
13498        TimeCol.prototype.renderFillSegs = function (segs, fillType) {
13499            var _this = this;
13500            var props = this.props;
13501            if (!props.slatCoords) {
13502                return null;
13503            }
13504            var segInputs = this.buildSegInputs(segs);
13505            var children = segInputs.map(function (segInput) {
13506                var seg = segs[segInput.index];
13507                return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: _this.computeSegTopBottomCss(segInput) }, fillType === 'bg-event' ?
13508                    createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) :
13509                    renderFill(fillType)));
13510            });
13511            return createElement(Fragment, null, children);
13512        };
13513        TimeCol.prototype.renderNowIndicator = function (segs) {
13514            var _a = this.props, slatCoords = _a.slatCoords, date = _a.date;
13515            if (!slatCoords) {
13516                return null;
13517            }
13518            return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date,
13519                // key doesn't matter. will only ever be one
13520                key: i }, 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)); })); });
13521        };
13522        TimeCol.prototype.computeSegTopBottomCss = function (segLike) {
13523            return {
13524                top: segLike.spanStart,
13525                bottom: -segLike.spanEnd,
13526            };
13527        };
13528        TimeCol.prototype.computeSegLeftRightCss = function (segRect) {
13529            var _a = this.context, isRtl = _a.isRtl, options = _a.options;
13530            var shouldOverlap = options.slotEventOverlap;
13531            var nearCoord = segRect.levelCoord; // the left side if LTR. the right side if RTL. floating-point
13532            var farCoord = segRect.levelCoord + segRect.thickness; // the right side if LTR. the left side if RTL. floating-point
13533            var left; // amount of space from left edge, a fraction of the total width
13534            var right; // amount of space from right edge, a fraction of the total width
13535            if (shouldOverlap) {
13536                // double the width, but don't go beyond the maximum forward coordinate (1.0)
13537                farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2);
13538            }
13539            if (isRtl) {
13540                left = 1 - farCoord;
13541                right = nearCoord;
13542            }
13543            else {
13544                left = nearCoord;
13545                right = 1 - farCoord;
13546            }
13547            var props = {
13548                zIndex: segRect.stackDepth + 1,
13549                left: left * 100 + '%',
13550                right: right * 100 + '%',
13551            };
13552            if (shouldOverlap && !segRect.stackForward) {
13553                // add padding to the edge so that forward stacked events don't cover the resizer's icon
13554                props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
13555            }
13556            return props;
13557        };
13558        return TimeCol;
13559    }(BaseComponent));
13560    function renderPlainFgSegs(sortedFgSegs, _a) {
13561        var todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize;
13562        var hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) ||
13563            (eventResize ? eventResize.affectedInstances : null) ||
13564            {};
13565        return (createElement(Fragment, null, sortedFgSegs.map(function (seg) {
13566            var instanceId = seg.eventRange.instance.instanceId;
13567            return (createElement("div", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } },
13568                createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate)))));
13569        })));
13570    }
13571    function compileSegsFromEntries(segEntries, allSegs) {
13572        return segEntries.map(function (segEntry) { return allSegs[segEntry.segInput.index]; });
13573    }
13574
13575    var TimeColsContent = /** @class */ (function (_super) {
13576        __extends(TimeColsContent, _super);
13577        function TimeColsContent() {
13578            var _this = _super !== null && _super.apply(this, arguments) || this;
13579            _this.splitFgEventSegs = memoize(splitSegsByCol);
13580            _this.splitBgEventSegs = memoize(splitSegsByCol);
13581            _this.splitBusinessHourSegs = memoize(splitSegsByCol);
13582            _this.splitNowIndicatorSegs = memoize(splitSegsByCol);
13583            _this.splitDateSelectionSegs = memoize(splitSegsByCol);
13584            _this.splitEventDrag = memoize(splitInteractionByCol);
13585            _this.splitEventResize = memoize(splitInteractionByCol);
13586            _this.rootElRef = createRef();
13587            _this.cellElRefs = new RefMap();
13588            return _this;
13589        }
13590        TimeColsContent.prototype.render = function () {
13591            var _this = this;
13592            var _a = this, props = _a.props, context = _a.context;
13593            var nowIndicatorTop = context.options.nowIndicator &&
13594                props.slatCoords &&
13595                props.slatCoords.safeComputeTop(props.nowDate); // might return void
13596            var colCnt = props.cells.length;
13597            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);
13598            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);
13599            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);
13600            var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);
13601            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);
13602            var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);
13603            var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);
13604            return (createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef },
13605                createElement("table", { style: {
13606                        minWidth: props.tableMinWidth,
13607                        width: props.clientWidth,
13608                    } },
13609                    props.tableColGroupNode,
13610                    createElement("tbody", null,
13611                        createElement("tr", null,
13612                            props.axis && (createElement("td", { className: "fc-timegrid-col fc-timegrid-axis" },
13613                                createElement("div", { className: "fc-timegrid-col-frame" },
13614                                    createElement("div", { className: "fc-timegrid-now-indicator-container" }, typeof nowIndicatorTop === 'number' && (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)); })))))),
13615                            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, extraDateSpan: cell.extraDateSpan, 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 })); }))))));
13616        };
13617        TimeColsContent.prototype.componentDidMount = function () {
13618            this.updateCoords();
13619        };
13620        TimeColsContent.prototype.componentDidUpdate = function () {
13621            this.updateCoords();
13622        };
13623        TimeColsContent.prototype.updateCoords = function () {
13624            var props = this.props;
13625            if (props.onColCoords &&
13626                props.clientWidth !== null // means sizing has stabilized
13627            ) {
13628                props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal
13629                false));
13630            }
13631        };
13632        return TimeColsContent;
13633    }(BaseComponent));
13634    function collectCellEls(elMap, cells) {
13635        return cells.map(function (cell) { return elMap[cell.key]; });
13636    }
13637
13638    /* A component that renders one or more columns of vertical time slots
13639    ----------------------------------------------------------------------------------------------------------------------*/
13640    var TimeCols = /** @class */ (function (_super) {
13641        __extends(TimeCols, _super);
13642        function TimeCols() {
13643            var _this = _super !== null && _super.apply(this, arguments) || this;
13644            _this.processSlotOptions = memoize(processSlotOptions);
13645            _this.state = {
13646                slatCoords: null,
13647            };
13648            _this.handleRootEl = function (el) {
13649                if (el) {
13650                    _this.context.registerInteractiveComponent(_this, {
13651                        el: el,
13652                        isHitComboAllowed: _this.props.isHitComboAllowed,
13653                    });
13654                }
13655                else {
13656                    _this.context.unregisterInteractiveComponent(_this);
13657                }
13658            };
13659            _this.handleScrollRequest = function (request) {
13660                var onScrollTopRequest = _this.props.onScrollTopRequest;
13661                var slatCoords = _this.state.slatCoords;
13662                if (onScrollTopRequest && slatCoords) {
13663                    if (request.time) {
13664                        var top_1 = slatCoords.computeTimeTop(request.time);
13665                        top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further
13666                        if (top_1) {
13667                            top_1 += 1; // to overcome top border that slots beyond the first have. looks better
13668                        }
13669                        onScrollTopRequest(top_1);
13670                    }
13671                    return true;
13672                }
13673                return false;
13674            };
13675            _this.handleColCoords = function (colCoords) {
13676                _this.colCoords = colCoords;
13677            };
13678            _this.handleSlatCoords = function (slatCoords) {
13679                _this.setState({ slatCoords: slatCoords });
13680                if (_this.props.onSlatCoords) {
13681                    _this.props.onSlatCoords(slatCoords);
13682                }
13683            };
13684            return _this;
13685        }
13686        TimeCols.prototype.render = function () {
13687            var _a = this, props = _a.props, state = _a.state;
13688            return (createElement("div", { className: "fc-timegrid-body", ref: this.handleRootEl, style: {
13689                    // these props are important to give this wrapper correct dimensions for interactions
13690                    // TODO: if we set it here, can we avoid giving to inner tables?
13691                    width: props.clientWidth,
13692                    minWidth: props.tableMinWidth,
13693                } },
13694                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 }),
13695                createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
13695EventSegs, 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 })));
13696        };
13697        TimeCols.prototype.componentDidMount = function () {
13698            this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);
13699        };
13700        TimeCols.prototype.componentDidUpdate = function (prevProps) {
13701            this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);
13702        };
13703        TimeCols.prototype.componentWillUnmount = function () {
13704            this.scrollResponder.detach();
13705        };
13706        TimeCols.prototype.queryHit = function (positionLeft, positionTop) {
13707            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options;
13708            var colCoords = this.colCoords;
13709            var dateProfile = this.props.dateProfile;
13710            var slatCoords = this.state.slatCoords;
13711            var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot;
13712            var colIndex = colCoords.leftToIndex(positionLeft);
13713            var slatIndex = slatCoords.positions.topToIndex(positionTop);
13714            if (colIndex != null && slatIndex != null) {
13715                var cell = this.props.cells[colIndex];
13716                var slatTop = slatCoords.positions.tops[slatIndex];
13717                var slatHeight = slatCoords.positions.getHeight(slatIndex);
13718                var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
13719                var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
13720                var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
13721                var dayDate = this.props.cells[colIndex].date;
13722                var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex));
13723                var start = dateEnv.add(dayDate, time);
13724                var end = dateEnv.add(start, snapDuration);
13725                return {
13726                    dateProfile: dateProfile,
13727                    dateSpan: __assign({ range: { start: start, end: end }, allDay: false }, cell.extraDateSpan),
13728                    dayEl: colCoords.els[colIndex],
13729                    rect: {
13730                        left: colCoords.lefts[colIndex],
13731                        right: colCoords.rights[colIndex],
13732                        top: slatTop,
13733                        bottom: slatTop + slatHeight,
13734                    },
13735                    layer: 0,
13736                };
13737            }
13738            return null;
13739        };
13740        return TimeCols;
13741    }(DateComponent));
13742    function processSlotOptions(slotDuration, snapDurationOverride) {
13743        var snapDuration = snapDurationOverride || slotDuration;
13744        var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration);
13745        if (snapsPerSlot === null) {
13746            snapDuration = slotDuration;
13747            snapsPerSlot = 1;
13748            // TODO: say warning?
13749        }
13750        return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot };
13751    }
13752
13753    var DayTimeColsSlicer = /** @class */ (function (_super) {
13754        __extends(DayTimeColsSlicer, _super);
13755        function DayTimeColsSlicer() {
13756            return _super !== null && _super.apply(this, arguments) || this;
13757        }
13758        DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) {
13759            var segs = [];
13760            for (var col = 0; col < dayRanges.length; col += 1) {
13761                var segRange = intersectRanges(range, dayRanges[col]);
13762                if (segRange) {
13763                    segs.push({
13764                        start: segRange.start,
13765                        end: segRange.end,
13766                        isStart: segRange.start.valueOf() === range.start.valueOf(),
13767                        isEnd: segRange.end.valueOf() === range.end.valueOf(),
13768                        col: col,
13769                    });
13770                }
13771            }
13772            return segs;
13773        };
13774        return DayTimeColsSlicer;
13775    }(Slicer));
13776
13777    var DayTimeCols = /** @class */ (function (_super) {
13778        __extends(DayTimeCols, _super);
13779        function DayTimeCols() {
13780            var _this = _super !== null && _super.apply(this, arguments) || this;
13781            _this.buildDayRanges = memoize(buildDayRanges);
13782            _this.slicer = new DayTimeColsSlicer();
13783            _this.timeColsRef = createRef();
13784            return _this;
13785        }
13786        DayTimeCols.prototype.render = function () {
13787            var _this = this;
13788            var _a = this, props = _a.props, context = _a.context;
13789            var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel;
13790            var isNowIndicator = context.options.nowIndicator;
13791            var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);
13792            // give it the first row of cells
13793            // TODO: would move this further down hierarchy, but sliceNowDate needs it
13794            return (createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (createElement(TimeCols, __assign({ ref: _this.timeColsRef }, _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
13794owDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); }));
13795        };
13796        return DayTimeCols;
13797    }(DateComponent));
13798    function buildDayRanges(dayTableModel, dateProfile, dateEnv) {
13799        var ranges = [];
13800        for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) {
13801            var date = _a[_i];
13802            ranges.push({
13803                start: dateEnv.add(date, dateProfile.slotMinTime),
13804                end: dateEnv.add(date, dateProfile.slotMaxTime),
13805            });
13806        }
13807        return ranges;
13808    }
13809
13810    // potential nice values for the slot-duration and interval-duration
13811    // from largest to smallest
13812    var STOCK_SUB_DURATIONS = [
13813        { hours: 1 },
13814        { minutes: 30 },
13815        { minutes: 15 },
13816        { seconds: 30 },
13817        { seconds: 15 },
13818    ];
13819    function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {
13820        var dayStart = new Date(0);
13821        var slatTime = slotMinTime;
13822        var slatIterator = createDuration(0);
13823        var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);
13824        var metas = [];
13825        while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) {
13826            var date = dateEnv.add(dayStart, slatTime);
13827            var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null;
13828            metas.push({
13829                date: date,
13830                time: slatTime,
13831                key: date.toISOString(),
13832                isoTimeStr: formatIsoTimeString(date),
13833                isLabeled: isLabeled,
13834            });
13835            slatTime = addDurations(slatTime, slotDuration);
13836            slatIterator = addDurations(slatIterator, slotDuration);
13837        }
13838        return metas;
13839    }
13840    // Computes an automatic value for slotLabelInterval
13841    function computeLabelInterval(slotDuration) {
13842        var i;
13843        var labelInterval;
13844        var slotsPerLabel;
13845        // find the smallest stock label interval that results in more than one slots-per-label
13846        for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) {
13847            labelInterval = createDuration(STOCK_SUB_DURATIONS[i]);
13848            slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
13849            if (slotsPerLabel !== null && slotsPerLabel > 1) {
13850                return labelInterval;
13851            }
13852        }
13853        return slotDuration; // fall back
13854    }
13855
13856    var DayTimeColsView = /** @class */ (function (_super) {
13857        __extends(DayTimeColsView, _super);
13858        function DayTimeColsView() {
13859            var _this = _super !== null && _super.apply(this, arguments) || this;
13860            _this.buildTimeColsModel = memoize(buildTimeColsModel);
13861            _this.buildSlatMetas = memoize(buildSlatMetas);
13862            return _this;
13863        }
13864        DayTimeColsView.prototype.render = function () {
13865            var _this = this;
13866            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator;
13867            var props = this.props;
13868            var dateProfile = props.dateProfile;
13869            var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);
13870            var splitProps = this.allDaySplitter.splitProps(props);
13871            var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);
13872            var dayMinWidth = options.dayMinWidth;
13873            var hasAttachedAxis = !dayMinWidth;
13874            var hasDetachedAxis = dayMinWidth;
13875            var headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null }));
13876            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()))); });
13877            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 }))); };
13878            return hasDetachedAxis
13879                ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)
13880                : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);
13881        };
13882        return DayTimeColsView;
13883    }(TimeColsView));
13884    function buildTimeColsModel(dateProfile, dateProfileGenerator) {
13885        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
13886        return new DayTableModel(daySeries, false);
13887    }
13888
13889    var OPTION_REFINERS$2 = {
13890        allDaySlot: Boolean,
13891    };
13892
13893    var timeGridPlugin = createPlugin({
13894        initialView: 'timeGridWeek',
13895        optionRefiners: OPTION_REFINERS$2,
13896        views: {
13897            timeGrid: {
13898                component: DayTimeColsView,
13899                usesMinMaxTime: true,
13900                allDaySlot: true,
13901                slotDuration: '00:30:00',
13902                slotEventOverlap: true, // a bad name. confused with overlap/constraint system
13903            },
13904            timeGridDay: {
13905                type: 'timeGrid',
13906                duration: { days: 1 },
13907            },
13908            timeGridWeek: {
13909                type: 'timeGrid',
13910                duration: { weeks: 1 },
13911            },
13912        },
13913    });
13914
13915    var ListViewHeaderRow = /** @class */ (function (_super) {
13916        __extends(ListViewHeaderRow, _super);
13917        function ListViewHeaderRow() {
13918            return _super !== null && _super.apply(this, arguments) || this;
13919        }
13920        ListViewHeaderRow.prototype.render = function () {
13921            var _a = this.props, dayDate = _a.dayDate, todayRange = _a.todayRange;
13922            var _b = this.context, theme = _b.theme, dateEnv = _b.dateEnv, options = _b.options, viewApi = _b.viewApi;
13923            var dayMeta = getDateMeta(dayDate, todayRange);
13924            // will ever be falsy?
13925            var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : '';
13926            // will ever be falsy? also, BAD NAME "alt"
13927            var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : '';
13928            var navLinkData = options.navLinks
13929                ? buildNavLinkData(dayDate)
13930                : null;
13931            var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, text: text,
13932                sideText: sideText,
13933                navLinkData: navLinkData }, dayMeta);
13934            var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme));
13935            // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)
13936            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInnerContent, 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) },
13937                createElement("th", { colSpan: 3 },
13938                    createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); }));
13939        };
13940        return ListViewHeaderRow;
13941    }(BaseComponent));
13942    function renderInnerContent(props) {
13943        var navLinkAttrs = props.navLinkData // is there a type for this?
13944            ? { 'data-navlink': props.navLinkData, tabIndex: 0 }
13945            : {};
13946        return (createElement(Fragment, null,
13947            props.text && (createElement("a", __assign({ className: "fc-list-day-text" }, navLinkAttrs), props.text)),
13948            props.sideText && (createElement("a", __assign({ className: "fc-list-day-side-text" }, navLinkAttrs), props.sideText))));
13949    }
13950
13951    var DEFAULT_TIME_FORMAT = createFormatter({
13952        hour: 'numeric',
13953        minute: '2-digit',
13954        meridiem: 'short',
13955    });
13956    var ListViewEventRow = /** @class */ (function (_super) {
13957        __extends(ListViewEventRow, _super);
13958        function ListViewEventRow() {
13959            return _super !== null && _super.apply(this, arguments) || this;
13960        }
13961        ListViewEventRow.prototype.render = function () {
13962            var _a = this, props = _a.props, context = _a.context;
13963            var seg = props.seg;
13964            var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT;
13965            return (createElement(EventRoot, { seg: seg, timeText: "" // BAD. because of all-day content
13966                , 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 },
13967                buildTimeContent(seg, timeFormat, context),
13968                createElement("td", { className: "fc-list-event-graphic" },
13969                    createElement("span", { className: "fc-list-event-dot", style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })),
13970                createElement("td", { className: "fc-list-event-title", ref: innerElRef }, innerContent))); }));
13971        };
13972        return ListViewEventRow;
13973    }(BaseComponent));
13974    function renderEventInnerContent(props) {
13975        var event = props.event;
13976        var url = event.url;
13977        var anchorAttrs = url ? { href: url } : {};
13978        return (createElement("a", __assign({}, anchorAttrs), event.title));
13979    }
13980    function buildTimeContent(seg, timeFormat, context) {
13981        var options = context.options;
13982        if (options.displayEventTime !== false) {
13983            var eventDef = seg.eventRange.def;
13984            var eventInstance = seg.eventRange.instance;
13985            var doAllDay = false;
13986            var timeText = void 0;
13987            if (eventDef.allDay) {
13988                doAllDay = true;
13989            }
13990            else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead?
13991                if (seg.isStart) {
13992                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end);
13993                }
13994                else if (seg.isEnd) {
13995                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end);
13996                }
13997                else {
13998                    doAllDay = true;
13999                }
14000            }
14001            else {
14002                timeText = buildSegTimeText(seg, timeFormat, context);
14003            }
14004            if (doAllDay) {
14005                var hookProps = {
14006                    text: context.options.allDayText,
14007                    view: context.viewApi,
14008                };
14009                return (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", { className: ['fc-list-event-time'].concat(classNames).join(' '), ref: rootElRef }, innerContent)); }));
14010            }
14011            return (createElement("td", { className: "fc-list-event-time" }, timeText));
14012        }
14013        return null;
14014    }
14015    function renderAllDayInner(hookProps) {
14016        return hookProps.text;
14017    }
14018
14019    /*
14020    Responsible for the scroller, and forwarding event-related actions into the "grid".
14021    */
14022    var ListView = /** @class */ (function (_super) {
14023        __extends(ListView, _super);
14024        function ListView() {
14025            var _this = _super !== null && _super.apply(this, arguments) || this;
14026            _this.computeDateVars = memoize(computeDateVars);
14027            _this.eventStoreToSegs = memoize(_this._eventStoreToSegs);
14028            _this.setRootEl = function (rootEl) {
14029                if (rootEl) {
14030                    _this.context.registerInteractiveComponent(_this, {
14031                        el: rootEl,
14032                    });
14033                }
14034                else {
14035                    _this.context.unregisterInteractiveComponent(_this);
14036                }
14037            };
14038            return _this;
14039        }
14040        ListView.prototype.render = function () {
14041            var _this = this;
14042            var _a = this, props = _a.props, context = _a.context;
14043            var extraClassNames = [
14044                'fc-list',
14045                context.theme.getClass('table'),
14046                context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : '',
14047            ];
14048            var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges;
14049            var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
14050            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.concat(classNames).join(' ') },
14051                createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ?
14052                    _this.renderSegList(eventSegs, dayDates) :
14053                    _this.renderEmptyMessage()))); }));
14054        };
14055        ListView.prototype.renderEmptyMessage = function () {
14056            var _a = this.context, options = _a.options, viewApi = _a.viewApi;
14057            var hookProps = {
14058                text: options.noEventsText,
14059                view: viewApi,
14060            };
14061            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 },
14062                createElement("div", { className: "fc-list-empty-cushion", ref: innerElRef }, innerContent))); }));
14063        };
14064        ListView.prototype.renderSegList = function (allSegs, dayDates) {
14065            var _a = this.context, theme = _a.theme, options = _a.options;
14066            var segsByDay = groupSegsByDay(allSegs); // sparse array
14067            return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) {
14068                var innerNodes = [];
14069                for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
14070                    var daySegs = segsByDay[dayIndex];
14071                    if (daySegs) { // sparse array, so might be undefined
14072                        var dayStr = dayDates[dayIndex].toISOString();
14073                        // append a day header
14074                        innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, dayDate: dayDates[dayIndex], todayRange: todayRange }));
14075                        daySegs = sortEventSegs(daySegs, options.eventOrder);
14076                        for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) {
14077                            var seg = daySegs_1[_i];
14078                            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))));
14079                        }
14080                    }
14081                }
14082                return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') },
14083                    createElement("tbody", null, innerNodes)));
14084            }));
14085        };
14086        ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) {
14087            return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
14088        };
14089        ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) {
14090            var segs = [];
14091            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
14092                var eventRange = eventRanges_1[_i];
14093                segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges));
14094            }
14095            return segs;
14096        };
14097        ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) {
14098            var dateEnv = this.context.dateEnv;
14099            var nextDayThreshold = this.context.options.nextDayThreshold;
14100            var range = eventRange.range;
14101            var allDay = eventRange.def.allDay;
14102            var dayIndex;
14103            var segRange;
14104            var seg;
14105            var segs = [];
14106            for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
14107                segRange = intersectRanges(range, dayRanges[dayIndex]);
14108                if (segRange) {
14109                    seg = {
14110                        component: this,
14111                        eventRange: eventRange,
14112                        start: segRange.start,
14113                        end: segRange.end,
14114                        isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
14115                        isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
14116                        dayIndex: dayIndex,
14117                    };
14118                    segs.push(seg);
14119                    // detect when range won't go fully into the next day,
14120                    // and mutate the latest seg to the be the end.
14121                    if (!seg.isEnd && !allDay &&
14122                        dayIndex + 1 < dayRanges.length &&
14123                        range.end <
14124                            dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
14125                        seg.end = range.end;
14126                        seg.isEnd = true;
14127                        break;
14128                    }
14129                }
14130            }
14131            return segs;
14132        };
14133        return ListView;
14134    }(DateComponent));
14135    function renderNoEventsInner(hookProps) {
14136        return hookProps.text;
14137    }
14138    function computeDateVars(dateProfile) {
14139        var dayStart = startOfDay(dateProfile.renderRange.start);
14140        var viewEnd = dateProfile.renderRange.end;
14141        var dayDates = [];
14142        var dayRanges = [];
14143        while (dayStart < viewEnd) {
14144            dayDates.push(dayStart);
14145            dayRanges.push({
14146                start: dayStart,
14147                end: addDays(dayStart, 1),
14148            });
14149            dayStart = addDays(dayStart, 1);
14150        }
14151        return { dayDates: dayDates, dayRanges: dayRanges };
14152    }
14153    // Returns a sparse array of arrays, segs grouped by their dayIndex
14154    function groupSegsByDay(segs) {
14155        var segsByDay = []; // sparse array
14156        var i;
14157        var seg;
14158        for (i = 0; i < segs.length; i += 1) {
14159            seg = segs[i];
14160            (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
14161                .push(seg);
14162        }
14163        return segsByDay;
14164    }
14165
14166    var OPTION_REFINERS$1 = {
14167        listDayFormat: createFalsableFormatter,
14168        listDaySideFormat: createFalsableFormatter,
14169        noEventsClassNames: identity,
14170        noEventsContent: identity,
14171        noEventsDidMount: identity,
14172        noEventsWillUnmount: identity,
14173        // noEventsText is defined in base options
14174    };
14175    function createFalsableFormatter(input) {
14176        return input === false ? null : createFormatter(input);
14177    }
14178
14179    var listPlugin = createPlugin({
14180        optionRefiners: OPTION_REFINERS$1,
14181        views: {
14182            list: {
14183                component: ListView,
14184                buttonTextKey: 'list',
14185                listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like "January 1, 2016"
14186            },
14187            listDay: {
14188                type: 'list',
14189                duration: { days: 1 },
14190                listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar
14191            },
14192            listWeek: {
14193                type: 'list',
14194                duration: { weeks: 1 },
14195                listDayFormat: { weekday: 'long' },
14196                listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' },
14197            },
14198            listMonth: {
14199                type: 'list',
14200                duration: { month: 1 },
14201                listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have
14202            },
14203            listYear: {
14204                type: 'list',
14205                duration: { year: 1 },
14206                listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have
14207            },
14208        },
14209    });
14210
14211    var BootstrapTheme = /** @class */ (function (_super) {
14212        __extends(BootstrapTheme, _super);
14213        function BootstrapTheme() {
14214            return _super !== null && _super.apply(this, arguments) || this;
14215        }
14216        return BootstrapTheme;
14217    }(Theme));
14218    BootstrapTheme.prototype.classes = {
14219        root: 'fc-theme-bootstrap',
14220        table: 'table-bordered',
14221        tableCellShaded: 'table-active',
14222        buttonGroup: 'btn-group',
14223        button: 'btn btn-primary',
14224        buttonActive: 'active',
14225        popover: 'popover',
14226        popoverHeader: 'popover-header',
14227        popoverContent: 'popover-body',
14228    };
14229    BootstrapTheme.prototype.baseIconClass = 'fa';
14230    BootstrapTheme.prototype.iconClasses = {
14231        close: 'fa-times',
14232        prev: 'fa-chevron-left',
14233        next: 'fa-chevron-right',
14234        prevYear: 'fa-angle-double-left',
14235        nextYear: 'fa-angle-double-right',
14236    };
14237    BootstrapTheme.prototype.rtlIconClasses = {
14238        prev: 'fa-chevron-right',
14239        next: 'fa-chevron-left',
14240        prevYear: 'fa-angle-double-right',
14241        nextYear: 'fa-angle-double-left',
14242    };
14243    BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
14243 // TODO: make TS-friendly. move the option-processing into this plugin
14244    BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
14245    BootstrapTheme.prototype.iconOverridePrefix = 'fa-';
14246    var plugin = createPlugin({
14247        themeClasses: {
14248            bootstrap: BootstrapTheme,
14249        },
14250    });
14251
14252    // rename this file to options.ts like other packages?
14253    var OPTION_REFINERS = {
14254        googleCalendarApiKey: String,
14255    };
14256
14257    var EVENT_SOURCE_REFINERS = {
14258        googleCalendarApiKey: String,
14259        googleCalendarId: String,
14260        googleCalendarApiBase: String,
14261        extraParams: identity,
14262    };
14263
14264    // TODO: expose somehow
14265    var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
14266    var eventSourceDef = {
14267        parseMeta: function (refined) {
14268            var googleCalendarId = refined.googleCalendarId;
14269            if (!googleCalendarId && refined.url) {
14270                googleCalendarId = parseGoogleCalendarId(refined.url);
14271            }
14272            if (googleCalendarId) {
14273                return {
14274                    googleCalendarId: googleCalendarId,
14275                    googleCalendarApiKey: refined.googleCalendarApiKey,
14276                    googleCalendarApiBase: refined.googleCalendarApiBase,
14277                    extraParams: refined.extraParams,
14278                };
14279            }
14280            return null;
14281        },
14282        fetch: function (arg, onSuccess, onFailure) {
14283            var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options;
14284            var meta = arg.eventSource.meta;
14285            var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey;
14286            if (!apiKey) {
14287                onFailure({
14288                    message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/',
14289                });
14290            }
14291            else {
14292                var url = buildUrl(meta);
14293                // TODO: make DRY with json-feed-event-source
14294                var extraParams = meta.extraParams;
14295                var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams;
14296                var requestParams_1 = buildRequestParams(arg.range, apiKey, extraParamsObj, dateEnv);
14297                requestJson('GET', url, requestParams_1, function (body, xhr) {
14298                    if (body.error) {
14299                        onFailure({
14300                            message: 'Google Calendar API: ' + body.error.message,
14301                            errors: body.error.errors,
14302                            xhr: xhr,
14303                        });
14304                    }
14305                    else {
14306                        onSuccess({
14307                            rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
14308                            xhr: xhr,
14309                        });
14310                    }
14311                }, function (message, xhr) {
14312                    onFailure({ message: message, xhr: xhr });
14313                });
14314            }
14315        },
14316    };
14317    function parseGoogleCalendarId(url) {
14318        var match;
14319        // detect if the ID was specified as a single string.
14320        // will match calendars like "[email protected]" in addition to person email calendars.
14321        if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
14322            return url;
14323        }
14324        if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) ||
14325            (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) {
14326            return decodeURIComponent(match[1]);
14327        }
14328        return null;
14329    }
14330    function buildUrl(meta) {
14331        var apiBase = meta.googleCalendarApiBase;
14332        if (!apiBase) {
14333            apiBase = API_BASE;
14334        }
14335        return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
14336    }
14337    function buildRequestParams(range, apiKey, extraParams, dateEnv) {
14338        var params;
14339        var startStr;
14340        var endStr;
14341        if (dateEnv.canComputeOffset) {
14342            // strings will naturally have offsets, which GCal needs
14343            startStr = dateEnv.formatIso(range.start);
14344            endStr = dateEnv.formatIso(range.end);
14345        }
14346        else {
14347            // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
14348            // from the UTC day-start to guarantee we're getting all the events
14349            // (start/end will be UTC-coerced dates, so toISOString is okay)
14350            startStr = addDays(range.start, -1).toISOString();
14351            endStr = addDays(range.end, 1).toISOString();
14352        }
14353        params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
14354        if (dateEnv.timeZone !== 'local') {
14355            params.timeZone = dateEnv.timeZone;
14356        }
14357        return params;
14358    }
14359    function gcalItemsToRawEventDefs(items, gcalTimezone) {
14360        return items.map(function (item) { return gcalItemToRawEventDef(item, gcalTimezone); });
14361    }
14362    function gcalItemToRawEventDef(item, gcalTimezone) {
14363        var url = item.htmlLink || null;
14364        // make the URLs for each event show times in the correct timezone
14365        if (url && gcalTimezone) {
14366            url = injectQsComponent(url, 'ctz=' + gcalTimezone);
14367        }
14368        return {
14369            id: item.id,
14370            title: item.summary,
14371            start: item.start.dateTime || item.start.date,
14372            end: item.end.dateTime || item.end.date,
14373            url: url,
14374            location: item.location,
14375            description: item.description,
14376            attachments: item.attachments || [],
14377            extendedProps: (item.extendedProperties || {}).shared || {},
14378        };
14379    }
14380    // Injects a string like "arg=value" into the querystring of a URL
14381    // TODO: move to a general util file?
14382    function injectQsComponent(url, component) {
14383        // inject it after the querystring but before the fragment
14384        return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { return (qs ? qs + '&' : '?') + component + hash; });
14385    }
14386    var googleCalendarPlugin = createPlugin({
14387        eventSourceDefs: [eventSourceDef],
14388        optionRefiners: OPTION_REFINERS,
14389        eventSourceRefiners: EVENT_SOURCE_REFINERS,
14390    });
14391
14392    globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin, googleCalendarPlugin);
14393
14394    exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS;
14395    exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS;
14396    exports.BaseComponent = BaseComponent;
14397    exports.BgEvent = BgEvent;
14398    exports.BootstrapTheme = BootstrapTheme;
14399    exports.Calendar = Calendar;
14400    exports.CalendarApi = CalendarApi;
14401    exports.CalendarContent = CalendarContent;
14402    exports.CalendarDataManager = CalendarDataManager;
14403    exports.CalendarDataProvider = CalendarDataProvider;
14404    exports.CalendarRoot = CalendarRoot;
14405    exports.Component = Component;
14406    exports.ContentHook = ContentHook;
14407    exports.CustomContentRenderContext = CustomContentRenderContext;
14408    exports.DateComponent = DateComponent;
14409    exports.DateEnv = DateEnv;
14410    exports.DateProfileGenerator = DateProfileGenerator;
14411    exports.DayCellContent = DayCellContent;
14412    exports.DayCellRoot = DayCellRoot;
14413    exports.DayGridView = DayTableView;
14414    exports.DayHeader = DayHeader;
14415    exports.DaySeriesModel = DaySeriesModel;
14416    exports.DayTable = DayTable;
14417    exports.DayTableModel = DayTableModel;
14418    exports.DayTableSlicer = DayTableSlicer;
14419    exports.DayTimeCols = DayTimeCols;
14420    exports.DayTimeColsSlicer = DayTimeColsSlicer;
14421    exports.DayTimeColsView = DayTimeColsView;
14422    exports.DelayedRunner = DelayedRunner;
14423    exports.Draggable = ExternalDraggable;
14424    exports.ElementDragging = ElementDragging;
14425    exports.ElementScrollController = ElementScrollController;
14426    exports.Emitter = Emitter;
14427    exports.EventApi = EventApi;
14428    exports.EventRoot = EventRoot;
14429    exports.EventSourceApi = EventSourceApi;
14430    exports.FeaturefulElementDragging = FeaturefulElementDragging;
14431    exports.Fragment = Fragment;
14432    exports.Interaction = Interaction;
14433    exports.ListView = ListView;
14434    exports.MoreLinkRoot = MoreLinkRoot;
14435    exports.MountHook = MountHook;
14436    exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
14437    exports.NowIndicatorRoot = NowIndicatorRoot;
14438    exports.NowTimer = NowTimer;
14439    exports.PointerDragging = PointerDragging;
14440    exports.PositionCache = PositionCache;
14441    exports.RefMap = RefMap;
14442    exports.RenderHook = RenderHook;
14443    exports.ScrollController = ScrollController;
14444    exports.ScrollResponder = ScrollResponder;
14445    exports.Scroller = Scroller;
14446    exports.SegHierarchy = SegHierarchy;
14447    exports.SimpleScrollGrid = SimpleScrollGrid;
14448    exports.Slicer = Slicer;
14449    exports.Splitter = Splitter;
14450    exports.StandardEvent = StandardEvent;
14451    exports.Table = Table;
14452    exports.TableDateCell = TableDateCell;
14453    exports.TableDowCell = TableDowCell;
14454    exports.TableView = TableView;
14455    exports.Theme = Theme;
14456    exports.ThirdPartyDraggable = ThirdPartyDraggable;
14457    exports.TimeCols = TimeCols;
14458    exports.TimeColsSlatsCoords = TimeColsSlatsCoords;
14459    exports.TimeColsView = TimeColsView;
14460    exports.ViewApi = ViewApi;
14461    exports.ViewContextType = ViewContextType;
14462    exports.ViewRoot = ViewRoot;
14463    exports.WeekNumberRoot = WeekNumberRoot;
14464    exports.WindowScrollController = WindowScrollController;
14465    exports.addDays = addDays;
14466    exports.addDurations = addDurations;
14467    exports.addMs = addMs;
14468    exports.addWeeks = addWeeks;
14469    exports.allowContextMenu = allowContextMenu;
14470    exports.allowSelection = allowSelection;
14471    exports.applyMutationToEventStore = applyMutationToEventStore;
14472    exports.applyStyle = applyStyle;
14473    exports.applyStyleProp = applyStyleProp;
14474    exports.asCleanDays = asCleanDays;
14475    exports.asRoughMinutes = asRoughMinutes;
14476    exports.asRoughMs = asRoughMs;
14477    exports.asRoughSeconds = asRoughSeconds;
14478    exports.binarySearch = binarySearch;
14479    exports.buildClassNameNormalizer = buildClassNameNormalizer;
14480    exports.buildDayRanges = buildDayRanges;
14481    exports.buildDayTableModel = buildDayTableModel;
14482    exports.buildEntryKey = buildEntryKey;
14483    exports.buildEventApis = buildEventApis;
14484    exports.buildEventRangeKey = buildEventRangeKey;
14485    exports.buildHashFromArray = buildHashFromArray;
14486    exports.buildIsoString = buildIsoString;
14487    exports.buildNavLinkData = buildNavLinkData;
14488    exports.buildSegCompareObj = buildSegCompareObj;
14489    exports.buildSegTimeText = buildSegTimeText;
14490    exports.buildSlatMetas = buildSlatMetas;
14491    exports.buildTimeColsModel = buildTimeColsModel;
14492    exports.collectFromHash = collectFromHash;
14493    exports.combineEventUis = combineEventUis;
14494    exports.compareByFieldSpec = compareByFieldSpec;
14495    exports.compareByFieldSpecs = compareByFieldSpecs;
14496    exports.compareNumbers = compareNumbers;
14497    exports.compareObjs = compareObjs;
14498    exports.computeEarliestSegStart = computeEarliestSegStart;
14499    exports.computeEdges = computeEdges;
14500    exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
14501    exports.computeHeightAndMargins = computeHeightAndMargins;
14502    exports.computeInnerRect = computeInnerRect;
14503    exports.computeRect = computeRect;
14504    exports.computeSegDraggable = computeSegDraggable;
14505    exports.computeSegEndResizable = computeSegEndResizable;
14506    exports.computeSegStartResizable = computeSegStartResizable;
14507    exports.computeShrinkWidth = computeShrinkWidth;
14508    exports.computeSmallestCellWidth = computeSmallestCellWidth;
14509    exports.computeVisibleDayRange = computeVisibleDayRange;
14510    exports.config = config;
14511    exports.constrainPoint = constrainPoint;
14512    exports.createContext = createContext;
14513    exports.createDuration = createDuration;
14514    exports.createElement = createElement;
14515    exports.createEmptyEventStore = createEmptyEventStore;
14516    exports.createEventInstance = createEventInstance;
14517    exports.createEventUi = createEventUi;
14518    exports.createFormatter = createFormatter;
14519    exports.createPlugin = createPlugin;
14520    exports.createPortal = createPortal;
14521    exports.createRef = createRef;
14522    exports.diffDates = diffDates;
14523    exports.diffDayAndTime = diffDayAndTime;
14524    exports.diffDays = diffDays;
14525    exports.diffPoints = diffPoints;
14526    exports.diffWeeks = diffWeeks;
14527    exports.diffWholeDays = diffWholeDays;
14528    exports.diffWholeWeeks = diffWholeWeeks;
14529    exports.disableCursor = disableCursor;
14530    exports.elementClosest = elementClosest;
14531    exports.elementMatches = elementMatches;
14532    exports.enableCursor = enableCursor;
14533    exports.eventTupleToStore = eventTupleToStore;
14534    exports.filterEventStoreDefs = filterEventStoreDefs;
14535    exports.filterHash = filterHash;
14536    exports.findDirectChildren = findDirectChildren;
14537    exports.findElements = findElements;
14538    exports.flexibleCompare = flexibleCompare;
14539    exports.flushToDom = flushToDom;
14540    exports.formatDate = formatDate;
14541    exports.formatDayString = formatDayString;
14542    exports.formatIsoTimeString = formatIsoTimeString;
14543    exports.formatRange = formatRange;
14544    exports.getAllowYScrolling = getAllowYScrolling;
14545    exports.getCanVGrowWithinCell = getCanVGrowWithinCell;
14546    exports.getClippingParents = getClippingParents;
14547    exports.getDateMeta = getDateMeta;
14548    exports.getDayClassNames = getDayClassNames;
14549    exports.getDefaultEventEnd = getDefaultEventEnd;
14550    exports.getElSeg = getElSeg;
14551    exports.getEntrySpanEnd = getEntrySpanEnd;
14552    exports.getEventClassNames = getEventClassNames;
14553    exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft;
14554    exports.getRectCenter = getRectCenter;
14555    exports.getRelevantEvents = getRelevantEvents;
14556    exports.getScrollGridClassNames = getScrollGridClassNames;
14557    exports.getScrollbarWidths = getScrollbarWidths;
14558    exports.getSectionClassNames = getSectionClassNames;
14559    exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight;
14560    exports.getSegMeta = getSegMeta;
14561    exports.getSlotClassNames = getSlotClassNames;
14562    exports.getStickyFooterScrollbar = getStickyFooterScrollbar;
14563    exports.getStickyHeaderDates = getStickyHeaderDates;
14564    exports.getUnequalProps = getUnequalProps;
14565    exports.globalLocales = globalLocales;
14566    exports.globalPlugins = globalPlugins;
14567    exports.greatestDurationDenominator = greatestDurationDenominator;
14568    exports.groupIntersectingEntries = groupIntersectingEntries;
14569    exports.guid = guid;
14570    exports.hasBgRendering = hasBgRendering;
14571    exports.hasShrinkWidth = hasShrinkWidth;
14572    exports.identity = identity;
14573    exports.interactionSettingsStore = interactionSettingsStore;
14574    exports.interactionSettingsToStore = interactionSettingsToStore;
14575    exports.intersectRanges = intersectRanges;
14576    exports.intersectRects = intersectRects;
14577    exports.isArraysEqual = isArraysEqual;
14578    exports.isColPropsEqual = isColPropsEqual;
14579    exports.isDateSelectionValid = isDateSelectionValid;
14580    exports.isDateSpansEqual = isDateSpansEqual;
14581    exports.isInt = isInt;
14582    exports.isInteractionValid = isInteractionValid;
14583    exports.isMultiDayRange = isMultiDayRange;
14584    exports.isPropsEqual = isPropsEqual;
14585    exports.isPropsValid = isPropsValid;
14586    exports.isValidDate = isValidDate;
14587    exports.listenBySelector = listenBySelector;
14588    exports.mapHash = mapHash;
14589    exports.memoize = memoize;
14590    exports.memoizeArraylike = memoizeArraylike;
14591    exports.memoizeHashlike = memoizeHashlike;
14592    exports.memoizeObjArg = memoizeObjArg;
14593    exports.mergeEventStores = mergeEventStores;
14594    exports.multiplyDuration = multiplyDuration;
14595    exports.padStart = padStart;
14596    exports.parseBusinessHours = parseBusinessHours;
14597    exports.parseClassNames = parseClassNames;
14598    exports.parseDragMeta = parseDragMeta;
14599    exports.parseEventDef = parseEventDef;
14600    exports.parseFieldSpecs = parseFieldSpecs;
14601    exports.parseMarker = parse;
14602    exports.pointInsideRect = pointInsideRect;
14603    exports.preventContextMenu = preventContextMenu;
14604    exports.preventDefault = preventDefault;
14605    exports.preventSelection = preventSelection;
14606    exports.rangeContainsMarker = rangeContainsMarker;
14607    exports.rangeContainsRange = rangeContainsRange;
14608    exports.rangesEqual = rangesEqual;
14609    exports.rangesIntersect = rangesIntersect;
14610    exports.refineEventDef = refineEventDef;
14611    exports.refineProps = refineProps;
14612    exports.removeElement = removeElement;
14613    exports.removeExact = removeExact;
14614    exports.render = render;
14615    exports.renderChunkContent = renderChunkContent;
14616    exports.renderFill = renderFill;
14617    exports.renderMicroColGroup = renderMicroColGroup;
14618    exports.renderScrollShim = renderScrollShim;
14619    exports.requestJson = requestJson;
14620    exports.sanitizeShrinkWidth = sanitizeShrinkWidth;
14621    exports.setElSeg = setElSeg;
14622    exports.setRef = setRef;
14623    exports.sliceEventStore = sliceEventStore;
14624    exports.sliceEvents = sliceEvents;
14625    exports.sortEventSegs = sortEventSegs;
14626    exports.startOfDay = startOfDay;
14627    exports.translateRect = translateRect;
14628    exports.triggerDateSelect = triggerDateSelect;
14629    exports.unmountComponentAtNode = unmountComponentAtNode;
14630    exports.unpromisify = unpromisify;
14631    exports.version = version;
14632    exports.whenTransitionDone = whenTransitionDone;
14633    exports.wholeDivideDurations = wholeDivideDurations;
14634
14635    Object.defineProperty(exports, '__esModule', { value: true });
14636
14637    return exports;
14638
14639}({}));

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.