');\n\n const nowTimeInMinutes = moment\n .duration(\n moment(TODAY).diff(\n moment(TODAY).startOf('day'),\n ),\n )\n .as('minutes');\n\n // Skip if it's not included in the selected delta time view\n if (\n nowTimeInMinutes >= timeData.end ||\n nowTimeInMinutes <= timeData.start\n ) {\n return;\n }\n\n // Calculate position\n const eventPositionPerc = (\n nowTimeInMinutes / dayViewDuration -\n timeData.start / dayViewDuration\n ) * 100;\n\n $nowMarker.css(\n 'top',\n eventPositionPerc + '%',\n );\n\n // Append marker to container\n $nowMarker.appendTo($container);\n }\n\n /**\n * Add events to calendar\n */\n function addEventsToCalendarBase() {\n events.forEach((event) => {\n const startDate = moment(event.startDate).startOf('date');\n\n // Check if event is an all day\n // (startDate 00:00 day 1, endDate 00:00 day after last day)\n const allDayEvent =\n moment(event.startDate).isSame(startDate) &&\n moment(event.endDate).isSame(moment(event.endDate).startOf('date'));\n event.allDay = allDayEvent;\n\n const endDate = allDayEvent ?\n moment(event.endDate).startOf('date').subtract(1, 'd') :\n moment(event.endDate).startOf('date');\n\n const eventTotalDays = endDate.diff(startDate, 'days') + 1;\n let currentDayOfEvent = 1;\n\n // Days loop\n const momentAux = moment(startDate);\n while (momentAux <= endDate) {\n addEventToDay(momentAux, event, eventTotalDays, currentDayOfEvent);\n currentDayOfEvent++;\n momentAux.add(1, 'd');\n }\n });\n }\n\n /**\n * Add event to specific day\n * @param {object} date momentjs date\n * @param {object} event\n * @param {number} eventTotalDays\n * @param {number} currentDayOfEvent\n */\n function addEventToDay(date, event, eventTotalDays, currentDayOfEvent) {\n /**\n * Get container by date\n * @param {object} date\n * @return {object} Jquery container\n */\n function getEventContainer(date) {\n return (options.calendarType == 2) ?\n $('.calendar-day .calendar-events-container') :\n $('#day_' + date.date()).find('.calendar-events-container');\n }\n\n /**\n * Get all days container by date\n * @param {object} date\n * @return {object} Jquery container\n */\n function getAllDayEventsContainer(date) {\n return (options.calendarType == 2) ?\n $('.calendar-day .calendar-all-day-events-container') :\n $('#day_' + date.date()).find('.calendar-all-day-events-container');\n }\n\n const $newEvent = $('
');\n const weekDay = getWeekday(date);\n let eventDuration = 1;\n\n // Mark event as an all day\n if (event.allDay) {\n $newEvent.addClass('all-day');\n }\n\n if (eventTotalDays > 1) {\n // Multiple day event\n let htmlToAdd =\n '
' + event.summary + '';\n\n // Mark as multi event\n $newEvent.addClass('multi-day');\n\n // Draw only on the first day of the event\n // or at the beggining of the weeks when it breaks\n if (currentDayOfEvent == 1 || weekDay == 1) {\n if (currentDayOfEvent == 1 && !event.allDay) {\n htmlToAdd =\n '
' +\n moment(event.startDate).format(TIME_FORMAT) +\n '
' +\n htmlToAdd;\n }\n\n // Show event content in multiple days\n $newEvent.html(htmlToAdd);\n\n // Update element duration based on event duration\n eventDuration = eventTotalDays - (currentDayOfEvent - 1);\n\n const remainingDays = 8 - weekDay;\n if (eventDuration > remainingDays) {\n eventDuration = remainingDays;\n $newEvent.addClass('cropped-event-end');\n }\n\n if (currentDayOfEvent > 1) {\n $newEvent.addClass('cropped-event-start');\n }\n $newEvent.css(\n 'width',\n 'calc(' +\n eventDuration * 100 +\n '% + ' +\n eventDuration * 2 +\n 'px)',\n );\n } else {\n // Multiple event that was extended, no need to be rendered\n return;\n }\n } else {\n // Single day event\n let htmlToAdd =\n '
' + event.summary + '
';\n\n // Mark event as an all day\n if (event.allDay) {\n $newEvent.addClass('all-day');\n } else {\n htmlToAdd =\n htmlToAdd +\n '
' +\n moment(event.startDate).format(TIME_FORMAT) +\n ' - ' +\n moment(event.endDate).format(TIME_FORMAT) +\n '
';\n }\n\n // Add inner html\n $newEvent.html(htmlToAdd);\n }\n\n // All day or multi day events\n if (eventTotalDays > 1 || event.allDay) {\n // If there's at least one daily event\n // enable the container in the calendar view\n $('.calendar-container').addClass('show-all-day-events');\n\n const $dailyEventsContainer = getAllDayEventsContainer(date);\n\n // Calculate event slot\n let slots = $dailyEventsContainer.data('slots');\n let daySlot;\n if (slots != undefined) {\n for (let index = 0; index < slots.length; index++) {\n const slot = slots[index];\n if (slot === undefined) {\n daySlot = index;\n slots[index] = 1;\n break;\n }\n }\n\n if (daySlot === undefined) {\n daySlot = slots.length;\n slots.push(1);\n }\n } else {\n daySlot = 0;\n slots = [1];\n }\n\n $dailyEventsContainer.data('slots', slots);\n\n // Extend event to the remaining days\n if (eventDuration > 1 && options.calendarType != 2) {\n for (let dayAfter = 1; dayAfter < eventDuration; dayAfter++) {\n const $newContainer = getAllDayEventsContainer(\n moment(date).add(dayAfter, 'd'),\n );\n let dataSlots = $newContainer.data('slots');\n\n if (dataSlots === undefined) {\n dataSlots = [];\n }\n\n dataSlots[daySlot] = 2;\n $newContainer.data('slots', dataSlots);\n }\n }\n\n $newEvent.css('top', 1.875 * daySlot + 'rem');\n\n // Append event to container\n $newEvent.appendTo($dailyEventsContainer);\n\n // Check container height and slots to show number of extra events\n updateContainerExtraEvents($dailyEventsContainer, slots);\n } else {\n // Daily timed event\n const $eventsContainer = getEventContainer(date);\n const containerData = $('.hour-grid').data();\n\n const dayViewDuration = containerData.end - containerData.start;\n const eventData = {\n start: moment\n .duration(\n moment(event.startDate).diff(\n moment(event.startDate).startOf('day'),\n ),\n )\n .as('minutes'),\n duration: moment\n .duration(moment(event.endDate).diff(moment(event.startDate)))\n .as('minutes'),\n };\n\n // Skip event if it's not included in the selected delta time view\n if (\n eventData.start >= containerData.end ||\n eventData.start + eventData.duration <= containerData.start\n ) {\n return;\n }\n\n // Calculate position\n let eventPositionPerc = (\n eventData.start / dayViewDuration -\n containerData.start / dayViewDuration\n ) * 100;\n let eventHeightAdj = 0;\n\n // Check if event starts before view time\n if (eventPositionPerc < 0) {\n $newEvent.addClass('before-view');\n eventHeightAdj = eventPositionPerc;\n eventPositionPerc = 0;\n }\n\n $newEvent.css(\n 'top',\n eventPositionPerc + '%',\n );\n\n // Calculate event slot\n let slots = $eventsContainer.data('slots');\n let eventLevel = 0;\n if (slots != undefined) {\n let newLevel = 0;\n for (let index = 0; index < slots.length; index++) {\n const slot = slots[index];\n if (\n !(\n eventData.start >= slot.end ||\n eventData.start + eventData.duration <= slot.start\n )\n ) {\n newLevel = slot.level + 1;\n }\n }\n\n slots.push({\n level: newLevel,\n start: eventData.start,\n end: eventData.start + eventData.duration,\n });\n\n eventLevel = newLevel;\n } else {\n slots = [\n {\n level: 0,\n start: eventData.start,\n end: eventData.start + eventData.duration,\n },\n ];\n\n eventLevel = 0;\n }\n\n // Update container slots\n $eventsContainer.data('slots', slots);\n\n // Assign level\n $newEvent.addClass('level-' + eventLevel);\n $newEvent.toggleClass('concurrent', eventLevel > 0);\n\n // Calculate height\n const eventHeight = ((eventData.duration / dayViewDuration) * 100) +\n eventHeightAdj;\n\n $newEvent.height(eventHeight + '%');\n\n // Append event to container\n $newEvent.appendTo($eventsContainer);\n\n // Mark shorter events to be styled\n if ($newEvent.height() < parseFloat($newEvent.css('font-size')) * 2) {\n $newEvent.addClass('shorter-event');\n $newEvent.find('.event-time').prependTo($newEvent);\n }\n }\n }\n\n /**\n * Update container and hide the number of extra events\n * @param {object} $container jquery container\n * @param {object} slots occupied slots\n */\n function updateContainerExtraEvents($container, slots) {\n // Calculate max events per container (if not defined)\n if (!maxEventPerDay) {\n const bodyFontSize = parseInt(\n $('body').css('font-size').split('px')[0],\n );\n const singleEventHeight =\n bodyFontSize * 1.25 + bodyFontSize * 0.5 + bodyFontSize * 0.125;\n const extraEventsHeight = bodyFontSize * 1.25 + bodyFontSize * 0.125;\n maxEventPerDay = Math.floor($container.height() / singleEventHeight);\n\n maxEventPerDayWithExtra = Math.floor(\n ($container.height() - extraEventsHeight) / singleEventHeight,\n );\n }\n\n // If we show extra. get number of events\n // that fit inside that space ( smaller )\n let maxEventsForThisDay = maxEventPerDay;\n if (slots.length > maxEventPerDay) {\n maxEventsForThisDay = maxEventPerDayWithExtra;\n }\n\n // Get number of dummy events that were generated\n // by extended events in the visible elements\n const numberOfExtendedEvents = slots.filter((ev, idx) => {\n return ev == 2 && idx <= maxEventsForThisDay;\n }).length;\n\n // Remove extra elements\n if (\n maxEventsForThisDay > 0 &&\n maxEventsForThisDay > numberOfExtendedEvents\n ) {\n $container\n .find(\n '.calendar-event:gt(' +\n (maxEventsForThisDay - numberOfExtendedEvents - 1) +\n ')',\n )\n .remove();\n } else {\n $container.find('.calendar-event').remove();\n }\n\n // Calculate number of events that were hidden\n let numEventsToHide = 0;\n for (let index = maxEventsForThisDay; index < slots.length; index++) {\n if (slots[index] != undefined) {\n numEventsToHide++;\n }\n }\n\n // Fix for extended events\n let numExtendedEventsFix = 0;\n if (maxEventsForThisDay > 0 &&\n maxEventsForThisDay < numberOfExtendedEvents) {\n numExtendedEventsFix = numberOfExtendedEvents - maxEventsForThisDay;\n }\n numEventsToHide -= numExtendedEventsFix;\n\n // Update extra events label\n if (numEventsToHide > 0) {\n if ($container.find('.extra-events').length > 0) {\n $container.find('.extra-events span').html('+ ' + numEventsToHide);\n } else {\n $container.append(\n '',\n );\n }\n }\n }\n\n /**\n * Create hour grid\n * @param {object} $container jquery container\n * @param {string} start\n * @param {string} end\n */\n function createCalendarHourGrid($container, start, end) {\n start =\n start == '' ?\n moment(DEFAULT_DAY_START_TIME, TIME_FORMAT) :\n moment(start, TIME_FORMAT);\n end =\n end == '' ?\n moment(DEFAULT_DAY_END_TIME, TIME_FORMAT) :\n moment(end, TIME_FORMAT);\n\n // Hour loop\n const momentAux = moment(start);\n while (momentAux <= end) {\n $container.append(\n '
' + momentAux.format(TIME_FORMAT) + '',\n );\n momentAux.add(GRID_STEP, 'm');\n }\n\n // Save properties to the container for later use\n const containerData = {\n start: moment\n .duration(moment(start).diff(moment(start).startOf('day')))\n .as('minutes'),\n end: moment\n .duration(moment(end).diff(moment(end).startOf('day')))\n .as('minutes'),\n };\n $container.data(containerData);\n\n // Calculate hour grid spacing\n const gridSpacing =\n (1 / ((containerData.end - containerData.start) / GRID_STEP)) * 100;\n $container.find('.hour-time').height(gridSpacing + '%');\n }\n\n // Functions by calendar type\n if (options.calendarType == 1) {\n // Schedule View\n const $calendarContainer = $('.calendar-container');\n let addedEvents = 0;\n\n /**\n * Add event to specific day (override)\n * @param {object} date momentjs date\n * @param {object} event\n * @param {number} eventTotalDays\n * @param {number} currentDayOfEvent\n */\n function addEventToDay(date, event, eventTotalDays, currentDayOfEvent) {\n /**\n * Get container by date\n * @param {object} date\n * @return {object} Jquery container\n */\n function getDayContainer(date) {\n let $dayContainerTemp;\n let $dayContainerTitle;\n\n if ($('#day_' + date.month() + '_' + date.date()).length > 0) {\n $dayContainerTemp = $('#day_' + date.month() + '_' + date.date());\n } else {\n $dayContainerTemp = $('
').attr('id', 'day_' +\n date.month() + '_' + date.date()).addClass('day-container');\n\n $dayContainerTitle = $('
').appendTo(\n $dayContainerTemp);\n\n if (moment(date).startOf('d').isSame(moment(TODAY).startOf('d'))) {\n $dayContainerTemp.addClass('today');\n }\n\n $('
' +\n date.date() +\n '
').appendTo($dayContainerTitle);\n\n $('
' +\n monthsNames[date.month()] +\n '
').appendTo($dayContainerTitle);\n\n $('
' +\n weekdaysNames[date.weekday()] +\n '
').appendTo($dayContainerTitle);\n\n $('
').appendTo($dayContainerTemp);\n\n $dayContainerTemp.appendTo($calendarContainer);\n }\n\n // $calendarContainer\n return $dayContainerTemp;\n }\n\n const $newEvent = $('
');\n const $dayContainer = getDayContainer(date);\n const $dayContainerEvents = $dayContainer.find('.day-events');\n let htmlToAdd = '';\n\n // Add time\n if (!event.allDay) {\n if (currentDayOfEvent == 1) {\n htmlToAdd +=\n '
' +\n moment(event.startDate).format(TIME_FORMAT) +\n '';\n\n // Save start date to object data\n $newEvent.data('start', event.startDate);\n\n if (eventTotalDays == 1) {\n htmlToAdd +=\n ' -
' +\n moment(event.endDate).format(TIME_FORMAT) +\n '';\n }\n }\n } else {\n // Mark event as an all day\n $newEvent.addClass('all-day');\n }\n\n // Mark event as a multi-day\n if (eventTotalDays > 1) {\n $newEvent.addClass('multi');\n }\n\n // Add summary\n htmlToAdd += '
' + event.summary + '';\n\n if (options.showDescription == 1 && event.description) {\n htmlToAdd += '
' +\n event.description + '
';\n }\n\n // Add inner html\n $newEvent.html(htmlToAdd);\n\n // Append event to container\n if (event.allDay) {\n $newEvent.prependTo($dayContainerEvents);\n } else {\n $newEvent.appendTo($dayContainerEvents);\n }\n\n addedEvents++;\n }\n\n // Override addEventsToCalendarBase\n addEventsToCalendar = function(events) {\n events.forEach((event) => {\n const startDate = moment(event.startDate).startOf('date');\n\n // Check if event is an all day\n // (startDate 00:00 day 1, endDate 00:00 day after last day)\n const allDayEvent =\n moment(event.startDate).isSame(startDate) &&\n moment(event.endDate).isSame(moment(event.endDate).startOf('date'));\n event.allDay = allDayEvent;\n\n const endDate = allDayEvent ?\n moment(event.endDate).startOf('date').subtract(1, 'd') :\n moment(event.endDate).startOf('date');\n\n const eventTotalDays = endDate.diff(startDate, 'days') + 1;\n let currentDayOfEvent = 1;\n\n // Days loop\n const momentAux = moment(startDate);\n\n while (momentAux <= endDate) {\n let startDate = null;\n let endDate = null;\n\n // If we're using a date range\n // show only events from the start date onwards\n // and before the end date\n if (options.useDateRange == 1) {\n (options.rangeStart) && (startDate = moment(options.rangeStart));\n (options.rangeEnd) && (endDate = moment(options.rangeEnd));\n } else {\n startDate = TODAY.startOf('d');\n }\n\n // Add event\n if ((!startDate || momentAux >= startDate) &&\n (!endDate || momentAux <= endDate)) {\n addEventToDay(\n momentAux,\n event,\n eventTotalDays,\n currentDayOfEvent);\n }\n\n currentDayOfEvent++;\n momentAux.add(1, 'd');\n }\n });\n\n // Create now marker\n if (options.showNowMarker == 1) {\n const $nowMarker = $('
');\n const $dayEventsContainer = $calendarContainer.find('#day_' +\n moment(TODAY).month() + '_' + moment(TODAY).date() +\n ' .day-events');\n let $targetElement;\n\n if ($dayEventsContainer.length > 0) {\n // Calculate position\n $dayEventsContainer.find('.calendar-event').each((idx, event) => {\n const start = $(event).data('start');\n\n if (start && TODAY < moment(start)) {\n $targetElement = $(event);\n $nowMarker.insertBefore($targetElement);\n return false;\n }\n });\n\n // Append marker to container\n if (!$targetElement) {\n $nowMarker.appendTo($dayEventsContainer);\n }\n }\n }\n\n // Show no events message\n if (options.noEventsMessage != '' && addedEvents == 0) {\n $calendarContainer.append('
' +\n options.noEventsMessage + '
');\n }\n // noEventsMessage\n };\n } else if (options.calendarType == 2) {\n // Daily View\n const $hourGrid = $('.hour-grid');\n const $dayTitle = $('.day-title');\n const $dayContainer = $('.day-container');\n\n createCalendar = function() {\n // Add day label\n const $weekDay = $('
');\n $dayTitle.append($weekDay);\n $weekDay.html('' +\n weekdaysNames[TODAY.weekday()] +\n '
');\n\n const today = moment(TODAY);\n const day = {\n date: today.format('YYYY-MM-DD'),\n dayOfMonth: today.date(),\n };\n\n const $dayOfMonthElement = $('');\n $dayOfMonthElement.html(day.dayOfMonth);\n $weekDay.append($dayOfMonthElement);\n\n // Add hour grid\n createCalendarHourGrid($hourGrid, options.startTime, options.endTime);\n\n // Add day element\n const $dayElement = $('
');\n $dayElement.addClass('calendar-day');\n\n // Append all day events container\n $dayElement.append(\n $(''),\n );\n\n // Append normal events container\n $dayElement.append($('
'));\n\n // Append day to container\n $dayContainer.append($dayElement);\n\n if (options.showNowMarker == 1) {\n createNowMarker(\n $dayElement.find('.calendar-events-container'),\n $('.hour-grid').data(),\n );\n }\n };\n\n addEventsToCalendar = addEventsToCalendarBase;\n } else if (options.calendarType == 3) {\n // Weekly View\n const $daysOfWeek = $('.day-of-week');\n const $calendarDays = $('.days-row');\n const $hourGrid = $('.hour-grid');\n\n createCalendar = function() {\n const year = INITIAL_YEAR;\n const month = INITIAL_MONTH;\n const date = INITIAL_DATE;\n\n weekdaysNames.forEach((weekday, idx) => {\n const $weekDay = $('
');\n $daysOfWeek.append($weekDay);\n $weekDay.html('' + weekday + '
');\n });\n\n // Add hour grid\n createCalendarHourGrid($hourGrid, options.startTime, options.endTime);\n\n // Remove all days\n $calendarDays.find('.calendar-day').remove();\n\n currentWeekDays = createDaysForCurrentWeek(year, month, date);\n\n currentWeekDays.forEach((day) => {\n appendDay(day, $calendarDays);\n });\n };\n\n /**\n * Create days for current week\n * @param {string} year\n * @param {string} month\n * @param {string} date\n * @return {array} Days of the week\n */\n function createDaysForCurrentWeek(year, month, date) {\n const startOfWeek = moment({\n year: year,\n month: month,\n date: date,\n }).startOf('week');\n\n return [...Array(7)].map((day, index) => {\n const weekDay = moment(startOfWeek).add(index, 'd');\n return {\n date: weekDay.format('YYYY-MM-DD'),\n dayOfMonth: weekDay.date(),\n dayOfWeek: index,\n };\n });\n }\n\n /**\n * Append new day\n * @param {object} day\n * @param {object} $calendarDays\n */\n function appendDay(day, $calendarDays) {\n const $daysOfWeek = $('.day-of-week');\n const $dayElement = $('');\n $dayElement.addClass('calendar-day');\n\n // Append all day events container\n $dayElement.append(\n $(''),\n );\n\n // Append normal events container\n $dayElement.append($('
'));\n\n // Append week day name element\n const $dayOfMonthElement = $('
');\n $dayOfMonthElement.html(day.dayOfMonth);\n $daysOfWeek.find('#' + day.dayOfWeek).append($dayOfMonthElement);\n\n $calendarDays.append($dayElement);\n\n if (day.date === moment(TODAY).format('YYYY-MM-DD')) {\n $daysOfWeek.find('#' + day.dayOfWeek).addClass('day-of-week--today');\n\n if (options.showNowMarker == 1) {\n createNowMarker(\n $dayElement.find('.calendar-events-container'),\n $('.hour-grid').data(),\n );\n }\n }\n }\n\n // Override addEventsToCalendarBase\n addEventsToCalendar = function(events) {\n events.forEach((event) => {\n const startDate = moment(event.startDate).startOf('date');\n\n // Check if event is an all day\n // (startDate 00:00 day 1, endDate 00:00 day after last day)\n const allDayEvent =\n moment(event.startDate).isSame(startDate) &&\n moment(event.endDate).isSame(moment(event.endDate).startOf('date'));\n event.allDay = allDayEvent;\n\n const endDate = allDayEvent ?\n moment(event.endDate).startOf('date').subtract(1, 'd') :\n moment(event.endDate).startOf('date');\n\n const eventTotalDays = endDate.diff(startDate, 'days') + 1;\n let currentDayOfEvent = 1;\n\n // Days loop\n const momentAux = moment(startDate);\n while (momentAux <= endDate) {\n addEventToDay(momentAux, event, eventTotalDays, currentDayOfEvent);\n currentDayOfEvent++;\n momentAux.add(1, 'd');\n }\n });\n };\n } else if (options.calendarType == 4) {\n // Monthly View\n let currentMonthDays;\n let previousMonthDays;\n let nextMonthDays;\n\n createCalendar = function() {\n const $calendarDays = $('#calendarDays');\n const year = INITIAL_YEAR;\n const month = INITIAL_MONTH;\n const $daysOfWeek = $('#daysOfWeek');\n\n weekdaysNames.forEach((weekday) => {\n const $weekDay = $('
');\n $daysOfWeek.append($weekDay);\n $weekDay.html(weekday);\n });\n\n $('#selectedMonth').html(\n moment({\n year: year,\n month: month,\n }).format('MMMM YYYY'),\n );\n\n // Remove all days\n $calendarDays.find('.calendar-day').remove();\n\n currentMonthDays = createDaysForCurrentMonth(year, month);\n\n previousMonthDays = createDaysForPreviousMonth(year, month - 1);\n nextMonthDays = createDaysForNextMonth(year, month + 1);\n\n const days = [\n ...previousMonthDays,\n ...currentMonthDays,\n ...nextMonthDays,\n ];\n\n days.forEach((day) => {\n appendDay(day, $calendarDays);\n });\n };\n\n /**\n * Append new day\n * @param {object} day\n * @param {object} $calendarDays\n */\n function appendDay(day, $calendarDays) {\n const $dayElement = $(\n '',\n );\n $dayElement.addClass('calendar-day');\n\n // Append events container\n const $eventsContainer = $('');\n $dayElement.append($eventsContainer);\n\n // Append day\n const $dayOfMonthElement = $('
');\n $dayOfMonthElement.html(day.dayOfMonth);\n $dayElement.append($dayOfMonthElement);\n\n $calendarDays.append($dayElement);\n\n if (!day.isCurrentMonth) {\n $dayElement.addClass('calendar-day--not-current');\n }\n\n if (day.date === moment(TODAY).format('YYYY-MM-DD')) {\n $dayElement.addClass('calendar-day--today');\n }\n }\n\n /**\n * Get the number of days in a given month\n * @param {number} year\n * @param {number} month\n * @return {array} day objects\n */\n function getNumberOfDaysInMonth(year, month) {\n return moment({\n year: year,\n month: month,\n }).daysInMonth();\n }\n\n /**\n * Create days on current month\n * @param {number} year\n * @param {number} month\n * @return {array} day objects\n */\n function createDaysForCurrentMonth(year, month) {\n return [...Array(getNumberOfDaysInMonth(year, month))].map(\n (day, index) => {\n return {\n date: moment({\n year: year,\n month: month,\n day: index + 1,\n }).format('YYYY-MM-DD'),\n dayOfMonth: index + 1,\n month: month,\n isCurrentMonth: true,\n };\n },\n );\n }\n\n /**\n * Create days in previous month\n * @param {number} year\n * @param {number} month\n * @return {array} day objects\n */\n function createDaysForPreviousMonth(year, month) {\n const firstDayOfTheMonthWeekday = getWeekday(currentMonthDays[0].date);\n\n const previousMonth = moment({\n year: year,\n month: month - 1,\n });\n\n // Cover first day of the month\n // being sunday (firstDayOfTheMonthWeekday === 0)\n const visibleNumberOfDaysFromPreviousMonth = firstDayOfTheMonthWeekday ?\n firstDayOfTheMonthWeekday - 1 :\n 6;\n\n const previousMonthLastMondayDayOfMonth = moment(\n currentMonthDays[0].date,\n )\n .subtract(visibleNumberOfDaysFromPreviousMonth, 'day')\n .date();\n\n return [...Array(visibleNumberOfDaysFromPreviousMonth)].map(\n (day, index) => {\n return {\n date: moment({\n year: previousMonth.year(),\n month: previousMonth.month(),\n day: previousMonthLastMondayDayOfMonth + index,\n }).format('YYYY-MM-DD'),\n month: previousMonth.month(),\n dayOfMonth: previousMonthLastMondayDayOfMonth + index,\n isCurrentMonth: false,\n };\n },\n );\n }\n\n /**\n * Create days in next month\n * @param {number} year\n * @param {number} month\n * @return {array} day objects\n */\n function createDaysForNextMonth(year, month) {\n const lastDayOfTheMonthWeekday = getWeekday({\n year: year,\n month: month - 1,\n date: currentMonthDays.length,\n });\n\n const nextMonth = moment({\n year: year,\n month: month,\n });\n\n const visibleNumberOfDaysFromNextMonth = lastDayOfTheMonthWeekday ?\n 7 - lastDayOfTheMonthWeekday :\n lastDayOfTheMonthWeekday;\n\n return [...Array(visibleNumberOfDaysFromNextMonth)].map(\n (day, index) => {\n return {\n date: moment({\n year: nextMonth.year(),\n month: nextMonth.month(),\n day: index + 1,\n }).format('YYYY-MM-DD'),\n month: nextMonth.month(),\n dayOfMonth: index + 1,\n isCurrentMonth: false,\n };\n },\n );\n }\n\n addEventsToCalendar = function(events) {\n events.forEach((event) => {\n const startDate = moment(event.startDate).startOf('date');\n\n // Check if event is an all day\n // (startDate 00:00 day 1, endDate 00:00 day after last day)\n const allDayEvent =\n moment(event.startDate).isSame(startDate) &&\n moment(event.endDate).isSame(moment(event.endDate).startOf('date'));\n event.allDay = allDayEvent;\n\n const endDate = allDayEvent ?\n moment(event.endDate).startOf('date').subtract(1, 'd') :\n moment(event.endDate).startOf('date');\n\n const eventTotalDays = endDate.diff(startDate, 'days') + 1;\n\n // Days loop\n let currentDayOfEvent = 1;\n const momentAux = moment(startDate);\n while (momentAux <= endDate) {\n addEventToDay(momentAux, event, eventTotalDays, currentDayOfEvent);\n currentDayOfEvent++;\n momentAux.add(1, 'd');\n }\n });\n };\n\n /**\n * Add event to specific day (override)\n * @param {object} date momentjs date\n * @param {object} event\n * @param {number} eventTotalDays\n * @param {number} currentDayOfEvent\n */\n function addEventToDay(date, event, eventTotalDays, currentDayOfEvent) {\n /**\n * Get container by date\n * @param {object} date\n * @return {object} Jquery container\n */\n function getEventContainer(date) {\n return $('#day_' + date.month() + '_' + date.date()).find(\n '.calendar-events-container',\n );\n }\n\n const $newEvent = $('');\n const $eventsContainer = getEventContainer(date);\n const weekDay = getWeekday(date);\n let eventDuration = 1;\n\n // Mark event as an all day\n if (event.allDay) {\n $newEvent.addClass('all-day');\n }\n\n if (eventTotalDays > 1) {\n // Multiple day event\n let htmlToAdd =\n '' + event.summary + '';\n\n // Mark as multi event\n $newEvent.addClass('multi-day');\n\n // Draw only on the first day of the event\n // or at the beggining of the weeks when it breaks\n if (currentDayOfEvent == 1 || weekDay == 1) {\n if (currentDayOfEvent == 1 && !event.allDay) {\n htmlToAdd =\n '' +\n moment(event.startDate).format(TIME_FORMAT) +\n '' +\n htmlToAdd;\n }\n\n // Show event content in multiple days\n $newEvent.html(htmlToAdd);\n\n // Update element duration based on event duration\n eventDuration = eventTotalDays - (currentDayOfEvent - 1);\n\n const remainingDays = 8 - weekDay;\n if (eventDuration > remainingDays) {\n eventDuration = remainingDays;\n $newEvent.addClass('cropped-event-end');\n }\n\n if (currentDayOfEvent > 1) {\n $newEvent.addClass('cropped-event-start');\n }\n $newEvent.css(\n 'width',\n 'calc(' +\n eventDuration * 100 +\n '% + ' +\n eventDuration * 2 +\n 'px)',\n );\n } else {\n // Multiple event that was extended, no need to be rendered\n return;\n }\n } else {\n // Single day event\n let htmlToAdd =\n '' + event.summary + '';\n\n // Mark event as an all day\n if (event.allDay) {\n $newEvent.addClass('all-day');\n } else {\n htmlToAdd =\n '' +\n moment(event.startDate).format(TIME_FORMAT) +\n '' +\n htmlToAdd;\n }\n\n // Add inner html\n $newEvent.html(htmlToAdd);\n }\n\n // Calculate event slot\n let slots = $eventsContainer.data('slots');\n let daySlot;\n if (slots != undefined) {\n for (let index = 0; index < slots.length; index++) {\n const slot = slots[index];\n if (slot === undefined) {\n daySlot = index;\n slots[index] = 1;\n break;\n }\n }\n\n if (daySlot === undefined) {\n daySlot = slots.length;\n slots.push(1);\n }\n } else {\n daySlot = 0;\n slots = [1];\n }\n\n $eventsContainer.data('slots', slots);\n\n // Extend event to the remaining days\n if (eventDuration > 1) {\n for (let dayAfter = 1; dayAfter < eventDuration; dayAfter++) {\n const $newContainer = getEventContainer(\n moment(date).add(dayAfter, 'd'),\n );\n let dataSlots = $newContainer.data('slots');\n\n if (dataSlots === undefined) {\n dataSlots = [];\n }\n\n dataSlots[daySlot] = 2;\n $newContainer.data('slots', dataSlots);\n }\n }\n\n $newEvent.css('top', 2 + 1.875 * daySlot + 'rem');\n\n // Append event to container\n $newEvent.appendTo($eventsContainer);\n\n // Check container height and slots to show number of extra events\n updateContainerExtraEvents($eventsContainer, slots);\n }\n }\n\n // Create calendar\n applyStyleOptions(options);\n createCalendar();\n addEventsToCalendar(events);\n\n return true;\n },\n});\n"],"sourceRoot":""}