decidim-calendar 0.13.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +9 -0
  4. data/Rakefile +43 -0
  5. data/app/assets/config/decidim_calendar_manifest.css +2 -0
  6. data/app/assets/config/decidim_calendar_manifest.js +2 -0
  7. data/app/assets/images/decidim/calendar/icon.svg +51 -0
  8. data/app/assets/javascripts/decidim/calendar/calendar.js.es6 +6 -0
  9. data/app/assets/javascripts/decidim/calendar/gantt.js.es6 +1 -0
  10. data/app/assets/stylesheets/decidim/calendar/calendar.scss +102 -0
  11. data/app/assets/stylesheets/decidim/calendar/gantt.scss +1 -0
  12. data/app/commands/decidim/calendar/admin/create_external_event.rb +38 -0
  13. data/app/commands/decidim/calendar/admin/destroy_external_event.rb +27 -0
  14. data/app/commands/decidim/calendar/admin/update_external_event.rb +43 -0
  15. data/app/controllers/decidim/calendar/admin/application_controller.rb +23 -0
  16. data/app/controllers/decidim/calendar/admin/external_events_controller.rb +84 -0
  17. data/app/controllers/decidim/calendar/application_controller.rb +21 -0
  18. data/app/controllers/decidim/calendar/calendar_controller.rb +33 -0
  19. data/app/forms/decidim/calendar/admin/external_event_form.rb +21 -0
  20. data/app/helpers/decidim/calendar/calendar_helper.rb +57 -0
  21. data/app/models/decidim/calendar/application_record.rb +9 -0
  22. data/app/models/decidim/calendar/event.rb +25 -0
  23. data/app/models/decidim/calendar/external_event.rb +18 -0
  24. data/app/permissions/decidim/calendar/admin/permissions.rb +22 -0
  25. data/app/presenters/decidim/calendar/event_presenter.rb +104 -0
  26. data/app/queries/decidim/calendar/organization_calendar.rb +15 -0
  27. data/app/services/decidim/calendar/event_to_ical.rb +27 -0
  28. data/app/services/decidim/calendar/general_calendar.rb +13 -0
  29. data/app/services/decidim/calendar/meeting_to_event.rb +8 -0
  30. data/app/services/decidim/meetings/calendar/base_calendar.rb +61 -0
  31. data/app/views/decidim/calendar/admin/external_events/_form.html.erb +22 -0
  32. data/app/views/decidim/calendar/admin/external_events/edit.html.erb +6 -0
  33. data/app/views/decidim/calendar/admin/external_events/index.html.erb +66 -0
  34. data/app/views/decidim/calendar/admin/external_events/new.html.erb +6 -0
  35. data/app/views/decidim/calendar/calendar/gantt.html.erb +22 -0
  36. data/app/views/decidim/calendar/calendar/index.html.erb +63 -0
  37. data/app/views/decidim/shared/_extended_navigation_bar.html.erb +51 -0
  38. data/app/views/layouts/_calendar_navigation.html.erb +18 -0
  39. data/app/views/layouts/calendar.html.erb +4 -0
  40. data/config/locales/ca.yml +38 -0
  41. data/config/locales/de.yml +38 -0
  42. data/config/locales/en.yml +48 -0
  43. data/config/locales/es.yml +38 -0
  44. data/config/locales/fi.yml +38 -0
  45. data/config/locales/fr.yml +38 -0
  46. data/config/locales/it.yml +38 -0
  47. data/config/locales/pl.yml +38 -0
  48. data/config/locales/pt.yml +38 -0
  49. data/config/locales/ro.yml +38 -0
  50. data/config/locales/ru.yml +38 -0
  51. data/config/locales/sv.yml +38 -0
  52. data/config/locales/tr.yml +38 -0
  53. data/config/locales/uk.yml +38 -0
  54. data/db/migrate/20190312132654_create_decidim_calendar_external_events.rb +18 -0
  55. data/lib/decidim/calendar.rb +11 -0
  56. data/lib/decidim/calendar/admin.rb +9 -0
  57. data/lib/decidim/calendar/admin_engine.rb +30 -0
  58. data/lib/decidim/calendar/engine.rb +34 -0
  59. data/lib/decidim/calendar/participatory_space.rb +20 -0
  60. data/lib/decidim/calendar/test/factories.rb +12 -0
  61. data/lib/decidim/calendar/version.rb +10 -0
  62. data/vendor/assets/javascripts/frappe-gantt/frappe-gantt.css +119 -0
  63. data/vendor/assets/javascripts/frappe-gantt/frappe-gantt.js +1883 -0
  64. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.css +33 -0
  65. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.js +90 -0
  66. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.min.css +5 -0
  67. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.min.js +20 -0
  68. data/vendor/assets/javascripts/fullcalendar/core/locales-all.js +1353 -0
  69. data/vendor/assets/javascripts/fullcalendar/core/locales-all.min.js +6 -0
  70. data/vendor/assets/javascripts/fullcalendar/core/locales/af.js +30 -0
  71. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-dz.js +31 -0
  72. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-kw.js +31 -0
  73. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ly.js +31 -0
  74. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ma.js +31 -0
  75. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-sa.js +31 -0
  76. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-tn.js +31 -0
  77. data/vendor/assets/javascripts/fullcalendar/core/locales/ar.js +31 -0
  78. data/vendor/assets/javascripts/fullcalendar/core/locales/bg.js +31 -0
  79. data/vendor/assets/javascripts/fullcalendar/core/locales/bs.js +32 -0
  80. data/vendor/assets/javascripts/fullcalendar/core/locales/ca.js +30 -0
  81. data/vendor/assets/javascripts/fullcalendar/core/locales/cs.js +32 -0
  82. data/vendor/assets/javascripts/fullcalendar/core/locales/da.js +30 -0
  83. data/vendor/assets/javascripts/fullcalendar/core/locales/de.js +33 -0
  84. data/vendor/assets/javascripts/fullcalendar/core/locales/el.js +30 -0
  85. data/vendor/assets/javascripts/fullcalendar/core/locales/en-au.js +17 -0
  86. data/vendor/assets/javascripts/fullcalendar/core/locales/en-gb.js +17 -0
  87. data/vendor/assets/javascripts/fullcalendar/core/locales/en-nz.js +17 -0
  88. data/vendor/assets/javascripts/fullcalendar/core/locales/es-us.js +30 -0
  89. data/vendor/assets/javascripts/fullcalendar/core/locales/es.js +30 -0
  90. data/vendor/assets/javascripts/fullcalendar/core/locales/et.js +32 -0
  91. data/vendor/assets/javascripts/fullcalendar/core/locales/eu.js +30 -0
  92. data/vendor/assets/javascripts/fullcalendar/core/locales/fa.js +33 -0
  93. data/vendor/assets/javascripts/fullcalendar/core/locales/fi.js +30 -0
  94. data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ca.js +27 -0
  95. data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ch.js +31 -0
  96. data/vendor/assets/javascripts/fullcalendar/core/locales/fr.js +31 -0
  97. data/vendor/assets/javascripts/fullcalendar/core/locales/gl.js +30 -0
  98. data/vendor/assets/javascripts/fullcalendar/core/locales/he.js +27 -0
  99. data/vendor/assets/javascripts/fullcalendar/core/locales/hi.js +32 -0
  100. data/vendor/assets/javascripts/fullcalendar/core/locales/hr.js +32 -0
  101. data/vendor/assets/javascripts/fullcalendar/core/locales/hu.js +30 -0
  102. data/vendor/assets/javascripts/fullcalendar/core/locales/id.js +30 -0
  103. data/vendor/assets/javascripts/fullcalendar/core/locales/is.js +30 -0
  104. data/vendor/assets/javascripts/fullcalendar/core/locales/it.js +32 -0
  105. data/vendor/assets/javascripts/fullcalendar/core/locales/ja.js +28 -0
  106. data/vendor/assets/javascripts/fullcalendar/core/locales/ka.js +32 -0
  107. data/vendor/assets/javascripts/fullcalendar/core/locales/kk.js +32 -0
  108. data/vendor/assets/javascripts/fullcalendar/core/locales/ko.js +26 -0
  109. data/vendor/assets/javascripts/fullcalendar/core/locales/lb.js +30 -0
  110. data/vendor/assets/javascripts/fullcalendar/core/locales/lt.js +30 -0
  111. data/vendor/assets/javascripts/fullcalendar/core/locales/lv.js +32 -0
  112. data/vendor/assets/javascripts/fullcalendar/core/locales/mk.js +28 -0
  113. data/vendor/assets/javascripts/fullcalendar/core/locales/ms.js +32 -0
  114. data/vendor/assets/javascripts/fullcalendar/core/locales/nb.js +30 -0
  115. data/vendor/assets/javascripts/fullcalendar/core/locales/nl.js +30 -0
  116. data/vendor/assets/javascripts/fullcalendar/core/locales/nn.js +30 -0
  117. data/vendor/assets/javascripts/fullcalendar/core/locales/pl.js +30 -0
  118. data/vendor/assets/javascripts/fullcalendar/core/locales/pt-br.js +28 -0
  119. data/vendor/assets/javascripts/fullcalendar/core/locales/pt.js +30 -0
  120. data/vendor/assets/javascripts/fullcalendar/core/locales/ro.js +32 -0
  121. data/vendor/assets/javascripts/fullcalendar/core/locales/ru.js +32 -0
  122. data/vendor/assets/javascripts/fullcalendar/core/locales/sk.js +32 -0
  123. data/vendor/assets/javascripts/fullcalendar/core/locales/sl.js +30 -0
  124. data/vendor/assets/javascripts/fullcalendar/core/locales/sq.js +32 -0
  125. data/vendor/assets/javascripts/fullcalendar/core/locales/sr-cyrl.js +32 -0
  126. data/vendor/assets/javascripts/fullcalendar/core/locales/sr.js +32 -0
  127. data/vendor/assets/javascripts/fullcalendar/core/locales/sv.js +30 -0
  128. data/vendor/assets/javascripts/fullcalendar/core/locales/th.js +25 -0
  129. data/vendor/assets/javascripts/fullcalendar/core/locales/tr.js +30 -0
  130. data/vendor/assets/javascripts/fullcalendar/core/locales/uk.js +32 -0
  131. data/vendor/assets/javascripts/fullcalendar/core/locales/vi.js +32 -0
  132. data/vendor/assets/javascripts/fullcalendar/core/locales/zh-cn.js +33 -0
  133. data/vendor/assets/javascripts/fullcalendar/core/locales/zh-tw.js +26 -0
  134. data/vendor/assets/javascripts/fullcalendar/core/main.css +900 -0
  135. data/vendor/assets/javascripts/fullcalendar/core/main.js +8791 -0
  136. data/vendor/assets/javascripts/fullcalendar/core/main.min.css +5 -0
  137. data/vendor/assets/javascripts/fullcalendar/core/main.min.js +9 -0
  138. data/vendor/assets/javascripts/fullcalendar/daygrid/main.css +69 -0
  139. data/vendor/assets/javascripts/fullcalendar/daygrid/main.js +1630 -0
  140. data/vendor/assets/javascripts/fullcalendar/daygrid/main.min.css +5 -0
  141. data/vendor/assets/javascripts/fullcalendar/daygrid/main.min.js +20 -0
  142. data/vendor/assets/javascripts/fullcalendar/google-calendar/main.js +169 -0
  143. data/vendor/assets/javascripts/fullcalendar/google-calendar/main.min.js +20 -0
  144. data/vendor/assets/javascripts/fullcalendar/interaction/main.js +2155 -0
  145. data/vendor/assets/javascripts/fullcalendar/interaction/main.min.js +21 -0
  146. data/vendor/assets/javascripts/fullcalendar/list/main.css +101 -0
  147. data/vendor/assets/javascripts/fullcalendar/list/main.js +341 -0
  148. data/vendor/assets/javascripts/fullcalendar/list/main.min.css +5 -0
  149. data/vendor/assets/javascripts/fullcalendar/list/main.min.js +20 -0
  150. data/vendor/assets/javascripts/fullcalendar/luxon/main.js +162 -0
  151. data/vendor/assets/javascripts/fullcalendar/luxon/main.min.js +20 -0
  152. data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.js +64 -0
  153. data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.min.js +20 -0
  154. data/vendor/assets/javascripts/fullcalendar/moment/main.js +103 -0
  155. data/vendor/assets/javascripts/fullcalendar/moment/main.min.js +6 -0
  156. data/vendor/assets/javascripts/fullcalendar/rrule/main.js +127 -0
  157. data/vendor/assets/javascripts/fullcalendar/rrule/main.min.js +20 -0
  158. data/vendor/assets/javascripts/fullcalendar/timegrid/main.css +266 -0
  159. data/vendor/assets/javascripts/fullcalendar/timegrid/main.js +1339 -0
  160. data/vendor/assets/javascripts/fullcalendar/timegrid/main.min.css +5 -0
  161. data/vendor/assets/javascripts/fullcalendar/timegrid/main.min.js +20 -0
  162. metadata +247 -0
@@ -0,0 +1,5 @@
1
+ /*!
2
+ FullCalendar Day Grid Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */.fc-dayGridDay-view .fc-content-skeleton,.fc-dayGridWeek-view .fc-content-skeleton{padding-bottom:1em}.fc-dayGrid-view .fc-body .fc-row{min-height:4em}.fc-row.fc-rigid{overflow:hidden}.fc-row.fc-rigid .fc-content-skeleton{position:absolute;top:0;left:0;right:0}.fc-day-top.fc-other-month{opacity:.3}.fc-dayGrid-view .fc-day-number,.fc-dayGrid-view .fc-week-number{padding:2px}.fc-dayGrid-view th.fc-day-number,.fc-dayGrid-view th.fc-week-number{padding:0 2px}.fc-ltr .fc-dayGrid-view .fc-day-top .fc-day-number{float:right}.fc-rtl .fc-dayGrid-view .fc-day-top .fc-day-number{float:left}.fc-ltr .fc-dayGrid-view .fc-day-top .fc-week-number{float:left;border-radius:0 0 3px}.fc-rtl .fc-dayGrid-view .fc-day-top .fc-week-number{float:right;border-radius:0 0 0 3px}.fc-dayGrid-view .fc-day-top .fc-week-number{min-width:1.5em;text-align:center;background-color:#f2f2f2;color:grey}.fc-dayGrid-view td.fc-week-number{text-align:center}.fc-dayGrid-view td.fc-week-number>*{display:inline-block;min-width:1.25em}
@@ -0,0 +1,20 @@
1
+ /*!
2
+ FullCalendar Day Grid Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarDayGrid={},e.FullCalendar))}(this,function(e,t){"use strict";function r(e,t){function r(){this.constructor=e}l(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}function n(e,t){var r,n;for(r=0;r<t.length;r++)if(n=t[r],n.firstCol<=e.lastCol&&n.lastCol>=e.firstCol)return!0;return!1}function i(e,t){return e.leftCol-t.leftCol}function o(e,r,n,i){var o=n.dateEnv,s=n.theme,l=t.rangeContainsMarker(r.activeRange,e),a=t.getDayClasses(e,r,n);return a.unshift("fc-day",s.getClass("widgetContent")),'<td class="'+a.join(" ")+'"'+(l?' data-date="'+o.formatIso(e,{omitTime:!0})+'"':"")+(i?" "+i:"")+"></td>"}function s(e,r){var n=new t.DaySeries(e.renderRange,r);return new t.DayTable(n,/year|month|week/.test(e.currentRangeUnit))}/*! *****************************************************************************
7
+ Copyright (c) Microsoft Corporation. All rights reserved.
8
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
9
+ this file except in compliance with the License. You may obtain a copy of the
10
+ License at http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
14
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
15
+ MERCHANTABLITY OR NON-INFRINGEMENT.
16
+
17
+ See the Apache Version 2.0 License for specific language governing permissions
18
+ and limitations under the License.
19
+ ***************************************************************************** */
20
+ var l=function(e,t){return(l=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)},a=function(){return a=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++){t=arguments[r];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])}return e},a.apply(this,arguments)},d=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.buildRenderRange=function(r,n,i){var o,s=this.dateEnv,l=e.prototype.buildRenderRange.call(this,r,n,i),a=l.start,d=l.end;if(/^(year|month)$/.test(n)&&(a=s.startOfWeek(a),o=s.startOfWeek(d),o.valueOf()!==d.valueOf()&&(d=t.addWeeks(o,1))),this.options.monthMode&&this.options.fixedWeekCount){var c=Math.ceil(t.diffWeeks(a,d));d=t.addWeeks(d,6-c)}return{start:a,end:d}},n}(t.DateProfileGenerator),c=function(){function e(e){var t=this;this.isHidden=!0,this.margin=10,this.documentMousedown=function(e){t.el&&!t.el.contains(e.target)&&t.hide()},this.options=e}return e.prototype.show=function(){this.isHidden&&(this.el||this.render(),this.el.style.display="",this.position(),this.isHidden=!1,this.trigger("show"))},e.prototype.hide=function(){this.isHidden||(this.el.style.display="none",this.isHidden=!0,this.trigger("hide"))},e.prototype.render=function(){var e=this,r=this.options,n=this.el=t.createElement("div",{className:"fc-popover "+(r.className||""),style:{top:"0",left:"0"}});"function"==typeof r.content&&r.content(n),r.parentEl.appendChild(n),t.listenBySelector(n,"click",".fc-close",function(t){e.hide()}),r.autoHide&&document.addEventListener("mousedown",this.documentMousedown)},e.prototype.destroy=function(){this.hide(),this.el&&(t.removeElement(this.el),this.el=null),document.removeEventListener("mousedown",this.documentMousedown)},e.prototype.position=function(){var e,r,n=this.options,i=this.el,o=i.getBoundingClientRect(),s=t.computeRect(i.offsetParent),l=t.computeClippingRect(n.parentEl);e=n.top||0,r=void 0!==n.left?n.left:void 0!==n.right?n.right-o.width:0,e=Math.min(e,l.bottom-o.height-this.margin),e=Math.max(e,l.top+this.margin),r=Math.min(r,l.right-o.width-this.margin),r=Math.max(r,l.left+this.margin),t.applyStyle(i,{top:e-s.top,left:r-s.left})},e.prototype.trigger=function(e){this.options[e]&&this.options[e].apply(this,Array.prototype.slice.call(arguments,1))},e}(),h=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.renderSegHtml=function(e,r){var n,i,o=this.context.options,s=e.eventRange,l=s.def,a=s.ui,d=l.allDay,c=a.startEditable,h=d&&e.isStart&&a.durationEditable&&o.eventResizableFromStart,p=d&&e.isEnd&&a.durationEditable,u=this.getSegClasses(e,c,h||p,r),f=t.cssToStr(this.getSkinCss(a)),g="";return u.unshift("fc-day-grid-event","fc-h-event"),e.isStart&&(n=this.getTimeText(s))&&(g='<span class="fc-time">'+t.htmlEscape(n)+"</span>"),i='<span class="fc-title">'+(t.htmlEscape(l.title||"")||"&nbsp;")+"</span>",'<a class="'+u.join(" ")+'"'+(l.url?' href="'+t.htmlEscape(l.url)+'"':"")+(f?' style="'+f+'"':"")+'><div class="fc-content">'+("rtl"===o.dir?i+" "+g:g+" "+i)+"</div>"+(h?'<div class="fc-resizer fc-start-resizer"></div>':"")+(p?'<div class="fc-resizer fc-end-resizer"></div>':"")+"</a>"},n.prototype.computeEventTimeFormat=function(){return{hour:"numeric",minute:"2-digit",omitZeroMinute:!0,meridiem:"narrow"}},n.prototype.computeDisplayEventEnd=function(){return!1},n}(t.FgEventRenderer),p=function(e){function o(t){var r=e.call(this,t.context)||this;return r.dayGrid=t,r}return r(o,e),o.prototype.attachSegs=function(e,t){var r=this.rowStructs=this.renderSegRows(e);this.dayGrid.rowEls.forEach(function(e,t){e.querySelector(".fc-content-skeleton > table").appendChild(r[t].tbodyEl)}),t||this.dayGrid.removeSegPopover()},o.prototype.detachSegs=function(){for(var e,r=this.rowStructs||[];e=r.pop();)t.removeElement(e.tbodyEl);this.rowStructs=null},o.prototype.renderSegRows=function(e){var t,r,n=[];for(t=this.groupSegRows(e),r=0;r<t.length;r++)n.push(this.renderSegRow(r,t[r]));return n},o.prototype.renderSegRow=function(e,r){function n(e){for(;s<e;)c=(b[i-1]||[])[s],c?c.rowSpan=(c.rowSpan||1)+1:(c=document.createElement("td"),l.appendChild(c)),v[i][s]=c,b[i][s]=c,s++}var i,o,s,l,a,d,c,h=this.dayGrid,p=h.colCnt,u=h.isRtl,f=this.buildSegLevels(r),g=Math.max(1,f.length),m=document.createElement("tbody"),y=[],v=[],b=[];for(i=0;i<g;i++){if(o=f[i],s=0,l=document.createElement("tr"),y.push([]),v.push([]),b.push([]),o)for(a=0;a<o.length;a++){d=o[a];var w=u?p-1-d.lastCol:d.firstCol,S=u?p-1-d.firstCol:d.lastCol;for(n(w),c=t.createElement("td",{className:"fc-event-container"},d.el),w!==S?c.colSpan=S-w+1:b[i][s]=c;s<=S;)v[i][s]=c,y[i][s]=d,s++;l.appendChild(c)}n(p);var C=h.renderProps.renderIntroHtml();C&&(h.isRtl?t.appendToElement(l,C):t.prependToElement(l,C)),m.appendChild(l)}return{row:e,tbodyEl:m,cellMatrix:v,segMatrix:y,segLevels:f,segs:r}},o.prototype.buildSegLevels=function(e){var t,r,o,s=this.dayGrid,l=s.isRtl,a=s.colCnt,d=[];for(e=this.sortEventSegs(e),t=0;t<e.length;t++){for(r=e[t],o=0;o<d.length&&n(r,d[o]);o++);r.level=o,r.leftCol=l?a-1-r.lastCol:r.firstCol,r.rightCol=l?a-1-r.firstCol:r.lastCol,(d[o]||(d[o]=[])).push(r)}for(o=0;o<d.length;o++)d[o].sort(i);return d},o.prototype.groupSegRows=function(e){var t,r=[];for(t=0;t<this.dayGrid.rowCnt;t++)r.push([]);for(t=0;t<e.length;t++)r[e[t].row].push(e[t]);return r},o.prototype.computeDisplayEventEnd=function(){return 1===this.dayGrid.colCnt},o}(h),u=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.attachSegs=function(e,r){var n=r.sourceSeg,i=this.rowStructs=this.renderSegRows(e);this.dayGrid.rowEls.forEach(function(e,r){var o,s,l=t.htmlToElement('<div class="fc-mirror-skeleton"><table></table></div>');n&&n.row===r?o=n.el:(o=e.querySelector(".fc-content-skeleton tbody"))||(o=e.querySelector(".fc-content-skeleton table")),s=o.getBoundingClientRect().top-e.getBoundingClientRect().top,l.style.top=s+"px",l.querySelector("table").appendChild(i[r].tbodyEl),e.appendChild(l)})},n}(p),f=function(e){function n(t){var r=e.call(this,t.context)||this;return r.fillSegTag="td",r.dayGrid=t,r}return r(n,e),n.prototype.renderSegs=function(t,r){"bgEvent"===t&&(r=r.filter(function(e){return e.eventRange.def.allDay})),e.prototype.renderSegs.call(this,t,r)},n.prototype.attachSegs=function(e,t){var r,n,i,o=[];for(r=0;r<t.length;r++)n=t[r],i=this.renderFillRow(e,n),this.dayGrid.rowEls[n.row].appendChild(i),o.push(i);return o},n.prototype.renderFillRow=function(e,r){var n,i,o,s=this.dayGrid,l=s.colCnt,a=s.isRtl,d=a?l-1-r.lastCol:r.firstCol,c=a?l-1-r.firstCol:r.lastCol,h=d,p=c+1;n="businessHours"===e?"bgevent":e.toLowerCase(),i=t.htmlToElement('<div class="fc-'+n+'-skeleton"><table><tr></tr></table></div>'),o=i.getElementsByTagName("tr")[0],h>0&&t.appendToElement(o,new Array(h+1).join("<td></td>")),r.el.colSpan=p-h,o.appendChild(r.el),p<l&&t.appendToElement(o,new Array(l-p+1).join("<td></td>"));var u=s.renderProps.renderIntroHtml();return u&&(s.isRtl?t.appendToElement(o,u):t.prependToElement(o,u)),i},n}(t.FillRenderer),g=function(e){function n(r,n){var i=e.call(this,r,n)||this,o=i.eventRenderer=new m(i),s=i.renderFrame=t.memoizeRendering(i._renderFrame);return i.renderFgEvents=t.memoizeRendering(o.renderSegs.bind(o),o.unrender.bind(o),[s]),i.renderEventSelection=t.memoizeRendering(o.selectByInstanceId.bind(o),o.unselectByInstanceId.bind(o),[i.renderFgEvents]),i.renderEventDrag=t.memoizeRendering(o.hideByHash.bind(o),o.showByHash.bind(o),[s]),i.renderEventResize=t.memoizeRendering(o.hideByHash.bind(o),o.showByHash.bind(o),[s]),r.calendar.registerInteractiveComponent(i,{el:i.el,useEventCenter:!1}),i}return r(n,e),n.prototype.render=function(e){this.renderFrame(e.date),this.renderFgEvents(e.fgSegs),this.renderEventSelection(e.eventSelection),this.renderEventDrag(e.eventDragInstances),this.renderEventResize(e.eventResizeInstances)},n.prototype.destroy=function(){e.prototype.destroy.call(this),this.renderFrame.unrender(),this.calendar.unregisterInteractiveComponent(this)},n.prototype._renderFrame=function(e){var r=this,n=r.theme,i=r.dateEnv,o=i.format(e,t.createFormatter(this.opt("dayPopoverFormat")));this.el.innerHTML='<div class="fc-header '+n.getClass("popoverHeader")+'"><span class="fc-title">'+t.htmlEscape(o)+'</span><span class="fc-close '+n.getIconClass("close")+'"></span></div><div class="fc-body '+n.getClass("popoverContent")+'"><div class="fc-event-container"></div></div>',this.segContainerEl=this.el.querySelector(".fc-event-container")},n.prototype.queryHit=function(e,r,n,i){var o=this.props.date;if(e<n&&r<i)return{component:this,dateSpan:{allDay:!0,range:{start:o,end:t.addDays(o,1)}},dayEl:this.el,rect:{left:0,top:0,right:n,bottom:i},layer:1}},n}(t.DateComponent),m=function(e){function n(t){var r=e.call(this,t.context)||this;return r.dayTile=t,r}return r(n,e),n.prototype.attachSegs=function(e){for(var t=0,r=e;t<r.length;t++){var n=r[t];this.dayTile.segContainerEl.appendChild(n.el)}},n.prototype.detachSegs=function(e){for(var r=0,n=e;r<n.length;r++){var i=n[r];t.removeElement(i.el)}},n}(h),y=function(){function e(e){this.context=e}return e.prototype.renderHtml=function(e){var t=[];e.renderIntroHtml&&t.push(e.renderIntroHtml());for(var r=0,n=e.cells;r<n.length;r++){var i=n[r];t.push(o(i.date,e.dateProfile,this.context,i.htmlAttrs))}return e.cells.length||t.push('<td class="fc-day '+this.context.theme.getClass("widgetContent")+'"></td>'),"rtl"===this.context.options.dir&&t.reverse(),"<tr>"+t.join("")+"</tr>"},e}(),v=t.createFormatter({day:"numeric"}),b=t.createFormatter({week:"numeric"}),w=function(e){function n(r,n,i){var o=e.call(this,r,n)||this;o.bottomCoordPadding=0,o.isCellSizesDirty=!1;var s=o.eventRenderer=new p(o),l=o.fillRenderer=new f(o);o.mirrorRenderer=new u(o);var a=o.renderCells=t.memoizeRendering(o._renderCells,o._unrenderCells);return o.renderBusinessHours=t.memoizeRendering(l.renderSegs.bind(l,"businessHours"),l.unrender.bind(l,"businessHours"),[a]),o.renderDateSelection=t.memoizeRendering(l.renderSegs.bind(l,"highlight"),l.unrender.bind(l,"highlight"),[a]),o.renderBgEvents=t.memoizeRendering(l.renderSegs.bind(l,"bgEvent"),l.unrender.bind(l,"bgEvent"),[a]),o.renderFgEvents=t.memoizeRendering(s.renderSegs.bind(s),s.unrender.bind(s),[a]),o.renderEventSelection=t.memoizeRendering(s.selectByInstanceId.bind(s),s.unselectByInstanceId.bind(s),[o.renderFgEvents]),o.renderEventDrag=t.memoizeRendering(o._renderEventDrag,o._unrenderEventDrag,[a]),o.renderEventResize=t.memoizeRendering(o._renderEventResize,o._unrenderEventResize,[a]),o.renderProps=i,o}return r(n,e),n.prototype.render=function(e){var t=e.cells;this.rowCnt=t.length,this.colCnt=t[0].length,this.renderCells(t,e.isRigid),this.renderBusinessHours(e.businessHourSegs),this.renderDateSelection(e.dateSelectionSegs),this.renderBgEvents(e.bgEventSegs),this.renderFgEvents(e.fgEventSegs),this.renderEventSelection(e.eventSelection),this.renderEventDrag(e.eventDrag),this.renderEventResize(e.eventResize),this.segPopoverTile&&this.updateSegPopoverTile()},n.prototype.destroy=function(){e.prototype.destroy.call(this),this.renderCells.unrender()},n.prototype.getCellRange=function(e,r){var n=this.props.cells[e][r].date;return{start:n,end:t.addDays(n,1)}},n.prototype.updateSegPopoverTile=function(e,t){var r=this.props;this.segPopoverTile.receiveProps({date:e||this.segPopoverTile.props.date,fgSegs:t||this.segPopoverTile.props.fgSegs,eventSelection:r.eventSelection,eventDragInstances:r.eventDrag?r.eventDrag.affectedInstances:null,eventResizeInstances:r.eventResize?r.eventResize.affectedInstances:null})},n.prototype._renderCells=function(e,r){var n,i,o=this,s=o.view,l=o.dateEnv,a=this,d=a.rowCnt,c=a.colCnt,h="";for(n=0;n<d;n++)h+=this.renderDayRowHtml(n,r);for(this.el.innerHTML=h,this.rowEls=t.findElements(this.el,".fc-row"),this.cellEls=t.findElements(this.el,".fc-day, .fc-disabled-day"),this.isRtl&&this.cellEls.reverse(),this.rowPositions=new t.PositionCache(this.el,this.rowEls,!1,!0),this.colPositions=new t.PositionCache(this.el,this.cellEls.slice(0,c),!0,!1),n=0;n<d;n++)for(i=0;i<c;i++)this.publiclyTrigger("dayRender",[{date:l.toDate(e[n][i].date),el:this.getCellEl(n,i),view:s}]);this.isCellSizesDirty=!0},n.prototype._unrenderCells=function(){this.removeSegPopover()},n.prototype.renderDayRowHtml=function(e,t){var r=this.theme,n=["fc-row","fc-week",r.getClass("dayRow")];t&&n.push("fc-rigid");var i=new y(this.context);return'<div class="'+n.join(" ")+'"><div class="fc-bg"><table class="'+r.getClass("tableGrid")+'">'+i.renderHtml({cells:this.props.cells[e],dateProfile:this.props.dateProfile,renderIntroHtml:this.renderProps.renderBgIntroHtml})+'</table></div><div class="fc-content-skeleton"><table>'+(this.getIsNumbersVisible()?"<thead>"+this.renderNumberTrHtml(e)+"</thead>":"")+"</table></div></div>"},n.prototype.getIsNumbersVisible=function(){return this.getIsDayNumbersVisible()||this.renderProps.cellWeekNumbersVisible||this.renderProps.colWeekNumbersVisible},n.prototype.getIsDayNumbersVisible=function(){return this.rowCnt>1},n.prototype.renderNumberTrHtml=function(e){var t=this.renderProps.renderNumberIntroHtml(e,this);return"<tr>"+(this.isRtl?"":t)+this.renderNumberCellsHtml(e)+(this.isRtl?t:"")+"</tr>"},n.prototype.renderNumberCellsHtml=function(e){var t,r,n=[];for(t=0;t<this.colCnt;t++)r=this.props.cells[e][t].date,n.push(this.renderNumberCellHtml(r));return this.isRtl&&n.reverse(),n.join("")},n.prototype.renderNumberCellHtml=function(e){var r,n,i=this,o=i.view,s=i.dateEnv,l="",a=t.rangeContainsMarker(this.props.dateProfile.activeRange,e),d=this.getIsDayNumbersVisible()&&a;return d||this.renderProps.cellWeekNumbersVisible?(r=t.getDayClasses(e,this.props.dateProfile,this.context),r.unshift("fc-day-top"),this.renderProps.cellWeekNumbersVisible&&(n=s.weekDow),l+='<td class="'+r.join(" ")+'"'+(a?' data-date="'+s.formatIso(e,{omitTime:!0})+'"':"")+">",this.renderProps.cellWeekNumbersVisible&&e.getUTCDay()===n&&(l+=t.buildGotoAnchorHtml(o,{date:e,type:"week"},{class:"fc-week-number"},s.format(e,b))),d&&(l+=t.buildGotoAnchorHtml(o,e,{class:"fc-day-number"},s.format(e,v))),l+="</td>"):"<td></td>"},n.prototype.updateSize=function(e){var t=this,r=t.fillRenderer,n=t.eventRenderer,i=t.mirrorRenderer;(e||this.isCellSizesDirty)&&(this.buildColPositions(),this.buildRowPositions(),this.isCellSizesDirty=!1),r.computeSizes(e),n.computeSizes(e),i.computeSizes(e),r.assignSizes(e),n.assignSizes(e),i.assignSizes(e)},n.prototype.buildColPositions=function(){this.colPositions.build()},n.prototype.buildRowPositions=function(){this.rowPositions.build(),this.rowPositions.bottoms[this.rowCnt-1]+=this.bottomCoordPadding},n.prototype.positionToHit=function(e,t){var r=this,n=r.colPositions,i=r.rowPositions,o=n.leftToIndex(e),s=i.topToIndex(t);if(null!=s&&null!=o)return{row:s,col:o,dateSpan:{range:this.getCellRange(s,o),allDay:!0},dayEl:this.getCellEl(s,o),relativeRect:{left:n.lefts[o],right:n.rights[o],top:i.tops[s],bottom:i.bottoms[s]}}},n.prototype.getCellEl=function(e,t){return this.cellEls[e*this.colCnt+t]},n.prototype._renderEventDrag=function(e){e&&(this.eventRenderer.hideByHash(e.affectedInstances),this.fillRenderer.renderSegs("highlight",e.segs))},n.prototype._unrenderEventDrag=function(e){e&&(this.eventRenderer.showByHash(e.affectedInstances),this.fillRenderer.unrender("highlight"))},n.prototype._renderEventResize=function(e){e&&(this.eventRenderer.hideByHash(e.affectedInstances),this.fillRenderer.renderSegs("highlight",e.segs),this.mirrorRenderer.renderSegs(e.segs,{isResizing:!0,sourceSeg:e.sourceSeg}))},n.prototype._unrenderEventResize=function(e){e&&(this.eventRenderer.showByHash(e.affectedInstances),this.fillRenderer.unrender("highlight"),this.mirrorRenderer.unrender(e.segs,{isResizing:!0,sourceSeg:e.sourceSeg}))},n.prototype.removeSegPopover=function(){this.segPopover&&this.segPopover.hide()},n.prototype.limitRows=function(e){var t,r,n=this.eventRenderer.rowStructs||[];for(t=0;t<n.length;t++)this.unlimitRow(t),!1!==(r=!!e&&("number"==typeof e?e:this.computeRowLevelLimit(t)))&&this.limitRow(t,r)},n.prototype.computeRowLevelLimit=function(e){var r,n,i=this.rowEls[e],o=i.getBoundingClientRect().bottom,s=t.findChildren(this.eventRenderer.rowStructs[e].tbodyEl);for(r=0;r<s.length;r++)if(n=s[r],n.classList.remove("fc-limited"),n.getBoundingClientRect().bottom>o)return r;return!1},n.prototype.limitRow=function(e,r){var n,i,o,s,l,a,d,c,h,p,u,f,g,m,y,v=this,b=this,w=b.colCnt,S=b.isRtl,C=this.eventRenderer.rowStructs[e],E=[],R=0,H=function(n){for(;R<n;)a=v.getCellSegs(e,R,r),a.length&&(h=i[r-1][R],y=v.renderMoreLink(e,R,a),m=t.createElement("div",null,y),h.appendChild(m),E.push(m[0])),R++};if(r&&r<C.segLevels.length){for(n=C.segLevels[r-1],i=C.cellMatrix,o=t.findChildren(C.tbodyEl).slice(r),o.forEach(function(e){e.classList.add("fc-limited")}),s=0;s<n.length;s++){l=n[s];var D=S?w-1-l.lastCol:l.firstCol,P=S?w-1-l.firstCol:l.lastCol;for(H(D),c=[],d=0;R<=P;)a=this.getCellSegs(e,R,r),c.push(a),d+=a.length,R++;if(d){for(h=i[r-1][D],p=h.rowSpan||1,u=[],f=0;f<c.length;f++)g=t.createElement("td",{className:"fc-more-cell",rowSpan:p}),a=c[f],y=this.renderMoreLink(e,D+f,[l].concat(a)),m=t.createElement("div",null,y),g.appendChild(m),u.push(g),E.push(g);h.classList.add("fc-limited"),t.insertAfterElement(h,u),o.push(h)}}H(this.colCnt),C.moreEls=E,C.limitedEls=o}},n.prototype.unlimitRow=function(e){var r=this.eventRenderer.rowStructs[e];r.moreEls&&(r.moreEls.forEach(t.removeElement),r.moreEls=null),r.limitedEls&&(r.limitedEls.forEach(function(e){e.classList.remove("fc-limited")}),r.limitedEls=null)},n.prototype.renderMoreLink=function(e,r,n){var i=this,o=this,s=o.view,l=o.dateEnv,a=t.createElement("a",{className:"fc-more"});return a.innerText=this.getMoreLinkText(n.length),a.addEventListener("click",function(t){var o=i.opt("eventLimitClick"),a=i.isRtl?i.colCnt-r-1:r,d=i.props.cells[e][a].date,c=t.currentTarget,h=i.getCellEl(e,r),p=i.getCellSegs(e,r),u=i.resliceDaySegs(p,d),f=i.resliceDaySegs(n,d);"function"==typeof o&&(o=i.publiclyTrigger("eventLimitClick",[{date:l.toDate(d),allDay:!0,dayEl:h,moreEl:c,segs:u,hiddenSegs:f,jsEvent:t,view:s}])),"popover"===o?i.showSegPopover(e,r,c,u):"string"==typeof o&&s.calendar.zoomTo(d,o)}),a},n.prototype.showSegPopover=function(e,r,n,i){var o,s,l=this,a=this,d=a.calendar,h=a.view,p=a.theme,u=this.isRtl?this.colCnt-r-1:r,f=n.parentNode;o=1===this.rowCnt?h.el:this.rowEls[e],s={className:"fc-more-popover "+p.getClass("popover"),parentEl:h.el,top:t.computeRect(o).top,autoHide:!0,content:function(t){l.segPopoverTile=new g(l.context,t),l.updateSegPopoverTile(l.props.cells[e][u].date,i)},hide:function(){l.segPopoverTile.destroy(),l.segPopoverTile=null,l.segPopover.destroy(),l.segPopover=null}},this.isRtl?s.right=t.computeRect(f).right+1:s.left=t.computeRect(f).left-1,this.segPopover=new c(s),this.segPopover.show(),d.releaseAfterSizingTriggers()},n.prototype.resliceDaySegs=function(e,r){for(var n=r,i=t.addDays(n,1),o={start:n,end:i},s=[],l=0,d=e;l<d.length;l++){var c=d[l],h=c.eventRange,p=h.range,u=t.intersectRanges(p,o);u&&s.push(a({},c,{eventRange:{def:h.def,ui:a({},h.ui,{durationEditable:!1}),instance:h.instance,range:u},isStart:c.isStart&&u.start.valueOf()===p.start.valueOf(),isEnd:c.isEnd&&u.end.valueOf()===p.end.valueOf()}))}return s},n.prototype.getMoreLinkText=function(e){var t=this.opt("eventLimitText");return"function"==typeof t?t(e):"+"+e+" "+t},n.prototype.getCellSegs=function(e,t,r){for(var n,i=this.eventRenderer.rowStructs[e].segMatrix,o=r||0,s=[];o<i.length;)n=i[o][t],n&&s.push(n),o++;return s},n}(t.DateComponent),S=t.createFormatter({week:"numeric"}),C=function(e){function n(r,n,i,o){var s=e.call(this,r,n,i,o)||this;s.renderHeadIntroHtml=function(){var e=s.theme;return s.colWeekNumbersVisible?'<th class="fc-week-number '+e.getClass("widgetHeader")+'" '+s.weekNumberStyleAttr()+"><span>"+t.htmlEscape(s.opt("weekLabel"))+"</span></th>":""},s.renderDayGridNumberIntroHtml=function(e,r){var n=s.dateEnv,i=r.props.cells[e][0].date;return s.colWeekNumbersVisible?'<td class="fc-week-number" '+s.weekNumberStyleAttr()+">"+t.buildGotoAnchorHtml(s,{date:i,type:"week",forceOff:1===r.colCnt},n.format(i,S))+"</td>":""},s.renderDayGridBgIntroHtml=function(){var e=s.theme;return s.colWeekNumbersVisible?'<td class="fc-week-number '+e.getClass("widgetContent")+'" '+s.weekNumberStyleAttr()+"></td>":""},s.renderDayGridIntroHtml=function(){return s.colWeekNumbersVisible?'<td class="fc-week-number" '+s.weekNumberStyleAttr()+"></td>":""},s.el.classList.add("fc-dayGrid-view"),s.el.innerHTML=s.renderSkeletonHtml(),s.scroller=new t.ScrollComponent("hidden","auto");var l=s.scroller.el;s.el.querySelector(".fc-body > tr > td").appendChild(l),l.classList.add("fc-day-grid-container");var a=t.createElement("div",{className:"fc-day-grid"});l.appendChild(a);var d;return s.opt("weekNumbers")?s.opt("weekNumbersWithinDays")?(d=!0,s.colWeekNumbersVisible=!1):(d=!1,s.colWeekNumbersVisible=!0):(s.colWeekNumbersVisible=!1,d=!1),s.dayGrid=new w(s.context,a,{renderNumberIntroHtml:s.renderDayGridNumberIntroHtml,renderBgIntroHtml:s.renderDayGridBgIntroHtml,renderIntroHtml:s.renderDayGridIntroHtml,colWeekNumbersVisible:s.colWeekNumbersVisible,cellWeekNumbersVisible:d}),s}return r(n,e),n.prototype.destroy=function(){e.prototype.destroy.call(this),this.dayGrid.destroy(),this.scroller.destroy()},n.prototype.renderSkeletonHtml=function(){var e=this.theme;return'<table class="'+e.getClass("tableGrid")+'">'+(this.opt("columnHeader")?'<thead class="fc-head"><tr><td class="fc-head-container '+e.getClass("widgetHeader")+'">&nbsp;</td></tr></thead>':"")+'<tbody class="fc-body"><tr><td class="'+e.getClass("widgetContent")+'"></td></tr></tbody></table>'},n.prototype.weekNumberStyleAttr=function(){return null!=this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},n.prototype.hasRigidRows=function(){var e=this.opt("eventLimit");return e&&"number"!=typeof e},n.prototype.updateSize=function(t,r,n){e.prototype.updateSize.call(this,t,r,n),this.dayGrid.updateSize(t)},n.prototype.updateBaseSize=function(e,r,n){var i,o,s=this.dayGrid,l=this.opt("eventLimit"),a=this.header?this.header.el:null;if(!s.rowEls)return void(n||(i=this.computeScrollerHeight(r),this.scroller.setHeight(i)));this.colWeekNumbersVisible&&(this.weekNumberWidth=t.matchCellWidths(t.findElements(this.el,".fc-week-number"))),this.scroller.clear(),a&&t.uncompensateScroll(a),s.removeSegPopover(),l&&"number"==typeof l&&s.limitRows(l),i=this.computeScrollerHeight(r),this.setGridHeight(i,n),l&&"number"!=typeof l&&s.limitRows(l),n||(this.scroller.setHeight(i),o=this.scroller.getScrollbarWidths(),(o.left||o.right)&&(a&&t.compensateScroll(a,o),i=this.computeScrollerHeight(r),this.scroller.setHeight(i)),this.scroller.lockOverflow(o))},n.prototype.computeScrollerHeight=function(e){return e-t.subtractInnerElHeight(this.el,this.scroller.el)},n.prototype.setGridHeight=function(e,r){this.opt("monthMode")?(r&&(e*=this.dayGrid.rowCnt/6),t.distributeHeight(this.dayGrid.rowEls,e,!r)):r?t.undistributeHeight(this.dayGrid.rowEls):t.distributeHeight(this.dayGrid.rowEls,e,!0)},n.prototype.computeInitialDateScroll=function(){return{top:0}},n.prototype.queryDateScroll=function(){return{top:this.scroller.getScrollTop()}},n.prototype.applyDateScroll=function(e){void 0!==e.top&&this.scroller.setScrollTop(e.top)},n}(t.View);C.prototype.dateProfileGeneratorClass=d;var E=function(e){function t(t,r){var n=e.call(this,t,r.el)||this;return n.slicer=new R,n.dayGrid=r,t.calendar.registerInteractiveComponent(n,{el:n.dayGrid.el}),n}return r(t,e),t.prototype.destroy=function(){e.prototype.destroy.call(this),this.calendar.unregisterInteractiveComponent(this)},t.prototype.render=function(e){var t=this.dayGrid,r=e.dateProfile,n=e.dayTable;t.receiveProps(a({},this.slicer.sliceProps(e,r,e.nextDayThreshold,t,n),{dateProfile:r,cells:n.cells,isRigid:e.isRigid}))},t.prototype.queryHit=function(e,t){var r=this.dayGrid.positionToHit(e,t);if(r)return{component:this.dayGrid,dateSpan:r.dateSpan,dayEl:r.dayEl,rect:{left:r.relativeRect.left,right:r.relativeRect.right,top:r.relativeRect.top,bottom:r.relativeRect.bottom},layer:0}},t}(t.DateComponent),R=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r(t,e),t.prototype.sliceRange=function(e,t){return t.sliceRange(e)},t}(t.Slicer),H=function(e){function n(r,n,i,o){var l=e.call(this,r,n,i,o)||this;return l.buildDayTable=t.memoize(s),l.opt("columnHeader")&&(l.header=new t.DayHeader(l.context,l.el.querySelector(".fc-head-container"))),l.simpleDayGrid=new E(l.context,l.dayGrid),l}return r(n,e),n.prototype.destroy=function(){e.prototype.destroy.call(this),this.header&&this.header.destroy(),this.simpleDayGrid.destroy()},n.prototype.render=function(t){e.prototype.render.call(this,t);var r=this.props.dateProfile,n=this.dayTable=this.buildDayTable(r,this.dateProfileGenerator);this.header&&this.header.receiveProps({dateProfile:r,dates:n.headerDates,datesRepDistinctDays:1===n.rowCnt,renderIntroHtml:this.renderHeadIntroHtml}),this.simpleDayGrid.receiveProps({dateProfile:r,dayTable:n,businessHours:t.businessHours,dateSelection:t.dateSelection,eventStore:t.eventStore,eventUiBases:t.eventUiBases,eventSelection:t.eventSelection,eventDrag:t.eventDrag,eventResize:t.eventResize,isRigid:this.hasRigidRows(),nextDayThreshold:this.nextDayThreshold})},n}(C),D=t.createPlugin({defaultView:"dayGridMonth",views:{dayGrid:H,dayGridDay:{type:"dayGrid",duration:{days:1}},dayGridWeek:{type:"dayGrid",duration:{weeks:1}},dayGridMonth:{type:"dayGrid",duration:{months:1},monthMode:!0,fixedWeekCount:!0}}});e.AbstractDayGridView=C,e.DayBgRow=y,e.DayGrid=w,e.DayGridSlicer=R,e.DayGridView=H,e.SimpleDayGrid=E,e.buildBasicDayTable=s,e.default=D,Object.defineProperty(e,"__esModule",{value:!0})});
@@ -0,0 +1,169 @@
1
+ /*!
2
+ FullCalendar Google Calendar Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ (function (global, factory) {
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
8
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
9
+ (global = global || self, factory(global.FullCalendarGoogleCalendar = {}, global.FullCalendar));
10
+ }(this, function (exports, core) { 'use strict';
11
+
12
+ /*! *****************************************************************************
13
+ Copyright (c) Microsoft Corporation. All rights reserved.
14
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
15
+ this file except in compliance with the License. You may obtain a copy of the
16
+ License at http://www.apache.org/licenses/LICENSE-2.0
17
+
18
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
20
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
21
+ MERCHANTABLITY OR NON-INFRINGEMENT.
22
+
23
+ See the Apache Version 2.0 License for specific language governing permissions
24
+ and limitations under the License.
25
+ ***************************************************************************** */
26
+
27
+ var __assign = function() {
28
+ __assign = Object.assign || function __assign(t) {
29
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
30
+ s = arguments[i];
31
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
32
+ }
33
+ return t;
34
+ };
35
+ return __assign.apply(this, arguments);
36
+ };
37
+
38
+ // TODO: expose somehow
39
+ var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
40
+ var STANDARD_PROPS = {
41
+ url: String,
42
+ googleCalendarApiKey: String,
43
+ googleCalendarId: String,
44
+ data: null
45
+ };
46
+ var eventSourceDef = {
47
+ parseMeta: function (raw) {
48
+ if (typeof raw === 'string') {
49
+ raw = { url: raw };
50
+ }
51
+ if (typeof raw === 'object') {
52
+ var standardProps = core.refineProps(raw, STANDARD_PROPS);
53
+ if (!standardProps.googleCalendarId && standardProps.url) {
54
+ standardProps.googleCalendarId = parseGoogleCalendarId(standardProps.url);
55
+ }
56
+ delete standardProps.url;
57
+ if (standardProps.googleCalendarId) {
58
+ return standardProps;
59
+ }
60
+ }
61
+ return null;
62
+ },
63
+ fetch: function (arg, onSuccess, onFailure) {
64
+ var calendar = arg.calendar;
65
+ var meta = arg.eventSource.meta;
66
+ var apiKey = meta.googleCalendarApiKey || calendar.opt('googleCalendarApiKey');
67
+ if (!apiKey) {
68
+ onFailure({
69
+ message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/'
70
+ });
71
+ }
72
+ else {
73
+ var url = buildUrl(meta);
74
+ var requestParams_1 = buildRequestParams(arg.range, apiKey, meta.data, calendar.dateEnv);
75
+ core.requestJson('GET', url, requestParams_1, function (body, xhr) {
76
+ if (body.error) {
77
+ onFailure({
78
+ message: 'Google Calendar API: ' + body.error.message,
79
+ errors: body.error.errors,
80
+ xhr: xhr
81
+ });
82
+ }
83
+ else {
84
+ onSuccess({
85
+ rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
86
+ xhr: xhr
87
+ });
88
+ }
89
+ }, function (message, xhr) {
90
+ onFailure({ message: message, xhr: xhr });
91
+ });
92
+ }
93
+ }
94
+ };
95
+ function parseGoogleCalendarId(url) {
96
+ var match;
97
+ // detect if the ID was specified as a single string.
98
+ // will match calendars like "asdf1234@calendar.google.com" in addition to person email calendars.
99
+ if (/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
100
+ return url;
101
+ }
102
+ else if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) ||
103
+ (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))) {
104
+ return decodeURIComponent(match[1]);
105
+ }
106
+ }
107
+ function buildUrl(meta) {
108
+ return API_BASE + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
109
+ }
110
+ function buildRequestParams(range, apiKey, extraParams, dateEnv) {
111
+ var params;
112
+ var startStr;
113
+ var endStr;
114
+ if (dateEnv.canComputeOffset) {
115
+ // strings will naturally have offsets, which GCal needs
116
+ startStr = dateEnv.formatIso(range.start);
117
+ endStr = dateEnv.formatIso(range.end);
118
+ }
119
+ else {
120
+ // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
121
+ // from the UTC day-start to guarantee we're getting all the events
122
+ // (start/end will be UTC-coerced dates, so toISOString is okay)
123
+ startStr = core.addDays(range.start, -1).toISOString();
124
+ endStr = core.addDays(range.end, 1).toISOString();
125
+ }
126
+ params = __assign({}, (extraParams || {}), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
127
+ if (dateEnv.timeZone !== 'local') {
128
+ params.timeZone = dateEnv.timeZone;
129
+ }
130
+ return params;
131
+ }
132
+ function gcalItemsToRawEventDefs(items, gcalTimezone) {
133
+ return items.map(function (item) {
134
+ return gcalItemToRawEventDef(item, gcalTimezone);
135
+ });
136
+ }
137
+ function gcalItemToRawEventDef(item, gcalTimezone) {
138
+ var url = item.htmlLink || null;
139
+ // make the URLs for each event show times in the correct timezone
140
+ if (url && gcalTimezone) {
141
+ url = injectQsComponent(url, 'ctz=' + gcalTimezone);
142
+ }
143
+ return {
144
+ id: item.id,
145
+ title: item.summary,
146
+ start: item.start.dateTime || item.start.date,
147
+ end: item.end.dateTime || item.end.date,
148
+ url: url,
149
+ location: item.location,
150
+ description: item.description
151
+ };
152
+ }
153
+ // Injects a string like "arg=value" into the querystring of a URL
154
+ // TODO: move to a general util file?
155
+ function injectQsComponent(url, component) {
156
+ // inject it after the querystring but before the fragment
157
+ return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) {
158
+ return (qs ? qs + '&' : '?') + component + hash;
159
+ });
160
+ }
161
+ var main = core.createPlugin({
162
+ eventSourceDefs: [eventSourceDef]
163
+ });
164
+
165
+ exports.default = main;
166
+
167
+ Object.defineProperty(exports, '__esModule', { value: true });
168
+
169
+ }));
@@ -0,0 +1,20 @@
1
+ /*!
2
+ FullCalendar Google Calendar Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core"],r):(e=e||self,r(e.FullCalendarGoogleCalendar={},e.FullCalendar))}(this,function(e,r){"use strict";function t(e){var r;return/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(e)?e:(r=/^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(e))||(r=/^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(e))?decodeURIComponent(r[1]):void 0}function n(e){return s+"/"+encodeURIComponent(e.googleCalendarId)+"/events"}function o(e,t,n,o){var a,l,i;return o.canComputeOffset?(l=o.formatIso(e.start),i=o.formatIso(e.end)):(l=r.addDays(e.start,-1).toISOString(),i=r.addDays(e.end,1).toISOString()),a=d({},n||{},{key:t,timeMin:l,timeMax:i,singleEvents:!0,maxResults:9999}),"local"!==o.timeZone&&(a.timeZone=o.timeZone),a}function a(e,r){return e.map(function(e){return l(e,r)})}function l(e,r){var t=e.htmlLink||null;return t&&r&&(t=i(t,"ctz="+r)),{id:e.id,title:e.summary,start:e.start.dateTime||e.start.date,end:e.end.dateTime||e.end.date,url:t,location:e.location,description:e.description}}function i(e,r){return e.replace(/(\?.*?)?(#|$)/,function(e,t,n){return(t?t+"&":"?")+r+n})}/*! *****************************************************************************
7
+ Copyright (c) Microsoft Corporation. All rights reserved.
8
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
9
+ this file except in compliance with the License. You may obtain a copy of the
10
+ License at http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
14
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
15
+ MERCHANTABLITY OR NON-INFRINGEMENT.
16
+
17
+ See the Apache Version 2.0 License for specific language governing permissions
18
+ and limitations under the License.
19
+ ***************************************************************************** */
20
+ var d=function(){return d=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++){r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e},d.apply(this,arguments)},s="https://www.googleapis.com/calendar/v3/calendars",c={url:String,googleCalendarApiKey:String,googleCalendarId:String,data:null},u={parseMeta:function(e){if("string"==typeof e&&(e={url:e}),"object"==typeof e){var n=r.refineProps(e,c);if(!n.googleCalendarId&&n.url&&(n.googleCalendarId=t(n.url)),delete n.url,n.googleCalendarId)return n}return null},fetch:function(e,t,l){var i=e.calendar,d=e.eventSource.meta,s=d.googleCalendarApiKey||i.opt("googleCalendarApiKey");if(s){var c=n(d),u=o(e.range,s,d.data,i.dateEnv);r.requestJson("GET",c,u,function(e,r){e.error?l({message:"Google Calendar API: "+e.error.message,errors:e.error.errors,xhr:r}):t({rawEvents:a(e.items,u.timeZone),xhr:r})},function(e,r){l({message:e,xhr:r})})}else l({message:"Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/"})}},g=r.createPlugin({eventSourceDefs:[u]});e.default=g,Object.defineProperty(e,"__esModule",{value:!0})});
@@ -0,0 +1,2155 @@
1
+ /*!
2
+ FullCalendar Interaction Plugin v4.0.2
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ (function (global, factory) {
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
8
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
9
+ (global = global || self, factory(global.FullCalendarInteraction = {}, global.FullCalendar));
10
+ }(this, function (exports, core) { 'use strict';
11
+
12
+ /*! *****************************************************************************
13
+ Copyright (c) Microsoft Corporation. All rights reserved.
14
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
15
+ this file except in compliance with the License. You may obtain a copy of the
16
+ License at http://www.apache.org/licenses/LICENSE-2.0
17
+
18
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
20
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
21
+ MERCHANTABLITY OR NON-INFRINGEMENT.
22
+
23
+ See the Apache Version 2.0 License for specific language governing permissions
24
+ and limitations under the License.
25
+ ***************************************************************************** */
26
+ /* global Reflect, Promise */
27
+
28
+ var extendStatics = function(d, b) {
29
+ extendStatics = Object.setPrototypeOf ||
30
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
32
+ return extendStatics(d, b);
33
+ };
34
+
35
+ function __extends(d, b) {
36
+ extendStatics(d, b);
37
+ function __() { this.constructor = d; }
38
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
39
+ }
40
+
41
+ var __assign = function() {
42
+ __assign = Object.assign || function __assign(t) {
43
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
44
+ s = arguments[i];
45
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
46
+ }
47
+ return t;
48
+ };
49
+ return __assign.apply(this, arguments);
50
+ };
51
+
52
+ core.config.touchMouseIgnoreWait = 500;
53
+ var ignoreMouseDepth = 0;
54
+ var listenerCnt = 0;
55
+ var isWindowTouchMoveCancelled = false;
56
+ /*
57
+ Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
58
+ Tracks when the pointer "drags" on a certain element, meaning down+move+up.
59
+
60
+ Also, tracks if there was touch-scrolling.
61
+ Also, can prevent touch-scrolling from happening.
62
+ Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
63
+
64
+ emits:
65
+ - pointerdown
66
+ - pointermove
67
+ - pointerup
68
+ */
69
+ var PointerDragging = /** @class */ (function () {
70
+ function PointerDragging(containerEl) {
71
+ var _this = this;
72
+ this.subjectEl = null;
73
+ this.downEl = null;
74
+ // options that can be directly assigned by caller
75
+ this.selector = ''; // will cause subjectEl in all emitted events to be this element
76
+ this.handleSelector = '';
77
+ this.shouldIgnoreMove = false;
78
+ this.shouldWatchScroll = true; // for simulating pointermove on scroll
79
+ // internal states
80
+ this.isDragging = false;
81
+ this.isTouchDragging = false;
82
+ this.wasTouchScroll = false;
83
+ // Mouse
84
+ // ----------------------------------------------------------------------------------------------------
85
+ this.handleMouseDown = function (ev) {
86
+ if (!_this.shouldIgnoreMouse() &&
87
+ isPrimaryMouseButton(ev) &&
88
+ _this.tryStart(ev)) {
89
+ var pev = _this.createEventFromMouse(ev, true);
90
+ _this.emitter.trigger('pointerdown', pev);
91
+ _this.initScrollWatch(pev);
92
+ if (!_this.shouldIgnoreMove) {
93
+ document.addEventListener('mousemove', _this.handleMouseMove);
94
+ }
95
+ document.addEventListener('mouseup', _this.handleMouseUp);
96
+ }
97
+ };
98
+ this.handleMouseMove = function (ev) {
99
+ var pev = _this.createEventFromMouse(ev);
100
+ _this.recordCoords(pev);
101
+ _this.emitter.trigger('pointermove', pev);
102
+ };
103
+ this.handleMouseUp = function (ev) {
104
+ document.removeEventListener('mousemove', _this.handleMouseMove);
105
+ document.removeEventListener('mouseup', _this.handleMouseUp);
106
+ _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
107
+ _this.cleanup(); // call last so that pointerup has access to props
108
+ };
109
+ // Touch
110
+ // ----------------------------------------------------------------------------------------------------
111
+ this.handleTouchStart = function (ev) {
112
+ if (_this.tryStart(ev)) {
113
+ _this.isTouchDragging = true;
114
+ var pev = _this.createEventFromTouch(ev, true);
115
+ _this.emitter.trigger('pointerdown', pev);
116
+ _this.initScrollWatch(pev);
117
+ // unlike mouse, need to attach to target, not document
118
+ // https://stackoverflow.com/a/45760014
119
+ var target = ev.target;
120
+ if (!_this.shouldIgnoreMove) {
121
+ target.addEventListener('touchmove', _this.handleTouchMove);
122
+ }
123
+ target.addEventListener('touchend', _this.handleTouchEnd);
124
+ target.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
125
+ // attach a handler to get called when ANY scroll action happens on the page.
126
+ // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
127
+ // http://stackoverflow.com/a/32954565/96342
128
+ window.addEventListener('scroll', _this.handleTouchScroll, true // useCapture
129
+ );
130
+ }
131
+ };
132
+ this.handleTouchMove = function (ev) {
133
+ var pev = _this.createEventFromTouch(ev);
134
+ _this.recordCoords(pev);
135
+ _this.emitter.trigger('pointermove', pev);
136
+ };
137
+ this.handleTouchEnd = function (ev) {
138
+ if (_this.isDragging) { // done to guard against touchend followed by touchcancel
139
+ var target = ev.target;
140
+ target.removeEventListener('touchmove', _this.handleTouchMove);
141
+ target.removeEventListener('touchend', _this.handleTouchEnd);
142
+ target.removeEventListener('touchcancel', _this.handleTouchEnd);
143
+ window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
144
+ _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
145
+ _this.cleanup(); // call last so that pointerup has access to props
146
+ _this.isTouchDragging = false;
147
+ startIgnoringMouse();
148
+ }
149
+ };
150
+ this.handleTouchScroll = function () {
151
+ _this.wasTouchScroll = true;
152
+ };
153
+ this.handleScroll = function (ev) {
154
+ if (!_this.shouldIgnoreMove) {
155
+ var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
156
+ var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
157
+ _this.emitter.trigger('pointermove', {
158
+ origEvent: ev,
159
+ isTouch: _this.isTouchDragging,
160
+ subjectEl: _this.subjectEl,
161
+ pageX: pageX,
162
+ pageY: pageY,
163
+ deltaX: pageX - _this.origPageX,
164
+ deltaY: pageY - _this.origPageY
165
+ });
166
+ }
167
+ };
168
+ this.containerEl = containerEl;
169
+ this.emitter = new core.EmitterMixin();
170
+ containerEl.addEventListener('mousedown', this.handleMouseDown);
171
+ containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
172
+ listenerCreated();
173
+ }
174
+ PointerDragging.prototype.destroy = function () {
175
+ this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
176
+ this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
177
+ listenerDestroyed();
178
+ };
179
+ PointerDragging.prototype.tryStart = function (ev) {
180
+ var subjectEl = this.querySubjectEl(ev);
181
+ var downEl = ev.target;
182
+ if (subjectEl &&
183
+ (!this.handleSelector || core.elementClosest(downEl, this.handleSelector))) {
184
+ this.subjectEl = subjectEl;
185
+ this.downEl = downEl;
186
+ this.isDragging = true; // do this first so cancelTouchScroll will work
187
+ this.wasTouchScroll = false;
188
+ return true;
189
+ }
190
+ return false;
191
+ };
192
+ PointerDragging.prototype.cleanup = function () {
193
+ isWindowTouchMoveCancelled = false;
194
+ this.isDragging = false;
195
+ this.subjectEl = null;
196
+ this.downEl = null;
197
+ // keep wasTouchScroll around for later access
198
+ this.destroyScrollWatch();
199
+ };
200
+ PointerDragging.prototype.querySubjectEl = function (ev) {
201
+ if (this.selector) {
202
+ return core.elementClosest(ev.target, this.selector);
203
+ }
204
+ else {
205
+ return this.containerEl;
206
+ }
207
+ };
208
+ PointerDragging.prototype.shouldIgnoreMouse = function () {
209
+ return ignoreMouseDepth || this.isTouchDragging;
210
+ };
211
+ // can be called by user of this class, to cancel touch-based scrolling for the current drag
212
+ PointerDragging.prototype.cancelTouchScroll = function () {
213
+ if (this.isDragging) {
214
+ isWindowTouchMoveCancelled = true;
215
+ }
216
+ };
217
+ // Scrolling that simulates pointermoves
218
+ // ----------------------------------------------------------------------------------------------------
219
+ PointerDragging.prototype.initScrollWatch = function (ev) {
220
+ if (this.shouldWatchScroll) {
221
+ this.recordCoords(ev);
222
+ window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
223
+ }
224
+ };
225
+ PointerDragging.prototype.recordCoords = function (ev) {
226
+ if (this.shouldWatchScroll) {
227
+ this.prevPageX = ev.pageX;
228
+ this.prevPageY = ev.pageY;
229
+ this.prevScrollX = window.pageXOffset;
230
+ this.prevScrollY = window.pageYOffset;
231
+ }
232
+ };
233
+ PointerDragging.prototype.destroyScrollWatch = function () {
234
+ if (this.shouldWatchScroll) {
235
+ window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
236
+ }
237
+ };
238
+ // Event Normalization
239
+ // ----------------------------------------------------------------------------------------------------
240
+ PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
241
+ var deltaX = 0;
242
+ var deltaY = 0;
243
+ // TODO: repeat code
244
+ if (isFirst) {
245
+ this.origPageX = ev.pageX;
246
+ this.origPageY = ev.pageY;
247
+ }
248
+ else {
249
+ deltaX = ev.pageX - this.origPageX;
250
+ deltaY = ev.pageY - this.origPageY;
251
+ }
252
+ return {
253
+ origEvent: ev,
254
+ isTouch: false,
255
+ subjectEl: this.subjectEl,
256
+ pageX: ev.pageX,
257
+ pageY: ev.pageY,
258
+ deltaX: deltaX,
259
+ deltaY: deltaY
260
+ };
261
+ };
262
+ PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
263
+ var touches = ev.touches;
264
+ var pageX;
265
+ var pageY;
266
+ var deltaX = 0;
267
+ var deltaY = 0;
268
+ // if touch coords available, prefer,
269
+ // because FF would give bad ev.pageX ev.pageY
270
+ if (touches && touches.length) {
271
+ pageX = touches[0].pageX;
272
+ pageY = touches[0].pageY;
273
+ }
274
+ else {
275
+ pageX = ev.pageX;
276
+ pageY = ev.pageY;
277
+ }
278
+ // TODO: repeat code
279
+ if (isFirst) {
280
+ this.origPageX = pageX;
281
+ this.origPageY = pageY;
282
+ }
283
+ else {
284
+ deltaX = pageX - this.origPageX;
285
+ deltaY = pageY - this.origPageY;
286
+ }
287
+ return {
288
+ origEvent: ev,
289
+ isTouch: true,
290
+ subjectEl: this.subjectEl,
291
+ pageX: pageX,
292
+ pageY: pageY,
293
+ deltaX: deltaX,
294
+ deltaY: deltaY
295
+ };
296
+ };
297
+ return PointerDragging;
298
+ }());
299
+ // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
300
+ function isPrimaryMouseButton(ev) {
301
+ return ev.button === 0 && !ev.ctrlKey;
302
+ }
303
+ // Ignoring fake mouse events generated by touch
304
+ // ----------------------------------------------------------------------------------------------------
305
+ function startIgnoringMouse() {
306
+ ignoreMouseDepth++;
307
+ setTimeout(function () {
308
+ ignoreMouseDepth--;
309
+ }, core.config.touchMouseIgnoreWait);
310
+ }
311
+ // We want to attach touchmove as early as possible for Safari
312
+ // ----------------------------------------------------------------------------------------------------
313
+ function listenerCreated() {
314
+ if (!(listenerCnt++)) {
315
+ window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
316
+ }
317
+ }
318
+ function listenerDestroyed() {
319
+ if (!(--listenerCnt)) {
320
+ window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
321
+ }
322
+ }
323
+ function onWindowTouchMove(ev) {
324
+ if (isWindowTouchMoveCancelled) {
325
+ ev.preventDefault();
326
+ }
327
+ }
328
+
329
+ /*
330
+ An effect in which an element follows the movement of a pointer across the screen.
331
+ The moving element is a clone of some other element.
332
+ Must call start + handleMove + stop.
333
+ */
334
+ var ElementMirror = /** @class */ (function () {
335
+ function ElementMirror() {
336
+ this.isVisible = false; // must be explicitly enabled
337
+ this.sourceEl = null;
338
+ this.mirrorEl = null;
339
+ this.sourceElRect = null; // screen coords relative to viewport
340
+ // options that can be set directly by caller
341
+ this.parentNode = document.body;
342
+ this.zIndex = 9999;
343
+ this.revertDuration = 0;
344
+ }
345
+ ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
346
+ this.sourceEl = sourceEl;
347
+ this.sourceElRect = this.sourceEl.getBoundingClientRect();
348
+ this.origScreenX = pageX - window.pageXOffset;
349
+ this.origScreenY = pageY - window.pageYOffset;
350
+ this.deltaX = 0;
351
+ this.deltaY = 0;
352
+ this.updateElPosition();
353
+ };
354
+ ElementMirror.prototype.handleMove = function (pageX, pageY) {
355
+ this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
356
+ this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
357
+ this.updateElPosition();
358
+ };
359
+ // can be called before start
360
+ ElementMirror.prototype.setIsVisible = function (bool) {
361
+ if (bool) {
362
+ if (!this.isVisible) {
363
+ if (this.mirrorEl) {
364
+ this.mirrorEl.style.display = '';
365
+ }
366
+ this.isVisible = bool; // needs to happen before updateElPosition
367
+ this.updateElPosition(); // because was not updating the position while invisible
368
+ }
369
+ }
370
+ else {
371
+ if (this.isVisible) {
372
+ if (this.mirrorEl) {
373
+ this.mirrorEl.style.display = 'none';
374
+ }
375
+ this.isVisible = bool;
376
+ }
377
+ }
378
+ };
379
+ // always async
380
+ ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
381
+ var _this = this;
382
+ var done = function () {
383
+ _this.cleanup();
384
+ callback();
385
+ };
386
+ if (needsRevertAnimation &&
387
+ this.mirrorEl &&
388
+ this.isVisible &&
389
+ this.revertDuration && // if 0, transition won't work
390
+ (this.deltaX || this.deltaY) // if same coords, transition won't work
391
+ ) {
392
+ this.doRevertAnimation(done, this.revertDuration);
393
+ }
394
+ else {
395
+ setTimeout(done, 0);
396
+ }
397
+ };
398
+ ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
399
+ var mirrorEl = this.mirrorEl;
400
+ var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
401
+ mirrorEl.style.transition =
402
+ 'top ' + revertDuration + 'ms,' +
403
+ 'left ' + revertDuration + 'ms';
404
+ core.applyStyle(mirrorEl, {
405
+ left: finalSourceElRect.left,
406
+ top: finalSourceElRect.top
407
+ });
408
+ core.whenTransitionDone(mirrorEl, function () {
409
+ mirrorEl.style.transition = '';
410
+ callback();
411
+ });
412
+ };
413
+ ElementMirror.prototype.cleanup = function () {
414
+ if (this.mirrorEl) {
415
+ core.removeElement(this.mirrorEl);
416
+ this.mirrorEl = null;
417
+ }
418
+ this.sourceEl = null;
419
+ };
420
+ ElementMirror.prototype.updateElPosition = function () {
421
+ if (this.sourceEl && this.isVisible) {
422
+ core.applyStyle(this.getMirrorEl(), {
423
+ left: this.sourceElRect.left + this.deltaX,
424
+ top: this.sourceElRect.top + this.deltaY
425
+ });
426
+ }
427
+ };
428
+ ElementMirror.prototype.getMirrorEl = function () {
429
+ var sourceElRect = this.sourceElRect;
430
+ var mirrorEl = this.mirrorEl;
431
+ if (!mirrorEl) {
432
+ mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
433
+ // we don't want long taps or any mouse interaction causing selection/menus.
434
+ // would use preventSelection(), but that prevents selectstart, causing problems.
435
+ mirrorEl.classList.add('fc-unselectable');
436
+ mirrorEl.classList.add('fc-dragging');
437
+ core.applyStyle(mirrorEl, {
438
+ position: 'fixed',
439
+ zIndex: this.zIndex,
440
+ visibility: '',
441
+ boxSizing: 'border-box',
442
+ width: sourceElRect.right - sourceElRect.left,
443
+ height: sourceElRect.bottom - sourceElRect.top,
444
+ right: 'auto',
445
+ bottom: 'auto',
446
+ margin: 0
447
+ });
448
+ this.parentNode.appendChild(mirrorEl);
449
+ }
450
+ return mirrorEl;
451
+ };
452
+ return ElementMirror;
453
+ }());
454
+
455
+ /*
456
+ Is a cache for a given element's scroll information (all the info that ScrollController stores)
457
+ in addition the "client rectangle" of the element.. the area within the scrollbars.
458
+
459
+ The cache can be in one of two modes:
460
+ - doesListening:false - ignores when the container is scrolled by someone else
461
+ - doesListening:true - watch for scrolling and update the cache
462
+ */
463
+ var ScrollGeomCache = /** @class */ (function (_super) {
464
+ __extends(ScrollGeomCache, _super);
465
+ function ScrollGeomCache(scrollController, doesListening) {
466
+ var _this = _super.call(this) || this;
467
+ _this.handleScroll = function () {
468
+ _this.scrollTop = _this.scrollController.getScrollTop();
469
+ _this.scrollLeft = _this.scrollController.getScrollLeft();
470
+ _this.handleScrollChange();
471
+ };
472
+ _this.scrollController = scrollController;
473
+ _this.doesListening = doesListening;
474
+ _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
475
+ _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
476
+ _this.scrollWidth = scrollController.getScrollWidth();
477
+ _this.scrollHeight = scrollController.getScrollHeight();
478
+ _this.clientWidth = scrollController.getClientWidth();
479
+ _this.clientHeight = scrollController.getClientHeight();
480
+ _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
481
+ if (_this.doesListening) {
482
+ _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
483
+ }
484
+ return _this;
485
+ }
486
+ ScrollGeomCache.prototype.destroy = function () {
487
+ if (this.doesListening) {
488
+ this.getEventTarget().removeEventListener('scroll', this.handleScroll);
489
+ }
490
+ };
491
+ ScrollGeomCache.prototype.getScrollTop = function () {
492
+ return this.scrollTop;
493
+ };
494
+ ScrollGeomCache.prototype.getScrollLeft = function () {
495
+ return this.scrollLeft;
496
+ };
497
+ ScrollGeomCache.prototype.setScrollTop = function (top) {
498
+ this.scrollController.setScrollTop(top);
499
+ if (!this.doesListening) {
500
+ // we are not relying on the element to normalize out-of-bounds scroll values
501
+ // so we need to sanitize ourselves
502
+ this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
503
+ this.handleScrollChange();
504
+ }
505
+ };
506
+ ScrollGeomCache.prototype.setScrollLeft = function (top) {
507
+ this.scrollController.setScrollLeft(top);
508
+ if (!this.doesListening) {
509
+ // we are not relying on the element to normalize out-of-bounds scroll values
510
+ // so we need to sanitize ourselves
511
+ this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
512
+ this.handleScrollChange();
513
+ }
514
+ };
515
+ ScrollGeomCache.prototype.getClientWidth = function () {
516
+ return this.clientWidth;
517
+ };
518
+ ScrollGeomCache.prototype.getClientHeight = function () {
519
+ return this.clientHeight;
520
+ };
521
+ ScrollGeomCache.prototype.getScrollWidth = function () {
522
+ return this.scrollWidth;
523
+ };
524
+ ScrollGeomCache.prototype.getScrollHeight = function () {
525
+ return this.scrollHeight;
526
+ };
527
+ ScrollGeomCache.prototype.handleScrollChange = function () {
528
+ };
529
+ return ScrollGeomCache;
530
+ }(core.ScrollController));
531
+ var ElementScrollGeomCache = /** @class */ (function (_super) {
532
+ __extends(ElementScrollGeomCache, _super);
533
+ function ElementScrollGeomCache(el, doesListening) {
534
+ return _super.call(this, new core.ElementScrollController(el), doesListening) || this;
535
+ }
536
+ ElementScrollGeomCache.prototype.getEventTarget = function () {
537
+ return this.scrollController.el;
538
+ };
539
+ ElementScrollGeomCache.prototype.computeClientRect = function () {
540
+ return core.computeInnerRect(this.scrollController.el);
541
+ };
542
+ return ElementScrollGeomCache;
543
+ }(ScrollGeomCache));
544
+ var WindowScrollGeomCache = /** @class */ (function (_super) {
545
+ __extends(WindowScrollGeomCache, _super);
546
+ function WindowScrollGeomCache(doesListening) {
547
+ return _super.call(this, new core.WindowScrollController(), doesListening) || this;
548
+ }
549
+ WindowScrollGeomCache.prototype.getEventTarget = function () {
550
+ return window;
551
+ };
552
+ WindowScrollGeomCache.prototype.computeClientRect = function () {
553
+ return {
554
+ left: this.scrollLeft,
555
+ right: this.scrollLeft + this.clientWidth,
556
+ top: this.scrollTop,
557
+ bottom: this.scrollTop + this.clientHeight
558
+ };
559
+ };
560
+ // the window is the only scroll object that changes it's rectangle relative
561
+ // to the document's topleft as it scrolls
562
+ WindowScrollGeomCache.prototype.handleScrollChange = function () {
563
+ this.clientRect = this.computeClientRect();
564
+ };
565
+ return WindowScrollGeomCache;
566
+ }(ScrollGeomCache));
567
+
568
+ // If available we are using native "performance" API instead of "Date"
569
+ // Read more about it on MDN:
570
+ // https://developer.mozilla.org/en-US/docs/Web/API/Performance
571
+ var getTime = typeof performance === 'function' ? performance.now : Date.now;
572
+ /*
573
+ For a pointer interaction, automatically scrolls certain scroll containers when the pointer
574
+ approaches the edge.
575
+
576
+ The caller must call start + handleMove + stop.
577
+ */
578
+ var AutoScroller = /** @class */ (function () {
579
+ function AutoScroller() {
580
+ var _this = this;
581
+ // options that can be set by caller
582
+ this.isEnabled = true;
583
+ this.scrollQuery = [window, '.fc-scroller'];
584
+ this.edgeThreshold = 50; // pixels
585
+ this.maxVelocity = 300; // pixels per second
586
+ // internal state
587
+ this.pointerScreenX = null;
588
+ this.pointerScreenY = null;
589
+ this.isAnimating = false;
590
+ this.scrollCaches = null;
591
+ // protect against the initial pointerdown being too close to an edge and starting the scroll
592
+ this.everMovedUp = false;
593
+ this.everMovedDown = false;
594
+ this.everMovedLeft = false;
595
+ this.everMovedRight = false;
596
+ this.animate = function () {
597
+ if (_this.isAnimating) { // wasn't cancelled between animation calls
598
+ var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
599
+ if (edge) {
600
+ var now = getTime();
601
+ _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
602
+ _this.requestAnimation(now);
603
+ }
604
+ else {
605
+ _this.isAnimating = false; // will stop animation
606
+ }
607
+ }
608
+ };
609
+ }
610
+ AutoScroller.prototype.start = function (pageX, pageY) {
611
+ if (this.isEnabled) {
612
+ this.scrollCaches = this.buildCaches();
613
+ this.pointerScreenX = null;
614
+ this.pointerScreenY = null;
615
+ this.everMovedUp = false;
616
+ this.everMovedDown = false;
617
+ this.everMovedLeft = false;
618
+ this.everMovedRight = false;
619
+ this.handleMove(pageX, pageY);
620
+ }
621
+ };
622
+ AutoScroller.prototype.handleMove = function (pageX, pageY) {
623
+ if (this.isEnabled) {
624
+ var pointerScreenX = pageX - window.pageXOffset;
625
+ var pointerScreenY = pageY - window.pageYOffset;
626
+ var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
627
+ var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
628
+ if (yDelta < 0) {
629
+ this.everMovedUp = true;
630
+ }
631
+ else if (yDelta > 0) {
632
+ this.everMovedDown = true;
633
+ }
634
+ if (xDelta < 0) {
635
+ this.everMovedLeft = true;
636
+ }
637
+ else if (xDelta > 0) {
638
+ this.everMovedRight = true;
639
+ }
640
+ this.pointerScreenX = pointerScreenX;
641
+ this.pointerScreenY = pointerScreenY;
642
+ if (!this.isAnimating) {
643
+ this.isAnimating = true;
644
+ this.requestAnimation(getTime());
645
+ }
646
+ }
647
+ };
648
+ AutoScroller.prototype.stop = function () {
649
+ if (this.isEnabled) {
650
+ this.isAnimating = false; // will stop animation
651
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
652
+ var scrollCache = _a[_i];
653
+ scrollCache.destroy();
654
+ }
655
+ this.scrollCaches = null;
656
+ }
657
+ };
658
+ AutoScroller.prototype.requestAnimation = function (now) {
659
+ this.msSinceRequest = now;
660
+ requestAnimationFrame(this.animate);
661
+ };
662
+ AutoScroller.prototype.handleSide = function (edge, seconds) {
663
+ var scrollCache = edge.scrollCache;
664
+ var edgeThreshold = this.edgeThreshold;
665
+ var invDistance = edgeThreshold - edge.distance;
666
+ var velocity = // the closer to the edge, the faster we scroll
667
+ (invDistance * invDistance) / (edgeThreshold * edgeThreshold) * // quadratic
668
+ this.maxVelocity * seconds;
669
+ var sign = 1;
670
+ switch (edge.name) {
671
+ case 'left':
672
+ sign = -1;
673
+ // falls through
674
+ case 'right':
675
+ scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
676
+ break;
677
+ case 'top':
678
+ sign = -1;
679
+ // falls through
680
+ case 'bottom':
681
+ scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
682
+ break;
683
+ }
684
+ };
685
+ // left/top are relative to document topleft
686
+ AutoScroller.prototype.computeBestEdge = function (left, top) {
687
+ var edgeThreshold = this.edgeThreshold;
688
+ var bestSide = null;
689
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
690
+ var scrollCache = _a[_i];
691
+ var rect = scrollCache.clientRect;
692
+ var leftDist = left - rect.left;
693
+ var rightDist = rect.right - left;
694
+ var topDist = top - rect.top;
695
+ var bottomDist = rect.bottom - top;
696
+ // completely within the rect?
697
+ if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
698
+ if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
699
+ (!bestSide || bestSide.distance > topDist)) {
700
+ bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
701
+ }
702
+ if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
703
+ (!bestSide || bestSide.distance > bottomDist)) {
704
+ bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
705
+ }
706
+ if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
707
+ (!bestSide || bestSide.distance > leftDist)) {
708
+ bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
709
+ }
710
+ if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
711
+ (!bestSide || bestSide.distance > rightDist)) {
712
+ bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
713
+ }
714
+ }
715
+ }
716
+ return bestSide;
717
+ };
718
+ AutoScroller.prototype.buildCaches = function () {
719
+ return this.queryScrollEls().map(function (el) {
720
+ if (el === window) {
721
+ return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
722
+ }
723
+ else {
724
+ return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
725
+ }
726
+ });
727
+ };
728
+ AutoScroller.prototype.queryScrollEls = function () {
729
+ var els = [];
730
+ for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
731
+ var query = _a[_i];
732
+ if (typeof query === 'object') {
733
+ els.push(query);
734
+ }
735
+ else {
736
+ els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query)));
737
+ }
738
+ }
739
+ return els;
740
+ };
741
+ return AutoScroller;
742
+ }());
743
+
744
+ /*
745
+ Monitors dragging on an element. Has a number of high-level features:
746
+ - minimum distance required before dragging
747
+ - minimum wait time ("delay") before dragging
748
+ - a mirror element that follows the pointer
749
+ */
750
+ var FeaturefulElementDragging = /** @class */ (function (_super) {
751
+ __extends(FeaturefulElementDragging, _super);
752
+ function FeaturefulElementDragging(containerEl) {
753
+ var _this = _super.call(this, containerEl) || this;
754
+ // options that can be directly set by caller
755
+ // the caller can also set the PointerDragging's options as well
756
+ _this.delay = null;
757
+ _this.minDistance = 0;
758
+ _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
759
+ _this.mirrorNeedsRevert = false;
760
+ _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
761
+ _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
762
+ _this.isDelayEnded = false;
763
+ _this.isDistanceSurpassed = false;
764
+ _this.delayTimeoutId = null;
765
+ _this.onPointerDown = function (ev) {
766
+ if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
767
+ _this.isInteracting = true;
768
+ _this.isDelayEnded = false;
769
+ _this.isDistanceSurpassed = false;
770
+ core.preventSelection(document.body);
771
+ core.preventContextMenu(document.body);
772
+ // prevent links from being visited if there's an eventual drag.
773
+ // also prevents selection in older browsers (maybe?).
774
+ // not necessary for touch, besides, browser would complain about passiveness.
775
+ if (!ev.isTouch) {
776
+ ev.origEvent.preventDefault();
777
+ }
778
+ _this.emitter.trigger('pointerdown', ev);
779
+ if (!_this.pointer.shouldIgnoreMove) {
780
+ // actions related to initiating dragstart+dragmove+dragend...
781
+ _this.mirror.setIsVisible(false); // reset. caller must set-visible
782
+ _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
783
+ _this.startDelay(ev);
784
+ if (!_this.minDistance) {
785
+ _this.handleDistanceSurpassed(ev);
786
+ }
787
+ }
788
+ }
789
+ };
790
+ _this.onPointerMove = function (ev) {
791
+ if (_this.isInteracting) { // if false, still waiting for previous drag's revert
792
+ _this.emitter.trigger('pointermove', ev);
793
+ if (!_this.isDistanceSurpassed) {
794
+ var minDistance = _this.minDistance;
795
+ var distanceSq = void 0; // current distance from the origin, squared
796
+ var deltaX = ev.deltaX, deltaY = ev.deltaY;
797
+ distanceSq = deltaX * deltaX + deltaY * deltaY;
798
+ if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
799
+ _this.handleDistanceSurpassed(ev);
800
+ }
801
+ }
802
+ if (_this.isDragging) {
803
+ // a real pointer move? (not one simulated by scrolling)
804
+ if (ev.origEvent.type !== 'scroll') {
805
+ _this.mirror.handleMove(ev.pageX, ev.pageY);
806
+ _this.autoScroller.handleMove(ev.pageX, ev.pageY);
807
+ }
808
+ _this.emitter.trigger('dragmove', ev);
809
+ }
810
+ }
811
+ };
812
+ _this.onPointerUp = function (ev) {
813
+ if (_this.isInteracting) { // if false, still waiting for previous drag's revert
814
+ _this.isInteracting = false;
815
+ core.allowSelection(document.body);
816
+ core.allowContextMenu(document.body);
817
+ _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
818
+ if (_this.isDragging) {
819
+ _this.autoScroller.stop();
820
+ _this.tryStopDrag(ev); // which will stop the mirror
821
+ }
822
+ if (_this.delayTimeoutId) {
823
+ clearTimeout(_this.delayTimeoutId);
824
+ _this.delayTimeoutId = null;
825
+ }
826
+ }
827
+ };
828
+ var pointer = _this.pointer = new PointerDragging(containerEl);
829
+ pointer.emitter.on('pointerdown', _this.onPointerDown);
830
+ pointer.emitter.on('pointermove', _this.onPointerMove);
831
+ pointer.emitter.on('pointerup', _this.onPointerUp);
832
+ _this.mirror = new ElementMirror();
833
+ _this.autoScroller = new AutoScroller();
834
+ return _this;
835
+ }
836
+ FeaturefulElementDragging.prototype.destroy = function () {
837
+ this.pointer.destroy();
838
+ };
839
+ FeaturefulElementDragging.prototype.startDelay = function (ev) {
840
+ var _this = this;
841
+ if (typeof this.delay === 'number') {
842
+ this.delayTimeoutId = setTimeout(function () {
843
+ _this.delayTimeoutId = null;
844
+ _this.handleDelayEnd(ev);
845
+ }, this.delay);
846
+ }
847
+ else {
848
+ this.handleDelayEnd(ev);
849
+ }
850
+ };
851
+ FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
852
+ this.isDelayEnded = true;
853
+ this.tryStartDrag(ev);
854
+ };
855
+ FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
856
+ this.isDistanceSurpassed = true;
857
+ this.tryStartDrag(ev);
858
+ };
859
+ FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
860
+ if (this.isDelayEnded && this.isDistanceSurpassed) {
861
+ if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
862
+ this.isDragging = true;
863
+ this.mirrorNeedsRevert = false;
864
+ this.autoScroller.start(ev.pageX, ev.pageY);
865
+ this.emitter.trigger('dragstart', ev);
866
+ if (this.touchScrollAllowed === false) {
867
+ this.pointer.cancelTouchScroll();
868
+ }
869
+ }
870
+ }
871
+ };
872
+ FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
873
+ // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
874
+ // that come from the document to fire beforehand. much more convenient this way.
875
+ this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev) // bound with args
876
+ );
877
+ };
878
+ FeaturefulElementDragging.prototype.stopDrag = function (ev) {
879
+ this.isDragging = false;
880
+ this.emitter.trigger('dragend', ev);
881
+ };
882
+ // fill in the implementations...
883
+ FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
884
+ this.pointer.shouldIgnoreMove = bool;
885
+ };
886
+ FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
887
+ this.mirror.setIsVisible(bool);
888
+ };
889
+ FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
890
+ this.mirrorNeedsRevert = bool;
891
+ };
892
+ FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
893
+ this.autoScroller.isEnabled = bool;
894
+ };
895
+ return FeaturefulElementDragging;
896
+ }(core.ElementDragging));
897
+
898
+ /*
899
+ When this class is instantiated, it records the offset of an element (relative to the document topleft),
900
+ and continues to monitor scrolling, updating the cached coordinates if it needs to.
901
+ Does not access the DOM after instantiation, so highly performant.
902
+
903
+ Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
904
+ and an determine if a given point is inside the combined clipping rectangle.
905
+ */
906
+ var OffsetTracker = /** @class */ (function () {
907
+ function OffsetTracker(el) {
908
+ this.origRect = core.computeRect(el);
909
+ // will work fine for divs that have overflow:hidden
910
+ this.scrollCaches = core.getClippingParents(el).map(function (el) {
911
+ return new ElementScrollGeomCache(el, true); // listen=true
912
+ });
913
+ }
914
+ OffsetTracker.prototype.destroy = function () {
915
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
916
+ var scrollCache = _a[_i];
917
+ scrollCache.destroy();
918
+ }
919
+ };
920
+ OffsetTracker.prototype.computeLeft = function () {
921
+ var left = this.origRect.left;
922
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
923
+ var scrollCache = _a[_i];
924
+ left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
925
+ }
926
+ return left;
927
+ };
928
+ OffsetTracker.prototype.computeTop = function () {
929
+ var top = this.origRect.top;
930
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
931
+ var scrollCache = _a[_i];
932
+ top += scrollCache.origScrollTop - scrollCache.getScrollTop();
933
+ }
934
+ return top;
935
+ };
936
+ OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
937
+ var point = { left: pageX, top: pageY };
938
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
939
+ var scrollCache = _a[_i];
940
+ if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
941
+ !core.pointInsideRect(point, scrollCache.clientRect)) {
942
+ return false;
943
+ }
944
+ }
945
+ return true;
946
+ };
947
+ return OffsetTracker;
948
+ }());
949
+ // certain clipping containers should never constrain interactions, like <html> and <body>
950
+ // https://github.com/fullcalendar/fullcalendar/issues/3615
951
+ function isIgnoredClipping(node) {
952
+ var tagName = node.tagName;
953
+ return tagName === 'HTML' || tagName === 'BODY';
954
+ }
955
+
956
+ /*
957
+ Tracks movement over multiple droppable areas (aka "hits")
958
+ that exist in one or more DateComponents.
959
+ Relies on an existing draggable.
960
+
961
+ emits:
962
+ - pointerdown
963
+ - dragstart
964
+ - hitchange - fires initially, even if not over a hit
965
+ - pointerup
966
+ - (hitchange - again, to null, if ended over a hit)
967
+ - dragend
968
+ */
969
+ var HitDragging = /** @class */ (function () {
970
+ function HitDragging(dragging, droppableStore) {
971
+ var _this = this;
972
+ // options that can be set by caller
973
+ this.useSubjectCenter = false;
974
+ this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
975
+ this.initialHit = null;
976
+ this.movingHit = null;
977
+ this.finalHit = null; // won't ever be populated if shouldIgnoreMove
978
+ this.handlePointerDown = function (ev) {
979
+ var dragging = _this.dragging;
980
+ _this.initialHit = null;
981
+ _this.movingHit = null;
982
+ _this.finalHit = null;
983
+ _this.prepareHits();
984
+ _this.processFirstCoord(ev);
985
+ if (_this.initialHit || !_this.requireInitial) {
986
+ dragging.setIgnoreMove(false);
987
+ _this.emitter.trigger('pointerdown', ev); // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
988
+ }
989
+ else {
990
+ dragging.setIgnoreMove(true);
991
+ }
992
+ };
993
+ this.handleDragStart = function (ev) {
994
+ _this.emitter.trigger('dragstart', ev);
995
+ _this.handleMove(ev, true); // force = fire even if initially null
996
+ };
997
+ this.handleDragMove = function (ev) {
998
+ _this.emitter.trigger('dragmove', ev);
999
+ _this.handleMove(ev);
1000
+ };
1001
+ this.handlePointerUp = function (ev) {
1002
+ _this.releaseHits();
1003
+ _this.emitter.trigger('pointerup', ev);
1004
+ };
1005
+ this.handleDragEnd = function (ev) {
1006
+ if (_this.movingHit) {
1007
+ _this.emitter.trigger('hitupdate', null, true, ev);
1008
+ }
1009
+ _this.finalHit = _this.movingHit;
1010
+ _this.movingHit = null;
1011
+ _this.emitter.trigger('dragend', ev);
1012
+ };
1013
+ this.droppableStore = droppableStore;
1014
+ dragging.emitter.on('pointerdown', this.handlePointerDown);
1015
+ dragging.emitter.on('dragstart', this.handleDragStart);
1016
+ dragging.emitter.on('dragmove', this.handleDragMove);
1017
+ dragging.emitter.on('pointerup', this.handlePointerUp);
1018
+ dragging.emitter.on('dragend', this.handleDragEnd);
1019
+ this.dragging = dragging;
1020
+ this.emitter = new core.EmitterMixin();
1021
+ }
1022
+ // sets initialHit
1023
+ // sets coordAdjust
1024
+ HitDragging.prototype.processFirstCoord = function (ev) {
1025
+ var origPoint = { left: ev.pageX, top: ev.pageY };
1026
+ var adjustedPoint = origPoint;
1027
+ var subjectEl = ev.subjectEl;
1028
+ var subjectRect;
1029
+ if (subjectEl !== document) {
1030
+ subjectRect = core.computeRect(subjectEl);
1031
+ adjustedPoint = core.constrainPoint(adjustedPoint, subjectRect);
1032
+ }
1033
+ var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
1034
+ if (initialHit) {
1035
+ if (this.useSubjectCenter && subjectRect) {
1036
+ var slicedSubjectRect = core.intersectRects(subjectRect, initialHit.rect);
1037
+ if (slicedSubjectRect) {
1038
+ adjustedPoint = core.getRectCenter(slicedSubjectRect);
1039
+ }
1040
+ }
1041
+ this.coordAdjust = core.diffPoints(adjustedPoint, origPoint);
1042
+ }
1043
+ else {
1044
+ this.coordAdjust = { left: 0, top: 0 };
1045
+ }
1046
+ };
1047
+ HitDragging.prototype.handleMove = function (ev, forceHandle) {
1048
+ var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
1049
+ if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
1050
+ this.movingHit = hit;
1051
+ this.emitter.trigger('hitupdate', hit, false, ev);
1052
+ }
1053
+ };
1054
+ HitDragging.prototype.prepareHits = function () {
1055
+ this.offsetTrackers = core.mapHash(this.droppableStore, function (interactionSettings) {
1056
+ return new OffsetTracker(interactionSettings.el);
1057
+ });
1058
+ };
1059
+ HitDragging.prototype.releaseHits = function () {
1060
+ var offsetTrackers = this.offsetTrackers;
1061
+ for (var id in offsetTrackers) {
1062
+ offsetTrackers[id].destroy();
1063
+ }
1064
+ this.offsetTrackers = {};
1065
+ };
1066
+ HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
1067
+ var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
1068
+ var bestHit = null;
1069
+ for (var id in droppableStore) {
1070
+ var component = droppableStore[id].component;
1071
+ var offsetTracker = offsetTrackers[id];
1072
+ if (offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
1073
+ var originLeft = offsetTracker.computeLeft();
1074
+ var originTop = offsetTracker.computeTop();
1075
+ var positionLeft = offsetLeft - originLeft;
1076
+ var positionTop = offsetTop - originTop;
1077
+ var origRect = offsetTracker.origRect;
1078
+ var width = origRect.right - origRect.left;
1079
+ var height = origRect.bottom - origRect.top;
1080
+ if (
1081
+ // must be within the element's bounds
1082
+ positionLeft >= 0 && positionLeft < width &&
1083
+ positionTop >= 0 && positionTop < height) {
1084
+ var hit = component.queryHit(positionLeft, positionTop, width, height);
1085
+ if (hit &&
1086
+ (
1087
+ // make sure the hit is within activeRange, meaning it's not a deal cell
1088
+ !component.props.dateProfile || // hack for DayTile
1089
+ core.rangeContainsRange(component.props.dateProfile.activeRange, hit.dateSpan.range)) &&
1090
+ (!bestHit || hit.layer > bestHit.layer)) {
1091
+ // TODO: better way to re-orient rectangle
1092
+ hit.rect.left += originLeft;
1093
+ hit.rect.right += originLeft;
1094
+ hit.rect.top += originTop;
1095
+ hit.rect.bottom += originTop;
1096
+ bestHit = hit;
1097
+ }
1098
+ }
1099
+ }
1100
+ }
1101
+ return bestHit;
1102
+ };
1103
+ return HitDragging;
1104
+ }());
1105
+ function isHitsEqual(hit0, hit1) {
1106
+ if (!hit0 && !hit1) {
1107
+ return true;
1108
+ }
1109
+ if (Boolean(hit0) !== Boolean(hit1)) {
1110
+ return false;
1111
+ }
1112
+ return core.isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
1113
+ }
1114
+
1115
+ /*
1116
+ Monitors when the user clicks on a specific date/time of a component.
1117
+ A pointerdown+pointerup on the same "hit" constitutes a click.
1118
+ */
1119
+ var DateClicking = /** @class */ (function (_super) {
1120
+ __extends(DateClicking, _super);
1121
+ function DateClicking(settings) {
1122
+ var _this = _super.call(this, settings) || this;
1123
+ _this.handlePointerDown = function (ev) {
1124
+ var dragging = _this.dragging;
1125
+ // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
1126
+ dragging.setIgnoreMove(!_this.component.isValidDateDownEl(dragging.pointer.downEl));
1127
+ };
1128
+ // won't even fire if moving was ignored
1129
+ _this.handleDragEnd = function (ev) {
1130
+ var component = _this.component;
1131
+ var pointer = _this.dragging.pointer;
1132
+ if (!pointer.wasTouchScroll) {
1133
+ var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
1134
+ if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
1135
+ component.calendar.triggerDateClick(initialHit.dateSpan, initialHit.dayEl, component.view, ev.origEvent);
1136
+ }
1137
+ }
1138
+ };
1139
+ var component = settings.component;
1140
+ // we DO want to watch pointer moves because otherwise finalHit won't get populated
1141
+ _this.dragging = new FeaturefulElementDragging(component.el);
1142
+ _this.dragging.autoScroller.isEnabled = false;
1143
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
1144
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1145
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
1146
+ return _this;
1147
+ }
1148
+ DateClicking.prototype.destroy = function () {
1149
+ this.dragging.destroy();
1150
+ };
1151
+ return DateClicking;
1152
+ }(core.Interaction));
1153
+
1154
+ /*
1155
+ Tracks when the user selects a portion of time of a component,
1156
+ constituted by a drag over date cells, with a possible delay at the beginning of the drag.
1157
+ */
1158
+ var DateSelecting = /** @class */ (function (_super) {
1159
+ __extends(DateSelecting, _super);
1160
+ function DateSelecting(settings) {
1161
+ var _this = _super.call(this, settings) || this;
1162
+ _this.dragSelection = null;
1163
+ _this.handlePointerDown = function (ev) {
1164
+ var _a = _this, component = _a.component, dragging = _a.dragging;
1165
+ var canSelect = component.opt('selectable') &&
1166
+ component.isValidDateDownEl(ev.origEvent.target);
1167
+ // don't bother to watch expensive moves if component won't do selection
1168
+ dragging.setIgnoreMove(!canSelect);
1169
+ // if touch, require user to hold down
1170
+ dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null;
1171
+ };
1172
+ _this.handleDragStart = function (ev) {
1173
+ _this.component.calendar.unselect(ev); // unselect previous selections
1174
+ };
1175
+ _this.handleHitUpdate = function (hit, isFinal) {
1176
+ var calendar = _this.component.calendar;
1177
+ var dragSelection = null;
1178
+ var isInvalid = false;
1179
+ if (hit) {
1180
+ dragSelection = joinHitsIntoSelection(_this.hitDragging.initialHit, hit, calendar.pluginSystem.hooks.dateSelectionTransformers);
1181
+ if (!dragSelection || !_this.component.isDateSelectionValid(dragSelection)) {
1182
+ isInvalid = true;
1183
+ dragSelection = null;
1184
+ }
1185
+ }
1186
+ if (dragSelection) {
1187
+ calendar.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
1188
+ }
1189
+ else if (!isFinal) { // only unselect if moved away while dragging
1190
+ calendar.dispatch({ type: 'UNSELECT_DATES' });
1191
+ }
1192
+ if (!isInvalid) {
1193
+ core.enableCursor();
1194
+ }
1195
+ else {
1196
+ core.disableCursor();
1197
+ }
1198
+ if (!isFinal) {
1199
+ _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
1200
+ }
1201
+ };
1202
+ _this.handlePointerUp = function (pev) {
1203
+ if (_this.dragSelection) {
1204
+ // selection is already rendered, so just need to report selection
1205
+ _this.component.calendar.triggerDateSelect(_this.dragSelection, pev);
1206
+ _this.dragSelection = null;
1207
+ }
1208
+ };
1209
+ var component = settings.component;
1210
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
1211
+ dragging.touchScrollAllowed = false;
1212
+ dragging.minDistance = component.opt('selectMinDistance') || 0;
1213
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
1214
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
1215
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1216
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
1217
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
1218
+ hitDragging.emitter.on('pointerup', _this.handlePointerUp);
1219
+ return _this;
1220
+ }
1221
+ DateSelecting.prototype.destroy = function () {
1222
+ this.dragging.destroy();
1223
+ };
1224
+ return DateSelecting;
1225
+ }(core.Interaction));
1226
+ function getComponentTouchDelay(component) {
1227
+ var delay = component.opt('selectLongPressDelay');
1228
+ if (delay == null) {
1229
+ delay = component.opt('longPressDelay');
1230
+ }
1231
+ return delay;
1232
+ }
1233
+ function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
1234
+ var dateSpan0 = hit0.dateSpan;
1235
+ var dateSpan1 = hit1.dateSpan;
1236
+ var ms = [
1237
+ dateSpan0.range.start,
1238
+ dateSpan0.range.end,
1239
+ dateSpan1.range.start,
1240
+ dateSpan1.range.end
1241
+ ];
1242
+ ms.sort(core.compareNumbers);
1243
+ var props = {};
1244
+ for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
1245
+ var transformer = dateSelectionTransformers_1[_i];
1246
+ var res = transformer(hit0, hit1);
1247
+ if (res === false) {
1248
+ return null;
1249
+ }
1250
+ else if (res) {
1251
+ __assign(props, res);
1252
+ }
1253
+ }
1254
+ props.range = { start: ms[0], end: ms[3] };
1255
+ props.allDay = dateSpan0.allDay;
1256
+ return props;
1257
+ }
1258
+
1259
+ var EventDragging = /** @class */ (function (_super) {
1260
+ __extends(EventDragging, _super);
1261
+ function EventDragging(settings) {
1262
+ var _this = _super.call(this, settings) || this;
1263
+ // internal state
1264
+ _this.subjectSeg = null; // the seg being selected/dragged
1265
+ _this.isDragging = false;
1266
+ _this.eventRange = null;
1267
+ _this.relevantEvents = null; // the events being dragged
1268
+ _this.receivingCalendar = null;
1269
+ _this.validMutation = null;
1270
+ _this.mutatedRelevantEvents = null;
1271
+ _this.handlePointerDown = function (ev) {
1272
+ var origTarget = ev.origEvent.target;
1273
+ var _a = _this, component = _a.component, dragging = _a.dragging;
1274
+ var mirror = dragging.mirror;
1275
+ var initialCalendar = component.calendar;
1276
+ var subjectSeg = _this.subjectSeg = core.getElSeg(ev.subjectEl);
1277
+ var eventRange = _this.eventRange = subjectSeg.eventRange;
1278
+ var eventInstanceId = eventRange.instance.instanceId;
1279
+ _this.relevantEvents = core.getRelevantEvents(initialCalendar.state.eventStore, eventInstanceId);
1280
+ dragging.minDistance = ev.isTouch ? 0 : component.opt('eventDragMinDistance');
1281
+ dragging.delay =
1282
+ // only do a touch delay if touch and this event hasn't been selected yet
1283
+ (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
1284
+ getComponentTouchDelay$1(component) :
1285
+ null;
1286
+ mirror.parentNode = initialCalendar.el;
1287
+ mirror.revertDuration = component.opt('dragRevertDuration');
1288
+ var isValid = component.isValidSegDownEl(origTarget) &&
1289
+ !core.elementClosest(origTarget, '.fc-resizer');
1290
+ dragging.setIgnoreMove(!isValid);
1291
+ // disable dragging for elements that are resizable (ie, selectable)
1292
+ // but are not draggable
1293
+ _this.isDragging = isValid &&
1294
+ ev.subjectEl.classList.contains('fc-draggable');
1295
+ };
1296
+ _this.handleDragStart = function (ev) {
1297
+ var initialCalendar = _this.component.calendar;
1298
+ var eventRange = _this.eventRange;
1299
+ var eventInstanceId = eventRange.instance.instanceId;
1300
+ if (ev.isTouch) {
1301
+ // need to select a different event?
1302
+ if (eventInstanceId !== _this.component.props.eventSelection) {
1303
+ initialCalendar.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
1304
+ }
1305
+ }
1306
+ else {
1307
+ // if now using mouse, but was previous touch interaction, clear selected event
1308
+ initialCalendar.dispatch({ type: 'UNSELECT_EVENT' });
1309
+ }
1310
+ if (_this.isDragging) {
1311
+ initialCalendar.unselect(ev); // unselect *date* selection
1312
+ initialCalendar.publiclyTrigger('eventDragStart', [
1313
+ {
1314
+ el: _this.subjectSeg.el,
1315
+ event: new core.EventApi(initialCalendar, eventRange.def, eventRange.instance),
1316
+ jsEvent: ev.origEvent,
1317
+ view: _this.component.view
1318
+ }
1319
+ ]);
1320
+ }
1321
+ };
1322
+ _this.handleHitUpdate = function (hit, isFinal) {
1323
+ if (!_this.isDragging) {
1324
+ return;
1325
+ }
1326
+ var relevantEvents = _this.relevantEvents;
1327
+ var initialHit = _this.hitDragging.initialHit;
1328
+ var initialCalendar = _this.component.calendar;
1329
+ // states based on new hit
1330
+ var receivingCalendar = null;
1331
+ var mutation = null;
1332
+ var mutatedRelevantEvents = null;
1333
+ var isInvalid = false;
1334
+ var interaction = {
1335
+ affectedEvents: relevantEvents,
1336
+ mutatedEvents: core.createEmptyEventStore(),
1337
+ isEvent: true,
1338
+ origSeg: _this.subjectSeg
1339
+ };
1340
+ if (hit) {
1341
+ var receivingComponent = hit.component;
1342
+ receivingCalendar = receivingComponent.calendar;
1343
+ if (initialCalendar === receivingCalendar ||
1344
+ receivingComponent.opt('editable') && receivingComponent.opt('droppable')) {
1345
+ mutation = computeEventMutation(initialHit, hit, receivingCalendar.pluginSystem.hooks.eventDragMutationMassagers);
1346
+ if (mutation) {
1347
+ mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, receivingCalendar.eventUiBases, mutation, receivingCalendar);
1348
+ interaction.mutatedEvents = mutatedRelevantEvents;
1349
+ if (!receivingComponent.isInteractionValid(interaction)) {
1350
+ isInvalid = true;
1351
+ mutation = null;
1352
+ mutatedRelevantEvents = null;
1353
+ interaction.mutatedEvents = core.createEmptyEventStore();
1354
+ }
1355
+ }
1356
+ }
1357
+ else {
1358
+ receivingCalendar = null;
1359
+ }
1360
+ }
1361
+ _this.displayDrag(receivingCalendar, interaction);
1362
+ if (!isInvalid) {
1363
+ core.enableCursor();
1364
+ }
1365
+ else {
1366
+ core.disableCursor();
1367
+ }
1368
+ if (!isFinal) {
1369
+ if (initialCalendar === receivingCalendar && // TODO: write test for this
1370
+ isHitsEqual(initialHit, hit)) {
1371
+ mutation = null;
1372
+ }
1373
+ _this.dragging.setMirrorNeedsRevert(!mutation);
1374
+ // render the mirror if no already-rendered mirror
1375
+ // TODO: wish we could somehow wait for dispatch to guarantee render
1376
+ _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-mirror'));
1377
+ // assign states based on new hit
1378
+ _this.receivingCalendar = receivingCalendar;
1379
+ _this.validMutation = mutation;
1380
+ _this.mutatedRelevantEvents = mutatedRelevantEvents;
1381
+ }
1382
+ };
1383
+ _this.handlePointerUp = function () {
1384
+ if (!_this.isDragging) {
1385
+ _this.cleanup(); // because handleDragEnd won't fire
1386
+ }
1387
+ };
1388
+ _this.handleDragEnd = function (ev) {
1389
+ if (_this.isDragging) {
1390
+ var initialCalendar_1 = _this.component.calendar;
1391
+ var initialView = _this.component.view;
1392
+ var receivingCalendar = _this.receivingCalendar;
1393
+ var eventDef = _this.eventRange.def;
1394
+ var eventInstance = _this.eventRange.instance;
1395
+ var eventApi = new core.EventApi(initialCalendar_1, eventDef, eventInstance);
1396
+ var relevantEvents_1 = _this.relevantEvents;
1397
+ var mutatedRelevantEvents = _this.mutatedRelevantEvents;
1398
+ var finalHit = _this.hitDragging.finalHit;
1399
+ _this.clearDrag(); // must happen after revert animation
1400
+ initialCalendar_1.publiclyTrigger('eventDragStop', [
1401
+ {
1402
+ el: _this.subjectSeg.el,
1403
+ event: eventApi,
1404
+ jsEvent: ev.origEvent,
1405
+ view: initialView
1406
+ }
1407
+ ]);
1408
+ if (_this.validMutation) {
1409
+ // dropped within same calendar
1410
+ if (receivingCalendar === initialCalendar_1) {
1411
+ initialCalendar_1.dispatch({
1412
+ type: 'MERGE_EVENTS',
1413
+ eventStore: mutatedRelevantEvents
1414
+ });
1415
+ var eventDropArg = {};
1416
+ for (var _i = 0, _a = initialCalendar_1.pluginSystem.hooks.eventDropTransformers; _i < _a.length; _i++) {
1417
+ var transformer = _a[_i];
1418
+ __assign(eventDropArg, transformer(_this.validMutation, initialCalendar_1));
1419
+ }
1420
+ __assign(eventDropArg, {
1421
+ el: ev.subjectEl,
1422
+ delta: _this.validMutation.startDelta,
1423
+ oldEvent: eventApi,
1424
+ event: new core.EventApi(// the data AFTER the mutation
1425
+ initialCalendar_1, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null),
1426
+ revert: function () {
1427
+ initialCalendar_1.dispatch({
1428
+ type: 'MERGE_EVENTS',
1429
+ eventStore: relevantEvents_1
1430
+ });
1431
+ },
1432
+ jsEvent: ev.origEvent,
1433
+ view: initialView
1434
+ });
1435
+ initialCalendar_1.publiclyTrigger('eventDrop', [eventDropArg]);
1436
+ // dropped in different calendar
1437
+ }
1438
+ else if (receivingCalendar) {
1439
+ initialCalendar_1.publiclyTrigger('eventLeave', [
1440
+ {
1441
+ draggedEl: ev.subjectEl,
1442
+ event: eventApi,
1443
+ view: initialView
1444
+ }
1445
+ ]);
1446
+ initialCalendar_1.dispatch({
1447
+ type: 'REMOVE_EVENT_INSTANCES',
1448
+ instances: _this.mutatedRelevantEvents.instances
1449
+ });
1450
+ receivingCalendar.dispatch({
1451
+ type: 'MERGE_EVENTS',
1452
+ eventStore: _this.mutatedRelevantEvents
1453
+ });
1454
+ if (ev.isTouch) {
1455
+ receivingCalendar.dispatch({
1456
+ type: 'SELECT_EVENT',
1457
+ eventInstanceId: eventInstance.instanceId
1458
+ });
1459
+ }
1460
+ var dropArg = receivingCalendar.buildDatePointApi(finalHit.dateSpan);
1461
+ dropArg.draggedEl = ev.subjectEl;
1462
+ dropArg.jsEvent = ev.origEvent;
1463
+ dropArg.view = finalHit.component; // ?
1464
+ receivingCalendar.publiclyTrigger('drop', [dropArg]);
1465
+ receivingCalendar.publiclyTrigger('eventReceive', [
1466
+ {
1467
+ draggedEl: ev.subjectEl,
1468
+ event: new core.EventApi(// the data AFTER the mutation
1469
+ receivingCalendar, mutatedRelevantEvents.defs[eventDef.defId], mutatedRelevantEvents.instances[eventInstance.instanceId]),
1470
+ view: finalHit.component
1471
+ }
1472
+ ]);
1473
+ }
1474
+ }
1475
+ else {
1476
+ initialCalendar_1.publiclyTrigger('_noEventDrop');
1477
+ }
1478
+ }
1479
+ _this.cleanup();
1480
+ };
1481
+ var component = _this.component;
1482
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
1483
+ dragging.pointer.selector = EventDragging.SELECTOR;
1484
+ dragging.touchScrollAllowed = false;
1485
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
1486
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsStore);
1487
+ hitDragging.useSubjectCenter = settings.useEventCenter;
1488
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1489
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
1490
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
1491
+ hitDragging.emitter.on('pointerup', _this.handlePointerUp);
1492
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
1493
+ return _this;
1494
+ }
1495
+ EventDragging.prototype.destroy = function () {
1496
+ this.dragging.destroy();
1497
+ };
1498
+ // render a drag state on the next receivingCalendar
1499
+ EventDragging.prototype.displayDrag = function (nextCalendar, state) {
1500
+ var initialCalendar = this.component.calendar;
1501
+ var prevCalendar = this.receivingCalendar;
1502
+ // does the previous calendar need to be cleared?
1503
+ if (prevCalendar && prevCalendar !== nextCalendar) {
1504
+ // does the initial calendar need to be cleared?
1505
+ // if so, don't clear all the way. we still need to to hide the affectedEvents
1506
+ if (prevCalendar === initialCalendar) {
1507
+ prevCalendar.dispatch({
1508
+ type: 'SET_EVENT_DRAG',
1509
+ state: {
1510
+ affectedEvents: state.affectedEvents,
1511
+ mutatedEvents: core.createEmptyEventStore(),
1512
+ isEvent: true,
1513
+ origSeg: state.origSeg
1514
+ }
1515
+ });
1516
+ // completely clear the old calendar if it wasn't the initial
1517
+ }
1518
+ else {
1519
+ prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1520
+ }
1521
+ }
1522
+ if (nextCalendar) {
1523
+ nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
1524
+ }
1525
+ };
1526
+ EventDragging.prototype.clearDrag = function () {
1527
+ var initialCalendar = this.component.calendar;
1528
+ var receivingCalendar = this.receivingCalendar;
1529
+ if (receivingCalendar) {
1530
+ receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1531
+ }
1532
+ // the initial calendar might have an dummy drag state from displayDrag
1533
+ if (initialCalendar !== receivingCalendar) {
1534
+ initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1535
+ }
1536
+ };
1537
+ EventDragging.prototype.cleanup = function () {
1538
+ this.subjectSeg = null;
1539
+ this.isDragging = false;
1540
+ this.eventRange = null;
1541
+ this.relevantEvents = null;
1542
+ this.receivingCalendar = null;
1543
+ this.validMutation = null;
1544
+ this.mutatedRelevantEvents = null;
1545
+ };
1546
+ EventDragging.SELECTOR = '.fc-draggable, .fc-resizable'; // TODO: test this in IE11
1547
+ return EventDragging;
1548
+ }(core.Interaction));
1549
+ function computeEventMutation(hit0, hit1, massagers) {
1550
+ var dateSpan0 = hit0.dateSpan;
1551
+ var dateSpan1 = hit1.dateSpan;
1552
+ var date0 = dateSpan0.range.start;
1553
+ var date1 = dateSpan1.range.start;
1554
+ var standardProps = {};
1555
+ if (dateSpan0.allDay !== dateSpan1.allDay) {
1556
+ standardProps.allDay = dateSpan1.allDay;
1557
+ standardProps.hasEnd = hit1.component.opt('allDayMaintainDuration');
1558
+ if (dateSpan1.allDay) {
1559
+ // means date1 is already start-of-day,
1560
+ // but date0 needs to be converted
1561
+ date0 = core.startOfDay(date0);
1562
+ }
1563
+ }
1564
+ var delta = core.diffDates(date0, date1, hit0.component.dateEnv, hit0.component === hit1.component ?
1565
+ hit0.component.largeUnit :
1566
+ null);
1567
+ if (delta.milliseconds) { // has hours/minutes/seconds
1568
+ standardProps.allDay = false;
1569
+ }
1570
+ var mutation = {
1571
+ startDelta: delta,
1572
+ endDelta: delta,
1573
+ standardProps: standardProps
1574
+ };
1575
+ for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
1576
+ var massager = massagers_1[_i];
1577
+ massager(mutation, hit0, hit1);
1578
+ }
1579
+ return mutation;
1580
+ }
1581
+ function getComponentTouchDelay$1(component) {
1582
+ var delay = component.opt('eventLongPressDelay');
1583
+ if (delay == null) {
1584
+ delay = component.opt('longPressDelay');
1585
+ }
1586
+ return delay;
1587
+ }
1588
+
1589
+ var EventDragging$1 = /** @class */ (function (_super) {
1590
+ __extends(EventDragging, _super);
1591
+ function EventDragging(settings) {
1592
+ var _this = _super.call(this, settings) || this;
1593
+ // internal state
1594
+ _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
1595
+ _this.eventRange = null;
1596
+ _this.relevantEvents = null;
1597
+ _this.validMutation = null;
1598
+ _this.mutatedRelevantEvents = null;
1599
+ _this.handlePointerDown = function (ev) {
1600
+ var component = _this.component;
1601
+ var seg = _this.querySeg(ev);
1602
+ var eventRange = _this.eventRange = seg.eventRange;
1603
+ _this.dragging.minDistance = component.opt('eventDragMinDistance');
1604
+ // if touch, need to be working with a selected event
1605
+ _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
1606
+ (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
1607
+ };
1608
+ _this.handleDragStart = function (ev) {
1609
+ var calendar = _this.component.calendar;
1610
+ var eventRange = _this.eventRange;
1611
+ _this.relevantEvents = core.getRelevantEvents(calendar.state.eventStore, _this.eventRange.instance.instanceId);
1612
+ _this.draggingSeg = _this.querySeg(ev);
1613
+ calendar.unselect();
1614
+ calendar.publiclyTrigger('eventResizeStart', [
1615
+ {
1616
+ el: _this.draggingSeg.el,
1617
+ event: new core.EventApi(calendar, eventRange.def, eventRange.instance),
1618
+ jsEvent: ev.origEvent,
1619
+ view: _this.component.view
1620
+ }
1621
+ ]);
1622
+ };
1623
+ _this.handleHitUpdate = function (hit, isFinal, ev) {
1624
+ var calendar = _this.component.calendar;
1625
+ var relevantEvents = _this.relevantEvents;
1626
+ var initialHit = _this.hitDragging.initialHit;
1627
+ var eventInstance = _this.eventRange.instance;
1628
+ var mutation = null;
1629
+ var mutatedRelevantEvents = null;
1630
+ var isInvalid = false;
1631
+ var interaction = {
1632
+ affectedEvents: relevantEvents,
1633
+ mutatedEvents: core.createEmptyEventStore(),
1634
+ isEvent: true,
1635
+ origSeg: _this.draggingSeg
1636
+ };
1637
+ if (hit) {
1638
+ mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-start-resizer'), eventInstance.range, calendar.pluginSystem.hooks.eventResizeJoinTransforms);
1639
+ }
1640
+ if (mutation) {
1641
+ mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, calendar.eventUiBases, mutation, calendar);
1642
+ interaction.mutatedEvents = mutatedRelevantEvents;
1643
+ if (!_this.component.isInteractionValid(interaction)) {
1644
+ isInvalid = true;
1645
+ mutation = null;
1646
+ mutatedRelevantEvents = null;
1647
+ interaction.mutatedEvents = null;
1648
+ }
1649
+ }
1650
+ if (mutatedRelevantEvents) {
1651
+ calendar.dispatch({
1652
+ type: 'SET_EVENT_RESIZE',
1653
+ state: interaction
1654
+ });
1655
+ }
1656
+ else {
1657
+ calendar.dispatch({ type: 'UNSET_EVENT_RESIZE' });
1658
+ }
1659
+ if (!isInvalid) {
1660
+ core.enableCursor();
1661
+ }
1662
+ else {
1663
+ core.disableCursor();
1664
+ }
1665
+ if (!isFinal) {
1666
+ if (mutation && isHitsEqual(initialHit, hit)) {
1667
+ mutation = null;
1668
+ }
1669
+ _this.validMutation = mutation;
1670
+ _this.mutatedRelevantEvents = mutatedRelevantEvents;
1671
+ }
1672
+ };
1673
+ _this.handleDragEnd = function (ev) {
1674
+ var calendar = _this.component.calendar;
1675
+ var view = _this.component.view;
1676
+ var eventDef = _this.eventRange.def;
1677
+ var eventInstance = _this.eventRange.instance;
1678
+ var eventApi = new core.EventApi(calendar, eventDef, eventInstance);
1679
+ var relevantEvents = _this.relevantEvents;
1680
+ var mutatedRelevantEvents = _this.mutatedRelevantEvents;
1681
+ calendar.publiclyTrigger('eventResizeStop', [
1682
+ {
1683
+ el: _this.draggingSeg.el,
1684
+ event: eventApi,
1685
+ jsEvent: ev.origEvent,
1686
+ view: view
1687
+ }
1688
+ ]);
1689
+ if (_this.validMutation) {
1690
+ calendar.dispatch({
1691
+ type: 'MERGE_EVENTS',
1692
+ eventStore: mutatedRelevantEvents
1693
+ });
1694
+ calendar.publiclyTrigger('eventResize', [
1695
+ {
1696
+ el: _this.draggingSeg.el,
1697
+ startDelta: _this.validMutation.startDelta || core.createDuration(0),
1698
+ endDelta: _this.validMutation.endDelta || core.createDuration(0),
1699
+ prevEvent: eventApi,
1700
+ event: new core.EventApi(// the data AFTER the mutation
1701
+ calendar, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null),
1702
+ revert: function () {
1703
+ calendar.dispatch({
1704
+ type: 'MERGE_EVENTS',
1705
+ eventStore: relevantEvents
1706
+ });
1707
+ },
1708
+ jsEvent: ev.origEvent,
1709
+ view: view
1710
+ }
1711
+ ]);
1712
+ }
1713
+ else {
1714
+ calendar.publiclyTrigger('_noEventResize');
1715
+ }
1716
+ // reset all internal state
1717
+ _this.draggingSeg = null;
1718
+ _this.relevantEvents = null;
1719
+ _this.validMutation = null;
1720
+ // okay to keep eventInstance around. useful to set it in handlePointerDown
1721
+ };
1722
+ var component = settings.component;
1723
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
1724
+ dragging.pointer.selector = '.fc-resizer';
1725
+ dragging.touchScrollAllowed = false;
1726
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
1727
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
1728
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1729
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
1730
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
1731
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
1732
+ return _this;
1733
+ }
1734
+ EventDragging.prototype.destroy = function () {
1735
+ this.dragging.destroy();
1736
+ };
1737
+ EventDragging.prototype.querySeg = function (ev) {
1738
+ return core.getElSeg(core.elementClosest(ev.subjectEl, this.component.fgSegSelector));
1739
+ };
1740
+ return EventDragging;
1741
+ }(core.Interaction));
1742
+ function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) {
1743
+ var dateEnv = hit0.component.dateEnv;
1744
+ var date0 = hit0.dateSpan.range.start;
1745
+ var date1 = hit1.dateSpan.range.start;
1746
+ var delta = core.diffDates(date0, date1, dateEnv, hit0.component.largeUnit);
1747
+ var props = {};
1748
+ for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) {
1749
+ var transform = transforms_1[_i];
1750
+ var res = transform(hit0, hit1);
1751
+ if (res === false) {
1752
+ return null;
1753
+ }
1754
+ else if (res) {
1755
+ __assign(props, res);
1756
+ }
1757
+ }
1758
+ if (isFromStart) {
1759
+ if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
1760
+ props.startDelta = delta;
1761
+ return props;
1762
+ }
1763
+ }
1764
+ else {
1765
+ if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
1766
+ props.endDelta = delta;
1767
+ return props;
1768
+ }
1769
+ }
1770
+ return null;
1771
+ }
1772
+
1773
+ var UnselectAuto = /** @class */ (function () {
1774
+ function UnselectAuto(calendar) {
1775
+ var _this = this;
1776
+ this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
1777
+ this.onSelect = function (selectInfo) {
1778
+ if (selectInfo.jsEvent) {
1779
+ _this.isRecentPointerDateSelect = true;
1780
+ }
1781
+ };
1782
+ this.onDocumentPointerUp = function (pev) {
1783
+ var _a = _this, calendar = _a.calendar, documentPointer = _a.documentPointer;
1784
+ var state = calendar.state;
1785
+ // touch-scrolling should never unfocus any type of selection
1786
+ if (!documentPointer.wasTouchScroll) {
1787
+ if (state.dateSelection && // an existing date selection?
1788
+ !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
1789
+ ) {
1790
+ var unselectAuto = calendar.viewOpt('unselectAuto');
1791
+ var unselectCancel = calendar.viewOpt('unselectCancel');
1792
+ if (unselectAuto && (!unselectAuto || !core.elementClosest(documentPointer.downEl, unselectCancel))) {
1793
+ calendar.unselect(pev);
1794
+ }
1795
+ }
1796
+ if (state.eventSelection && // an existing event selected?
1797
+ !core.elementClosest(documentPointer.downEl, EventDragging.SELECTOR) // interaction DIDN'T start on an event
1798
+ ) {
1799
+ calendar.dispatch({ type: 'UNSELECT_EVENT' });
1800
+ }
1801
+ }
1802
+ _this.isRecentPointerDateSelect = false;
1803
+ };
1804
+ this.calendar = calendar;
1805
+ var documentPointer = this.documentPointer = new PointerDragging(document);
1806
+ documentPointer.shouldIgnoreMove = true;
1807
+ documentPointer.shouldWatchScroll = false;
1808
+ documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
1809
+ /*
1810
+ TODO: better way to know about whether there was a selection with the pointer
1811
+ */
1812
+ calendar.on('select', this.onSelect);
1813
+ }
1814
+ UnselectAuto.prototype.destroy = function () {
1815
+ this.calendar.off('select', this.onSelect);
1816
+ this.documentPointer.destroy();
1817
+ };
1818
+ return UnselectAuto;
1819
+ }());
1820
+
1821
+ /*
1822
+ Given an already instantiated draggable object for one-or-more elements,
1823
+ Interprets any dragging as an attempt to drag an events that lives outside
1824
+ of a calendar onto a calendar.
1825
+ */
1826
+ var ExternalElementDragging = /** @class */ (function () {
1827
+ function ExternalElementDragging(dragging, suppliedDragMeta) {
1828
+ var _this = this;
1829
+ this.receivingCalendar = null;
1830
+ this.droppableEvent = null; // will exist for all drags, even if create:false
1831
+ this.suppliedDragMeta = null;
1832
+ this.dragMeta = null;
1833
+ this.handleDragStart = function (ev) {
1834
+ _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
1835
+ };
1836
+ this.handleHitUpdate = function (hit, isFinal, ev) {
1837
+ var dragging = _this.hitDragging.dragging;
1838
+ var receivingCalendar = null;
1839
+ var droppableEvent = null;
1840
+ var isInvalid = false;
1841
+ var interaction = {
1842
+ affectedEvents: core.createEmptyEventStore(),
1843
+ mutatedEvents: core.createEmptyEventStore(),
1844
+ isEvent: _this.dragMeta.create,
1845
+ origSeg: null
1846
+ };
1847
+ if (hit) {
1848
+ receivingCalendar = hit.component.calendar;
1849
+ if (_this.canDropElOnCalendar(ev.subjectEl, receivingCalendar)) {
1850
+ droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingCalendar);
1851
+ interaction.mutatedEvents = core.eventTupleToStore(droppableEvent);
1852
+ isInvalid = !core.isInteractionValid(interaction, receivingCalendar);
1853
+ if (isInvalid) {
1854
+ interaction.mutatedEvents = core.createEmptyEventStore();
1855
+ droppableEvent = null;
1856
+ }
1857
+ }
1858
+ }
1859
+ _this.displayDrag(receivingCalendar, interaction);
1860
+ // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
1861
+ // TODO: wish we could somehow wait for dispatch to guarantee render
1862
+ dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-mirror'));
1863
+ if (!isInvalid) {
1864
+ core.enableCursor();
1865
+ }
1866
+ else {
1867
+ core.disableCursor();
1868
+ }
1869
+ if (!isFinal) {
1870
+ dragging.setMirrorNeedsRevert(!droppableEvent);
1871
+ _this.receivingCalendar = receivingCalendar;
1872
+ _this.droppableEvent = droppableEvent;
1873
+ }
1874
+ };
1875
+ this.handleDragEnd = function (pev) {
1876
+ var _a = _this, receivingCalendar = _a.receivingCalendar, droppableEvent = _a.droppableEvent;
1877
+ _this.clearDrag();
1878
+ if (receivingCalendar && droppableEvent) {
1879
+ var finalHit = _this.hitDragging.finalHit;
1880
+ var finalView = finalHit.component.view;
1881
+ var dragMeta = _this.dragMeta;
1882
+ var arg = receivingCalendar.buildDatePointApi(finalHit.dateSpan);
1883
+ arg.draggedEl = pev.subjectEl;
1884
+ arg.jsEvent = pev.origEvent;
1885
+ arg.view = finalView;
1886
+ receivingCalendar.publiclyTrigger('drop', [arg]);
1887
+ if (dragMeta.create) {
1888
+ receivingCalendar.dispatch({
1889
+ type: 'MERGE_EVENTS',
1890
+ eventStore: core.eventTupleToStore(droppableEvent)
1891
+ });
1892
+ if (pev.isTouch) {
1893
+ receivingCalendar.dispatch({
1894
+ type: 'SELECT_EVENT',
1895
+ eventInstanceId: droppableEvent.instance.instanceId
1896
+ });
1897
+ }
1898
+ // signal that an external event landed
1899
+ receivingCalendar.publiclyTrigger('eventReceive', [
1900
+ {
1901
+ draggedEl: pev.subjectEl,
1902
+ event: new core.EventApi(receivingCalendar, droppableEvent.def, droppableEvent.instance),
1903
+ view: finalView
1904
+ }
1905
+ ]);
1906
+ }
1907
+ }
1908
+ _this.receivingCalendar = null;
1909
+ _this.droppableEvent = null;
1910
+ };
1911
+ var hitDragging = this.hitDragging = new HitDragging(dragging, core.interactionSettingsStore);
1912
+ hitDragging.requireInitial = false; // will start outside of a component
1913
+ hitDragging.emitter.on('dragstart', this.handleDragStart);
1914
+ hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
1915
+ hitDragging.emitter.on('dragend', this.handleDragEnd);
1916
+ this.suppliedDragMeta = suppliedDragMeta;
1917
+ }
1918
+ ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) {
1919
+ if (typeof this.suppliedDragMeta === 'object') {
1920
+ return core.parseDragMeta(this.suppliedDragMeta);
1921
+ }
1922
+ else if (typeof this.suppliedDragMeta === 'function') {
1923
+ return core.parseDragMeta(this.suppliedDragMeta(subjectEl));
1924
+ }
1925
+ else {
1926
+ return getDragMetaFromEl(subjectEl);
1927
+ }
1928
+ };
1929
+ ExternalElementDragging.prototype.displayDrag = function (nextCalendar, state) {
1930
+ var prevCalendar = this.receivingCalendar;
1931
+ if (prevCalendar && prevCalendar !== nextCalendar) {
1932
+ prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1933
+ }
1934
+ if (nextCalendar) {
1935
+ nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
1936
+ }
1937
+ };
1938
+ ExternalElementDragging.prototype.clearDrag = function () {
1939
+ if (this.receivingCalendar) {
1940
+ this.receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1941
+ }
1942
+ };
1943
+ ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingCalendar) {
1944
+ var dropAccept = receivingCalendar.opt('dropAccept');
1945
+ if (typeof dropAccept === 'function') {
1946
+ return dropAccept(el);
1947
+ }
1948
+ else if (typeof dropAccept === 'string' && dropAccept) {
1949
+ return Boolean(core.elementMatches(el, dropAccept));
1950
+ }
1951
+ return true;
1952
+ };
1953
+ return ExternalElementDragging;
1954
+ }());
1955
+ // Utils for computing event store from the DragMeta
1956
+ // ----------------------------------------------------------------------------------------------------
1957
+ function computeEventForDateSpan(dateSpan, dragMeta, calendar) {
1958
+ var defProps = __assign({}, dragMeta.leftoverProps);
1959
+ for (var _i = 0, _a = calendar.pluginSystem.hooks.externalDefTransforms; _i < _a.length; _i++) {
1960
+ var transform = _a[_i];
1961
+ __assign(defProps, transform(dateSpan, dragMeta));
1962
+ }
1963
+ var def = core.parseEventDef(defProps, dragMeta.sourceId, dateSpan.allDay, calendar.opt('forceEventDuration') || Boolean(dragMeta.duration), // hasEnd
1964
+ calendar);
1965
+ var start = dateSpan.range.start;
1966
+ // only rely on time info if drop zone is all-day,
1967
+ // otherwise, we already know the time
1968
+ if (dateSpan.allDay && dragMeta.startTime) {
1969
+ start = calendar.dateEnv.add(start, dragMeta.startTime);
1970
+ }
1971
+ var end = dragMeta.duration ?
1972
+ calendar.dateEnv.add(start, dragMeta.duration) :
1973
+ calendar.getDefaultEventEnd(dateSpan.allDay, start);
1974
+ var instance = core.createEventInstance(def.defId, { start: start, end: end });
1975
+ return { def: def, instance: instance };
1976
+ }
1977
+ // Utils for extracting data from element
1978
+ // ----------------------------------------------------------------------------------------------------
1979
+ function getDragMetaFromEl(el) {
1980
+ var str = getEmbeddedElData(el, 'event');
1981
+ var obj = str ?
1982
+ JSON.parse(str) :
1983
+ { create: false }; // if no embedded data, assume no event creation
1984
+ return core.parseDragMeta(obj);
1985
+ }
1986
+ core.config.dataAttrPrefix = '';
1987
+ function getEmbeddedElData(el, name) {
1988
+ var prefix = core.config.dataAttrPrefix;
1989
+ var prefixedName = (prefix ? prefix + '-' : '') + name;
1990
+ return el.getAttribute('data-' + prefixedName) || '';
1991
+ }
1992
+
1993
+ /*
1994
+ Makes an element (that is *external* to any calendar) draggable.
1995
+ Can pass in data that determines how an event will be created when dropped onto a calendar.
1996
+ Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
1997
+ */
1998
+ var ExternalDraggable = /** @class */ (function () {
1999
+ function ExternalDraggable(el, settings) {
2000
+ var _this = this;
2001
+ if (settings === void 0) { settings = {}; }
2002
+ this.handlePointerDown = function (ev) {
2003
+ var dragging = _this.dragging;
2004
+ var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
2005
+ dragging.minDistance =
2006
+ minDistance != null ?
2007
+ minDistance :
2008
+ (ev.isTouch ? 0 : core.globalDefaults.eventDragMinDistance);
2009
+ dragging.delay =
2010
+ ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
2011
+ (longPressDelay != null ? longPressDelay : core.globalDefaults.longPressDelay) :
2012
+ 0;
2013
+ };
2014
+ this.handleDragStart = function (ev) {
2015
+ if (ev.isTouch &&
2016
+ _this.dragging.delay &&
2017
+ ev.subjectEl.classList.contains('fc-event')) {
2018
+ _this.dragging.mirror.getMirrorEl().classList.add('fc-selected');
2019
+ }
2020
+ };
2021
+ this.settings = settings;
2022
+ var dragging = this.dragging = new FeaturefulElementDragging(el);
2023
+ dragging.touchScrollAllowed = false;
2024
+ if (settings.itemSelector != null) {
2025
+ dragging.pointer.selector = settings.itemSelector;
2026
+ }
2027
+ if (settings.appendTo != null) {
2028
+ dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
2029
+ }
2030
+ dragging.emitter.on('pointerdown', this.handlePointerDown);
2031
+ dragging.emitter.on('dragstart', this.handleDragStart);
2032
+ new ExternalElementDragging(dragging, settings.eventData);
2033
+ }
2034
+ ExternalDraggable.prototype.destroy = function () {
2035
+ this.dragging.destroy();
2036
+ };
2037
+ return ExternalDraggable;
2038
+ }());
2039
+
2040
+ /*
2041
+ Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
2042
+ The third-party system is responsible for drawing the visuals effects of the drag.
2043
+ This class simply monitors for pointer movements and fires events.
2044
+ It also has the ability to hide the moving element (the "mirror") during the drag.
2045
+ */
2046
+ var InferredElementDragging = /** @class */ (function (_super) {
2047
+ __extends(InferredElementDragging, _super);
2048
+ function InferredElementDragging(containerEl) {
2049
+ var _this = _super.call(this, containerEl) || this;
2050
+ _this.shouldIgnoreMove = false;
2051
+ _this.mirrorSelector = '';
2052
+ _this.currentMirrorEl = null;
2053
+ _this.handlePointerDown = function (ev) {
2054
+ _this.emitter.trigger('pointerdown', ev);
2055
+ if (!_this.shouldIgnoreMove) {
2056
+ // fire dragstart right away. does not support delay or min-distance
2057
+ _this.emitter.trigger('dragstart', ev);
2058
+ }
2059
+ };
2060
+ _this.handlePointerMove = function (ev) {
2061
+ if (!_this.shouldIgnoreMove) {
2062
+ _this.emitter.trigger('dragmove', ev);
2063
+ }
2064
+ };
2065
+ _this.handlePointerUp = function (ev) {
2066
+ _this.emitter.trigger('pointerup', ev);
2067
+ if (!_this.shouldIgnoreMove) {
2068
+ // fire dragend right away. does not support a revert animation
2069
+ _this.emitter.trigger('dragend', ev);
2070
+ }
2071
+ };
2072
+ var pointer = _this.pointer = new PointerDragging(containerEl);
2073
+ pointer.emitter.on('pointerdown', _this.handlePointerDown);
2074
+ pointer.emitter.on('pointermove', _this.handlePointerMove);
2075
+ pointer.emitter.on('pointerup', _this.handlePointerUp);
2076
+ return _this;
2077
+ }
2078
+ InferredElementDragging.prototype.destroy = function () {
2079
+ this.pointer.destroy();
2080
+ };
2081
+ InferredElementDragging.prototype.setIgnoreMove = function (bool) {
2082
+ this.shouldIgnoreMove = bool;
2083
+ };
2084
+ InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
2085
+ if (bool) {
2086
+ // restore a previously hidden element.
2087
+ // use the reference in case the selector class has already been removed.
2088
+ if (this.currentMirrorEl) {
2089
+ this.currentMirrorEl.style.visibility = '';
2090
+ this.currentMirrorEl = null;
2091
+ }
2092
+ }
2093
+ else {
2094
+ var mirrorEl = this.mirrorSelector ?
2095
+ document.querySelector(this.mirrorSelector) :
2096
+ null;
2097
+ if (mirrorEl) {
2098
+ this.currentMirrorEl = mirrorEl;
2099
+ mirrorEl.style.visibility = 'hidden';
2100
+ }
2101
+ }
2102
+ };
2103
+ return InferredElementDragging;
2104
+ }(core.ElementDragging));
2105
+
2106
+ /*
2107
+ Bridges third-party drag-n-drop systems with FullCalendar.
2108
+ Must be instantiated and destroyed by caller.
2109
+ */
2110
+ var ThirdPartyDraggable = /** @class */ (function () {
2111
+ function ThirdPartyDraggable(containerOrSettings, settings) {
2112
+ var containerEl = document;
2113
+ if (
2114
+ // wish we could just test instanceof EventTarget, but doesn't work in IE11
2115
+ containerOrSettings === document ||
2116
+ containerOrSettings instanceof Element) {
2117
+ containerEl = containerOrSettings;
2118
+ settings = settings || {};
2119
+ }
2120
+ else {
2121
+ settings = (containerOrSettings || {});
2122
+ }
2123
+ var dragging = this.dragging = new InferredElementDragging(containerEl);
2124
+ if (typeof settings.itemSelector === 'string') {
2125
+ dragging.pointer.selector = settings.itemSelector;
2126
+ }
2127
+ else if (containerEl === document) {
2128
+ dragging.pointer.selector = '[data-event]';
2129
+ }
2130
+ if (typeof settings.mirrorSelector === 'string') {
2131
+ dragging.mirrorSelector = settings.mirrorSelector;
2132
+ }
2133
+ new ExternalElementDragging(dragging, settings.eventData);
2134
+ }
2135
+ ThirdPartyDraggable.prototype.destroy = function () {
2136
+ this.dragging.destroy();
2137
+ };
2138
+ return ThirdPartyDraggable;
2139
+ }());
2140
+
2141
+ var main = core.createPlugin({
2142
+ componentInteractions: [DateClicking, DateSelecting, EventDragging, EventDragging$1],
2143
+ calendarInteractions: [UnselectAuto],
2144
+ elementDraggingImpl: FeaturefulElementDragging
2145
+ });
2146
+
2147
+ exports.Draggable = ExternalDraggable;
2148
+ exports.FeaturefulElementDragging = FeaturefulElementDragging;
2149
+ exports.PointerDragging = PointerDragging;
2150
+ exports.ThirdPartyDraggable = ThirdPartyDraggable;
2151
+ exports.default = main;
2152
+
2153
+ Object.defineProperty(exports, '__esModule', { value: true });
2154
+
2155
+ }));