@forcecalendar/interface 1.0.59 → 1.0.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  var H = Object.defineProperty;
2
- var F = (h, t, e) => t in h ? H(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
3
- var v = (h, t, e) => F(h, typeof t != "symbol" ? t + "" : t, e);
4
- import { Calendar as L, DateUtils as I } from "@forcecalendar/core";
5
- class M extends HTMLElement {
2
+ var L = (h, t, e) => t in h ? H(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
3
+ var m = (h, t, e) => L(h, typeof t != "symbol" ? t + "" : t, e);
4
+ import { Calendar as F, DateUtils as I } from "@forcecalendar/core";
5
+ class $ extends HTMLElement {
6
6
  constructor() {
7
7
  super(), this.attachShadow({ mode: "open" }), this._listeners = [], this._state = null, this._props = /* @__PURE__ */ new Map(), this._initialized = !1;
8
8
  }
@@ -104,9 +104,11 @@ class M extends HTMLElement {
104
104
  * @param {Map<string, {top: number, left: number}>} positions
105
105
  */
106
106
  _restoreScrollPositions(t) {
107
- !this._contentWrapper || t.size === 0 || t.forEach((e, r) => {
108
- const i = this._contentWrapper.querySelector(`[id="${CSS.escape(r)}"]`);
109
- i && (i.scrollTop = e.top, i.scrollLeft = e.left);
107
+ if (!this._contentWrapper || t.size === 0) return;
108
+ const e = typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape : (r) => String(r).replace(/["\\]/g, "\\$&");
109
+ t.forEach((r, i) => {
110
+ const s = this._contentWrapper.querySelector(`[id="${e(i)}"]`);
111
+ s && (s.scrollTop = r.top, s.scrollLeft = r.left);
110
112
  });
111
113
  }
112
114
  /**
@@ -289,10 +291,10 @@ class S {
289
291
  return t;
290
292
  }
291
293
  }
292
- const U = new S();
293
- class V {
294
+ const j = new S();
295
+ class z {
294
296
  constructor(t = {}) {
295
- this.eventBus = new S(), this.calendar = new L({
297
+ this.eventBus = new S(), this.calendar = new F({
296
298
  view: t.view || "month",
297
299
  date: t.date || /* @__PURE__ */ new Date(),
298
300
  weekStartsOn: t.weekStartsOn ?? 0,
@@ -647,7 +649,7 @@ class u extends I {
647
649
  return s && (s.toLowerCase() === "pm" && n < 12 ? o = n + 12 : s.toLowerCase() === "am" && n === 12 && (o = 0)), r.setHours(o, a || 0, 0, 0), r;
648
650
  }
649
651
  }
650
- class y {
652
+ class g {
651
653
  /**
652
654
  * Create element with attributes and children
653
655
  */
@@ -739,13 +741,19 @@ class y {
739
741
  }
740
742
  /**
741
743
  * Wait for animation/transition to complete
742
- */
743
- static waitForAnimation(t, e = "animationend") {
744
- return new Promise((r) => {
745
- const i = () => {
746
- t.removeEventListener(e, i), r();
744
+ * Resolves after `timeout` ms even if the event never fires (animation
745
+ * cancelled, element removed from DOM, etc.) so awaiting callers can't hang.
746
+ * @param {Element} element - Element to listen on
747
+ * @param {string} [eventType='animationend'] - Event to wait for
748
+ * @param {number} [timeout=3000] - Max wait in ms; 0 disables the timeout
749
+ */
750
+ static waitForAnimation(t, e = "animationend", r = 3e3) {
751
+ return new Promise((i) => {
752
+ let s = null;
753
+ const n = () => {
754
+ s !== null && clearTimeout(s), t.removeEventListener(e, n), i();
747
755
  };
748
- t.addEventListener(e, i);
756
+ t.addEventListener(e, n), r > 0 && (s = setTimeout(n, r));
749
757
  });
750
758
  }
751
759
  /**
@@ -756,10 +764,30 @@ class y {
756
764
  }
757
765
  /**
758
766
  * Parse HTML string safely
759
- */
760
- static parseHTML(t) {
761
- const e = document.createElement("template");
762
- return e.innerHTML = t.trim(), e.content.firstChild;
767
+ * Sanitizes by default: strips script-capable elements, inline event
768
+ * handlers and javascript: URLs so the returned node is inert even if the
769
+ * input contains an XSS payload. Pass { sanitize: false } only for trusted,
770
+ * non-user-controlled markup.
771
+ */
772
+ static parseHTML(t, { sanitize: e = !0 } = {}) {
773
+ const r = document.createElement("template");
774
+ return r.innerHTML = t.trim(), e && this._sanitizeNode(r.content), r.content.firstChild;
775
+ }
776
+ /**
777
+ * Remove script-capable elements, on* handlers and javascript: URLs
778
+ * from a parsed DOM fragment (in place)
779
+ */
780
+ static _sanitizeNode(t) {
781
+ t.querySelectorAll("script, iframe, object, embed, link, meta, base").forEach((s) => s.remove());
782
+ const r = document.createTreeWalker(t, NodeFilter.SHOW_ELEMENT);
783
+ let i = r.nextNode();
784
+ for (; i; ) {
785
+ for (const s of Array.from(i.attributes)) {
786
+ const n = s.name.toLowerCase(), a = s.value.replace(/[\u0000-\u0020]/g, "").toLowerCase();
787
+ (n.startsWith("on") || a.startsWith("javascript:") || a.startsWith("data:text/html")) && i.removeAttribute(s.name);
788
+ }
789
+ i = r.nextNode();
790
+ }
763
791
  }
764
792
  /**
765
793
  * Escape HTML to prevent XSS
@@ -819,7 +847,10 @@ class y {
819
847
  };
820
848
  }
821
849
  /**
822
- * Clone element with event listeners
850
+ * Clone an element. Event listeners are NOT copied — the Web Platform
851
+ * provides no way to enumerate listeners, so callers must re-attach their
852
+ * own handlers to the clone.
853
+ * @deprecated Use element.cloneNode(deep) directly and re-bind listeners.
823
854
  */
824
855
  static cloneWithEvents(t, e = !0) {
825
856
  return t.cloneNode(e);
@@ -834,7 +865,9 @@ class y {
834
865
  if (e.length === 0)
835
866
  return t.setAttribute("tabindex", "-1"), t.focus(), () => t.removeAttribute("tabindex");
836
867
  const r = e[0], i = e[e.length - 1], s = (n) => {
837
- n.key === "Tab" && (n.shiftKey ? document.activeElement === r && (i == null || i.focus(), n.preventDefault()) : document.activeElement === i && (r == null || r.focus(), n.preventDefault()));
868
+ if (n.key !== "Tab") return;
869
+ const o = t.getRootNode().activeElement ?? document.activeElement;
870
+ n.shiftKey ? o === r && (i == null || i.focus(), n.preventDefault()) : o === i && (r == null || r.focus(), n.preventDefault());
838
871
  };
839
872
  return t.addEventListener("keydown", s), r == null || r.focus(), () => t.removeEventListener("keydown", s);
840
873
  }
@@ -1021,7 +1054,7 @@ class f {
1021
1054
  * Get contrast color (black or white) for background
1022
1055
  */
1023
1056
  static getContrastColor(t) {
1024
- const e = t.replace("#", ""), r = parseInt(e.substr(0, 2), 16), i = parseInt(e.substr(2, 2), 16), s = parseInt(e.substr(4, 2), 16);
1057
+ const e = t.replace("#", ""), r = parseInt(e.substring(0, 2), 16), i = parseInt(e.substring(2, 4), 16), s = parseInt(e.substring(4, 6), 16);
1025
1058
  return (r * 299 + i * 587 + s * 114) / 1e3 >= 128 ? "#000000" : "#FFFFFF";
1026
1059
  }
1027
1060
  /**
@@ -1064,7 +1097,7 @@ class f {
1064
1097
  * Convert hex to rgba
1065
1098
  */
1066
1099
  static hexToRgba(t, e = 1) {
1067
- const r = t.replace("#", ""), i = parseInt(r.substr(0, 2), 16), s = parseInt(r.substr(2, 2), 16), n = parseInt(r.substr(4, 2), 16);
1100
+ const r = t.replace("#", ""), i = parseInt(r.substring(0, 2), 16), s = parseInt(r.substring(2, 4), 16), n = parseInt(r.substring(4, 6), 16);
1068
1101
  return `rgba(${i}, ${s}, ${n}, ${e})`;
1069
1102
  }
1070
1103
  /**
@@ -1176,7 +1209,7 @@ class f {
1176
1209
  /**
1177
1210
  * Default theme colors
1178
1211
  */
1179
- v(f, "colors", {
1212
+ m(f, "colors", {
1180
1213
  primary: "#3B82F6",
1181
1214
  // Modern Blue
1182
1215
  secondary: "#64748B",
@@ -1209,7 +1242,7 @@ v(f, "colors", {
1209
1242
  }), /**
1210
1243
  * Common CSS variables
1211
1244
  */
1212
- v(f, "cssVariables", {
1245
+ m(f, "cssVariables", {
1213
1246
  // "Pro" Palette - Functional & Sharp
1214
1247
  "--fc-primary-color": "#2563EB",
1215
1248
  // International Blue (Focus)
@@ -1277,7 +1310,7 @@ v(f, "cssVariables", {
1277
1310
  }), /**
1278
1311
  * Get responsive breakpoints
1279
1312
  */
1280
- v(f, "breakpoints", {
1313
+ m(f, "breakpoints", {
1281
1314
  xs: "320px",
1282
1315
  sm: "576px",
1283
1316
  md: "768px",
@@ -1285,7 +1318,7 @@ v(f, "breakpoints", {
1285
1318
  xl: "1200px",
1286
1319
  "2xl": "1400px"
1287
1320
  });
1288
- class k {
1321
+ class D {
1289
1322
  /**
1290
1323
  * @param {HTMLElement} container - The DOM element to render into
1291
1324
  * @param {StateManager} stateManager - The state manager instance
@@ -1324,7 +1357,7 @@ class k {
1324
1357
  * @returns {string}
1325
1358
  */
1326
1359
  escapeHTML(t) {
1327
- return t == null ? "" : y.escapeHTML(String(t));
1360
+ return t == null ? "" : g.escapeHTML(String(t));
1328
1361
  }
1329
1362
  /**
1330
1363
  * Check if a date is today
@@ -1439,13 +1472,13 @@ class k {
1439
1472
  * @returns {string} HTML string
1440
1473
  */
1441
1474
  renderTimedEvent(t, e = {}) {
1442
- const { compact: r = !0, overlapLayout: i = null } = e, s = new Date(t.start), n = new Date(t.end), a = s.getHours() * 60 + s.getMinutes(), o = Math.max((n - s) / (1e3 * 60), r ? 20 : 30), c = this.getEventColor(t), l = this.getContrastingTextColor(c), d = r ? "4px 8px" : "8px 12px", p = r ? "11px" : "13px", g = r ? 2 : 12, b = r ? 2 : 24, T = r ? "4px" : "6px";
1475
+ const { compact: r = !0, overlapLayout: i = null } = e, s = new Date(t.start), n = new Date(t.end), a = s.getHours() * 60 + s.getMinutes(), o = Math.max((n - s) / (1e3 * 60), r ? 20 : 30), c = this.getEventColor(t), l = this.getContrastingTextColor(c), d = r ? "4px 8px" : "8px 12px", p = r ? "11px" : "13px", v = r ? 2 : 12, y = r ? 2 : 24, T = r ? "4px" : "6px";
1443
1476
  let x, w;
1444
1477
  if (i && i.has(t.id)) {
1445
- const { column: C, totalColumns: E } = i.get(t.id), $ = `(100% - ${g + b}px)`;
1446
- x = `calc(${g}px + ${C} * ${$} / ${E})`, w = `calc(${$} / ${E})`;
1478
+ const { column: C, totalColumns: E } = i.get(t.id), M = `(100% - ${v + y}px)`;
1479
+ x = `calc(${v}px + ${C} * ${M} / ${E})`, w = `calc(${M} / ${E})`;
1447
1480
  } else
1448
- x = `${g}px`, w = `calc(100% - ${g + b}px)`;
1481
+ x = `${v}px`, w = `calc(100% - ${v + y}px)`;
1449
1482
  return `
1450
1483
  <div class="fc-event fc-timed-event" data-event-id="${this.escapeHTML(t.id)}"
1451
1484
  style="position: absolute; top: ${a}px; height: ${o}px;
@@ -1485,7 +1518,7 @@ class k {
1485
1518
  });
1486
1519
  }
1487
1520
  }
1488
- class _ extends k {
1521
+ class _ extends D {
1489
1522
  constructor(t, e) {
1490
1523
  super(t, e), this.maxEventsToShow = 3;
1491
1524
  }
@@ -1560,7 +1593,7 @@ class _ extends k {
1560
1593
  }), this.attachCommonEventHandlers();
1561
1594
  }
1562
1595
  }
1563
- class z extends k {
1596
+ class V extends D {
1564
1597
  constructor(t, e) {
1565
1598
  super(t, e), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
1566
1599
  }
@@ -1699,7 +1732,7 @@ class z extends k {
1699
1732
  t && (t.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
1700
1733
  }
1701
1734
  }
1702
- class B extends k {
1735
+ class B extends D {
1703
1736
  constructor(t, e) {
1704
1737
  super(t, e), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
1705
1738
  }
@@ -1719,7 +1752,7 @@ class B extends k {
1719
1752
  const r = ((p = (d = this.stateManager) == null ? void 0 : d.getState()) == null ? void 0 : p.currentDate) || /* @__PURE__ */ new Date(), i = this._extractDayData(t, r);
1720
1753
  if (!i)
1721
1754
  return '<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for day view.</div>';
1722
- const { dayDate: s, dayName: n, isToday: a, allDayEvents: o, timedEvents: c } = i, l = Array.from({ length: 24 }, (g, b) => b);
1755
+ const { dayDate: s, dayName: n, isToday: a, allDayEvents: o, timedEvents: c } = i, l = Array.from({ length: 24 }, (v, y) => y);
1723
1756
  return `
1724
1757
  <div class="fc-day-view" style="display: flex; flex-direction: column; height: 100%; background: var(--fc-background); overflow: hidden;">
1725
1758
  ${this._renderHeader(s, n, a)}
@@ -1845,7 +1878,7 @@ class B extends k {
1845
1878
  t && (t.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
1846
1879
  }
1847
1880
  }
1848
- class A extends M {
1881
+ class A extends $ {
1849
1882
  constructor() {
1850
1883
  super(), this._isVisible = !1, this._cleanupFocusTrap = null, this.config = {
1851
1884
  title: "New Event",
@@ -2082,12 +2115,12 @@ class A extends M {
2082
2115
  <div class="color-options" id="color-picker" role="radiogroup" aria-labelledby="color-label">
2083
2116
  ${this.config.colors.map(
2084
2117
  (t) => `
2085
- <button type="button"
2086
- class="color-btn ${t.color === this._formData.color ? "selected" : ""}"
2087
- style="background-color: ${t.color}"
2088
- data-color="${t.color}"
2089
- title="${t.label}"
2090
- aria-label="${t.label}"
2118
+ <button type="button"
2119
+ class="color-btn ${t.color === this._formData.color ? "selected" : ""}"
2120
+ style="background-color: ${f.sanitizeColor(t.color)}"
2121
+ data-color="${g.escapeHTML(t.color)}"
2122
+ title="${g.escapeHTML(t.label)}"
2123
+ aria-label="${g.escapeHTML(t.label)}"
2091
2124
  aria-checked="${t.color === this._formData.color ? "true" : "false"}"
2092
2125
  role="radio"></button>
2093
2126
  `
@@ -2121,7 +2154,7 @@ class A extends M {
2121
2154
  });
2122
2155
  }
2123
2156
  open(t = /* @__PURE__ */ new Date()) {
2124
- this.hasAttribute("open") || this.setAttribute("open", ""), this.titleGroup.classList.remove("has-error"), this.endGroup.classList.remove("has-error"), this._formData.start = t, this._formData.end = new Date(t.getTime() + this.config.defaultDuration * 60 * 1e3), this._formData.title = "", this._formData.color = this.config.colors[0].color, this.startInput && (this.titleInput.value = "", this.startInput.value = this.formatDateForInput(this._formData.start), this.endInput.value = this.formatDateForInput(this._formData.end), this.updateColorSelection(), this._cleanupFocusTrap && this._cleanupFocusTrap(), this._cleanupFocusTrap = y.trapFocus(this.modalContent));
2157
+ this.hasAttribute("open") || this.setAttribute("open", ""), this.titleGroup.classList.remove("has-error"), this.endGroup.classList.remove("has-error"), this._formData.start = t, this._formData.end = new Date(t.getTime() + this.config.defaultDuration * 60 * 1e3), this._formData.title = "", this._formData.color = this.config.colors[0].color, this.startInput && (this.titleInput.value = "", this.startInput.value = this.formatDateForInput(this._formData.start), this.endInput.value = this.formatDateForInput(this._formData.end), this.updateColorSelection(), this._cleanupFocusTrap && this._cleanupFocusTrap(), this._cleanupFocusTrap = g.trapFocus(this.modalContent));
2125
2158
  }
2126
2159
  close() {
2127
2160
  this.removeAttribute("open"), this._cleanupFocusTrap && (this._cleanupFocusTrap(), this._cleanupFocusTrap = null);
@@ -2151,13 +2184,43 @@ class A extends M {
2151
2184
  }
2152
2185
  }
2153
2186
  customElements.get("forcecal-event-form") || customElements.define("forcecal-event-form", A);
2154
- const m = class m extends M {
2187
+ const b = class b extends $ {
2155
2188
  static get observedAttributes() {
2156
2189
  return ["view", "date", "locale", "timezone", "week-starts-on", "height"];
2157
2190
  }
2158
2191
  constructor() {
2159
2192
  super(), this.stateManager = null, this.currentView = null, this._hasRendered = !1, this._busUnsubscribers = [];
2160
2193
  }
2194
+ /**
2195
+ * Route observed-attribute changes into the StateManager.
2196
+ * Without this, attribute updates after mount (view, locale, timezone,
2197
+ * week-starts-on, date) only re-rendered from stale state and had no
2198
+ * visible effect. 'height' is presentational and picked up by render().
2199
+ */
2200
+ propChanged(t, e, r) {
2201
+ if (!(!this.stateManager || e === r))
2202
+ switch (t) {
2203
+ case "view":
2204
+ r && this.stateManager.setView(r);
2205
+ break;
2206
+ case "date": {
2207
+ const i = r ? new Date(r) : null;
2208
+ i && !isNaN(i.getTime()) && this.stateManager.setDate(i);
2209
+ break;
2210
+ }
2211
+ case "locale":
2212
+ r && this.stateManager.updateConfig({ locale: r });
2213
+ break;
2214
+ case "timezone":
2215
+ r && this.stateManager.updateConfig({ timeZone: r });
2216
+ break;
2217
+ case "week-starts-on": {
2218
+ const i = parseInt(r, 10);
2219
+ Number.isNaN(i) || this.stateManager.updateConfig({ weekStartsOn: i });
2220
+ break;
2221
+ }
2222
+ }
2223
+ }
2161
2224
  initialize() {
2162
2225
  const t = {
2163
2226
  view: this.getAttribute("view") || "month",
@@ -2166,7 +2229,7 @@ const m = class m extends M {
2166
2229
  timeZone: this.getAttribute("timezone") || Intl.DateTimeFormat().resolvedOptions().timeZone,
2167
2230
  weekStartsOn: parseInt(this.getAttribute("week-starts-on") || "0")
2168
2231
  };
2169
- this.stateManager = new V(t), this._stateUnsubscribe = this.stateManager.subscribe(this.handleStateChange.bind(this)), this.setupEventListeners();
2232
+ this.stateManager = new z(t), this._stateUnsubscribe = this.stateManager.subscribe(this.handleStateChange.bind(this)), this.setupEventListeners();
2170
2233
  }
2171
2234
  setupEventListeners() {
2172
2235
  this._busUnsubscribers.forEach((r) => r()), this._busUnsubscribers = [];
@@ -2256,7 +2319,7 @@ const m = class m extends M {
2256
2319
  if (t) {
2257
2320
  this._currentViewInstance && this._currentViewInstance.cleanup && this._currentViewInstance.cleanup();
2258
2321
  try {
2259
- const e = m.RENDERERS[this.currentView] || _, r = new e(t, this.stateManager);
2322
+ const e = b.RENDERERS[this.currentView] || _, r = new e(t, this.stateManager);
2260
2323
  r._viewType = this.currentView, this._currentViewInstance = r, r.render();
2261
2324
  } catch (e) {
2262
2325
  console.error("[ForceCalendar] Error switching view:", e);
@@ -2677,7 +2740,7 @@ const m = class m extends M {
2677
2740
  return `
2678
2741
  <div class="force-calendar">
2679
2742
  <div class="fc-error">
2680
- <p><strong>Error:</strong> ${y.escapeHTML(s.message || "An error occurred")}</p>
2743
+ <p><strong>Error:</strong> ${g.escapeHTML(s.message || "An error occurred")}</p>
2681
2744
  </div>
2682
2745
  </div>
2683
2746
  `;
@@ -2695,7 +2758,7 @@ const m = class m extends M {
2695
2758
  <button class="fc-nav-arrow" data-action="previous" title="Previous">
2696
2759
  ${this.getIcon("chevron-left")}
2697
2760
  </button>
2698
- <h2 class="fc-title">${y.escapeHTML(n)}</h2>
2761
+ <h2 class="fc-title">${g.escapeHTML(n)}</h2>
2699
2762
  <button class="fc-nav-arrow" data-action="next" title="Next">
2700
2763
  ${this.getIcon("chevron-right")}
2701
2764
  </button>
@@ -2740,7 +2803,7 @@ const m = class m extends M {
2740
2803
  return;
2741
2804
  this._currentViewInstance && (this._currentViewInstance.cleanup && this._currentViewInstance.cleanup(), this._viewUnsubscribe && (this._viewUnsubscribe(), this._viewUnsubscribe = null));
2742
2805
  try {
2743
- const i = m.RENDERERS[this.currentView] || _, s = new i(t, this.stateManager);
2806
+ const i = b.RENDERERS[this.currentView] || _, s = new i(t, this.stateManager);
2744
2807
  s._viewType = this.currentView, this._currentViewInstance = s, s.render();
2745
2808
  } catch (i) {
2746
2809
  console.error("[ForceCalendar] Error creating/rendering view:", i);
@@ -2850,25 +2913,25 @@ const m = class m extends M {
2850
2913
  this._busUnsubscribers.forEach((t) => t()), this._busUnsubscribers = [], this._stateUnsubscribe && (this._stateUnsubscribe(), this._stateUnsubscribe = null), this._currentViewInstance && this._currentViewInstance.cleanup && (this._currentViewInstance.cleanup(), this._currentViewInstance = null), this.stateManager && this.stateManager.destroy(), super.cleanup();
2851
2914
  }
2852
2915
  };
2853
- v(m, "RENDERERS", {
2916
+ m(b, "RENDERERS", {
2854
2917
  month: _,
2855
- week: z,
2918
+ week: V,
2856
2919
  day: B
2857
2920
  });
2858
- let D = m;
2859
- customElements.get("forcecal-main") || customElements.define("forcecal-main", D);
2921
+ let k = b;
2922
+ customElements.get("forcecal-main") || customElements.define("forcecal-main", k);
2860
2923
  export {
2861
- M as BaseComponent,
2862
- k as BaseViewRenderer,
2863
- y as DOMUtils,
2924
+ $ as BaseComponent,
2925
+ D as BaseViewRenderer,
2926
+ g as DOMUtils,
2864
2927
  u as DateUtils,
2865
2928
  B as DayViewRenderer,
2866
2929
  S as EventBus,
2867
- D as ForceCalendar,
2930
+ k as ForceCalendar,
2868
2931
  _ as MonthViewRenderer,
2869
- V as StateManager,
2932
+ z as StateManager,
2870
2933
  f as StyleUtils,
2871
- z as WeekViewRenderer,
2872
- U as eventBus
2934
+ V as WeekViewRenderer,
2935
+ j as eventBus
2873
2936
  };
2874
2937
  //# sourceMappingURL=force-calendar-interface.esm.js.map