summaryrefslogtreecommitdiff
path: root/public/js/fullcalendar/packages/icalendar/index.global.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/js/fullcalendar/packages/icalendar/index.global.js')
-rw-r--r--public/js/fullcalendar/packages/icalendar/index.global.js225
1 files changed, 225 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/*!
2FullCalendar iCalendar Plugin v6.1.17
3Docs & License: https://fullcalendar.io/docs/icalendar
4(c) 2024 Adam Shaw
5*/
6FullCalendar.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);