/*!
FullCalendar v5.3.1
Docs & License: https://fullcalendar.io/
(c) 2020 Adam Shaw
*/
var FullCalendarTimeGrid = (function (exports, common, daygrid) {
    'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* global Reflect, Promise */

    var extendStatics = function(d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var __assign = function() {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };

    var AllDaySplitter = /** @class */ (function (_super) {
        __extends(AllDaySplitter, _super);
        function AllDaySplitter() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        AllDaySplitter.prototype.getKeyInfo = function () {
            return {
                allDay: {},
                timed: {}
            };
        };
        AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
            if (dateSpan.allDay) {
                return ['allDay'];
            }
            else {
                return ['timed'];
            }
        };
        AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
            if (!eventDef.allDay) {
                return ['timed'];
            }
            else if (common.hasBgRendering(eventDef)) {
                return ['timed', 'allDay'];
            }
            else {
                return ['allDay'];
            }
        };
        return AllDaySplitter;
    }(common.Splitter));

    var TimeColsSlatsCoords = /** @class */ (function () {
        function TimeColsSlatsCoords(positions, dateProfile, slatMetas) {
            this.positions = positions;
            this.dateProfile = dateProfile;
            this.slatMetas = slatMetas;
        }
        TimeColsSlatsCoords.prototype.safeComputeTop = function (date) {
            var dateProfile = this.dateProfile;
            if (common.rangeContainsMarker(dateProfile.currentRange, date)) {
                var startOfDayDate = common.startOfDay(date);
                var timeMs = date.valueOf() - startOfDayDate.valueOf();
                if (timeMs >= common.asRoughMs(dateProfile.slotMinTime) &&
                    timeMs < common.asRoughMs(dateProfile.slotMaxTime)) {
                    return this.computeTimeTop(common.createDuration(timeMs));
                }
            }
        };
        // Computes the top coordinate, relative to the bounds of the grid, of the given date.
        // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
        TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) {
            if (!startOfDayDate) {
                startOfDayDate = common.startOfDay(when);
            }
            return this.computeTimeTop(common.createDuration(when.valueOf() - startOfDayDate.valueOf()));
        };
        // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
        // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.
        // Eventually allow computation with arbirary slat dates.
        TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) {
            var _a = this, positions = _a.positions, dateProfile = _a.dateProfile, slatMetas = _a.slatMetas;
            var len = positions.els.length;
            var slotDurationMs = slatMetas[1].date.valueOf() - slatMetas[0].date.valueOf(); // we assume dates are uniform
            var slatCoverage = (duration.milliseconds - common.asRoughMs(dateProfile.slotMinTime)) / slotDurationMs; // floating-point value of # of slots covered
            var slatIndex;
            var slatRemainder;
            // compute a floating-point number for how many slats should be progressed through.
            // from 0 to number of slats (inclusive)
            // constrained because slotMinTime/slotMaxTime might be customized.
            slatCoverage = Math.max(0, slatCoverage);
            slatCoverage = Math.min(len, slatCoverage);
            // an integer index of the furthest whole slat
            // from 0 to number slats (*exclusive*, so len-1)
            slatIndex = Math.floor(slatCoverage);
            slatIndex = Math.min(slatIndex, len - 1);
            // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
            // could be 1.0 if slatCoverage is covering *all* the slots
            slatRemainder = slatCoverage - slatIndex;
            return positions.tops[slatIndex] +
                positions.getHeight(slatIndex) * slatRemainder;
        };
        return TimeColsSlatsCoords;
    }());

    // potential nice values for the slot-duration and interval-duration
    // from largest to smallest
    var STOCK_SUB_DURATIONS = [
        { hours: 1 },
        { minutes: 30 },
        { minutes: 15 },
        { seconds: 30 },
        { seconds: 15 }
    ];
    /*
    for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
    */
    var TimeColsSlats = /** @class */ (function (_super) {
        __extends(TimeColsSlats, _super);
        function TimeColsSlats() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.rootElRef = common.createRef();
            _this.slatElRefs = new common.RefMap();
            return _this;
        }
        TimeColsSlats.prototype.render = function () {
            var _a = this, props = _a.props, context = _a.context;
            return (common.createElement("div", { className: 'fc-timegrid-slots', ref: this.rootElRef },
                common.createElement("table", { className: context.theme.getClass('table'), style: {
                        minWidth: props.tableMinWidth,
                        width: props.clientWidth,
                        height: props.minHeight
                    } },
                    props.tableColGroupNode /* relies on there only being a single <col> for the axis */,
                    common.createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));
        };
        TimeColsSlats.prototype.componentDidMount = function () {
            this.updateSizing();
        };
        TimeColsSlats.prototype.componentDidUpdate = function () {
            this.updateSizing();
        };
        TimeColsSlats.prototype.componentWillUnmount = function () {
            if (this.props.onCoords) {
                this.props.onCoords(null);
            }
        };
        TimeColsSlats.prototype.updateSizing = function () {
            var props = this.props;
            if (props.onCoords &&
                props.clientWidth !== null // means sizing has stabilized
            ) {
                var rootEl = this.rootElRef.current;
                if (rootEl.offsetHeight) { // not hidden by css
                    props.onCoords(new TimeColsSlatsCoords(new common.PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true // vertical
                    ), this.props.dateProfile, props.slatMetas));
                }
            }
        };
        return TimeColsSlats;
    }(common.BaseComponent));
    function collectSlatEls(elMap, slatMetas) {
        return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; });
    }
    var TimeColsSlatsBody = /** @class */ (function (_super) {
        __extends(TimeColsSlatsBody, _super);
        function TimeColsSlatsBody() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TimeColsSlatsBody.prototype.render = function () {
            var _a = this, props = _a.props, context = _a.context;
            var options = context.options;
            var slatElRefs = props.slatElRefs;
            return (common.createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) {
                var hookProps = {
                    time: slatMeta.time,
                    date: context.dateEnv.toDate(slatMeta.date),
                    view: context.viewApi
                };
                var classNames = [
                    'fc-timegrid-slot',
                    'fc-timegrid-slot-lane',
                    slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor'
                ];
                return (common.createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },
                    props.axis &&
                        common.createElement(TimeColsAxisCell, __assign({}, slatMeta)),
                    common.createElement(common.RenderHook, { hookProps: hookProps, classNames: options.slotLaneClassNames, content: options.slotLaneContent, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (common.createElement("td", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); })));
            })));
        };
        return TimeColsSlatsBody;
    }(common.BaseComponent));
    var DEFAULT_SLAT_LABEL_FORMAT = common.createFormatter({
        hour: 'numeric',
        minute: '2-digit',
        omitZeroMinute: true,
        meridiem: 'short'
    });
    function TimeColsAxisCell(props) {
        var classNames = [
            'fc-timegrid-slot',
            'fc-timegrid-slot-label',
            props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor'
        ];
        return (common.createElement(common.ViewContextType.Consumer, null, function (context) {
            if (!props.isLabeled) {
                return (common.createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr }));
            }
            else {
                var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi;
                var labelFormat = // TODO: fully pre-parse
                 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :
                    Array.isArray(options.slotLabelFormat) ? common.createFormatter(options.slotLabelFormat[0]) :
                        common.createFormatter(options.slotLabelFormat);
                var hookProps = {
                    level: 0,
                    time: props.time,
                    date: dateEnv.toDate(props.date),
                    view: viewApi,
                    text: dateEnv.format(props.date, labelFormat)
                };
                return (common.createElement(common.RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (common.createElement("td", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-time": props.isoTimeStr },
                    common.createElement("div", { className: 'fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame' },
                        common.createElement("div", { className: 'fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion', ref: innerElRef }, innerContent)))); }));
            }
        }));
    }
    function renderInnerContent(props) {
        return props.text;
    }
    function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {
        var dayStart = new Date(0);
        var slatTime = slotMinTime;
        var slatIterator = common.createDuration(0);
        var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);
        var metas = [];
        while (common.asRoughMs(slatTime) < common.asRoughMs(slotMaxTime)) {
            var date = dateEnv.add(dayStart, slatTime);
            var isLabeled = common.wholeDivideDurations(slatIterator, labelInterval) !== null;
            metas.push({
                date: date,
                time: slatTime,
                key: date.toISOString(),
                isoTimeStr: common.formatIsoTimeString(date),
                isLabeled: isLabeled
            });
            slatTime = common.addDurations(slatTime, slotDuration);
            slatIterator = common.addDurations(slatIterator, slotDuration);
        }
        return metas;
    }
    // Computes an automatic value for slotLabelInterval
    function computeLabelInterval(slotDuration) {
        var i;
        var labelInterval;
        var slotsPerLabel;
        // find the smallest stock label interval that results in more than one slots-per-label
        for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
            labelInterval = common.createDuration(STOCK_SUB_DURATIONS[i]);
            slotsPerLabel = common.wholeDivideDurations(labelInterval, slotDuration);
            if (slotsPerLabel !== null && slotsPerLabel > 1) {
                return labelInterval;
            }
        }
        return slotDuration; // fall back
    }

    var DEFAULT_WEEK_NUM_FORMAT = common.createFormatter({ week: 'short' });
    var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;
    var TimeColsView = /** @class */ (function (_super) {
        __extends(TimeColsView, _super);
        function TimeColsView() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses
            _this.headerElRef = common.createRef();
            _this.rootElRef = common.createRef();
            _this.scrollerElRef = common.createRef();
            _this.state = {
                slatCoords: null
            };
            _this.handleScrollTopRequest = function (scrollTop) {
                var scrollerEl = _this.scrollerElRef.current;
                if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer
                    scrollerEl.scrollTop = scrollTop;
                }
            };
            /* Header Render Methods
            ------------------------------------------------------------------------------------------------------------------*/
            _this.renderHeadAxis = function (frameHeight) {
                if (frameHeight === void 0) { frameHeight = ''; }
                var options = _this.context.options;
                var dateProfile = _this.props.dateProfile;
                var range = dateProfile.renderRange;
                var dayCnt = common.diffDays(range.start, range.end);
                var navLinkAttrs = (options.navLinks && dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it)
                    ? { 'data-navlink': common.buildNavLinkData(range.start, 'week'), tabIndex: 0 }
                    : {};
                if (options.weekNumbers) {
                    return (common.createElement(common.WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("th", { ref: rootElRef, className: [
                            'fc-timegrid-axis',
                            'fc-scrollgrid-shrink'
                        ].concat(classNames).join(' ') },
                        common.createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid', style: { height: frameHeight } },
                            common.createElement("a", __assign({ ref: innerElRef, className: 'fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner' }, navLinkAttrs), innerContent)))); }));
                }
                return (common.createElement("th", { className: 'fc-timegrid-axis' },
                    common.createElement("div", { className: 'fc-timegrid-axis-frame', style: { height: frameHeight } })));
            };
            /* Table Component Render Methods
            ------------------------------------------------------------------------------------------------------------------*/
            // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,
            // but DayGrid still needs to have classNames on inner elements in order to measure.
            _this.renderTableRowAxis = function (rowHeight) {
                var _a = _this.context, options = _a.options, viewApi = _a.viewApi;
                var hookProps = {
                    text: options.allDayText,
                    view: viewApi
                };
                return (
                // TODO: make reusable hook. used in list view too
                common.createElement(common.RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("td", { ref: rootElRef, className: [
                        'fc-timegrid-axis',
                        'fc-scrollgrid-shrink'
                    ].concat(classNames).join(' ') },
                    common.createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } },
                        common.createElement("span", { className: 'fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner', ref: innerElRef }, innerContent)))); }));
            };
            _this.handleSlatCoords = function (slatCoords) {
                _this.setState({ slatCoords: slatCoords });
            };
            return _this;
        }
        // rendering
        // ----------------------------------------------------------------------------------------------------
        TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) {
            var _a = this, context = _a.context, props = _a.props;
            var sections = [];
            var stickyHeaderDates = common.getStickyHeaderDates(context.options);
            if (headerRowContent) {
                sections.push({
                    type: 'header',
                    key: 'header',
                    isSticky: stickyHeaderDates,
                    chunk: {
                        elRef: this.headerElRef,
                        tableClassName: 'fc-col-header',
                        rowContent: headerRowContent
                    }
                });
            }
            if (allDayContent) {
                sections.push({
                    type: 'body',
                    key: 'all-day',
                    chunk: { content: allDayContent }
                });
                sections.push({
                    type: 'body',
                    key: 'all-day-divider',
                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
                    common.createElement("tr", { className: 'fc-scrollgrid-section' },
                        common.createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') })))
                });
            }
            sections.push({
                type: 'body',
                key: 'body',
                liquid: true,
                expandRows: Boolean(context.options.expandRows),
                chunk: {
                    scrollerElRef: this.scrollerElRef,
                    content: timeContent
                }
            });
            return (common.createElement(common.ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (common.createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
                common.createElement(common.SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); }));
        };
        TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords // yuck
        ) {
            var _this = this;
            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
            if (!ScrollGrid) {
                throw new Error('No ScrollGrid implementation');
            }
            var _a = this, context = _a.context, props = _a.props;
            var stickyHeaderDates = !props.forPrint && common.getStickyHeaderDates(context.options);
            var stickyFooterScrollbar = !props.forPrint && common.getStickyFooterScrollbar(context.options);
            var sections = [];
            if (headerRowContent) {
                sections.push({
                    type: 'header',
                    key: 'header',
                    isSticky: stickyHeaderDates,
                    syncRowHeights: true,
                    chunks: [
                        {
                            key: 'axis',
                            rowContent: function (arg) { return (common.createElement("tr", null, _this.renderHeadAxis(arg.rowSyncHeights[0]))); }
                        },
                        {
                            key: 'cols',
                            elRef: this.headerElRef,
                            tableClassName: 'fc-col-header',
                            rowContent: headerRowContent
                        }
                    ]
                });
            }
            if (allDayContent) {
                sections.push({
                    type: 'body',
                    key: 'all-day',
                    syncRowHeights: true,
                    chunks: [
                        {
                            key: 'axis',
                            rowContent: function (contentArg) { return (common.createElement("tr", null, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); },
                        },
                        {
                            key: 'cols',
                            content: allDayContent
                        }
                    ]
                });
                sections.push({
                    key: 'all-day-divider',
                    type: 'body',
                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
                    common.createElement("tr", { className: 'fc-scrollgrid-section' },
                        common.createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') })))
                });
            }
            var isNowIndicator = context.options.nowIndicator;
            sections.push({
                type: 'body',
                key: 'body',
                liquid: true,
                expandRows: Boolean(context.options.expandRows),
                chunks: [
                    {
                        key: 'axis',
                        content: function (arg) {
                            // TODO: make this now-indicator arrow more DRY with TimeColsContent
                            return (common.createElement("div", { className: 'fc-timegrid-axis-chunk' },
                                common.createElement("table", { style: { height: arg.expandRows ? arg.clientHeight : '' } },
                                    arg.tableColGroupNode,
                                    common.createElement("tbody", null,
                                        common.createElement(TimeBodyAxis, { slatMetas: slatMetas }))),
                                common.createElement("div", { className: 'fc-timegrid-now-indicator-container' },
                                    common.createElement(common.NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) {
                                        var nowIndicatorTop = isNowIndicator &&
                                            slatCoords &&
                                            slatCoords.safeComputeTop(nowDate); // might return void
                                        if (typeof nowIndicatorTop === 'number') {
                                            return (common.createElement(common.NowIndicatorRoot, { isAxis: true, date: nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); }));
                                        }
                                        return null;
                                    }))));
                        }
                    },
                    {
                        key: 'cols',
                        scrollerElRef: this.scrollerElRef,
                        content: timeContent
                    }
                ]
            });
            if (stickyFooterScrollbar) {
                sections.push({
                    key: 'footer',
                    type: 'footer',
                    isSticky: true,
                    chunks: [
                        {
                            key: 'axis',
                            content: common.renderScrollShim
                        },
                        {
                            key: 'cols',
                            content: common.renderScrollShim
                        }
                    ]
                });
            }
            return (common.createElement(common.ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (common.createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
                common.createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, colGroups: [
                        { width: 'shrink', cols: [{ width: 'shrink' }] },
                        { cols: [{ span: colCnt, minWidth: dayMinWidth }] }
                    ], sections: sections }))); }));
        };
        /* Dimensions
        ------------------------------------------------------------------------------------------------------------------*/
        TimeColsView.prototype.getAllDayMaxEventProps = function () {
            var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows;
            if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?
                dayMaxEvents = undefined;
                dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number
            }
            return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows };
        };
        return TimeColsView;
    }(common.DateComponent));
    function renderAllDayInner(hookProps) {
        return hookProps.text;
    }
    var TimeBodyAxis = /** @class */ (function (_super) {
        __extends(TimeBodyAxis, _super);
        function TimeBodyAxis() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TimeBodyAxis.prototype.render = function () {
            return this.props.slatMetas.map(function (slatMeta) { return (common.createElement("tr", { key: slatMeta.key },
                common.createElement(TimeColsAxisCell, __assign({}, slatMeta)))); });
        };
        return TimeBodyAxis;
    }(common.BaseComponent));

    function splitSegsByCol(segs, colCnt) {
        var segsByCol = [];
        var i;
        for (i = 0; i < colCnt; i++) {
            segsByCol.push([]);
        }
        if (segs) {
            for (i = 0; i < segs.length; i++) {
                segsByCol[segs[i].col].push(segs[i]);
            }
        }
        return segsByCol;
    }
    function splitInteractionByCol(ui, colCnt) {
        var byRow = [];
        if (!ui) {
            for (var i = 0; i < colCnt; i++) {
                byRow[i] = null;
            }
        }
        else {
            for (var i = 0; i < colCnt; i++) {
                byRow[i] = {
                    affectedInstances: ui.affectedInstances,
                    isEvent: ui.isEvent,
                    segs: []
                };
            }
            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
                var seg = _a[_i];
                byRow[seg.col].segs.push(seg);
            }
        }
        return byRow;
    }

    // UNFORTUNATELY, assigns results to the top/bottom/level/forwardCoord/backwardCoord props of the actual segs.
    // TODO: return hash (by instanceId) of results
    function computeSegCoords(segs, dayDate, slatCoords, eventMinHeight, eventOrderSpecs) {
        computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight);
        return computeSegHorizontals(segs, eventOrderSpecs); // requires top/bottom from computeSegVerticals
    }
    // For each segment in an array, computes and assigns its top and bottom properties
    function computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight) {
        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
            var seg = segs_1[_i];
            seg.top = slatCoords.computeDateTop(seg.start, dayDate);
            seg.bottom = Math.max(seg.top + (eventMinHeight || 0), // yuck
            slatCoords.computeDateTop(seg.end, dayDate));
        }
    }
    // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
    // Assumed the segs are already ordered.
    // NOTE: Also reorders the given array by date!
    function computeSegHorizontals(segs, eventOrderSpecs) {
        // IMPORTANT TO CLEAR OLD RESULTS :(
        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
            var seg = segs_2[_i];
            seg.level = null;
            seg.forwardCoord = null;
            seg.backwardCoord = null;
            seg.forwardPressure = null;
        }
        segs = common.sortEventSegs(segs, eventOrderSpecs);
        var level0;
        var levels = buildSlotSegLevels(segs);
        computeForwardSlotSegs(levels);
        if ((level0 = levels[0])) {
            for (var _a = 0, level0_1 = level0; _a < level0_1.length; _a++) {
                var seg = level0_1[_a];
                computeSlotSegPressures(seg);
            }
            for (var _b = 0, level0_2 = level0; _b < level0_2.length; _b++) {
                var seg = level0_2[_b];
                computeSegForwardBack(seg, 0, 0, eventOrderSpecs);
            }
        }
        return segs;
    }
    // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
    // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
    function buildSlotSegLevels(segs) {
        var levels = [];
        var i;
        var seg;
        var j;
        for (i = 0; i < segs.length; i++) {
            seg = segs[i];
            // go through all the levels and stop on the first level where there are no collisions
            for (j = 0; j < levels.length; j++) {
                if (!computeSlotSegCollisions(seg, levels[j]).length) {
                    break;
                }
            }
            seg.level = j;
            (levels[j] || (levels[j] = [])).push(seg);
        }
        return levels;
    }
    // Find all the segments in `otherSegs` that vertically collide with `seg`.
    // Append into an optionally-supplied `results` array and return.
    function computeSlotSegCollisions(seg, otherSegs, results) {
        if (results === void 0) { results = []; }
        for (var i = 0; i < otherSegs.length; i++) {
            if (isSlotSegCollision(seg, otherSegs[i])) {
                results.push(otherSegs[i]);
            }
        }
        return results;
    }
    // Do these segments occupy the same vertical space?
    function isSlotSegCollision(seg1, seg2) {
        return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
    }
    // For every segment, figure out the other segments that are in subsequent
    // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
    function computeForwardSlotSegs(levels) {
        var i;
        var level;
        var j;
        var seg;
        var k;
        for (i = 0; i < levels.length; i++) {
            level = levels[i];
            for (j = 0; j < level.length; j++) {
                seg = level[j];
                seg.forwardSegs = [];
                for (k = i + 1; k < levels.length; k++) {
                    computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
                }
            }
        }
    }
    // Figure out which path forward (via seg.forwardSegs) results in the longest path until
    // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
    function computeSlotSegPressures(seg) {
        var forwardSegs = seg.forwardSegs;
        var forwardPressure = 0;
        var i;
        var forwardSeg;
        if (seg.forwardPressure == null) { // not already computed
            for (i = 0; i < forwardSegs.length; i++) {
                forwardSeg = forwardSegs[i];
                // figure out the child's maximum forward path
                computeSlotSegPressures(forwardSeg);
                // either use the existing maximum, or use the child's forward pressure
                // plus one (for the forwardSeg itself)
                forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
            }
            seg.forwardPressure = forwardPressure;
        }
    }
    // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
    // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
    // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
    //
    // The segment might be part of a "series", which means consecutive segments with the same pressure
    // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
    // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
    // coordinate of the first segment in the series.
    function computeSegForwardBack(seg, seriesBackwardPressure, seriesBackwardCoord, eventOrderSpecs) {
        var forwardSegs = seg.forwardSegs;
        var i;
        if (seg.forwardCoord == null) { // not already computed
            if (!forwardSegs.length) {
                // if there are no forward segments, this segment should butt up against the edge
                seg.forwardCoord = 1;
            }
            else {
                // sort highest pressure first
                sortForwardSegs(forwardSegs, eventOrderSpecs);
                // this segment's forwardCoord will be calculated from the backwardCoord of the
                // highest-pressure forward segment.
                computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord, eventOrderSpecs);
                seg.forwardCoord = forwardSegs[0].backwardCoord;
            }
            // calculate the backwardCoord from the forwardCoord. consider the series
            seg.backwardCoord = seg.forwardCoord -
                (seg.forwardCoord - seriesBackwardCoord) / // available width for series
                    (seriesBackwardPressure + 1); // # of segments in the series
            // use this segment's coordinates to computed the coordinates of the less-pressurized
            // forward segments
            for (i = 0; i < forwardSegs.length; i++) {
                computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord, eventOrderSpecs);
            }
        }
    }
    function sortForwardSegs(forwardSegs, eventOrderSpecs) {
        var objs = forwardSegs.map(buildTimeGridSegCompareObj);
        var specs = [
            // put higher-pressure first
            { field: 'forwardPressure', order: -1 },
            // put segments that are closer to initial edge first (and favor ones with no coords yet)
            { field: 'backwardCoord', order: 1 }
        ].concat(eventOrderSpecs);
        objs.sort(function (obj0, obj1) {
            return common.compareByFieldSpecs(obj0, obj1, specs);
        });
        return objs.map(function (c) {
            return c._seg;
        });
    }
    function buildTimeGridSegCompareObj(seg) {
        var obj = common.buildSegCompareObj(seg);
        obj.forwardPressure = seg.forwardPressure;
        obj.backwardCoord = seg.backwardCoord;
        return obj;
    }

    var DEFAULT_TIME_FORMAT = common.createFormatter({
        hour: 'numeric',
        minute: '2-digit',
        meridiem: false
    });
    var TimeColEvent = /** @class */ (function (_super) {
        __extends(TimeColEvent, _super);
        function TimeColEvent() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TimeColEvent.prototype.render = function () {
            var classNames = [
                'fc-timegrid-event',
                'fc-v-event'
            ];
            if (this.props.isCondensed) {
                classNames.push('fc-timegrid-event-condensed');
            }
            return (common.createElement(common.StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT, extraClassNames: classNames })));
        };
        return TimeColEvent;
    }(common.BaseComponent));

    common.config.timeGridEventCondensedHeight = 30;
    var TimeCol = /** @class */ (function (_super) {
        __extends(TimeCol, _super);
        function TimeCol() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TimeCol.prototype.render = function () {
            var _this = this;
            var _a = this, props = _a.props, context = _a.context;
            var isSelectMirror = context.options.selectMirror;
            var mirrorSegs = (props.eventDrag && props.eventDrag.segs) ||
                (props.eventResize && props.eventResize.segs) ||
                (isSelectMirror && props.dateSelectionSegs) ||
                [];
            var interactionAffectedInstances = // TODO: messy way to compute this
             (props.eventDrag && props.eventDrag.affectedInstances) ||
                (props.eventResize && props.eventResize.affectedInstances) ||
                {};
            return (common.createElement(common.DayCellRoot, { elRef: props.elRef, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (rootElRef, classNames, dataAttrs) { return (common.createElement("td", __assign({ ref: rootElRef, className: ['fc-timegrid-col'].concat(classNames, props.extraClassNames || []).join(' ') }, dataAttrs, props.extraDataAttrs),
                common.createElement("div", { className: 'fc-timegrid-col-frame' },
                    common.createElement("div", { className: 'fc-timegrid-col-bg' },
                        _this.renderFillSegs(props.businessHourSegs, 'non-business'),
                        _this.renderFillSegs(props.bgEventSegs, 'bg-event'),
                        _this.renderFillSegs(props.dateSelectionSegs, 'highlight')),
                    common.createElement("div", { className: 'fc-timegrid-col-events' }, _this.renderFgSegs(props.fgEventSegs, interactionAffectedInstances)),
                    common.createElement("div", { className: 'fc-timegrid-col-events' }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror)
                    // TODO: pass in left/right instead of using only computeSegTopBottomCss
                    )),
                    common.createElement("div", { className: 'fc-timegrid-now-indicator-container' }, _this.renderNowIndicator(props.nowIndicatorSegs)),
                    common.createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); }));
        };
        TimeCol.prototype.renderFgSegs = function (segs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
            var props = this.props;
            if (props.forPrint) {
                return this.renderPrintFgSegs(segs);
            }
            else if (props.slatCoords) {
                return this.renderPositionedFgSegs(segs, segIsInvisible, isDragging, isResizing, isDateSelecting);
            }
        };
        TimeCol.prototype.renderPrintFgSegs = function (segs) {
            var _a = this, props = _a.props, context = _a.context;
            // not DRY
            segs = common.sortEventSegs(segs, context.options.eventOrder);
            return segs.map(function (seg) { return (common.createElement("div", { className: 'fc-timegrid-event-harness', key: seg.eventRange.instance.instanceId },
                common.createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isCondensed: false }, common.getSegMeta(seg, props.todayRange, props.nowDate))))); });
        };
        TimeCol.prototype.renderPositionedFgSegs = function (segs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
            var _this = this;
            var _a = this, context = _a.context, props = _a.props;
            // assigns TO THE SEGS THEMSELVES
            // also, receives resorted array
            segs = computeSegCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight, context.options.eventOrder);
            return segs.map(function (seg) {
                var instanceId = seg.eventRange.instance.instanceId;
                var isMirror = isDragging || isResizing || isDateSelecting;
                var positionCss = isMirror ? __assign({ left: 0, right: 0 }, _this.computeSegTopBottomCss(seg)) :
                    _this.computeFgSegPositionCss(seg);
                return (common.createElement("div", { className: 'fc-timegrid-event-harness' + (seg.level > 0 ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign({ visibility: segIsInvisible[instanceId] ? 'hidden' : '' }, positionCss) },
                    common.createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === props.eventSelection, isCondensed: (seg.bottom - seg.top) < common.config.timeGridEventCondensedHeight }, common.getSegMeta(seg, props.todayRange, props.nowDate)))));
            });
        };
        TimeCol.prototype.renderFillSegs = function (segs, fillType) {
            var _this = this;
            var _a = this, context = _a.context, props = _a.props;
            if (!props.slatCoords) {
                return;
            }
            // BAD: assigns TO THE SEGS THEMSELVES
            computeSegVerticals(segs, props.date, props.slatCoords, context.options.eventMinHeight);
            var children = segs.map(function (seg) { return (common.createElement("div", { key: common.buildEventRangeKey(seg.eventRange), className: 'fc-timegrid-bg-harness', style: _this.computeSegTopBottomCss(seg) }, fillType === 'bg-event' ?
                common.createElement(common.BgEvent, __assign({ seg: seg }, common.getSegMeta(seg, props.todayRange, props.nowDate))) :
                common.renderFill(fillType))); });
            return common.createElement(common.Fragment, null, children);
        };
        TimeCol.prototype.renderNowIndicator = function (segs) {
            var _a = this.props, slatCoords = _a.slatCoords, date = _a.date;
            if (!slatCoords) {
                return;
            }
            return segs.map(function (seg, i) { return (common.createElement(common.NowIndicatorRoot, { isAxis: false, date: date, key: i /* key doesn't matter. will only ever be one */ }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); });
        };
        TimeCol.prototype.computeFgSegPositionCss = function (seg) {
            var _a = this.context, isRtl = _a.isRtl, options = _a.options;
            var shouldOverlap = options.slotEventOverlap;
            var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
            var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
            var left; // amount of space from left edge, a fraction of the total width
            var right; // amount of space from right edge, a fraction of the total width
            if (shouldOverlap) {
                // double the width, but don't go beyond the maximum forward coordinate (1.0)
                forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
            }
            if (isRtl) {
                left = 1 - forwardCoord;
                right = backwardCoord;
            }
            else {
                left = backwardCoord;
                right = 1 - forwardCoord;
            }
            var props = {
                zIndex: seg.level + 1,
                left: left * 100 + '%',
                right: right * 100 + '%'
            };
            if (shouldOverlap && seg.forwardPressure) {
                // add padding to the edge so that forward stacked events don't cover the resizer's icon
                props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
            }
            return __assign(__assign({}, props), this.computeSegTopBottomCss(seg));
        };
        TimeCol.prototype.computeSegTopBottomCss = function (seg) {
            return {
                top: seg.top,
                bottom: -seg.bottom
            };
        };
        return TimeCol;
    }(common.BaseComponent));
    var TimeColMisc = /** @class */ (function (_super) {
        __extends(TimeColMisc, _super);
        function TimeColMisc() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TimeColMisc.prototype.render = function () {
            var props = this.props;
            return (common.createElement(common.DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent &&
                common.createElement("div", { className: 'fc-timegrid-col-misc', ref: innerElRef }, innerContent)); }));
        };
        return TimeColMisc;
    }(common.BaseComponent));

    var TimeColsContent = /** @class */ (function (_super) {
        __extends(TimeColsContent, _super);
        function TimeColsContent() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.splitFgEventSegs = common.memoize(splitSegsByCol);
            _this.splitBgEventSegs = common.memoize(splitSegsByCol);
            _this.splitBusinessHourSegs = common.memoize(splitSegsByCol);
            _this.splitNowIndicatorSegs = common.memoize(splitSegsByCol);
            _this.splitDateSelectionSegs = common.memoize(splitSegsByCol);
            _this.splitEventDrag = common.memoize(splitInteractionByCol);
            _this.splitEventResize = common.memoize(splitInteractionByCol);
            _this.rootElRef = common.createRef();
            _this.cellElRefs = new common.RefMap();
            return _this;
        }
        TimeColsContent.prototype.render = function () {
            var _this = this;
            var _a = this, props = _a.props, context = _a.context;
            var nowIndicatorTop = context.options.nowIndicator &&
                props.slatCoords &&
                props.slatCoords.safeComputeTop(props.nowDate); // might return void
            var colCnt = props.cells.length;
            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);
            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);
            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);
            var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);
            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);
            var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);
            var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);
            return (common.createElement("div", { className: 'fc-timegrid-cols', ref: this.rootElRef },
                common.createElement("table", { style: {
                        minWidth: props.tableMinWidth,
                        width: props.clientWidth
                    } },
                    props.tableColGroupNode,
                    common.createElement("tbody", null,
                        common.createElement("tr", null,
                            props.axis &&
                                common.createElement("td", { className: 'fc-timegrid-col fc-timegrid-axis' },
                                    common.createElement("div", { className: 'fc-timegrid-col-frame' },
                                        common.createElement("div", { className: 'fc-timegrid-now-indicator-container' }, typeof nowIndicatorTop === 'number' &&
                                            common.createElement(common.NowIndicatorRoot, { isAxis: true, date: props.nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })))),
                            props.cells.map(function (cell, i) { return (common.createElement(TimeCol, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })); }))))));
        };
        TimeColsContent.prototype.componentDidMount = function () {
            this.updateCoords();
        };
        TimeColsContent.prototype.componentDidUpdate = function () {
            this.updateCoords();
        };
        TimeColsContent.prototype.updateCoords = function () {
            var props = this.props;
            if (props.onColCoords &&
                props.clientWidth !== null // means sizing has stabilized
            ) {
                props.onColCoords(new common.PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal
                false));
            }
        };
        return TimeColsContent;
    }(common.BaseComponent));
    function collectCellEls(elMap, cells) {
        return cells.map(function (cell) { return elMap[cell.key]; });
    }

    /* A component that renders one or more columns of vertical time slots
    ----------------------------------------------------------------------------------------------------------------------*/
    var TimeCols = /** @class */ (function (_super) {
        __extends(TimeCols, _super);
        function TimeCols() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.processSlotOptions = common.memoize(processSlotOptions);
            _this.state = {
                slatCoords: null
            };
            _this.handleScrollRequest = function (request) {
                var onScrollTopRequest = _this.props.onScrollTopRequest;
                var slatCoords = _this.state.slatCoords;
                if (onScrollTopRequest && slatCoords) {
                    if (request.time) {
                        var top_1 = slatCoords.computeTimeTop(request.time);
                        top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further
                        if (top_1) {
                            top_1++;
                        } // to overcome top border that slots beyond the first have. looks better
                        onScrollTopRequest(top_1);
                    }
                    return true;
                }
            };
            _this.handleColCoords = function (colCoords) {
                _this.colCoords = colCoords;
            };
            _this.handleSlatCoords = function (slatCoords) {
                _this.setState({ slatCoords: slatCoords });
                if (_this.props.onSlatCoords) {
                    _this.props.onSlatCoords(slatCoords);
                }
            };
            return _this;
        }
        TimeCols.prototype.render = function () {
            var _a = this, props = _a.props, state = _a.state;
            return (common.createElement("div", { className: 'fc-timegrid-body', ref: props.rootElRef, style: {
                    // these props are important to give this wrapper correct dimensions for interactions
                    // TODO: if we set it here, can we avoid giving to inner tables?
                    width: props.clientWidth,
                    minWidth: props.tableMinWidth
                } },
                common.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 }),
                common.createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bgEventSegs, 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 })));
        };
        TimeCols.prototype.componentDidMount = function () {
            this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);
        };
        TimeCols.prototype.componentDidUpdate = function (prevProps) {
            this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);
        };
        TimeCols.prototype.componentWillUnmount = function () {
            this.scrollResponder.detach();
        };
        TimeCols.prototype.positionToHit = function (positionLeft, positionTop) {
            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options;
            var colCoords = this.colCoords;
            var dateProfile = this.props.dateProfile;
            var slatCoords = this.state.slatCoords;
            var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot;
            var colIndex = colCoords.leftToIndex(positionLeft);
            var slatIndex = slatCoords.positions.topToIndex(positionTop);
            if (colIndex != null && slatIndex != null) {
                var slatTop = slatCoords.positions.tops[slatIndex];
                var slatHeight = slatCoords.positions.getHeight(slatIndex);
                var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
                var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
                var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
                var dayDate = this.props.cells[colIndex].date;
                var time = common.addDurations(dateProfile.slotMinTime, common.multiplyDuration(snapDuration, snapIndex));
                var start = dateEnv.add(dayDate, time);
                var end = dateEnv.add(start, snapDuration);
                return {
                    col: colIndex,
                    dateSpan: {
                        range: { start: start, end: end },
                        allDay: false
                    },
                    dayEl: colCoords.els[colIndex],
                    relativeRect: {
                        left: colCoords.lefts[colIndex],
                        right: colCoords.rights[colIndex],
                        top: slatTop,
                        bottom: slatTop + slatHeight
                    }
                };
            }
        };
        return TimeCols;
    }(common.BaseComponent));
    function processSlotOptions(slotDuration, snapDurationOverride) {
        var snapDuration = snapDurationOverride || slotDuration;
        var snapsPerSlot = common.wholeDivideDurations(slotDuration, snapDuration);
        if (snapsPerSlot === null) {
            snapDuration = slotDuration;
            snapsPerSlot = 1;
            // TODO: say warning?
        }
        return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot };
    }

    var DayTimeCols = /** @class */ (function (_super) {
        __extends(DayTimeCols, _super);
        function DayTimeCols() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.buildDayRanges = common.memoize(buildDayRanges);
            _this.slicer = new DayTimeColsSlicer();
            _this.timeColsRef = common.createRef();
            _this.handleRootEl = function (rootEl) {
                if (rootEl) {
                    _this.context.registerInteractiveComponent(_this, { el: rootEl });
                }
                else {
                    _this.context.unregisterInteractiveComponent(_this);
                }
            };
            return _this;
        }
        DayTimeCols.prototype.render = function () {
            var _this = this;
            var _a = this, props = _a.props, context = _a.context;
            var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel;
            var isNowIndicator = context.options.nowIndicator;
            var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);
            // give it the first row of cells
            // TODO: would move this further down hierarchy, but sliceNowDate needs it
            return (common.createElement(common.NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (common.createElement(TimeCols, __assign({ ref: _this.timeColsRef, rootElRef: _this.handleRootEl }, _this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: nowDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); }));
        };
        DayTimeCols.prototype.queryHit = function (positionLeft, positionTop) {
            var rawHit = this.timeColsRef.current.positionToHit(positionLeft, positionTop);
            if (rawHit) {
                return {
                    component: this,
                    dateSpan: rawHit.dateSpan,
                    dayEl: rawHit.dayEl,
                    rect: {
                        left: rawHit.relativeRect.left,
                        right: rawHit.relativeRect.right,
                        top: rawHit.relativeRect.top,
                        bottom: rawHit.relativeRect.bottom
                    },
                    layer: 0
                };
            }
        };
        return DayTimeCols;
    }(common.DateComponent));
    function buildDayRanges(dayTableModel, dateProfile, dateEnv) {
        var ranges = [];
        for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) {
            var date = _a[_i];
            ranges.push({
                start: dateEnv.add(date, dateProfile.slotMinTime),
                end: dateEnv.add(date, dateProfile.slotMaxTime)
            });
        }
        return ranges;
    }
    var DayTimeColsSlicer = /** @class */ (function (_super) {
        __extends(DayTimeColsSlicer, _super);
        function DayTimeColsSlicer() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) {
            var segs = [];
            for (var col = 0; col < dayRanges.length; col++) {
                var segRange = common.intersectRanges(range, dayRanges[col]);
                if (segRange) {
                    segs.push({
                        start: segRange.start,
                        end: segRange.end,
                        isStart: segRange.start.valueOf() === range.start.valueOf(),
                        isEnd: segRange.end.valueOf() === range.end.valueOf(),
                        col: col
                    });
                }
            }
            return segs;
        };
        return DayTimeColsSlicer;
    }(common.Slicer));

    var DayTimeColsView = /** @class */ (function (_super) {
        __extends(DayTimeColsView, _super);
        function DayTimeColsView() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.buildTimeColsModel = common.memoize(buildTimeColsModel);
            _this.buildSlatMetas = common.memoize(buildSlatMetas);
            return _this;
        }
        DayTimeColsView.prototype.render = function () {
            var _this = this;
            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator;
            var props = this.props;
            var dateProfile = props.dateProfile;
            var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);
            var splitProps = this.allDaySplitter.splitProps(props);
            var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);
            var dayMinWidth = options.dayMinWidth;
            var hasAttachedAxis = !dayMinWidth;
            var hasDetachedAxis = dayMinWidth;
            var headerContent = options.dayHeaders &&
                common.createElement(common.DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null });
            var allDayContent = (options.allDaySlot !== false) && (function (contentArg) { return (common.createElement(daygrid.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()))); });
            var timeGridContent = function (contentArg) { return (common.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 }))); };
            return hasDetachedAxis
                ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)
                : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);
        };
        return DayTimeColsView;
    }(TimeColsView));
    function buildTimeColsModel(dateProfile, dateProfileGenerator) {
        var daySeries = new common.DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
        return new common.DayTableModel(daySeries, false);
    }

    var OPTION_REFINERS = {
        allDaySlot: Boolean
    };

    var plugin = common.createPlugin({
        initialView: 'timeGridWeek',
        optionRefiners: OPTION_REFINERS,
        views: {
            timeGrid: {
                component: DayTimeColsView,
                usesMinMaxTime: true,
                allDaySlot: true,
                slotDuration: '00:30:00',
                slotEventOverlap: true // a bad name. confused with overlap/constraint system
            },
            timeGridDay: {
                type: 'timeGrid',
                duration: { days: 1 }
            },
            timeGridWeek: {
                type: 'timeGrid',
                duration: { weeks: 1 }
            }
        }
    });

    common.globalPlugins.push(plugin);

    exports.DayTimeCols = DayTimeCols;
    exports.DayTimeColsSlicer = DayTimeColsSlicer;
    exports.DayTimeColsView = DayTimeColsView;
    exports.TimeCols = TimeCols;
    exports.TimeColsSlatsCoords = TimeColsSlatsCoords;
    exports.TimeColsView = TimeColsView;
    exports.buildDayRanges = buildDayRanges;
    exports.buildSlatMetas = buildSlatMetas;
    exports.buildTimeColsModel = buildTimeColsModel;
    exports.default = plugin;

    return exports;

}({}, FullCalendar, FullCalendarDayGrid));
