diff options
Diffstat (limited to 'public/js/fullcalendar/packages/icalendar')
| -rw-r--r-- | public/js/fullcalendar/packages/icalendar/index.global.js | 225 | ||||
| -rw-r--r-- | public/js/fullcalendar/packages/icalendar/index.global.min.js | 6 |
2 files changed, 231 insertions, 0 deletions
diff --git a/public/js/fullcalendar/packages/icalendar/index.global.js b/public/js/fullcalendar/packages/icalendar/index.global.js new file mode 100644 index 0000000..1c965f6 --- /dev/null +++ b/public/js/fullcalendar/packages/icalendar/index.global.js | |||
| @@ -0,0 +1,225 @@ | |||
| 1 | /*! | ||
| 2 | FullCalendar iCalendar Plugin v6.1.17 | ||
| 3 | Docs & License: https://fullcalendar.io/docs/icalendar | ||
| 4 | (c) 2024 Adam Shaw | ||
| 5 | */ | ||
| 6 | FullCalendar.ICalendar = (function (exports, core, internal, ICAL) { | ||
| 7 | 'use strict'; | ||
| 8 | |||
| 9 | function _interopNamespace(e) { | ||
| 10 | if (e && e.__esModule) return e; | ||
| 11 | var n = Object.create(null); | ||
| 12 | if (e) { | ||
| 13 | Object.keys(e).forEach(function (k) { | ||
| 14 | if (k !== 'default') { | ||
| 15 | var d = Object.getOwnPropertyDescriptor(e, k); | ||
| 16 | Object.defineProperty(n, k, d.get ? d : { | ||
| 17 | enumerable: true, | ||
| 18 | get: function () { return e[k]; } | ||
| 19 | }); | ||
| 20 | } | ||
| 21 | }); | ||
| 22 | } | ||
| 23 | n["default"] = e; | ||
| 24 | return n; | ||
| 25 | } | ||
| 26 | |||
| 27 | var ICAL__namespace = /*#__PURE__*/_interopNamespace(ICAL); | ||
| 28 | |||
| 29 | /* eslint-disable */ | ||
| 30 | class IcalExpander { | ||
| 31 | constructor(opts) { | ||
| 32 | this.maxIterations = opts.maxIterations != null ? opts.maxIterations : 1000; | ||
| 33 | this.skipInvalidDates = opts.skipInvalidDates != null ? opts.skipInvalidDates : false; | ||
| 34 | this.jCalData = ICAL__namespace.parse(opts.ics); | ||
| 35 | this.component = new ICAL__namespace.Component(this.jCalData); | ||
| 36 | this.events = this.component.getAllSubcomponents('vevent').map(vevent => new ICAL__namespace.Event(vevent)); | ||
| 37 | if (this.skipInvalidDates) { | ||
| 38 | this.events = this.events.filter((evt) => { | ||
| 39 | try { | ||
| 40 | evt.startDate.toJSDate(); | ||
| 41 | evt.endDate.toJSDate(); | ||
| 42 | return true; | ||
| 43 | } | ||
| 44 | catch (err) { | ||
| 45 | // skipping events with invalid time | ||
| 46 | return false; | ||
| 47 | } | ||
| 48 | }); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | between(after, before) { | ||
| 52 | function isEventWithinRange(startTime, endTime) { | ||
| 53 | return (!after || endTime >= after.getTime()) && | ||
| 54 | (!before || startTime <= before.getTime()); | ||
| 55 | } | ||
| 56 | function getTimes(eventOrOccurrence) { | ||
| 57 | const startTime = eventOrOccurrence.startDate.toJSDate().getTime(); | ||
| 58 | let endTime = eventOrOccurrence.endDate.toJSDate().getTime(); | ||
| 59 | // If it is an all day event, the end date is set to 00:00 of the next day | ||
| 60 | // So we need to make it be 23:59:59 to compare correctly with the given range | ||
| 61 | if (eventOrOccurrence.endDate.isDate && (endTime > startTime)) { | ||
| 62 | endTime -= 1; | ||
| 63 | } | ||
| 64 | return { startTime, endTime }; | ||
| 65 | } | ||
| 66 | const exceptions = []; | ||
| 67 | this.events.forEach((event) => { | ||
| 68 | if (event.isRecurrenceException()) | ||
| 69 | exceptions.push(event); | ||
| 70 | }); | ||
| 71 | const ret = { | ||
| 72 | events: [], | ||
| 73 | occurrences: [], | ||
| 74 | }; | ||
| 75 | this.events.filter(e => !e.isRecurrenceException()).forEach((event) => { | ||
| 76 | const exdates = []; | ||
| 77 | event.component.getAllProperties('exdate').forEach((exdateProp) => { | ||
| 78 | const exdate = exdateProp.getFirstValue(); | ||
| 79 | exdates.push(exdate.toJSDate().getTime()); | ||
| 80 | }); | ||
| 81 | // Recurring event is handled differently | ||
| 82 | if (event.isRecurring()) { | ||
| 83 | const iterator = event.iterator(); | ||
| 84 | let next; | ||
| 85 | let i = 0; | ||
| 86 | do { | ||
| 87 | i += 1; | ||
| 88 | next = iterator.next(); | ||
| 89 | if (next) { | ||
| 90 | const occurrence = event.getOccurrenceDetails(next); | ||
| 91 | const { startTime, endTime } = getTimes(occurrence); | ||
| 92 | const isOccurrenceExcluded = exdates.indexOf(startTime) !== -1; | ||
| 93 | // TODO check that within same day? | ||
| 94 | const exception = exceptions.find(ex => ex.uid === event.uid && ex.recurrenceId.toJSDate().getTime() === occurrence.startDate.toJSDate().getTime()); | ||
| 95 | // We have passed the max date, stop | ||
| 96 | if (before && startTime > before.getTime()) | ||
| 97 | break; | ||
| 98 | // Check that we are within our range | ||
| 99 | if (isEventWithinRange(startTime, endTime)) { | ||
| 100 | if (exception) { | ||
| 101 | ret.events.push(exception); | ||
| 102 | } | ||
| 103 | else if (!isOccurrenceExcluded) { | ||
| 104 | ret.occurrences.push(occurrence); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } while (next && (!this.maxIterations || i < this.maxIterations)); | ||
| 109 | return; | ||
| 110 | } | ||
| 111 | // Non-recurring event: | ||
| 112 | const { startTime, endTime } = getTimes(event); | ||
| 113 | if (isEventWithinRange(startTime, endTime)) | ||
| 114 | ret.events.push(event); | ||
| 115 | }); | ||
| 116 | return ret; | ||
| 117 | } | ||
| 118 | before(before) { | ||
| 119 | return this.between(undefined, before); | ||
| 120 | } | ||
| 121 | after(after) { | ||
| 122 | return this.between(after); | ||
| 123 | } | ||
| 124 | all() { | ||
| 125 | return this.between(); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | const eventSourceDef = { | ||
| 130 | parseMeta(refined) { | ||
| 131 | if (refined.url && refined.format === 'ics') { | ||
| 132 | return { | ||
| 133 | url: refined.url, | ||
| 134 | format: 'ics', | ||
| 135 | }; | ||
| 136 | } | ||
| 137 | return null; | ||
| 138 | }, | ||
| 139 | fetch(arg, successCallback, errorCallback) { | ||
| 140 | let meta = arg.eventSource.meta; | ||
| 141 | let { internalState } = meta; | ||
| 142 | /* | ||
| 143 | NOTE: isRefetch is a HACK. we would do the recurring-expanding in a separate plugin hook, | ||
| 144 | but we couldn't leverage built-in allDay-guessing, among other things. | ||
| 145 | */ | ||
| 146 | if (!internalState || arg.isRefetch) { | ||
| 147 | internalState = meta.internalState = { | ||
| 148 | response: null, | ||
| 149 | iCalExpanderPromise: fetch(meta.url, { method: 'GET' }).then((response) => { | ||
| 150 | return response.text().then((icsText) => { | ||
| 151 | internalState.response = response; | ||
| 152 | return new IcalExpander({ | ||
| 153 | ics: icsText, | ||
| 154 | skipInvalidDates: true, | ||
| 155 | }); | ||
| 156 | }); | ||
| 157 | }), | ||
| 158 | }; | ||
| 159 | } | ||
| 160 | internalState.iCalExpanderPromise.then((iCalExpander) => { | ||
| 161 | successCallback({ | ||
| 162 | rawEvents: expandICalEvents(iCalExpander, arg.range), | ||
| 163 | response: internalState.response, | ||
| 164 | }); | ||
| 165 | }, errorCallback); | ||
| 166 | }, | ||
| 167 | }; | ||
| 168 | function expandICalEvents(iCalExpander, range) { | ||
| 169 | // expand the range. because our `range` is timeZone-agnostic UTC | ||
| 170 | // or maybe because ical.js always produces dates in local time? i forget | ||
| 171 | let rangeStart = internal.addDays(range.start, -1); | ||
| 172 | let rangeEnd = internal.addDays(range.end, 1); | ||
| 173 | let iCalRes = iCalExpander.between(rangeStart, rangeEnd); // end inclusive. will give extra results | ||
| 174 | let expanded = []; | ||
| 175 | // TODO: instead of using startDate/endDate.toString to communicate allDay, | ||
| 176 | // we can query startDate/endDate.isDate. More efficient to avoid formatting/reparsing. | ||
| 177 | // single events | ||
| 178 | for (let iCalEvent of iCalRes.events) { | ||
| 179 | expanded.push(Object.assign(Object.assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate) | ||
| 180 | ? iCalEvent.endDate.toString() | ||
| 181 | : null })); | ||
| 182 | } | ||
| 183 | // recurring event instances | ||
| 184 | for (let iCalOccurence of iCalRes.occurrences) { | ||
| 185 | let iCalEvent = iCalOccurence.item; | ||
| 186 | expanded.push(Object.assign(Object.assign({}, buildNonDateProps(iCalEvent)), { start: iCalOccurence.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalOccurence.endDate) | ||
| 187 | ? iCalOccurence.endDate.toString() | ||
| 188 | : null })); | ||
| 189 | } | ||
| 190 | return expanded; | ||
| 191 | } | ||
| 192 | function buildNonDateProps(iCalEvent) { | ||
| 193 | return { | ||
| 194 | title: iCalEvent.summary, | ||
| 195 | url: extractEventUrl(iCalEvent), | ||
| 196 | extendedProps: { | ||
| 197 | location: iCalEvent.location, | ||
| 198 | organizer: iCalEvent.organizer, | ||
| 199 | description: iCalEvent.description, | ||
| 200 | }, | ||
| 201 | }; | ||
| 202 | } | ||
| 203 | function extractEventUrl(iCalEvent) { | ||
| 204 | let urlProp = iCalEvent.component.getFirstProperty('url'); | ||
| 205 | return urlProp ? urlProp.getFirstValue() : ''; | ||
| 206 | } | ||
| 207 | function specifiesEnd(iCalEvent) { | ||
| 208 | return Boolean(iCalEvent.component.getFirstProperty('dtend')) || | ||
| 209 | Boolean(iCalEvent.component.getFirstProperty('duration')); | ||
| 210 | } | ||
| 211 | |||
| 212 | var plugin = core.createPlugin({ | ||
| 213 | name: '@fullcalendar/icalendar', | ||
| 214 | eventSourceDefs: [eventSourceDef], | ||
| 215 | }); | ||
| 216 | |||
| 217 | core.globalPlugins.push(plugin); | ||
| 218 | |||
| 219 | exports["default"] = plugin; | ||
| 220 | |||
| 221 | Object.defineProperty(exports, '__esModule', { value: true }); | ||
| 222 | |||
| 223 | return exports; | ||
| 224 | |||
| 225 | })({}, FullCalendar, FullCalendar.Internal, ICAL); | ||
diff --git a/public/js/fullcalendar/packages/icalendar/index.global.min.js b/public/js/fullcalendar/packages/icalendar/index.global.min.js new file mode 100644 index 0000000..2b97493 --- /dev/null +++ b/public/js/fullcalendar/packages/icalendar/index.global.min.js | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | /*! | ||
| 2 | FullCalendar iCalendar Plugin v6.1.17 | ||
| 3 | Docs & License: https://fullcalendar.io/docs/icalendar | ||
| 4 | (c) 2024 Adam Shaw | ||
| 5 | */ | ||
| 6 | FullCalendar.ICalendar=function(e,t,n,r){"use strict";function a(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,t}var s=a(r);class i{constructor(e){this.maxIterations=null!=e.maxIterations?e.maxIterations:1e3,this.skipInvalidDates=null!=e.skipInvalidDates&&e.skipInvalidDates,this.jCalData=s.parse(e.ics),this.component=new s.Component(this.jCalData),this.events=this.component.getAllSubcomponents("vevent").map(e=>new s.Event(e)),this.skipInvalidDates&&(this.events=this.events.filter(e=>{try{return e.startDate.toJSDate(),e.endDate.toJSDate(),!0}catch(e){return!1}}))}between(e,t){function n(n,r){return(!e||r>=e.getTime())&&(!t||n<=t.getTime())}function r(e){const t=e.startDate.toJSDate().getTime();let n=e.endDate.toJSDate().getTime();return e.endDate.isDate&&n>t&&(n-=1),{startTime:t,endTime:n}}const a=[];this.events.forEach(e=>{e.isRecurrenceException()&&a.push(e)});const s={events:[],occurrences:[]};return this.events.filter(e=>!e.isRecurrenceException()).forEach(e=>{const i=[];if(e.component.getAllProperties("exdate").forEach(e=>{const t=e.getFirstValue();i.push(t.toJSDate().getTime())}),e.isRecurring()){const o=e.iterator();let c,l=0;do{if(l+=1,c=o.next(),c){const o=e.getOccurrenceDetails(c),{startTime:l,endTime:u}=r(o),d=-1!==i.indexOf(l),p=a.find(t=>t.uid===e.uid&&t.recurrenceId.toJSDate().getTime()===o.startDate.toJSDate().getTime());if(t&&l>t.getTime())break;n(l,u)&&(p?s.events.push(p):d||s.occurrences.push(o))}}while(c&&(!this.maxIterations||l<this.maxIterations));return}const{startTime:o,endTime:c}=r(e);n(o,c)&&s.events.push(e)}),s}before(e){return this.between(void 0,e)}after(e){return this.between(e)}all(){return this.between()}}const o={parseMeta:e=>e.url&&"ics"===e.format?{url:e.url,format:"ics"}:null,fetch(e,t,n){let r=e.eventSource.meta,{internalState:a}=r;a&&!e.isRefetch||(a=r.internalState={response:null,iCalExpanderPromise:fetch(r.url,{method:"GET"}).then(e=>e.text().then(t=>(a.response=e,new i({ics:t,skipInvalidDates:!0}))))}),a.iCalExpanderPromise.then(n=>{t({rawEvents:c(n,e.range),response:a.response})},n)}};function c(e,t){let r=n.addDays(t.start,-1),a=n.addDays(t.end,1),s=e.between(r,a),i=[];for(let e of s.events)i.push(Object.assign(Object.assign({},l(e)),{start:e.startDate.toString(),end:d(e)&&e.endDate?e.endDate.toString():null}));for(let e of s.occurrences){let t=e.item;i.push(Object.assign(Object.assign({},l(t)),{start:e.startDate.toString(),end:d(t)&&e.endDate?e.endDate.toString():null}))}return i}function l(e){return{title:e.summary,url:u(e),extendedProps:{location:e.location,organizer:e.organizer,description:e.description}}}function u(e){let t=e.component.getFirstProperty("url");return t?t.getFirstValue():""}function d(e){return Boolean(e.component.getFirstProperty("dtend"))||Boolean(e.component.getFirstProperty("duration"))}var p=t.createPlugin({name:"@fullcalendar/icalendar",eventSourceDefs:[o]});return t.globalPlugins.push(p),e.default=p,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,FullCalendar.Internal,ICAL); \ No newline at end of file | ||
