@forcecalendar/interface 1.0.61 → 1.1.0

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,4 +1,4 @@
1
- (function(d,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("@forcecalendar/core")):typeof define=="function"&&define.amd?define(["exports","@forcecalendar/core"],f):(d=typeof globalThis<"u"?globalThis:d||self,f(d.ForceCalendarInterface={},d.ForceCalendarCore))})(this,function(d,f){"use strict";var A=Object.defineProperty;var R=(d,f,v)=>f in d?A(d,f,{enumerable:!0,configurable:!0,writable:!0,value:v}):d[f]=v;var w=(d,f,v)=>R(d,typeof f!="symbol"?f+"":f,v);class v extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._listeners=[],this._state=null,this._props=new Map,this._initialized=!1}connectedCallback(){this._initialized||(this.initialize(),this._initialized=!0),this.mount()}disconnectedCallback(){this.unmount(),this.cleanup(),this._styleEl=null,this._contentWrapper=null}initialize(){}mount(){this.render()}unmount(){}cleanup(){this._listeners.forEach(({element:t,event:e,handler:r})=>{t.removeEventListener(e,r)}),this._listeners=[]}setState(t){const e=this._state;this._state={...this._state,...t},this.stateChanged(e,this._state),this.render()}getState(){return this._state}stateChanged(t,e){}setProp(t,e){const r=this._props.get(t);this._props.set(t,e),this.propChanged(t,r,e)}getProp(t){return this._props.get(t)}propChanged(t,e,r){}addListener(t,e,r){if(!t||!e||!r){console.warn("addListener called with invalid parameters",{element:t,event:e,handler:r});return}const i=r.bind(this);t.addEventListener(e,i),this._listeners.push({element:t,event:e,handler:i})}emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e,bubbles:!0,composed:!0}))}getStyles(){return""}getBaseStyles(){return`
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("@forcecalendar/core")):typeof define==`function`&&define.amd?define([`exports`,`@forcecalendar/core`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ForceCalendarInterface={},e.ForceCalendarCore))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:`open`}),this._listeners=[],this._state=null,this._props=new Map,this._initialized=!1}connectedCallback(){this._initialized||=(this.initialize(),!0),this.mount()}disconnectedCallback(){this.unmount(),this.cleanup(),this._styleEl=null,this._contentWrapper=null}initialize(){}mount(){this.render()}unmount(){}cleanup(){this._listeners.forEach(({element:e,event:t,handler:n})=>{e.removeEventListener(t,n)}),this._listeners=[]}setState(e){let t=this._state;this._state={...this._state,...e},this.stateChanged(t,this._state),this.render()}getState(){return this._state}stateChanged(e,t){}setProp(e,t){let n=this._props.get(e);this._props.set(e,t),this.propChanged(e,n,t)}getProp(e){return this._props.get(e)}propChanged(e,t,n){}addListener(e,t,n){if(!e||!t||!n){console.warn(`addListener called with invalid parameters`,{element:e,event:t,handler:n});return}let r=n.bind(this);e.addEventListener(t,r),this._listeners.push({element:e,event:t,handler:r})}emit(e,t={}){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}getStyles(){return``}getBaseStyles(){return`
2
2
  :host {
3
3
  display: block;
4
4
  box-sizing: border-box;
@@ -7,11 +7,11 @@
7
7
  *, *::before, *::after {
8
8
  box-sizing: inherit;
9
9
  }
10
- `}render(){this.cleanup();const t=this.template();this._styleEl||(this._styleEl=document.createElement("style"),this.shadowRoot.appendChild(this._styleEl),this._contentWrapper=document.createElement("div"),this._contentWrapper.setAttribute("id","fc-root"),this._contentWrapper.style.display="contents",this.shadowRoot.appendChild(this._contentWrapper)),this._styleEl.textContent=this.getBaseStyles()+`
11
- `+this.getStyles();const e=this._saveScrollPositions(),r=this._getActiveElementSelector();this._contentWrapper.innerHTML=t,this._restoreScrollPositions(e),this._restoreFocus(r),this.afterRender()}_saveScrollPositions(){const t=new Map;return this._contentWrapper&&this._contentWrapper.querySelectorAll("[id]").forEach(r=>{(r.scrollTop!==0||r.scrollLeft!==0)&&t.set(r.id,{top:r.scrollTop,left:r.scrollLeft})}),t}_restoreScrollPositions(t){if(!this._contentWrapper||t.size===0)return;const e=typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape:r=>String(r).replace(/["\\]/g,"\\$&");t.forEach((r,i)=>{const s=this._contentWrapper.querySelector(`[id="${e(i)}"]`);s&&(s.scrollTop=r.top,s.scrollLeft=r.left)})}_getActiveElementSelector(){const t=this.shadowRoot.activeElement;return!t||t===this._contentWrapper?null:t.id?`[id="${CSS.escape(t.id)}"]`:t.dataset&&t.dataset.action?`[data-action="${CSS.escape(t.dataset.action)}"]`:t.dataset&&t.dataset.view?`[data-view="${CSS.escape(t.dataset.view)}"]`:t.tagName?t.tagName.toLowerCase():null}_restoreFocus(t){if(!(!t||!this._contentWrapper))try{const e=this._contentWrapper.querySelector(t);e&&typeof e.focus=="function"&&e.focus()}catch{}}template(){return""}afterRender(){}$(t){return this.shadowRoot.querySelector(t)}$$(t){return this.shadowRoot.querySelectorAll(t)}static get observedAttributes(){return[]}attributeChangedCallback(t,e,r){this.setProp(t,r),this._initialized&&this.render()}}class M{constructor(){this.events=new Map,this.wildcardHandlers=new Set}on(t,e,r={}){const{once:i=!1,priority:s=0}=r;if(t.includes("*")){const o={pattern:t,handler:e,once:i,priority:s};return this.wildcardHandlers.add(o),()=>this.wildcardHandlers.delete(o)}this.events.has(t)||this.events.set(t,[]);const n={handler:e,once:i,priority:s},a=this.events.get(t);return a.push(n),a.sort((o,c)=>c.priority-o.priority),()=>{const o=a.indexOf(n);o>-1&&a.splice(o,1)}}once(t,e,r={}){return this.on(t,e,{...r,once:!0})}off(t,e){if(t.includes("*")){for(const s of this.wildcardHandlers)if(s.pattern===t&&s.handler===e){this.wildcardHandlers.delete(s);return}return}if(!this.events.has(t))return;const r=this.events.get(t),i=r.findIndex(s=>s.handler===e);i>-1&&r.splice(i,1),r.length===0&&this.events.delete(t)}offWildcard(t){for(const e of[...this.wildcardHandlers])e.pattern===t&&this.wildcardHandlers.delete(e)}offAll(t){for(const[e,r]of this.events){const i=r.findIndex(s=>s.handler===t);i>-1&&r.splice(i,1),r.length===0&&this.events.delete(e)}for(const e of[...this.wildcardHandlers])e.handler===t&&this.wildcardHandlers.delete(e)}emit(t,e){if(this.events.has(t)){const i=[...this.events.get(t)];for(const s of i){const{handler:n,once:a}=s;a&&this.off(t,n);try{n(e,t)}catch(o){console.error(`Error in event handler for ${t}:`,o)}}}const r=[];for(const i of[...this.wildcardHandlers])if(this.matchesPattern(t,i.pattern)){const{handler:s,once:n}=i;n&&r.push(i);try{s(e,t)}catch(a){console.error(`Error in wildcard handler for ${t}:`,a)}}r.forEach(i=>this.wildcardHandlers.delete(i))}matchesPattern(t,e){const r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+r.replace(/\*/g,".*")+"$").test(t)}clear(){this.events.clear(),this.wildcardHandlers.clear()}getEventNames(){return Array.from(this.events.keys())}getHandlerCount(t){return this.events.has(t)?this.events.get(t).length:0}getWildcardHandlerCount(){return this.wildcardHandlers.size}getTotalHandlerCount(){let t=this.wildcardHandlers.size;for(const e of this.events.values())t+=e.length;return t}}const I=new M;class T{constructor(t={}){this.eventBus=new M,this.calendar=new f.Calendar({view:t.view||"month",date:t.date||new Date,weekStartsOn:t.weekStartsOn??0,locale:t.locale||"en-US",timeZone:t.timeZone||Intl.DateTimeFormat().resolvedOptions().timeZone,...t}),this.state={view:this.calendar.getView(),currentDate:this.calendar.getCurrentDate(),events:[],selectedEvent:null,selectedDate:null,loading:!1,error:null,config:{...t}},this.subscribers=new Set,this.subscribe=this.subscribe.bind(this),this.unsubscribe=this.unsubscribe.bind(this),this.setState=this.setState.bind(this),this._syncEventsFromCore({silent:!0})}_syncEventsFromCore(t={}){const{force:e=!1}=t,r=this.calendar.getEvents()||[];return(e||this.state.events.length!==r.length||!this._eventsMatch(this.state.events,r))&&this.setState({events:[...r]},t),r}_eventsMatch(t,e){if(t.length!==e.length)return!1;const r=new Set(t.map(i=>i.id));return e.every(i=>r.has(i.id))}getState(){return{...this.state,config:{...this.state.config},events:[...this.state.events]}}setState(t,e={}){const{silent:r=!1}=e,i={...this.state};return this.state={...this.state,...t},r||(this.notifySubscribers(i,this.state),this.emitStateChange(i,this.state)),this.state}subscribe(t,e=null){return this.subscribers.add(t),e&&(this._subscriberIds||(this._subscriberIds=new Map),this._subscriberIds.set(e,t)),()=>this.unsubscribe(t,e)}unsubscribe(t,e=null){this.subscribers.delete(t),e&&this._subscriberIds&&this._subscriberIds.delete(e)}unsubscribeById(t){if(!this._subscriberIds)return!1;const e=this._subscriberIds.get(t);return e?(this.subscribers.delete(e),this._subscriberIds.delete(t),!0):!1}getSubscriberCount(){return this.subscribers.size}notifySubscribers(t,e){this.subscribers.forEach(r=>{try{r(e,t)}catch(i){console.error("Error in state subscriber:",i)}})}emitStateChange(t,e){const r=Object.keys(e).filter(i=>t[i]!==e[i]);r.forEach(i=>{this.eventBus.emit(`state:${i}:changed`,{oldValue:t[i],newValue:e[i],state:e})}),r.length>0&&this.eventBus.emit("state:changed",{oldState:t,newState:e,changedKeys:r})}setView(t){this.calendar.setView(t),this.setState({view:t}),this.eventBus.emit("view:changed",{view:t})}getView(){return this.state.view}setDate(t){this.calendar.goToDate(t),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit("date:changed",{date:this.state.currentDate})}getCurrentDate(){return this.state.currentDate}next(){this.calendar.next(),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit("navigation:next",{date:this.state.currentDate})}previous(){this.calendar.previous(),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit("navigation:previous",{date:this.state.currentDate})}today(){this.calendar.today(),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit("navigation:today",{date:this.state.currentDate})}goToDate(t){this.calendar.goToDate(t),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit("navigation:goto",{date:this.state.currentDate})}addEvent(t){const e=this.calendar.addEvent(t);return e?(this._syncEventsFromCore(),this.eventBus.emit("event:add",{event:e}),this.eventBus.emit("event:added",{event:e}),e):(console.error("Failed to add event to calendar"),this.eventBus.emit("event:error",{action:"add",event:t,error:"Failed to add event"}),null)}updateEvent(t,e){this._syncEventsFromCore({silent:!0});const r=this.calendar.updateEvent(t,e);return r?(this._syncEventsFromCore({force:!0}),this.eventBus.emit("event:update",{event:r}),this.eventBus.emit("event:updated",{event:r}),r):(console.error(`Failed to update event: ${t}`),this.eventBus.emit("event:error",{action:"update",eventId:t,updates:e,error:"Event not found in calendar"}),null)}deleteEvent(t){return this._syncEventsFromCore({silent:!0}),this.calendar.removeEvent(t)?(this._syncEventsFromCore(),this.eventBus.emit("event:remove",{eventId:t}),this.eventBus.emit("event:deleted",{eventId:t}),!0):(console.error(`Failed to delete event: ${t}`),this.eventBus.emit("event:error",{action:"delete",eventId:t,error:"Event not found"}),!1)}getEvents(){return this.calendar.getEvents()||[]}syncEvents(){return this._syncEventsFromCore()}getEventsForDate(t){return this.calendar.getEventsForDate(t)}getEventsInRange(t,e){return this.calendar.getEventsInRange(t,e)}getViewData(){const t=this.calendar.getViewData();return this.enrichViewData(t)}enrichViewData(t){var i;const e={...t},r=(i=this.state.selectedDate)==null?void 0:i.toDateString();if(e.weeks&&(e.weeks=e.weeks.map(s=>({...s,days:s.days.map(n=>{const a=new Date(n.date);return{...n,isSelected:a.toDateString()===r,events:n.events||this.getEventsForDate(a)}})}))),e.days&&(e.days=e.days.map(s=>{const n=new Date(s.date);return{...s,isSelected:n.toDateString()===r,events:s.events||this.getEventsForDate(n)}})),e.date&&!e.days&&!e.weeks){const s=new Date(e.date);e.isSelected=s.toDateString()===r,e.events=e.events||this.getEventsForDate(s)}return e}selectEvent(t){this.setState({selectedEvent:t}),this.eventBus.emit("event:selected",{event:t})}selectEventById(t){const e=this.state.events.find(r=>r.id===t);e&&this.selectEvent(e)}deselectEvent(){this.setState({selectedEvent:null}),this.eventBus.emit("event:deselected",{})}selectDate(t){this.setState({selectedDate:t}),this.eventBus.emit("date:selected",{date:t})}deselectDate(){this.setState({selectedDate:null}),this.eventBus.emit("date:deselected",{})}isToday(t){const e=new Date;return t.toDateString()===e.toDateString()}isSelectedDate(t){return this.state.selectedDate&&t.toDateString()===this.state.selectedDate.toDateString()}isWeekend(t){const e=t.getDay();return e===0||e===6}setLoading(t){this.setState({loading:t})}setError(t){this.setState({error:t}),t&&this.eventBus.emit("error",{error:t})}clearError(){this.setState({error:null})}updateConfig(t){this.setState({config:{...this.state.config,...t}}),t.weekStartsOn!==void 0&&this.calendar.setWeekStartsOn(t.weekStartsOn),t.locale!==void 0&&this.calendar.setLocale(t.locale),t.timeZone!==void 0&&this.calendar.setTimezone(t.timeZone)}destroy(){this.subscribers.clear(),this._subscriberIds&&(this._subscriberIds.clear(),this._subscriberIds=null),this.eventBus&&(this.eventBus.clear(),this.eventBus=null),this.state=null,this.calendar=null}}class p extends f.DateUtils{static formatDate(t,e="default",r="en-US"){if(!t)return"";const i={default:{year:"numeric",month:"long",day:"numeric"},short:{year:"numeric",month:"short",day:"numeric"},long:{weekday:"long",year:"numeric",month:"long",day:"numeric"},month:{year:"numeric",month:"long"},monthShort:{year:"numeric",month:"short"},day:{weekday:"long",day:"numeric"},dayShort:{weekday:"short",day:"numeric"},time:{hour:"numeric",minute:"2-digit"},timeShort:{hour:"numeric"},datetime:{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}},s=i[e]||i.default;return new Intl.DateTimeFormat(r,s).format(t)}static formatTime(t,e=!0,r=!1,i="en-US"){if(!t)return"";const s={hour:"numeric",minute:e?"2-digit":void 0,hour12:!r};return new Intl.DateTimeFormat(i,s).format(t)}static formatDateRange(t,e,r="en-US"){if(!t)return"";if(!e||this.isSameDay(t,e))return this.formatDate(t,"default",r);const i=this.isSameYear(t,e)?"short":"default";return`${this.formatDate(t,i,r)} - ${this.formatDate(e,"default",r)}`}static formatTimeRange(t,e,r="en-US"){if(!t)return"";const i=this.formatTime(t,!0,!1,r);if(!e)return i;const s=this.formatTime(e,!0,!1,r);return`${i} - ${s}`}static getRelativeTime(t,e=new Date,r="en-US"){const i=new Intl.RelativeTimeFormat(r,{numeric:"auto"}),s=t-e,n=Math.floor(s/1e3),a=Math.floor(n/60),o=Math.floor(a/60),c=Math.floor(o/24),l=Math.floor(c/7),h=Math.floor(c/30),b=Math.floor(c/365);return Math.abs(n)<60?i.format(n,"second"):Math.abs(a)<60?i.format(a,"minute"):Math.abs(o)<24?i.format(o,"hour"):Math.abs(c)<7?i.format(c,"day"):Math.abs(l)<4?i.format(l,"week"):Math.abs(h)<12?i.format(h,"month"):i.format(b,"year")}static isToday(t){const e=new Date;return this.isSameDay(t,e)}static isPast(t){return t<new Date}static isFuture(t){return t>new Date}static getWeekNumber(t){const e=new Date(t.getFullYear(),0,1),r=(t-e)/864e5;return Math.ceil((r+e.getDay()+1)/7)}static getDayAbbreviation(t,e="en-US"){const r=new Date(2024,0,7+t);return new Intl.DateTimeFormat(e,{weekday:"short"}).format(r)}static getDayName(t,e="en-US"){const r=new Date(2024,0,7+t);return new Intl.DateTimeFormat(e,{weekday:"long"}).format(r)}static getMonthName(t,e="long",r="en-US"){const i=new Date(2024,t,1);return new Intl.DateTimeFormat(r,{month:e}).format(i)}static parseTimeString(t,e=new Date){const r=new Date(e),[i,s]=t.split(/\s+/),[n,a]=i.split(":").map(Number);let o=n;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}}class m{static createElement(t,e={},r=[]){const i=document.createElement(t);return Object.entries(e).forEach(([s,n])=>{if(s==="className")i.className=n;else if(s==="style"&&typeof n=="object")Object.assign(i.style,n);else if(s.startsWith("data-"))i.setAttribute(s,n);else if(s.startsWith("on")&&typeof n=="function"){const a=s.slice(2).toLowerCase();i.addEventListener(a,n)}else i[s]=n}),r.forEach(s=>{typeof s=="string"?i.appendChild(document.createTextNode(s)):s instanceof Node&&i.appendChild(s)}),i}static addEventListeners(t,e){return Object.entries(e).forEach(([r,i])=>{t.addEventListener(r,i)}),()=>{Object.entries(e).forEach(([r,i])=>{t.removeEventListener(r,i)})}}static delegate(t,e,r,i){const s=n=>{const a=n.target.closest(e);a&&t.contains(a)&&i.call(a,n)};return t.addEventListener(r,s),()=>t.removeEventListener(r,s)}static getPosition(t){const e=t.getBoundingClientRect();return{top:e.top+window.scrollY,left:e.left+window.scrollX,bottom:e.bottom+window.scrollY,right:e.right+window.scrollX,width:e.width,height:e.height}}static isInViewport(t,e=0){const r=t.getBoundingClientRect();return r.top>=-e&&r.left>=-e&&r.bottom<=(window.innerHeight||document.documentElement.clientHeight)+e&&r.right<=(window.innerWidth||document.documentElement.clientWidth)+e}static scrollToElement(t,e={}){const{behavior:r="smooth",block:i="start",inline:s="nearest"}=e;t.scrollIntoView({behavior:r,block:i,inline:s})}static getStyle(t,e){return window.getComputedStyle(t).getPropertyValue(e)}static setStyles(t,e){Object.assign(t.style,e)}static async animateClass(t,e,r=300){t.classList.add(e),await this.wait(r),t.classList.remove(e)}static waitForAnimation(t,e="animationend",r=3e3){return new Promise(i=>{let s=null;const n=()=>{s!==null&&clearTimeout(s),t.removeEventListener(e,n),i()};t.addEventListener(e,n),r>0&&(s=setTimeout(n,r))})}static wait(t){return new Promise(e=>setTimeout(e,t))}static parseHTML(t,{sanitize:e=!0}={}){const r=document.createElement("template");return r.innerHTML=t.trim(),e&&this._sanitizeNode(r.content),r.content.firstChild}static _sanitizeNode(t){t.querySelectorAll("script, iframe, object, embed, link, meta, base").forEach(s=>s.remove());const r=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT);let i=r.nextNode();for(;i;){for(const s of Array.from(i.attributes)){const n=s.name.toLowerCase(),a=s.value.replace(/[\u0000-\u0020]/g,"").toLowerCase();(n.startsWith("on")||a.startsWith("javascript:")||a.startsWith("data:text/html"))&&i.removeAttribute(s.name)}i=r.nextNode()}}static escapeHTML(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}static debounce(t,e=250){let r;return function(...s){clearTimeout(r),r=setTimeout(()=>t.apply(this,s),e)}}static throttle(t,e=250){let r;return function(...i){r||(t.apply(this,i),r=!0,setTimeout(()=>r=!1,e))}}static closest(t,e){return t.closest(e)}static parents(t,e){const r=[];let i=t.parentElement;for(;i;)i.matches(e)&&r.push(i),i=i.parentElement;return r}static getOuterDimensions(t){const e=window.getComputedStyle(t),r={top:parseInt(e.marginTop),right:parseInt(e.marginRight),bottom:parseInt(e.marginBottom),left:parseInt(e.marginLeft)};return{width:t.offsetWidth+r.left+r.right,height:t.offsetHeight+r.top+r.bottom,margin:r}}static cloneWithEvents(t,e=!0){return t.cloneNode(e)}static trapFocus(t){const e=t.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(e.length===0)return t.setAttribute("tabindex","-1"),t.focus(),()=>t.removeAttribute("tabindex");const r=e[0],i=e[e.length-1],s=n=>{if(n.key!=="Tab")return;const o=t.getRootNode().activeElement??document.activeElement;n.shiftKey?o===r&&(i==null||i.focus(),n.preventDefault()):o===i&&(r==null||r.focus(),n.preventDefault())};return t.addEventListener("keydown",s),r==null||r.focus(),()=>t.removeEventListener("keydown",s)}}class u{static getCSSVariable(t,e=document.documentElement){return getComputedStyle(e).getPropertyValue(t).trim()}static setCSSVariables(t,e=document.documentElement){Object.entries(t).forEach(([r,i])=>{e.style.setProperty(r,i)})}static getBaseStyles(){return`
10
+ `}render(){this.cleanup();let e=this.template();this._styleEl||(this._styleEl=document.createElement(`style`),this.shadowRoot.appendChild(this._styleEl),this._contentWrapper=document.createElement(`div`),this._contentWrapper.setAttribute(`id`,`fc-root`),this._contentWrapper.style.display=`contents`,this.shadowRoot.appendChild(this._contentWrapper)),this._styleEl.textContent=this.getBaseStyles()+`
11
+ `+this.getStyles();let t=this._saveScrollPositions(),n=this._getActiveElementSelector();this._contentWrapper.innerHTML=e,this._restoreScrollPositions(t),this._restoreFocus(n),this.afterRender()}_saveScrollPositions(){let e=new Map;return this._contentWrapper&&this._contentWrapper.querySelectorAll(`[id]`).forEach(t=>{(t.scrollTop!==0||t.scrollLeft!==0)&&e.set(t.id,{top:t.scrollTop,left:t.scrollLeft})}),e}_restoreScrollPositions(e){if(!this._contentWrapper||e.size===0)return;let t=typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape:e=>String(e).replace(/["\\]/g,`\\$&`);e.forEach((e,n)=>{let r=this._contentWrapper.querySelector(`[id="${t(n)}"]`);r&&(r.scrollTop=e.top,r.scrollLeft=e.left)})}_getActiveElementSelector(){let e=this.shadowRoot.activeElement;return!e||e===this._contentWrapper?null:e.id?`[id="${CSS.escape(e.id)}"]`:e.dataset&&e.dataset.action?`[data-action="${CSS.escape(e.dataset.action)}"]`:e.dataset&&e.dataset.view?`[data-view="${CSS.escape(e.dataset.view)}"]`:e.tagName?e.tagName.toLowerCase():null}_restoreFocus(e){if(!(!e||!this._contentWrapper))try{let t=this._contentWrapper.querySelector(e);t&&typeof t.focus==`function`&&t.focus()}catch{}}template(){return``}afterRender(){}$(e){return this.shadowRoot.querySelector(e)}$$(e){return this.shadowRoot.querySelectorAll(e)}static get observedAttributes(){return[]}attributeChangedCallback(e,t,n){this.setProp(e,n),this._initialized&&this.render()}},r=class{constructor(){this.events=new Map,this.wildcardHandlers=new Set}on(e,t,n={}){let{once:r=!1,priority:i=0}=n;if(e.includes(`*`)){let n={pattern:e,handler:t,once:r,priority:i};return this.wildcardHandlers.add(n),()=>this.wildcardHandlers.delete(n)}this.events.has(e)||this.events.set(e,[]);let a={handler:t,once:r,priority:i},o=this.events.get(e);return o.push(a),o.sort((e,t)=>t.priority-e.priority),()=>{let e=o.indexOf(a);e>-1&&o.splice(e,1)}}once(e,t,n={}){return this.on(e,t,{...n,once:!0})}off(e,t){if(e.includes(`*`)){for(let n of this.wildcardHandlers)if(n.pattern===e&&n.handler===t){this.wildcardHandlers.delete(n);return}return}if(!this.events.has(e))return;let n=this.events.get(e),r=n.findIndex(e=>e.handler===t);r>-1&&n.splice(r,1),n.length===0&&this.events.delete(e)}offWildcard(e){for(let t of[...this.wildcardHandlers])t.pattern===e&&this.wildcardHandlers.delete(t)}offAll(e){for(let[t,n]of this.events){let r=n.findIndex(t=>t.handler===e);r>-1&&n.splice(r,1),n.length===0&&this.events.delete(t)}for(let t of[...this.wildcardHandlers])t.handler===e&&this.wildcardHandlers.delete(t)}emit(e,t){if(this.events.has(e)){let n=[...this.events.get(e)];for(let r of n){let{handler:n,once:i}=r;i&&this.off(e,n);try{n(t,e)}catch(t){console.error(`Error in event handler for ${e}:`,t)}}}let n=[];for(let r of[...this.wildcardHandlers])if(this.matchesPattern(e,r.pattern)){let{handler:i,once:a}=r;a&&n.push(r);try{i(t,e)}catch(t){console.error(`Error in wildcard handler for ${e}:`,t)}}n.forEach(e=>this.wildcardHandlers.delete(e))}matchesPattern(e,t){let n=t.replace(/[.+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`^`+n.replace(/\*/g,`.*`)+`$`).test(e)}clear(){this.events.clear(),this.wildcardHandlers.clear()}getEventNames(){return Array.from(this.events.keys())}getHandlerCount(e){return this.events.has(e)?this.events.get(e).length:0}getWildcardHandlerCount(){return this.wildcardHandlers.size}getTotalHandlerCount(){let e=this.wildcardHandlers.size;for(let t of this.events.values())e+=t.length;return e}},i=new r,a=class{constructor(e={}){this.eventBus=new r,this.calendar=new t.Calendar({view:e.view||`month`,date:e.date||new Date,weekStartsOn:e.weekStartsOn??0,locale:e.locale||`en-US`,timeZone:e.timeZone||Intl.DateTimeFormat().resolvedOptions().timeZone,...e}),this.state={view:this.calendar.getView(),currentDate:this.calendar.getCurrentDate(),events:[],selectedEvent:null,selectedDate:null,loading:!1,error:null,config:{...e}},this.subscribers=new Set,this.subscribe=this.subscribe.bind(this),this.unsubscribe=this.unsubscribe.bind(this),this.setState=this.setState.bind(this),this._syncEventsFromCore({silent:!0})}_syncEventsFromCore(e={}){let{force:t=!1}=e,n=this.calendar.getEvents()||[];return(t||this.state.events.length!==n.length||!this._eventsMatch(this.state.events,n))&&this.setState({events:[...n]},e),n}_eventsMatch(e,t){if(e.length!==t.length)return!1;let n=new Set(e.map(e=>e.id));return t.every(e=>n.has(e.id))}getState(){return{...this.state,config:{...this.state.config},events:[...this.state.events]}}setState(e,t={}){let{silent:n=!1}=t,r={...this.state};return this.state={...this.state,...e},n||(this.notifySubscribers(r,this.state),this.emitStateChange(r,this.state)),this.state}subscribe(e,t=null){return this.subscribers.add(e),t&&(this._subscriberIds||=new Map,this._subscriberIds.set(t,e)),()=>this.unsubscribe(e,t)}unsubscribe(e,t=null){this.subscribers.delete(e),t&&this._subscriberIds&&this._subscriberIds.delete(t)}unsubscribeById(e){if(!this._subscriberIds)return!1;let t=this._subscriberIds.get(e);return t?(this.subscribers.delete(t),this._subscriberIds.delete(e),!0):!1}getSubscriberCount(){return this.subscribers.size}notifySubscribers(e,t){this.subscribers.forEach(n=>{try{n(t,e)}catch(e){console.error(`Error in state subscriber:`,e)}})}emitStateChange(e,t){let n=Object.keys(t).filter(n=>e[n]!==t[n]);n.forEach(n=>{this.eventBus.emit(`state:${n}:changed`,{oldValue:e[n],newValue:t[n],state:t})}),n.length>0&&this.eventBus.emit(`state:changed`,{oldState:e,newState:t,changedKeys:n})}setView(e){this.calendar.setView(e),this.setState({view:e}),this.eventBus.emit(`view:changed`,{view:e})}getView(){return this.state.view}setDate(e){this.calendar.goToDate(e),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit(`date:changed`,{date:this.state.currentDate})}getCurrentDate(){return this.state.currentDate}next(){this.calendar.next(),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit(`navigation:next`,{date:this.state.currentDate})}previous(){this.calendar.previous(),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit(`navigation:previous`,{date:this.state.currentDate})}today(){this.calendar.today(),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit(`navigation:today`,{date:this.state.currentDate})}goToDate(e){this.calendar.goToDate(e),this.setState({currentDate:this.calendar.getCurrentDate()}),this.eventBus.emit(`navigation:goto`,{date:this.state.currentDate})}addEvent(e){let t=this.calendar.addEvent(e);return t?(this._syncEventsFromCore(),this.eventBus.emit(`event:add`,{event:t}),this.eventBus.emit(`event:added`,{event:t}),t):(console.error(`Failed to add event to calendar`),this.eventBus.emit(`event:error`,{action:`add`,event:e,error:`Failed to add event`}),null)}updateEvent(e,t){this._syncEventsFromCore({silent:!0});let n=this.calendar.updateEvent(e,t);return n?(this._syncEventsFromCore({force:!0}),this.eventBus.emit(`event:update`,{event:n}),this.eventBus.emit(`event:updated`,{event:n}),n):(console.error(`Failed to update event: ${e}`),this.eventBus.emit(`event:error`,{action:`update`,eventId:e,updates:t,error:`Event not found in calendar`}),null)}deleteEvent(e){return this._syncEventsFromCore({silent:!0}),this.calendar.removeEvent(e)?(this._syncEventsFromCore(),this.eventBus.emit(`event:remove`,{eventId:e}),this.eventBus.emit(`event:deleted`,{eventId:e}),!0):(console.error(`Failed to delete event: ${e}`),this.eventBus.emit(`event:error`,{action:`delete`,eventId:e,error:`Event not found`}),!1)}getEvents(){return this.calendar.getEvents()||[]}syncEvents(){return this._syncEventsFromCore()}getEventsForDate(e){return this.calendar.getEventsForDate(e)}getEventsInRange(e,t){return this.calendar.getEventsInRange(e,t)}getViewData(){let e=this.calendar.getViewData();return this.enrichViewData(e)}enrichViewData(e){let t={...e},n=this.state.selectedDate?.toDateString();if(t.weeks&&=t.weeks.map(e=>({...e,days:e.days.map(e=>{let t=new Date(e.date);return{...e,isSelected:t.toDateString()===n,events:e.events||this.getEventsForDate(t)}})})),t.days&&=t.days.map(e=>{let t=new Date(e.date);return{...e,isSelected:t.toDateString()===n,events:e.events||this.getEventsForDate(t)}}),t.date&&!t.days&&!t.weeks){let e=new Date(t.date);t.isSelected=e.toDateString()===n,t.events=t.events||this.getEventsForDate(e)}return t}selectEvent(e){this.setState({selectedEvent:e}),this.eventBus.emit(`event:selected`,{event:e})}selectEventById(e){let t=this.state.events.find(t=>t.id===e);t&&this.selectEvent(t)}deselectEvent(){this.setState({selectedEvent:null}),this.eventBus.emit(`event:deselected`,{})}selectDate(e){this.setState({selectedDate:e}),this.eventBus.emit(`date:selected`,{date:e})}deselectDate(){this.setState({selectedDate:null}),this.eventBus.emit(`date:deselected`,{})}isToday(e){let t=new Date;return e.toDateString()===t.toDateString()}isSelectedDate(e){return this.state.selectedDate&&e.toDateString()===this.state.selectedDate.toDateString()}isWeekend(e){let t=e.getDay();return t===0||t===6}setLoading(e){this.setState({loading:e})}setError(e){this.setState({error:e}),e&&this.eventBus.emit(`error`,{error:e})}clearError(){this.setState({error:null})}updateConfig(e){this.setState({config:{...this.state.config,...e}}),e.weekStartsOn!==void 0&&this.calendar.setWeekStartsOn(e.weekStartsOn),e.locale!==void 0&&this.calendar.setLocale(e.locale),e.timeZone!==void 0&&this.calendar.setTimezone(e.timeZone)}destroy(){this.subscribers.clear(),this._subscriberIds&&=(this._subscriberIds.clear(),null),this.eventBus&&=(this.eventBus.clear(),null),this.state=null,this.calendar=null}},o=class extends t.DateUtils{static formatDate(e,t=`default`,n=`en-US`){if(!e)return``;let r={default:{year:`numeric`,month:`long`,day:`numeric`},short:{year:`numeric`,month:`short`,day:`numeric`},long:{weekday:`long`,year:`numeric`,month:`long`,day:`numeric`},month:{year:`numeric`,month:`long`},monthShort:{year:`numeric`,month:`short`},day:{weekday:`long`,day:`numeric`},dayShort:{weekday:`short`,day:`numeric`},time:{hour:`numeric`,minute:`2-digit`},timeShort:{hour:`numeric`},datetime:{year:`numeric`,month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`}},i=r[t]||r.default;return new Intl.DateTimeFormat(n,i).format(e)}static formatTime(e,t=!0,n=!1,r=`en-US`){if(!e)return``;let i={hour:`numeric`,minute:t?`2-digit`:void 0,hour12:!n};return new Intl.DateTimeFormat(r,i).format(e)}static formatDateRange(e,t,n=`en-US`){if(!e)return``;if(!t||this.isSameDay(e,t))return this.formatDate(e,`default`,n);let r=this.isSameYear(e,t)?`short`:`default`;return`${this.formatDate(e,r,n)} - ${this.formatDate(t,`default`,n)}`}static formatTimeRange(e,t,n=`en-US`){if(!e)return``;let r=this.formatTime(e,!0,!1,n);return t?`${r} - ${this.formatTime(t,!0,!1,n)}`:r}static getRelativeTime(e,t=new Date,n=`en-US`){let r=new Intl.RelativeTimeFormat(n,{numeric:`auto`}),i=e-t,a=Math.floor(i/1e3),o=Math.floor(a/60),s=Math.floor(o/60),c=Math.floor(s/24),l=Math.floor(c/7),u=Math.floor(c/30),d=Math.floor(c/365);return Math.abs(a)<60?r.format(a,`second`):Math.abs(o)<60?r.format(o,`minute`):Math.abs(s)<24?r.format(s,`hour`):Math.abs(c)<7?r.format(c,`day`):Math.abs(l)<4?r.format(l,`week`):Math.abs(u)<12?r.format(u,`month`):r.format(d,`year`)}static isToday(e){let t=new Date;return this.isSameDay(e,t)}static isPast(e){return e<new Date}static isFuture(e){return e>new Date}static getWeekNumber(e){let t=new Date(e.getFullYear(),0,1),n=(e-t)/864e5;return Math.ceil((n+t.getDay()+1)/7)}static getDayAbbreviation(e,t=`en-US`){let n=new Date(2024,0,7+e);return new Intl.DateTimeFormat(t,{weekday:`short`}).format(n)}static getDayName(e,t=`en-US`){let n=new Date(2024,0,7+e);return new Intl.DateTimeFormat(t,{weekday:`long`}).format(n)}static getMonthName(e,t=`long`,n=`en-US`){let r=new Date(2024,e,1);return new Intl.DateTimeFormat(n,{month:t}).format(r)}static parseTimeString(e,t=new Date){let n=new Date(t),[r,i]=e.split(/\s+/),[a,o]=r.split(`:`).map(Number),s=a;return i&&(i.toLowerCase()===`pm`&&a<12?s=a+12:i.toLowerCase()===`am`&&a===12&&(s=0)),n.setHours(s,o||0,0,0),n}},s=class{static createElement(e,t={},n=[]){let r=document.createElement(e);return Object.entries(t).forEach(([e,t])=>{if(e===`className`)r.className=t;else if(e===`style`&&typeof t==`object`)Object.assign(r.style,t);else if(e.startsWith(`data-`))r.setAttribute(e,t);else if(e.startsWith(`on`)&&typeof t==`function`){let n=e.slice(2).toLowerCase();r.addEventListener(n,t)}else r[e]=t}),n.forEach(e=>{typeof e==`string`?r.appendChild(document.createTextNode(e)):e instanceof Node&&r.appendChild(e)}),r}static addEventListeners(e,t){return Object.entries(t).forEach(([t,n])=>{e.addEventListener(t,n)}),()=>{Object.entries(t).forEach(([t,n])=>{e.removeEventListener(t,n)})}}static delegate(e,t,n,r){let i=n=>{let i=n.target.closest(t);i&&e.contains(i)&&r.call(i,n)};return e.addEventListener(n,i),()=>e.removeEventListener(n,i)}static getPosition(e){let t=e.getBoundingClientRect();return{top:t.top+window.scrollY,left:t.left+window.scrollX,bottom:t.bottom+window.scrollY,right:t.right+window.scrollX,width:t.width,height:t.height}}static isInViewport(e,t=0){let n=e.getBoundingClientRect();return n.top>=-t&&n.left>=-t&&n.bottom<=(window.innerHeight||document.documentElement.clientHeight)+t&&n.right<=(window.innerWidth||document.documentElement.clientWidth)+t}static scrollToElement(e,t={}){let{behavior:n=`smooth`,block:r=`start`,inline:i=`nearest`}=t;e.scrollIntoView({behavior:n,block:r,inline:i})}static getStyle(e,t){return window.getComputedStyle(e).getPropertyValue(t)}static setStyles(e,t){Object.assign(e.style,t)}static async animateClass(e,t,n=300){e.classList.add(t),await this.wait(n),e.classList.remove(t)}static waitForAnimation(e,t=`animationend`,n=3e3){return new Promise(r=>{let i=null,a=()=>{i!==null&&clearTimeout(i),e.removeEventListener(t,a),r()};e.addEventListener(t,a),n>0&&(i=setTimeout(a,n))})}static wait(e){return new Promise(t=>setTimeout(t,e))}static parseHTML(e,{sanitize:t=!0}={}){let n=document.createElement(`template`);return n.innerHTML=e.trim(),t&&this._sanitizeNode(n.content),n.content.firstChild}static _sanitizeNode(e){e.querySelectorAll(`script, iframe, object, embed, link, meta, base`).forEach(e=>e.remove());let t=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),n=t.nextNode();for(;n;){for(let e of Array.from(n.attributes)){let t=e.name.toLowerCase(),r=e.value.replace(/[\u0000-\u0020]/g,``).toLowerCase();(t.startsWith(`on`)||r.startsWith(`javascript:`)||r.startsWith(`data:text/html`))&&n.removeAttribute(e.name)}n=t.nextNode()}}static escapeHTML(e){let t=document.createElement(`div`);return t.textContent=e,t.innerHTML}static debounce(e,t=250){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>e.apply(this,r),t)}}static throttle(e,t=250){let n;return function(...r){n||(e.apply(this,r),n=!0,setTimeout(()=>n=!1,t))}}static closest(e,t){return e.closest(t)}static parents(e,t){let n=[],r=e.parentElement;for(;r;)r.matches(t)&&n.push(r),r=r.parentElement;return n}static getOuterDimensions(e){let t=window.getComputedStyle(e),n={top:parseInt(t.marginTop),right:parseInt(t.marginRight),bottom:parseInt(t.marginBottom),left:parseInt(t.marginLeft)};return{width:e.offsetWidth+n.left+n.right,height:e.offsetHeight+n.top+n.bottom,margin:n}}static cloneWithEvents(e,t=!0){return e.cloneNode(t)}static trapFocus(e){let t=e.querySelectorAll(`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`);if(t.length===0)return e.setAttribute(`tabindex`,`-1`),e.focus(),()=>e.removeAttribute(`tabindex`);let n=t[0],r=t[t.length-1],i=t=>{if(t.key!==`Tab`)return;let i=e.getRootNode().activeElement??document.activeElement;t.shiftKey?i===n&&(r?.focus(),t.preventDefault()):i===r&&(n?.focus(),t.preventDefault())};return e.addEventListener(`keydown`,i),n?.focus(),()=>e.removeEventListener(`keydown`,i)}},c=class{static colors={primary:`#3B82F6`,secondary:`#64748B`,accent:`#F59E0B`,danger:`#EF4444`,warning:`#F97316`,info:`#06B6D4`,success:`#22C55E`,light:`#F8FAFC`,dark:`#0F172A`,white:`#FFFFFF`,gray:{50:`#F8FAFC`,100:`#F1F5F9`,200:`#E2E8F0`,300:`#CBD5E1`,400:`#94A3B8`,500:`#64748B`,600:`#475569`,700:`#334155`,800:`#1E293B`,900:`#0F172A`}};static cssVariables={"--fc-primary-color":`#2563EB`,"--fc-primary-hover":`#1D4ED8`,"--fc-primary-light":`#EFF6FF`,"--fc-text-color":`#111827`,"--fc-text-secondary":`#6B7280`,"--fc-text-light":`#9CA3AF`,"--fc-border-color":`#E5E7EB`,"--fc-border-color-hover":`#D1D5DB`,"--fc-background":`#FFFFFF`,"--fc-background-alt":`#FAFAFA`,"--fc-background-hover":`#F3F4F6`,"--fc-background-active":`#E5E7EB`,"--fc-accent-color":`#F59E0B`,"--fc-danger-color":`#EF4444`,"--fc-success-color":`#10B981`,"--fc-font-family":`Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`,"--fc-font-size-xs":`11px`,"--fc-font-size-sm":`12px`,"--fc-font-size-base":`13px`,"--fc-font-size-lg":`15px`,"--fc-font-size-xl":`18px`,"--fc-font-size-2xl":`24px`,"--fc-line-height":`1.4`,"--fc-font-weight-normal":`400`,"--fc-font-weight-medium":`500`,"--fc-font-weight-semibold":`600`,"--fc-font-weight-bold":`700`,"--fc-spacing-xs":`2px`,"--fc-spacing-sm":`6px`,"--fc-spacing-md":`10px`,"--fc-spacing-lg":`14px`,"--fc-spacing-xl":`20px`,"--fc-spacing-2xl":`28px`,"--fc-border-width":`1px`,"--fc-border-radius-sm":`3px`,"--fc-border-radius":`5px`,"--fc-border-radius-lg":`8px`,"--fc-border-radius-full":`9999px`,"--fc-shadow-sm":`0 1px 1px rgba(0,0,0,0.05)`,"--fc-shadow":`0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06)`,"--fc-shadow-md":`0 4px 6px -1px rgba(0, 0, 0, 0.1)`,"--fc-shadow-lg":`0 10px 15px -3px rgba(0, 0, 0, 0.1)`,"--fc-transition-fast":`100ms ease-out`,"--fc-transition":`150ms ease-out`,"--fc-transition-slow":`250ms ease-out`,"--fc-z-dropdown":`1000`,"--fc-z-modal":`2000`,"--fc-z-tooltip":`3000`};static getCSSVariable(e,t=document.documentElement){return getComputedStyle(t).getPropertyValue(e).trim()}static setCSSVariables(e,t=document.documentElement){Object.entries(e).forEach(([e,n])=>{t.style.setProperty(e,n)})}static getBaseStyles(){return`
12
12
  :host {
13
13
  /* Apply CSS variables */
14
- ${Object.entries(this.cssVariables).map(([t,e])=>`${t}: ${e};`).join(`
14
+ ${Object.entries(this.cssVariables).map(([e,t])=>`${e}: ${t};`).join(`
15
15
  `)}
16
16
 
17
17
  /* Base styles */
@@ -145,7 +145,7 @@
145
145
  padding: 0;
146
146
  border-radius: var(--fc-border-radius-full);
147
147
  }
148
- `}static darken(t,e){const r=parseInt(t.replace("#",""),16),i=Math.round(2.55*e),s=(r>>16)-i,n=(r>>8&255)-i,a=(r&255)-i;return"#"+(16777216+(s<255?s<1?0:s:255)*65536+(n<255?n<1?0:n:255)*256+(a<255?a<1?0:a:255)).toString(16).slice(1)}static lighten(t,e){const r=parseInt(t.replace("#",""),16),i=Math.round(2.55*e),s=(r>>16)+i,n=(r>>8&255)+i,a=(r&255)+i;return"#"+(16777216+(s<255?s<1?0:s:255)*65536+(n<255?n<1?0:n:255)*256+(a<255?a<1?0:a:255)).toString(16).slice(1)}static getContrastColor(t){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);return(r*299+i*587+s*114)/1e3>=128?"#000000":"#FFFFFF"}static sanitizeColor(t,e="var(--fc-primary-color)"){if(!t||typeof t!="string")return e;const r=t.trim();return/[;{}()<>\"\'\\]/.test(r)?e:/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(r)||/^var\(--[a-zA-Z0-9-]+\)$/.test(r)||/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*(0|1|0?\.\d+))?\s*\)$/.test(r)||["transparent","currentColor","inherit","black","white","red","green","blue","yellow","orange","purple","pink","brown","gray","grey","cyan","magenta","lime","navy","teal","aqua","maroon","olive","silver","fuchsia"].includes(r.toLowerCase())?r:e}static hexToRgba(t,e=1){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);return`rgba(${i}, ${s}, ${n}, ${e})`}static getGridStyles(){return`
148
+ `}static darken(e,t){let n=parseInt(e.replace(`#`,``),16),r=Math.round(2.55*t),i=(n>>16)-r,a=(n>>8&255)-r,o=(n&255)-r;return`#`+(16777216+(i<255?i<1?0:i:255)*65536+(a<255?a<1?0:a:255)*256+(o<255?o<1?0:o:255)).toString(16).slice(1)}static lighten(e,t){let n=parseInt(e.replace(`#`,``),16),r=Math.round(2.55*t),i=(n>>16)+r,a=(n>>8&255)+r,o=(n&255)+r;return`#`+(16777216+(i<255?i<1?0:i:255)*65536+(a<255?a<1?0:a:255)*256+(o<255?o<1?0:o:255)).toString(16).slice(1)}static getContrastColor(e){let t=e.replace(`#`,``),n=parseInt(t.substring(0,2),16),r=parseInt(t.substring(2,4),16),i=parseInt(t.substring(4,6),16);return(n*299+r*587+i*114)/1e3>=128?`#000000`:`#FFFFFF`}static sanitizeColor(e,t=`var(--fc-primary-color)`){if(!e||typeof e!=`string`)return t;let n=e.trim();return/[;{}()<>\"\'\\]/.test(n)?t:/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(n)||/^var\(--[a-zA-Z0-9-]+\)$/.test(n)||/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*(0|1|0?\.\d+))?\s*\)$/.test(n)||[`transparent`,`currentColor`,`inherit`,`black`,`white`,`red`,`green`,`blue`,`yellow`,`orange`,`purple`,`pink`,`brown`,`gray`,`grey`,`cyan`,`magenta`,`lime`,`navy`,`teal`,`aqua`,`maroon`,`olive`,`silver`,`fuchsia`].includes(n.toLowerCase())?n:t}static hexToRgba(e,t=1){let n=e.replace(`#`,``);return`rgba(${parseInt(n.substring(0,2),16)}, ${parseInt(n.substring(2,4),16)}, ${parseInt(n.substring(4,6),16)}, ${t})`}static getGridStyles(){return`
149
149
  .fc-grid {
150
150
  display: grid;
151
151
  gap: 1px;
@@ -176,7 +176,7 @@
176
176
  text-transform: uppercase;
177
177
  letter-spacing: 0.5px;
178
178
  }
179
- `}static mediaQuery(t,e){const r=this.breakpoints[t];return r?`@media (min-width: ${r}) { ${e} }`:""}static getAnimations(){return`
179
+ `}static breakpoints={xs:`320px`,sm:`576px`,md:`768px`,lg:`992px`,xl:`1200px`,"2xl":`1400px`};static mediaQuery(e,t){let n=this.breakpoints[e];return n?`@media (min-width: ${n}) { ${t} }`:``}static getAnimations(){return`
180
180
  @keyframes fc-fade-in {
181
181
  from { opacity: 0; }
182
182
  to { opacity: 1; }
@@ -231,167 +231,172 @@
231
231
  .fc-scale-in {
232
232
  animation: fc-scale-in var(--fc-transition);
233
233
  }
234
- `}}w(u,"colors",{primary:"#3B82F6",secondary:"#64748B",accent:"#F59E0B",danger:"#EF4444",warning:"#F97316",info:"#06B6D4",success:"#22C55E",light:"#F8FAFC",dark:"#0F172A",white:"#FFFFFF",gray:{50:"#F8FAFC",100:"#F1F5F9",200:"#E2E8F0",300:"#CBD5E1",400:"#94A3B8",500:"#64748B",600:"#475569",700:"#334155",800:"#1E293B",900:"#0F172A"}}),w(u,"cssVariables",{"--fc-primary-color":"#2563EB","--fc-primary-hover":"#1D4ED8","--fc-primary-light":"#EFF6FF","--fc-text-color":"#111827","--fc-text-secondary":"#6B7280","--fc-text-light":"#9CA3AF","--fc-border-color":"#E5E7EB","--fc-border-color-hover":"#D1D5DB","--fc-background":"#FFFFFF","--fc-background-alt":"#FAFAFA","--fc-background-hover":"#F3F4F6","--fc-background-active":"#E5E7EB","--fc-accent-color":"#F59E0B","--fc-danger-color":"#EF4444","--fc-success-color":"#10B981","--fc-font-family":'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',"--fc-font-size-xs":"11px","--fc-font-size-sm":"12px","--fc-font-size-base":"13px","--fc-font-size-lg":"15px","--fc-font-size-xl":"18px","--fc-font-size-2xl":"24px","--fc-line-height":"1.4","--fc-font-weight-normal":"400","--fc-font-weight-medium":"500","--fc-font-weight-semibold":"600","--fc-font-weight-bold":"700","--fc-spacing-xs":"2px","--fc-spacing-sm":"6px","--fc-spacing-md":"10px","--fc-spacing-lg":"14px","--fc-spacing-xl":"20px","--fc-spacing-2xl":"28px","--fc-border-width":"1px","--fc-border-radius-sm":"3px","--fc-border-radius":"5px","--fc-border-radius-lg":"8px","--fc-border-radius-full":"9999px","--fc-shadow-sm":"0 1px 1px rgba(0,0,0,0.05)","--fc-shadow":"0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06)","--fc-shadow-md":"0 4px 6px -1px rgba(0, 0, 0, 0.1)","--fc-shadow-lg":"0 10px 15px -3px rgba(0, 0, 0, 0.1)","--fc-transition-fast":"100ms ease-out","--fc-transition":"150ms ease-out","--fc-transition-slow":"250ms ease-out","--fc-z-dropdown":"1000","--fc-z-modal":"2000","--fc-z-tooltip":"3000"}),w(u,"breakpoints",{xs:"320px",sm:"576px",md:"768px",lg:"992px",xl:"1200px","2xl":"1400px"});class _{constructor(t,e){this.container=t,this.stateManager=e,this._listeners=[],this._scrolled=!1,this._nowIndicatorTimer=null}render(){throw new Error("render() must be implemented by subclass")}cleanup(){this._listeners.forEach(({element:t,event:e,handler:r})=>{t.removeEventListener(e,r)}),this._listeners=[],this._nowIndicatorTimer&&(clearInterval(this._nowIndicatorTimer),this._nowIndicatorTimer=null)}addListener(t,e,r){const i=r.bind(this);t.addEventListener(e,i),this._listeners.push({element:t,event:e,handler:i})}escapeHTML(t){return t==null?"":m.escapeHTML(String(t))}isToday(t){const e=new Date;return t.getDate()===e.getDate()&&t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear()}isSameDay(t,e){return t.getDate()===e.getDate()&&t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear()}formatHour(t){const e=t>=12?"PM":"AM";return`${t%12||12} ${e}`}formatTime(t){const e=t.getHours(),r=t.getMinutes(),i=e>=12?"PM":"AM",s=e%12||12;return r===0?`${s} ${i}`:`${s}:${r.toString().padStart(2,"0")} ${i}`}getContrastingTextColor(t){return!t||typeof t!="string"||t.charAt(0)!=="#"?"white":u.getContrastColor(t)}renderNowIndicator(){const t=new Date;return`<div class="fc-now-indicator" style="position: absolute; left: 0; right: 0; top: ${t.getHours()*60+t.getMinutes()}px; height: 2px; background: var(--fc-danger-color); z-index: 15; pointer-events: none;"></div>`}startNowIndicatorTimer(){this._nowIndicatorTimer&&clearInterval(this._nowIndicatorTimer),this._nowIndicatorTimer=setInterval(()=>{const t=this.container.querySelector(".fc-now-indicator");if(t){const e=new Date;t.style.top=`${e.getHours()*60+e.getMinutes()}px`}},6e4)}computeOverlapLayout(t){if(!t||t.length===0)return new Map;const e=t.map(o=>{const c=new Date(o.start),l=new Date(o.end),h=c.getHours()*60+c.getMinutes(),b=Math.max(h+1,l.getHours()*60+l.getMinutes());return{id:o.id,startMin:h,endMin:b}});e.sort((o,c)=>o.startMin-c.startMin||c.endMin-c.startMin-(o.endMin-o.startMin));const r=[],i=new Map;for(const o of e){let c=!1;for(let l=0;l<r.length;l++)if(r[l]<=o.startMin){r[l]=o.endMin,i.set(o.id,{column:l,totalColumns:0}),c=!0;break}c||(i.set(o.id,{column:r.length,totalColumns:0}),r.push(o.endMin))}const s=[];let n=[],a=0;for(const o of e)n.length===0||o.startMin<a?(n.push(o),a=Math.max(a,o.endMin)):(s.push(n),n=[o],a=o.endMin);n.length>0&&s.push(n);for(const o of s){const c=Math.max(...o.map(l=>i.get(l.id).column))+1;for(const l of o)i.get(l.id).totalColumns=c}return i}renderTimedEvent(t,e={}){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),h=r?"4px 8px":"8px 12px",b=r?"11px":"13px",x=r?2:12,E=r?2:24,V=r?"4px":"6px";let $,S;if(i&&i.has(t.id)){const{column:B,totalColumns:L}=i.get(t.id),F=`(100% - ${x+E}px)`;$=`calc(${x}px + ${B} * ${F} / ${L})`,S=`calc(${F} / ${L})`}else $=`${x}px`,S=`calc(100% - ${x+E}px)`;return`
235
- <div class="fc-event fc-timed-event" data-event-id="${this.escapeHTML(t.id)}"
236
- style="position: absolute; top: ${a}px; height: ${o}px;
237
- left: ${$}; width: ${S};
238
- background-color: ${c}; border-radius: ${V};
239
- padding: ${h}; font-size: ${b};
234
+ `}},l=class{constructor(e,t){this.container=e,this.stateManager=t,this._listeners=[],this._scrolled=!1,this._nowIndicatorTimer=null}render(){throw Error(`render() must be implemented by subclass`)}cleanup(){this._listeners.forEach(({element:e,event:t,handler:n})=>{e.removeEventListener(t,n)}),this._listeners=[],this._nowIndicatorTimer&&=(clearInterval(this._nowIndicatorTimer),null)}addListener(e,t,n){let r=n.bind(this);e.addEventListener(t,r),this._listeners.push({element:e,event:t,handler:r})}escapeHTML(e){return e==null?``:s.escapeHTML(String(e))}isToday(e){let t=new Date;return e.getDate()===t.getDate()&&e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear()}isSameDay(e,t){return e.getDate()===t.getDate()&&e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear()}formatHour(e){let t=e>=12?`PM`:`AM`;return`${e%12||12} ${t}`}formatTime(e){let t=e.getHours(),n=e.getMinutes(),r=t>=12?`PM`:`AM`,i=t%12||12;return n===0?`${i} ${r}`:`${i}:${n.toString().padStart(2,`0`)} ${r}`}getContrastingTextColor(e){return!e||typeof e!=`string`||e.charAt(0)!==`#`?`white`:c.getContrastColor(e)}renderNowIndicator(){let e=new Date;return`<div class="fc-now-indicator" style="position: absolute; left: 0; right: 0; top: ${e.getHours()*60+e.getMinutes()}px; height: 2px; background: var(--fc-danger-color); z-index: 15; pointer-events: none;"></div>`}startNowIndicatorTimer(){this._nowIndicatorTimer&&clearInterval(this._nowIndicatorTimer),this._nowIndicatorTimer=setInterval(()=>{let e=this.container.querySelector(`.fc-now-indicator`);if(e){let t=new Date;e.style.top=`${t.getHours()*60+t.getMinutes()}px`}},6e4)}computeOverlapLayout(e){if(!e||e.length===0)return new Map;let t=e.map(e=>{let t=new Date(e.start),n=new Date(e.end),r=t.getHours()*60+t.getMinutes(),i=Math.max(r+1,n.getHours()*60+n.getMinutes());return{id:e.id,startMin:r,endMin:i}});t.sort((e,t)=>e.startMin-t.startMin||t.endMin-t.startMin-(e.endMin-e.startMin));let n=[],r=new Map;for(let e of t){let t=!1;for(let i=0;i<n.length;i++)if(n[i]<=e.startMin){n[i]=e.endMin,r.set(e.id,{column:i,totalColumns:0}),t=!0;break}t||(r.set(e.id,{column:n.length,totalColumns:0}),n.push(e.endMin))}let i=[],a=[],o=0;for(let e of t)a.length===0||e.startMin<o?(a.push(e),o=Math.max(o,e.endMin)):(i.push(a),a=[e],o=e.endMin);a.length>0&&i.push(a);for(let e of i){let t=Math.max(...e.map(e=>r.get(e.id).column))+1;for(let n of e)r.get(n.id).totalColumns=t}return r}renderTimedEvent(e,t={}){let{compact:n=!0,overlapLayout:r=null}=t,i=new Date(e.start),a=new Date(e.end),o=i.getHours()*60+i.getMinutes(),s=Math.max((a-i)/(1e3*60),n?20:30),c=this.getEventColor(e),l=this.getContrastingTextColor(c),u=n?`4px 8px`:`8px 12px`,d=n?`11px`:`13px`,f=n?2:12,p=n?2:24,m=n?`4px`:`6px`,h,g;if(r&&r.has(e.id)){let{column:t,totalColumns:n}=r.get(e.id),i=`(100% - ${f+p}px)`;h=`calc(${f}px + ${t} * ${i} / ${n})`,g=`calc(${i} / ${n})`}else h=`${f}px`,g=`calc(100% - ${f+p}px)`;return`
235
+ <div class="fc-event fc-timed-event" data-event-id="${this.escapeHTML(e.id)}"
236
+ style="position: absolute; top: ${o}px; height: ${s}px;
237
+ left: ${h}; width: ${g};
238
+ background-color: ${c}; border-radius: ${m};
239
+ padding: ${u}; font-size: ${d};
240
240
  font-weight: 500; color: ${l}; overflow: hidden;
241
241
  box-shadow: 0 1px 2px rgba(0,0,0,0.1);
242
242
  cursor: pointer; z-index: 5;">
243
243
  <div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
244
- ${this.escapeHTML(t.title)}
244
+ ${this.escapeHTML(e.title)}
245
245
  </div>
246
- <div style="font-size: ${r?"10px":"11px"}; opacity: 0.9;">
247
- ${this.formatTime(s)}${r?"":" - "+this.formatTime(n)}
246
+ <div style="font-size: ${n?`10px`:`11px`}; opacity: 0.9;">
247
+ ${this.formatTime(i)}${n?``:` - `+this.formatTime(a)}
248
248
  </div>
249
249
  </div>
250
- `}getEventColor(t){return u.sanitizeColor(t==null?void 0:t.backgroundColor,"#2563eb")}attachCommonEventHandlers(){this.addListener(this.container,"click",t=>{const e=t.target.closest(".fc-event");if(!e||!this.container.contains(e))return;t.stopPropagation();const r=e.dataset.eventId,i=this.stateManager.getEvents().find(s=>s.id===r);i&&this.stateManager.selectEvent(i)})}}class k extends _{constructor(t,e){super(t,e),this.maxEventsToShow=3}render(){if(!this.container||!this.stateManager)return;const t=this.stateManager.getViewData();if(!t||!t.weeks){this.container.innerHTML='<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for month view.</div>';return}this.cleanup();const e=this.stateManager.getState().config,r=this._renderMonthView(t,e);this.container.innerHTML=r,this._attachEventHandlers()}_renderMonthView(t,e){const r=e.weekStartsOn||0;let s=`
251
- <div class="fc-month-view" style="display: flex; flex-direction: column; height: 100%; min-height: 400px; background: var(--fc-background); border: 1px solid var(--fc-border-color);">
252
- <div class="fc-month-header" style="display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--fc-border-color); background: var(--fc-background-alt);">
253
- ${this._getDayNames(r).map(n=>`<div class="fc-month-header-cell" style="padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: var(--fc-text-light); text-transform: uppercase;">${this.escapeHTML(n)}</div>`).join("")}
250
+ `}getEventColor(e){return c.sanitizeColor(e?.backgroundColor,`#2563eb`)}attachCommonEventHandlers(){this.addListener(this.container,`click`,e=>{let t=e.target.closest(`.fc-event`);!t||!this.container.contains(t)||(e.stopPropagation(),this._selectEventFromElement(t))}),this.addListener(this.container,`keydown`,e=>{if(e.key!==`Enter`&&e.key!==` `)return;let t=e.target.closest(`.fc-event`);!t||!this.container.contains(t)||(e.preventDefault(),e.stopPropagation(),this._selectEventFromElement(t))}),this._enhanceEventAccessibility()}_selectEventFromElement(e){let t=e.dataset.eventId,n=this.stateManager.getEvents().find(e=>e.id===t);n&&this.stateManager.selectEvent(n)}_enhanceEventAccessibility(){for(let e of this.container.querySelectorAll(`.fc-event`))if(e.setAttribute(`role`,`button`),e.setAttribute(`tabindex`,`0`),!e.hasAttribute(`aria-label`)){let t=(e.getAttribute(`title`)||e.textContent||``).trim();t&&e.setAttribute(`aria-label`,`Event: ${t}`)}}},u=class extends l{constructor(e,t){super(e,t),this.maxEventsToShow=3}render(){if(!this.container||!this.stateManager)return;let e=this.stateManager.getViewData();if(!e||!e.weeks){this.container.innerHTML=`<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for month view.</div>`;return}this.cleanup();let t=this.stateManager.getState().config,n=this._renderMonthView(e,t);this.container.innerHTML=n,this._attachEventHandlers();let r=this._applyRovingTabindex(this._pendingFocusMs??null);this._pendingFocusMs!=null&&(this._pendingFocusMs=null,r&&r.focus())}_renderMonthView(e,t){let n=t.weekStartsOn||0,r=this._getDayNames(n),i=t.locale||`en-US`;this._dayLabelFormatter=new Intl.DateTimeFormat(i,{weekday:`long`,year:`numeric`,month:`long`,day:`numeric`});let a=this.stateManager.getState().currentDate,o=new Intl.DateTimeFormat(i,{month:`long`,year:`numeric`}).format(a||new Date),s=`
251
+ <div class="fc-month-view" role="grid" aria-label="${this.escapeHTML(o)}" style="display: flex; flex-direction: column; height: 100%; min-height: 400px; background: var(--fc-background); border: 1px solid var(--fc-border-color);">
252
+ <div class="fc-month-header" role="row" style="display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--fc-border-color); background: var(--fc-background-alt);">
253
+ ${r.map(e=>`<div class="fc-month-header-cell" role="columnheader" style="padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: var(--fc-text-light); text-transform: uppercase;">${this.escapeHTML(e)}</div>`).join(``)}
254
254
  </div>
255
255
  <div class="fc-month-body" style="display: flex; flex-direction: column; flex: 1;">
256
- `;return t.weeks.forEach(n=>{s+=this._renderWeek(n)}),s+="</div></div>",s}_getDayNames(t){const e=this.stateManager.getState().config.locale||"en-US",r=[];for(let i=0;i<7;i++){const s=(t+i)%7;r.push(p.getDayAbbreviation(s,e))}return r}_renderWeek(t){let e='<div class="fc-month-week" style="display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; min-height: 80px;">';return t.days.forEach(r=>{e+=this._renderDay(r)}),e+="</div>",e}_renderDay(t){const e=!t.isCurrentMonth,r=t.isToday,i=e?"var(--fc-background-hover)":"var(--fc-background)",s=e?"var(--fc-text-light)":"var(--fc-text-color)",n=r?"background: var(--fc-primary-color); color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;":"",a=t.events||[],o=a.slice(0,this.maxEventsToShow),c=a.length-this.maxEventsToShow;return`
257
- <div class="fc-month-day" data-date="${this.escapeHTML(t.date)}"
258
- style="background: ${i}; border-right: 1px solid var(--fc-border-color); border-bottom: 1px solid var(--fc-border-color); padding: 4px; min-height: 80px; cursor: pointer; display: flex; flex-direction: column;">
259
- <div class="fc-day-number" style="font-size: 13px; font-weight: 500; color: ${s}; padding: 2px 4px; margin-bottom: 4px; ${n}">
260
- ${this.escapeHTML(String(t.dayOfMonth))}
256
+ `;return e.weeks.forEach(e=>{s+=this._renderWeek(e)}),s+=`</div></div>`,s}_getDayNames(e){let t=this.stateManager.getState().config.locale||`en-US`,n=[];for(let r=0;r<7;r++){let i=(e+r)%7;n.push(o.getDayAbbreviation(i,t))}return n}_renderWeek(e){let t=`<div class="fc-month-week" role="row" style="display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; min-height: 80px;">`;return e.days.forEach(e=>{t+=this._renderDay(e)}),t+=`</div>`,t}_renderDay(e){let t=!e.isCurrentMonth,n=e.isToday,r=t?`var(--fc-background-hover)`:`var(--fc-background)`,i=t?`var(--fc-text-light)`:`var(--fc-text-color)`,a=n?`background: var(--fc-primary-color); color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;`:``,o=e.events||[],s=o.slice(0,this.maxEventsToShow),c=o.length-this.maxEventsToShow,l=this._dayLabelFormatter?this._dayLabelFormatter.format(new Date(e.date)):e.date;return o.length>0&&(l+=`, ${o.length} ${o.length===1?`event`:`events`}`),`
257
+ <div class="fc-month-day" data-date="${this.escapeHTML(e.date)}"
258
+ role="gridcell" tabindex="-1"
259
+ aria-selected="${e.isSelected?`true`:`false`}"
260
+ ${n?`aria-current="date"`:``}
261
+ ${t?`data-other-month="true"`:``}
262
+ aria-label="${this.escapeHTML(l)}"
263
+ style="background: ${r}; border-right: 1px solid var(--fc-border-color); border-bottom: 1px solid var(--fc-border-color); padding: 4px; min-height: 80px; cursor: pointer; display: flex; flex-direction: column;">
264
+ <div class="fc-day-number" style="font-size: 13px; font-weight: 500; color: ${i}; padding: 2px 4px; margin-bottom: 4px; ${a}">
265
+ ${this.escapeHTML(String(e.dayOfMonth))}
261
266
  </div>
262
267
  <div class="fc-day-events" style="display: flex; flex-direction: column; gap: 2px; flex: 1; overflow: hidden;">
263
- ${o.map(l=>this._renderEvent(l)).join("")}
264
- ${c>0?`<div class="fc-more-events" style="font-size: 10px; color: var(--fc-text-light); padding: 2px 4px; font-weight: 500;">+${c} more</div>`:""}
268
+ ${s.map(e=>this._renderEvent(e)).join(``)}
269
+ ${c>0?`<div class="fc-more-events" style="font-size: 10px; color: var(--fc-text-light); padding: 2px 4px; font-weight: 500;">+${c} more</div>`:``}
265
270
  </div>
266
271
  </div>
267
- `}_renderEvent(t){const e=this.getEventColor(t),r=this.getContrastingTextColor(e);return`
268
- <div class="fc-event" data-event-id="${this.escapeHTML(t.id)}"
269
- style="background-color: ${e}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: ${r}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">
270
- ${this.escapeHTML(t.title)}
272
+ `}_renderEvent(e){let t=this.getEventColor(e),n=this.getContrastingTextColor(t);return`
273
+ <div class="fc-event" data-event-id="${this.escapeHTML(e.id)}"
274
+ style="background-color: ${t}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: ${n}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">
275
+ ${this.escapeHTML(e.title)}
271
276
  </div>
272
- `}_attachEventHandlers(){this.addListener(this.container,"click",t=>{const e=t.target.closest(".fc-month-day");if(!e||!this.container.contains(e)||t.target.closest(".fc-event"))return;const r=new Date(e.dataset.date);this.stateManager.selectDate(r)}),this.attachCommonEventHandlers()}}class C extends _{constructor(t,e){super(t,e),this.hourHeight=60,this.totalHeight=24*this.hourHeight}render(){if(!this.container||!this.stateManager)return;const t=this.stateManager.getViewData();if(!t||!t.days||t.days.length===0){this.container.innerHTML='<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for week view.</div>';return}this.cleanup(),this._scrolled=!1;const e=this.stateManager.getState().config,r=this._renderWeekView(t,e);this.container.innerHTML=r,this._attachEventHandlers(),this._scrollToCurrentTime(),this.startNowIndicatorTimer()}_renderWeekView(t,e){const r=t.days,i=this.stateManager.getState().config.locale||"en-US",s=Array.from({length:24},(a,o)=>o),n=r.map(a=>{const o=new Date(a.date),c=a.events||[];return{...a,date:o,dayName:p.getDayAbbreviation(o.getDay(),i),dayOfMonth:o.getDate(),isToday:this.isToday(o),timedEvents:c.filter(l=>!l.allDay),allDayEvents:c.filter(l=>l.allDay)}});return`
277
+ `}_attachEventHandlers(){this.addListener(this.container,`click`,e=>{let t=e.target.closest(`.fc-month-day`);if(!t||!this.container.contains(t)||e.target.closest(`.fc-event`))return;let n=new Date(t.dataset.date);this.stateManager.selectDate(n)}),this.addListener(this.container,`keydown`,e=>{if(e.target.closest(`.fc-event`))return;let t=e.target.closest(`.fc-month-day`);if(!t||!this.container.contains(t))return;let n=Array.from(this.container.querySelectorAll(`.fc-month-day`)),r=n.indexOf(t),i;switch(e.key){case`ArrowRight`:i=r+1;break;case`ArrowLeft`:i=r-1;break;case`ArrowDown`:i=r+7;break;case`ArrowUp`:i=r-7;break;case`Home`:i=r-r%7;break;case`End`:i=r-r%7+6;break;case`PageUp`:case`PageDown`:{e.preventDefault();let n=new Date(t.dataset.date);n.setMonth(n.getMonth()+(e.key===`PageDown`?1:-1)),this._pendingFocusMs=n.getTime(),e.key===`PageDown`?this.stateManager.next():this.stateManager.previous();return}case`Enter`:case` `:{e.preventDefault();let n=new Date(t.dataset.date);this._pendingFocusMs=n.getTime(),this.stateManager.selectDate(n);return}default:return}if(e.preventDefault(),i>=0&&i<n.length)this._applyRovingTabindex(new Date(n[i].dataset.date).getTime()),n[i].focus();else{let e=new Date(t.dataset.date);e.setDate(e.getDate()+(i-r)),this._pendingFocusMs=e.getTime(),i<0?this.stateManager.previous():this.stateManager.next()}}),this.attachCommonEventHandlers()}_applyRovingTabindex(e=null){let t=Array.from(this.container.querySelectorAll(`.fc-month-day`));if(t.length===0)return null;let n=null;e!=null&&(n=t.find(t=>new Date(t.dataset.date).getTime()===e)),n||=t.find(e=>e.getAttribute(`aria-selected`)===`true`),n||=t.find(e=>e.hasAttribute(`aria-current`)),n||=t.find(e=>!e.dataset.otherMonth)||t[0];for(let e of t)e.setAttribute(`tabindex`,e===n?`0`:`-1`);return n}},d=class extends l{constructor(e,t){super(e,t),this.hourHeight=60,this.totalHeight=24*this.hourHeight}render(){if(!this.container||!this.stateManager)return;let e=this.stateManager.getViewData();if(!e||!e.days||e.days.length===0){this.container.innerHTML=`<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for week view.</div>`;return}this.cleanup(),this._scrolled=!1;let t=this.stateManager.getState().config,n=this._renderWeekView(e,t);this.container.innerHTML=n,this._attachEventHandlers(),this._scrollToCurrentTime(),this.startNowIndicatorTimer()}_renderWeekView(e,t){let n=e.days,r=this.stateManager.getState().config.locale||`en-US`,i=Array.from({length:24},(e,t)=>t),a=n.map(e=>{let t=new Date(e.date),n=e.events||[];return{...e,date:t,dayName:o.getDayAbbreviation(t.getDay(),r),dayOfMonth:t.getDate(),isToday:this.isToday(t),timedEvents:n.filter(e=>!e.allDay),allDayEvents:n.filter(e=>e.allDay)}});return`
273
278
  <div class="fc-week-view" style="display: flex; flex-direction: column; height: 100%; background: var(--fc-background); overflow: hidden;">
274
- ${this._renderHeader(n)}
275
- ${this._renderAllDayRow(n)}
276
- ${this._renderTimeGrid(n,s)}
279
+ ${this._renderHeader(a)}
280
+ ${this._renderAllDayRow(a)}
281
+ ${this._renderTimeGrid(a,i)}
277
282
  </div>
278
- `}_renderHeader(t){return`
283
+ `}_renderHeader(e){return`
279
284
  <div class="fc-week-header" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid var(--fc-border-color); background: var(--fc-background-alt); flex-shrink: 0;">
280
285
  <div style="border-right: 1px solid var(--fc-border-color);"></div>
281
- ${t.map(e=>`
286
+ ${e.map(e=>`
282
287
  <div style="padding: 12px 8px; text-align: center; border-right: 1px solid var(--fc-border-color);">
283
288
  <div style="font-size: 10px; font-weight: 700; color: var(--fc-text-light); text-transform: uppercase; letter-spacing: 0.1em;">
284
289
  ${this.escapeHTML(e.dayName)}
285
290
  </div>
286
- <div style="font-size: 16px; font-weight: 500; margin-top: 4px; ${e.isToday?"background: var(--fc-danger-color); color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;":"color: var(--fc-text-color);"}">
291
+ <div style="font-size: 16px; font-weight: 500; margin-top: 4px; ${e.isToday?`background: var(--fc-danger-color); color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;`:`color: var(--fc-text-color);`}">
287
292
  ${this.escapeHTML(String(e.dayOfMonth))}
288
293
  </div>
289
294
  </div>
290
- `).join("")}
295
+ `).join(``)}
291
296
  </div>
292
- `}_renderAllDayRow(t){return`
297
+ `}_renderAllDayRow(e){return`
293
298
  <div class="fc-all-day-row" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid var(--fc-border-color); background: var(--fc-background-alt); min-height: 32px; flex-shrink: 0;">
294
299
  <div style="font-size: 9px; color: var(--fc-text-light); display: flex; align-items: center; justify-content: center; border-right: 1px solid var(--fc-border-color); text-transform: uppercase; font-weight: 700;">
295
300
  All day
296
301
  </div>
297
- ${t.map(e=>`
302
+ ${e.map(e=>`
298
303
  <div class="fc-all-day-cell" data-date="${e.date.toISOString()}" style="border-right: 1px solid var(--fc-border-color); padding: 4px; display: flex; flex-direction: column; gap: 2px;">
299
- ${e.allDayEvents.map(r=>`
300
- <div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(r.id)}"
301
- style="background-color: ${this.getEventColor(r)}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
302
- ${this.escapeHTML(r.title)}
304
+ ${e.allDayEvents.map(e=>`
305
+ <div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(e.id)}"
306
+ style="background-color: ${this.getEventColor(e)}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
307
+ ${this.escapeHTML(e.title)}
303
308
  </div>
304
- `).join("")}
309
+ `).join(``)}
305
310
  </div>
306
- `).join("")}
311
+ `).join(``)}
307
312
  </div>
308
- `}_renderTimeGrid(t,e){return`
313
+ `}_renderTimeGrid(e,t){return`
309
314
  <div id="week-scroll-container" class="fc-time-grid-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
310
315
  <div class="fc-time-grid" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); position: relative; height: ${this.totalHeight}px;">
311
- ${this._renderTimeGutter(e)}
312
- ${t.map(r=>this._renderDayColumn(r,e)).join("")}
316
+ ${this._renderTimeGutter(t)}
317
+ ${e.map(e=>this._renderDayColumn(e,t)).join(``)}
313
318
  </div>
314
319
  </div>
315
- `}_renderTimeGutter(t){return`
320
+ `}_renderTimeGutter(e){return`
316
321
  <div class="fc-time-gutter" style="border-right: 1px solid var(--fc-border-color); background: var(--fc-background-alt);">
317
- ${t.map(e=>`
322
+ ${e.map(e=>`
318
323
  <div style="height: ${this.hourHeight}px; font-size: 10px; color: var(--fc-text-light); text-align: right; padding-right: 8px; font-weight: 500;">
319
- ${e===0?"":this.formatHour(e)}
324
+ ${e===0?``:this.formatHour(e)}
320
325
  </div>
321
- `).join("")}
326
+ `).join(``)}
322
327
  </div>
323
- `}_renderDayColumn(t,e){return`
324
- <div class="fc-week-day-column" data-date="${t.date.toISOString()}" style="border-right: 1px solid var(--fc-border-color); position: relative; cursor: pointer;">
328
+ `}_renderDayColumn(e,t){return`
329
+ <div class="fc-week-day-column" data-date="${e.date.toISOString()}" style="border-right: 1px solid var(--fc-border-color); position: relative; cursor: pointer;">
325
330
  <!-- Hour grid lines -->
326
- ${e.map(()=>`<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
331
+ ${t.map(()=>`<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join(``)}
327
332
 
328
333
  <!-- Now indicator for today -->
329
- ${t.isToday?this.renderNowIndicator():""}
334
+ ${e.isToday?this.renderNowIndicator():``}
330
335
 
331
336
  <!-- Timed events -->
332
- ${(()=>{const r=this.computeOverlapLayout(t.timedEvents);return t.timedEvents.map(i=>this.renderTimedEvent(i,{compact:!0,overlapLayout:r})).join("")})()}
337
+ ${(()=>{let t=this.computeOverlapLayout(e.timedEvents);return e.timedEvents.map(e=>this.renderTimedEvent(e,{compact:!0,overlapLayout:t})).join(``)})()}
333
338
  </div>
334
- `}_attachEventHandlers(){this.addListener(this.container,"click",t=>{const e=t.target.closest(".fc-week-day-column");if(!e||!this.container.contains(e)||t.target.closest(".fc-event"))return;const r=new Date(e.dataset.date),i=this.container.querySelector("#week-scroll-container"),s=e.offsetTop,n=t.clientY-e.getBoundingClientRect().top+(i?i.scrollTop:0)-s,a=Math.max(0,Math.min(n+s,this.totalHeight));r.setHours(Math.floor(a/this.hourHeight),Math.floor(a%this.hourHeight/(this.hourHeight/60)),0,0),this.stateManager.selectDate(r)}),this.attachCommonEventHandlers()}_scrollToCurrentTime(){if(this._scrolled)return;const t=this.container.querySelector("#week-scroll-container");t&&(t.scrollTop=8*this.hourHeight-50,this._scrolled=!0)}}class H extends _{constructor(t,e){super(t,e),this.hourHeight=60,this.totalHeight=24*this.hourHeight}render(){if(!this.container||!this.stateManager)return;const t=this.stateManager.getViewData();if(!t){this.container.innerHTML='<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for day view.</div>';return}this.cleanup(),this._scrolled=!1;const e=this.stateManager.getState().config,r=this._renderDayView(t,e);this.container.innerHTML=r,this._attachEventHandlers(),this._scrollToCurrentTime(),this.startNowIndicatorTimer()}_renderDayView(t,e){var h,b;const r=((b=(h=this.stateManager)==null?void 0:h.getState())==null?void 0:b.currentDate)||new Date,i=this._extractDayData(t,r);if(!i)return'<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for day view.</div>';const{dayDate:s,dayName:n,isToday:a,allDayEvents:o,timedEvents:c}=i,l=Array.from({length:24},(x,E)=>E);return`
339
+ `}_attachEventHandlers(){this.addListener(this.container,`click`,e=>{let t=e.target.closest(`.fc-week-day-column`);if(!t||!this.container.contains(t)||e.target.closest(`.fc-event`))return;let n=new Date(t.dataset.date),r=this.container.querySelector(`#week-scroll-container`),i=t.offsetTop,a=e.clientY-t.getBoundingClientRect().top+(r?r.scrollTop:0)-i,o=Math.max(0,Math.min(a+i,this.totalHeight));n.setHours(Math.floor(o/this.hourHeight),Math.floor(o%this.hourHeight/(this.hourHeight/60)),0,0),this.stateManager.selectDate(n)}),this.attachCommonEventHandlers()}_scrollToCurrentTime(){if(this._scrolled)return;let e=this.container.querySelector(`#week-scroll-container`);e&&(e.scrollTop=8*this.hourHeight-50,this._scrolled=!0)}},f=class extends l{constructor(e,t){super(e,t),this.hourHeight=60,this.totalHeight=24*this.hourHeight}render(){if(!this.container||!this.stateManager)return;let e=this.stateManager.getViewData();if(!e){this.container.innerHTML=`<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for day view.</div>`;return}this.cleanup(),this._scrolled=!1;let t=this.stateManager.getState().config,n=this._renderDayView(e,t);this.container.innerHTML=n,this._attachEventHandlers(),this._scrollToCurrentTime(),this.startNowIndicatorTimer()}_renderDayView(e,t){let n=this.stateManager?.getState()?.currentDate||new Date,r=this._extractDayData(e,n);if(!r)return`<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for day view.</div>`;let{dayDate:i,dayName:a,isToday:o,allDayEvents:s,timedEvents:c}=r,l=Array.from({length:24},(e,t)=>t);return`
335
340
  <div class="fc-day-view" style="display: flex; flex-direction: column; height: 100%; background: var(--fc-background); overflow: hidden;">
336
- ${this._renderHeader(s,n,a)}
337
- ${this._renderAllDayRow(o,s)}
338
- ${this._renderTimeGrid(c,a,s,l)}
341
+ ${this._renderHeader(i,a,o)}
342
+ ${this._renderAllDayRow(s,i)}
343
+ ${this._renderTimeGrid(c,o,i,l)}
339
344
  </div>
340
- `}_extractDayData(t,e){let r,i,s,n,a;const o=this.stateManager.getState().config.locale||"en-US";if(t.type==="day"&&t.date)if(r=new Date(t.date),i=t.dayName||p.getDayName(r.getDay(),o),s=t.isToday!==void 0?t.isToday:this.isToday(r),n=t.allDayEvents||[],t.hours&&Array.isArray(t.hours)){const c=new Map;t.hours.forEach(l=>{(l.events||[]).forEach(h=>{c.has(h.id)||c.set(h.id,h)})}),a=Array.from(c.values())}else a=[];else if(t.days&&t.days.length>0){const c=t.days.find(h=>this.isSameDay(new Date(h.date),e))||t.days[0];r=new Date(c.date),i=p.getDayName(r.getDay(),o),s=this.isToday(r);const l=c.events||[];n=l.filter(h=>h.allDay),a=l.filter(h=>!h.allDay)}else return null;return{dayDate:r,dayName:i,isToday:s,allDayEvents:n,timedEvents:a}}_renderHeader(t,e,r){return`
345
+ `}_extractDayData(e,t){let n,r,i,a,s,c=this.stateManager.getState().config.locale||`en-US`;if(e.type===`day`&&e.date)if(n=new Date(e.date),r=e.dayName||o.getDayName(n.getDay(),c),i=e.isToday===void 0?this.isToday(n):e.isToday,a=e.allDayEvents||[],e.hours&&Array.isArray(e.hours)){let t=new Map;e.hours.forEach(e=>{(e.events||[]).forEach(e=>{t.has(e.id)||t.set(e.id,e)})}),s=Array.from(t.values())}else s=[];else if(e.days&&e.days.length>0){let l=e.days.find(e=>this.isSameDay(new Date(e.date),t))||e.days[0];n=new Date(l.date),r=o.getDayName(n.getDay(),c),i=this.isToday(n);let u=l.events||[];a=u.filter(e=>e.allDay),s=u.filter(e=>!e.allDay)}else return null;return{dayDate:n,dayName:r,isToday:i,allDayEvents:a,timedEvents:s}}_renderHeader(e,t,n){return`
341
346
  <div class="fc-day-header" style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid var(--fc-border-color); background: var(--fc-background-alt); flex-shrink: 0;">
342
347
  <div style="border-right: 1px solid var(--fc-border-color);"></div>
343
348
  <div style="padding: 16px 24px;">
344
349
  <div style="font-size: 12px; font-weight: 700; color: var(--fc-text-light); text-transform: uppercase; letter-spacing: 0.1em;">
345
- ${this.escapeHTML(e)}
350
+ ${this.escapeHTML(t)}
346
351
  </div>
347
- <div style="font-size: 24px; font-weight: 600; margin-top: 4px; ${r?"color: var(--fc-danger-color);":"color: var(--fc-text-color);"}">
348
- ${this.escapeHTML(String(t.getDate()))}
352
+ <div style="font-size: 24px; font-weight: 600; margin-top: 4px; ${n?`color: var(--fc-danger-color);`:`color: var(--fc-text-color);`}">
353
+ ${this.escapeHTML(String(e.getDate()))}
349
354
  </div>
350
355
  </div>
351
356
  </div>
352
- `}_renderAllDayRow(t,e){return`
357
+ `}_renderAllDayRow(e,t){return`
353
358
  <div class="fc-all-day-row" style="display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid var(--fc-border-color); background: var(--fc-background-alt); min-height: 36px; flex-shrink: 0;">
354
359
  <div style="font-size: 9px; color: var(--fc-text-light); display: flex; align-items: center; justify-content: center; border-right: 1px solid var(--fc-border-color); text-transform: uppercase; font-weight: 700;">
355
360
  All day
356
361
  </div>
357
- <div class="fc-all-day-cell" data-date="${e.toISOString()}" style="padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;">
358
- ${t.map(r=>`
359
- <div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(r.id)}"
360
- style="background-color: ${this.getEventColor(r)}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;">
361
- ${this.escapeHTML(r.title)}
362
+ <div class="fc-all-day-cell" data-date="${t.toISOString()}" style="padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;">
363
+ ${e.map(e=>`
364
+ <div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(e.id)}"
365
+ style="background-color: ${this.getEventColor(e)}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;">
366
+ ${this.escapeHTML(e.title)}
362
367
  </div>
363
- `).join("")}
368
+ `).join(``)}
364
369
  </div>
365
370
  </div>
366
- `}_renderTimeGrid(t,e,r,i){return`
371
+ `}_renderTimeGrid(e,t,n,r){return`
367
372
  <div id="day-scroll-container" class="fc-time-grid-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
368
373
  <div class="fc-time-grid" style="display: grid; grid-template-columns: 60px 1fr; position: relative; height: ${this.totalHeight}px;">
369
- ${this._renderTimeGutter(i)}
370
- ${this._renderDayColumn(t,e,r,i)}
374
+ ${this._renderTimeGutter(r)}
375
+ ${this._renderDayColumn(e,t,n,r)}
371
376
  </div>
372
377
  </div>
373
- `}_renderTimeGutter(t){return`
378
+ `}_renderTimeGutter(e){return`
374
379
  <div class="fc-time-gutter" style="border-right: 1px solid var(--fc-border-color); background: var(--fc-background-alt);">
375
- ${t.map(e=>`
380
+ ${e.map(e=>`
376
381
  <div style="height: ${this.hourHeight}px; font-size: 11px; color: var(--fc-text-light); text-align: right; padding-right: 12px; font-weight: 500;">
377
- ${e===0?"":this.formatHour(e)}
382
+ ${e===0?``:this.formatHour(e)}
378
383
  </div>
379
- `).join("")}
384
+ `).join(``)}
380
385
  </div>
381
- `}_renderDayColumn(t,e,r,i){return`
382
- <div class="fc-day-column" data-date="${r.toISOString()}" style="position: relative; cursor: pointer;">
386
+ `}_renderDayColumn(e,t,n,r){return`
387
+ <div class="fc-day-column" data-date="${n.toISOString()}" style="position: relative; cursor: pointer;">
383
388
  <!-- Hour grid lines -->
384
- ${i.map(()=>`<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
389
+ ${r.map(()=>`<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join(``)}
385
390
 
386
391
  <!-- Now indicator for today -->
387
- ${e?this.renderNowIndicator():""}
392
+ ${t?this.renderNowIndicator():``}
388
393
 
389
394
  <!-- Timed events -->
390
- ${(()=>{const s=this.computeOverlapLayout(t);return t.map(n=>this.renderTimedEvent(n,{compact:!1,overlapLayout:s})).join("")})()}
395
+ ${(()=>{let t=this.computeOverlapLayout(e);return e.map(e=>this.renderTimedEvent(e,{compact:!1,overlapLayout:t})).join(``)})()}
391
396
  </div>
392
- `}_attachEventHandlers(){this.addListener(this.container,"click",t=>{const e=t.target.closest(".fc-day-column");if(!e||!this.container.contains(e)||t.target.closest(".fc-event"))return;const r=new Date(e.dataset.date),i=this.container.querySelector("#day-scroll-container"),s=e.offsetTop,n=t.clientY-e.getBoundingClientRect().top+(i?i.scrollTop:0)-s,a=Math.max(0,Math.min(n+s,this.totalHeight));r.setHours(Math.floor(a/this.hourHeight),Math.floor(a%this.hourHeight/(this.hourHeight/60)),0,0),this.stateManager.selectDate(r)}),this.attachCommonEventHandlers()}_scrollToCurrentTime(){if(this._scrolled)return;const t=this.container.querySelector("#day-scroll-container");t&&(t.scrollTop=8*this.hourHeight-50,this._scrolled=!0)}}class z extends v{constructor(){super(),this._isVisible=!1,this._cleanupFocusTrap=null,this.config={title:"New Event",defaultDuration:60,colors:[{color:"#2563EB",label:"Blue"},{color:"#10B981",label:"Green"},{color:"#F59E0B",label:"Amber"},{color:"#EF4444",label:"Red"},{color:"#8B5CF6",label:"Purple"},{color:"#6B7280",label:"Gray"}]},this._formData={title:"",start:new Date,end:new Date,allDay:!1,color:this.config.colors[0].color}}static get observedAttributes(){return["open"]}attributeChangedCallback(t,e,r){t==="open"&&(r!==null?this.open():this.close())}getStyles(){return`
393
- ${u.getBaseStyles()}
394
- ${u.getButtonStyles()}
397
+ `}_attachEventHandlers(){this.addListener(this.container,`click`,e=>{let t=e.target.closest(`.fc-day-column`);if(!t||!this.container.contains(t)||e.target.closest(`.fc-event`))return;let n=new Date(t.dataset.date),r=this.container.querySelector(`#day-scroll-container`),i=t.offsetTop,a=e.clientY-t.getBoundingClientRect().top+(r?r.scrollTop:0)-i,o=Math.max(0,Math.min(a+i,this.totalHeight));n.setHours(Math.floor(o/this.hourHeight),Math.floor(o%this.hourHeight/(this.hourHeight/60)),0,0),this.stateManager.selectDate(n)}),this.attachCommonEventHandlers()}_scrollToCurrentTime(){if(this._scrolled)return;let e=this.container.querySelector(`#day-scroll-container`);e&&(e.scrollTop=8*this.hourHeight-50,this._scrolled=!0)}},p=class extends n{constructor(){super(),this._isVisible=!1,this._cleanupFocusTrap=null,this.config={title:`New Event`,defaultDuration:60,colors:[{color:`#2563EB`,label:`Blue`},{color:`#10B981`,label:`Green`},{color:`#F59E0B`,label:`Amber`},{color:`#EF4444`,label:`Red`},{color:`#8B5CF6`,label:`Purple`},{color:`#6B7280`,label:`Gray`}]},this._formData={title:``,start:new Date,end:new Date,allDay:!1,color:this.config.colors[0].color}}static get observedAttributes(){return[`open`]}attributeChangedCallback(e,t,n){e===`open`&&(n===null?this.close():this.open())}getStyles(){return`
398
+ ${c.getBaseStyles()}
399
+ ${c.getButtonStyles()}
395
400
 
396
401
  :host {
397
402
  display: none;
@@ -592,16 +597,16 @@
592
597
  <div class="form-group">
593
598
  <label id="color-label">Color</label>
594
599
  <div class="color-options" id="color-picker" role="radiogroup" aria-labelledby="color-label">
595
- ${this.config.colors.map(t=>`
600
+ ${this.config.colors.map(e=>`
596
601
  <button type="button"
597
- class="color-btn ${t.color===this._formData.color?"selected":""}"
598
- style="background-color: ${u.sanitizeColor(t.color)}"
599
- data-color="${m.escapeHTML(t.color)}"
600
- title="${m.escapeHTML(t.label)}"
601
- aria-label="${m.escapeHTML(t.label)}"
602
- aria-checked="${t.color===this._formData.color?"true":"false"}"
602
+ class="color-btn ${e.color===this._formData.color?`selected`:``}"
603
+ style="background-color: ${c.sanitizeColor(e.color)}"
604
+ data-color="${s.escapeHTML(e.color)}"
605
+ title="${s.escapeHTML(e.label)}"
606
+ aria-label="${s.escapeHTML(e.label)}"
607
+ aria-checked="${e.color===this._formData.color?`true`:`false`}"
603
608
  role="radio"></button>
604
- `).join("")}
609
+ `).join(``)}
605
610
  </div>
606
611
  </div>
607
612
  </div>
@@ -611,14 +616,14 @@
611
616
  <button class="fc-btn fc-btn-primary" id="save-btn">Save Event</button>
612
617
  </footer>
613
618
  </div>
614
- `}afterRender(){this.modalContent=this.$(".modal-content"),this.titleInput=this.$("#event-title"),this.startInput=this.$("#event-start"),this.endInput=this.$("#event-end"),this.colorContainer=this.$("#color-picker"),this.titleGroup=this.$("#title-group"),this.endGroup=this.$("#end-group"),this.addListener(this.$("#close-x"),"click",()=>this.close()),this.addListener(this.$("#cancel-btn"),"click",()=>this.close()),this.addListener(this.$("#save-btn"),"click",()=>this.save()),this.colorContainer.querySelectorAll(".color-btn").forEach(t=>{this.addListener(t,"click",e=>{this._formData.color=e.currentTarget.dataset.color,this.updateColorSelection()})}),this.addListener(this,"click",t=>{t.target===this&&this.close()}),this._keydownListenerAdded||(this._handleKeyDown=t=>{t.key==="Escape"&&this.hasAttribute("open")&&this.close()},window.addEventListener("keydown",this._handleKeyDown),this._keydownListenerAdded=!0)}updateColorSelection(){this.colorContainer.querySelectorAll(".color-btn").forEach(e=>{const r=e.dataset.color===this._formData.color;e.classList.toggle("selected",r),e.setAttribute("aria-checked",r?"true":"false")})}open(t=new Date){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=m.trapFocus(this.modalContent))}close(){this.removeAttribute("open"),this._cleanupFocusTrap&&(this._cleanupFocusTrap(),this._cleanupFocusTrap=null)}validate(){let t=!0;this.titleGroup.classList.remove("has-error"),this.endGroup.classList.remove("has-error"),this.titleInput.value.trim()||(this.titleGroup.classList.add("has-error"),t=!1);const e=new Date(this.startInput.value);return new Date(this.endInput.value)<=e&&(this.endGroup.classList.add("has-error"),t=!1),t}save(){if(!this.validate())return;const t={title:this.titleInput.value.trim(),start:new Date(this.startInput.value),end:new Date(this.endInput.value),backgroundColor:this._formData.color};this.emit("save",t),this.close()}formatDateForInput(t){const e=o=>String(o).padStart(2,"0"),r=t.getFullYear(),i=e(t.getMonth()+1),s=e(t.getDate()),n=e(t.getHours()),a=e(t.getMinutes());return`${r}-${i}-${s}T${n}:${a}`}unmount(){this._cleanupFocusTrap&&this._cleanupFocusTrap(),this._handleKeyDown&&(window.removeEventListener("keydown",this._handleKeyDown),this._handleKeyDown=null,this._keydownListenerAdded=!1)}}customElements.get("forcecal-event-form")||customElements.define("forcecal-event-form",z);const y=class y extends v{static get observedAttributes(){return["view","date","locale","timezone","week-starts-on","height"]}constructor(){super(),this.stateManager=null,this.currentView=null,this._hasRendered=!1,this._busUnsubscribers=[]}propChanged(t,e,r){if(!(!this.stateManager||e===r))switch(t){case"view":r&&this.stateManager.setView(r);break;case"date":{const i=r?new Date(r):null;i&&!isNaN(i.getTime())&&this.stateManager.setDate(i);break}case"locale":r&&this.stateManager.updateConfig({locale:r});break;case"timezone":r&&this.stateManager.updateConfig({timeZone:r});break;case"week-starts-on":{const i=parseInt(r,10);Number.isNaN(i)||this.stateManager.updateConfig({weekStartsOn:i});break}}}initialize(){const t={view:this.getAttribute("view")||"month",date:this.getAttribute("date")?new Date(this.getAttribute("date")):new Date,locale:this.getAttribute("locale")||"en-US",timeZone:this.getAttribute("timezone")||Intl.DateTimeFormat().resolvedOptions().timeZone,weekStartsOn:parseInt(this.getAttribute("week-starts-on")||"0")};this.stateManager=new T(t),this._stateUnsubscribe=this.stateManager.subscribe(this.handleStateChange.bind(this)),this.setupEventListeners()}setupEventListeners(){this._busUnsubscribers.forEach(r=>r()),this._busUnsubscribers=[];const t=this.stateManager.eventBus;this._busUnsubscribers.push(t.on("navigation:*",(r,i)=>{this.emit("calendar-navigate",{action:i.split(":")[1],...r})})),this._busUnsubscribers.push(t.on("view:changed",r=>{this.emit("calendar-view-change",r)}));const e=(r,i)=>{this.emit(`calendar-event-${r}`,i)};this._busUnsubscribers.push(t.on("event:add",r=>{e("add",r)})),this._busUnsubscribers.push(t.on("event:update",r=>{e("update",r)})),this._busUnsubscribers.push(t.on("event:remove",r=>{e("remove",r)})),this._busUnsubscribers.push(t.on("event:added",r=>{this.emit("calendar-event-added",r)})),this._busUnsubscribers.push(t.on("event:updated",r=>{this.emit("calendar-event-updated",r)})),this._busUnsubscribers.push(t.on("event:deleted",r=>{this.emit("calendar-event-deleted",r)})),this._busUnsubscribers.push(t.on("date:selected",r=>{this.emit("calendar-date-select",r)}))}handleStateChange(t,e){var o,c;if(!this._hasRendered)return;const r=t.view!==(e==null?void 0:e.view),i=((o=t.currentDate)==null?void 0:o.getTime())!==((c=e==null?void 0:e.currentDate)==null?void 0:c.getTime()),s=t.events!==(e==null?void 0:e.events),n=t.loading!==(e==null?void 0:e.loading);if(t.error!==(e==null?void 0:e.error)){this.render();return}if(n){this._updateLoadingState(t.loading);return}r&&(this.currentView=t.view),r?(this._updateTitle(),this._updateViewButtons(),this._switchView()):i?(this._updateTitle(),this._updateViewContent()):s&&this._updateViewContent()}_updateTitle(){const t=this.$(".fc-title");if(t){const e=this.stateManager.getState();t.textContent=this.getTitle(e.currentDate,e.view)}}_updateViewButtons(){const t=this.stateManager.getState();this.$$("[data-view]").forEach(e=>{const r=e.dataset.view===t.view;e.classList.toggle("active",r)})}_switchView(){const t=this.$("#calendar-view-container");if(t){this._currentViewInstance&&this._currentViewInstance.cleanup&&this._currentViewInstance.cleanup();try{const e=y.RENDERERS[this.currentView]||k,r=new e(t,this.stateManager);r._viewType=this.currentView,this._currentViewInstance=r,r.render()}catch(e){console.error("[ForceCalendar] Error switching view:",e)}}}_updateViewContent(){this._currentViewInstance&&this._currentViewInstance.render&&this._currentViewInstance.render()}_updateLoadingState(t){const e=this.$(".fc-loading"),r=this.$(".fc-view-container");e&&(e.style.display=t?"flex":"none"),r&&(r.style.display=t?"none":"flex")}mount(){this.currentView=this.stateManager.getView(),super.mount()}loadView(t){!t||this.currentView===t||(this.currentView=t,this._switchView(),this._updateViewButtons(),this._updateTitle())}getStyles(){const t=this.getAttribute("height")||"800px";return`
615
- ${u.getBaseStyles()}
616
- ${u.getButtonStyles()}
617
- ${u.getGridStyles()}
618
- ${u.getAnimations()}
619
+ `}afterRender(){this.modalContent=this.$(`.modal-content`),this.titleInput=this.$(`#event-title`),this.startInput=this.$(`#event-start`),this.endInput=this.$(`#event-end`),this.colorContainer=this.$(`#color-picker`),this.titleGroup=this.$(`#title-group`),this.endGroup=this.$(`#end-group`),this.addListener(this.$(`#close-x`),`click`,()=>this.close()),this.addListener(this.$(`#cancel-btn`),`click`,()=>this.close()),this.addListener(this.$(`#save-btn`),`click`,()=>this.save()),this.colorContainer.querySelectorAll(`.color-btn`).forEach(e=>{this.addListener(e,`click`,e=>{this._formData.color=e.currentTarget.dataset.color,this.updateColorSelection()})}),this.addListener(this,`click`,e=>{e.target===this&&this.close()}),this._keydownListenerAdded||=(this._handleKeyDown=e=>{e.key===`Escape`&&this.hasAttribute(`open`)&&this.close()},window.addEventListener(`keydown`,this._handleKeyDown),!0)}updateColorSelection(){this.colorContainer.querySelectorAll(`.color-btn`).forEach(e=>{let t=e.dataset.color===this._formData.color;e.classList.toggle(`selected`,t),e.setAttribute(`aria-checked`,t?`true`:`false`)})}open(e=new Date){this.hasAttribute(`open`)||this.setAttribute(`open`,``),this.titleGroup.classList.remove(`has-error`),this.endGroup.classList.remove(`has-error`),this._formData.start=e,this._formData.end=new Date(e.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=s.trapFocus(this.modalContent))}close(){this.removeAttribute(`open`),this._cleanupFocusTrap&&=(this._cleanupFocusTrap(),null)}validate(){let e=!0;this.titleGroup.classList.remove(`has-error`),this.endGroup.classList.remove(`has-error`),this.titleInput.value.trim()||(this.titleGroup.classList.add(`has-error`),e=!1);let t=new Date(this.startInput.value);return new Date(this.endInput.value)<=t&&(this.endGroup.classList.add(`has-error`),e=!1),e}save(){if(!this.validate())return;let e={title:this.titleInput.value.trim(),start:new Date(this.startInput.value),end:new Date(this.endInput.value),backgroundColor:this._formData.color};this.emit(`save`,e),this.close()}formatDateForInput(e){let t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}T${t(e.getHours())}:${t(e.getMinutes())}`}unmount(){this._cleanupFocusTrap&&this._cleanupFocusTrap(),this._handleKeyDown&&(window.removeEventListener(`keydown`,this._handleKeyDown),this._handleKeyDown=null,this._keydownListenerAdded=!1)}};customElements.get(`forcecal-event-form`)||customElements.define(`forcecal-event-form`,p);var m=class e extends n{static RENDERERS={month:u,week:d,day:f};static get observedAttributes(){return[`view`,`date`,`locale`,`timezone`,`week-starts-on`,`height`]}constructor(){super(),this.stateManager=null,this.currentView=null,this._hasRendered=!1,this._busUnsubscribers=[]}propChanged(e,t,n){if(!(!this.stateManager||t===n))switch(e){case`view`:n&&this.stateManager.setView(n);break;case`date`:{let e=n?new Date(n):null;e&&!isNaN(e.getTime())&&this.stateManager.setDate(e);break}case`locale`:n&&this.stateManager.updateConfig({locale:n});break;case`timezone`:n&&this.stateManager.updateConfig({timeZone:n});break;case`week-starts-on`:{let e=parseInt(n,10);Number.isNaN(e)||this.stateManager.updateConfig({weekStartsOn:e});break}}}initialize(){let e={view:this.getAttribute(`view`)||`month`,date:this.getAttribute(`date`)?new Date(this.getAttribute(`date`)):new Date,locale:this.getAttribute(`locale`)||`en-US`,timeZone:this.getAttribute(`timezone`)||Intl.DateTimeFormat().resolvedOptions().timeZone,weekStartsOn:parseInt(this.getAttribute(`week-starts-on`)||`0`)};this.stateManager=new a(e),this._stateUnsubscribe=this.stateManager.subscribe(this.handleStateChange.bind(this)),this.setupEventListeners()}setupEventListeners(){this._busUnsubscribers.forEach(e=>e()),this._busUnsubscribers=[];let e=this.stateManager.eventBus;this._busUnsubscribers.push(e.on(`navigation:*`,(e,t)=>{this.emit(`calendar-navigate`,{action:t.split(`:`)[1],...e})})),this._busUnsubscribers.push(e.on(`view:changed`,e=>{this.emit(`calendar-view-change`,e)}));let t=(e,t)=>{this.emit(`calendar-event-${e}`,t)};this._busUnsubscribers.push(e.on(`event:add`,e=>{t(`add`,e)})),this._busUnsubscribers.push(e.on(`event:update`,e=>{t(`update`,e)})),this._busUnsubscribers.push(e.on(`event:remove`,e=>{t(`remove`,e)})),this._busUnsubscribers.push(e.on(`event:added`,e=>{this.emit(`calendar-event-added`,e)})),this._busUnsubscribers.push(e.on(`event:updated`,e=>{this.emit(`calendar-event-updated`,e)})),this._busUnsubscribers.push(e.on(`event:deleted`,e=>{this.emit(`calendar-event-deleted`,e)})),this._busUnsubscribers.push(e.on(`date:selected`,e=>{this.emit(`calendar-date-select`,e)}))}handleStateChange(e,t){if(!this._hasRendered)return;let n=e.view!==t?.view,r=e.currentDate?.getTime()!==t?.currentDate?.getTime(),i=e.events!==t?.events,a=e.loading!==t?.loading;if(e.error!==t?.error){this.render();return}if(a){this._updateLoadingState(e.loading);return}n&&(this.currentView=e.view),n?(this._updateTitle(),this._updateViewButtons(),this._switchView()):r?(this._updateTitle(),this._updateViewContent()):i&&this._updateViewContent()}_updateTitle(){let e=this.$(`.fc-title`);if(e){let t=this.stateManager.getState();e.textContent=this.getTitle(t.currentDate,t.view)}}_updateViewButtons(){let e=this.stateManager.getState();this.$$(`[data-view]`).forEach(t=>{let n=t.dataset.view===e.view;t.classList.toggle(`active`,n)})}_switchView(){let t=this.$(`#calendar-view-container`);if(t){this._currentViewInstance&&this._currentViewInstance.cleanup&&this._currentViewInstance.cleanup();try{let n=new(e.RENDERERS[this.currentView]||u)(t,this.stateManager);n._viewType=this.currentView,this._currentViewInstance=n,n.render()}catch(e){console.error(`[ForceCalendar] Error switching view:`,e)}}}_updateViewContent(){this._currentViewInstance&&this._currentViewInstance.render&&this._currentViewInstance.render()}_updateLoadingState(e){let t=this.$(`.fc-loading`),n=this.$(`.fc-view-container`);t&&(t.style.display=e?`flex`:`none`),n&&(n.style.display=e?`none`:`flex`)}mount(){this.currentView=this.stateManager.getView(),super.mount()}loadView(e){!e||this.currentView===e||(this.currentView=e,this._switchView(),this._updateViewButtons(),this._updateTitle())}getStyles(){let e=this.getAttribute(`height`)||`800px`;return`
620
+ ${c.getBaseStyles()}
621
+ ${c.getButtonStyles()}
622
+ ${c.getGridStyles()}
623
+ ${c.getAnimations()}
619
624
 
620
625
  :host {
621
- --calendar-height: ${t};
626
+ --calendar-height: ${e};
622
627
  display: block;
623
628
  font-family: var(--fc-font-family);
624
629
  }
@@ -716,6 +721,20 @@
716
721
  padding: 0;
717
722
  }
718
723
 
724
+ .fc-month-day:focus-visible,
725
+ .fc-event:focus-visible {
726
+ outline: 2px solid var(--fc-primary-color);
727
+ outline-offset: -2px;
728
+ }
729
+
730
+ .fc-nav-arrow:focus-visible,
731
+ .fc-btn:focus-visible,
732
+ .fc-btn-today:focus-visible,
733
+ .fc-view-button:focus-visible {
734
+ outline: 2px solid var(--fc-primary-color);
735
+ outline-offset: 2px;
736
+ }
737
+
719
738
  .fc-nav-arrow:hover {
720
739
  background: var(--fc-background-hover);
721
740
  color: var(--fc-text-color);
@@ -996,13 +1015,13 @@
996
1015
  height: 100%;
997
1016
  background: var(--fc-background);
998
1017
  }
999
- `}template(){const t=this.stateManager.getState(),{currentDate:e,view:r,loading:i,error:s}=t;if(s)return`
1018
+ `}template(){let{currentDate:e,view:t,loading:n,error:r}=this.stateManager.getState();if(r)return`
1000
1019
  <div class="force-calendar">
1001
1020
  <div class="fc-error">
1002
- <p><strong>Error:</strong> ${m.escapeHTML(s.message||"An error occurred")}</p>
1021
+ <p><strong>Error:</strong> ${s.escapeHTML(r.message||`An error occurred`)}</p>
1003
1022
  </div>
1004
1023
  </div>
1005
- `;const n=this.getTitle(e,r);return`
1024
+ `;let i=this.getTitle(e,t);return`
1006
1025
  <div class="force-calendar">
1007
1026
  <header class="fc-header">
1008
1027
  <div class="fc-header-left">
@@ -1012,12 +1031,12 @@
1012
1031
  </div>
1013
1032
 
1014
1033
  <div class="fc-header-center">
1015
- <button class="fc-nav-arrow" data-action="previous" title="Previous">
1016
- ${this.getIcon("chevron-left")}
1034
+ <button class="fc-nav-arrow" data-action="previous" title="Previous" aria-label="Previous ${t}">
1035
+ ${this.getIcon(`chevron-left`)}
1017
1036
  </button>
1018
- <h2 class="fc-title">${m.escapeHTML(n)}</h2>
1019
- <button class="fc-nav-arrow" data-action="next" title="Next">
1020
- ${this.getIcon("chevron-right")}
1037
+ <h2 class="fc-title" aria-live="polite">${s.escapeHTML(i)}</h2>
1038
+ <button class="fc-nav-arrow" data-action="next" title="Next" aria-label="Next ${t}">
1039
+ ${this.getIcon(`chevron-right`)}
1021
1040
  </button>
1022
1041
  </div>
1023
1042
 
@@ -1025,30 +1044,33 @@
1025
1044
  <button class="fc-btn fc-btn-primary" id="create-event-btn" style="height: 28px; padding: 0 12px; font-size: 12px;">
1026
1045
  + New Event
1027
1046
  </button>
1028
- <div class="fc-view-buttons" role="group">
1029
- <button class="fc-view-button ${r==="month"?"active":""}"
1047
+ <div class="fc-view-buttons" role="group" aria-label="Calendar view">
1048
+ <button class="fc-view-button ${t===`month`?`active`:``}"
1049
+ aria-pressed="${t===`month`?`true`:`false`}"
1030
1050
  data-view="month">Month</button>
1031
- <button class="fc-view-button ${r==="week"?"active":""}"
1051
+ <button class="fc-view-button ${t===`week`?`active`:``}"
1052
+ aria-pressed="${t===`week`?`true`:`false`}"
1032
1053
  data-view="week">Week</button>
1033
- <button class="fc-view-button ${r==="day"?"active":""}"
1054
+ <button class="fc-view-button ${t===`day`?`active`:``}"
1055
+ aria-pressed="${t===`day`?`true`:`false`}"
1034
1056
  data-view="day">Day</button>
1035
1057
  </div>
1036
1058
  </div>
1037
1059
  </header>
1038
1060
 
1039
1061
  <div class="fc-body">
1040
- <div class="fc-loading" style="display: ${i?"flex":"none"};">
1062
+ <div class="fc-loading" style="display: ${n?`flex`:`none`};">
1041
1063
  <div class="fc-spinner"></div>
1042
1064
  <span>Loading...</span>
1043
1065
  </div>
1044
- <div class="fc-view-container" style="display: ${i?"none":"flex"};">
1066
+ <div class="fc-view-container" style="display: ${n?`none`:`flex`};">
1045
1067
  ${this.renderView()}
1046
1068
  </div>
1047
1069
  </div>
1048
1070
 
1049
1071
  <forcecal-event-form id="event-modal"></forcecal-event-form>
1050
1072
  </div>
1051
- `}renderView(){return'<div id="calendar-view-container"></div>'}afterRender(){const t=this.$("#calendar-view-container");if(t&&this.stateManager&&this.currentView){if(this._currentViewInstance&&this._currentViewInstance._viewType===this.currentView&&t.children.length>0)return;this._currentViewInstance&&(this._currentViewInstance.cleanup&&this._currentViewInstance.cleanup(),this._viewUnsubscribe&&(this._viewUnsubscribe(),this._viewUnsubscribe=null));try{const i=y.RENDERERS[this.currentView]||k,s=new i(t,this.stateManager);s._viewType=this.currentView,this._currentViewInstance=s,s.render()}catch(i){console.error("[ForceCalendar] Error creating/rendering view:",i)}}this.$$("[data-action]").forEach(i=>{this.addListener(i,"click",this.handleNavigation)}),this.$$("[data-view]").forEach(i=>{this.addListener(i,"click",this.handleViewChange)});const e=this.$("#event-modal"),r=this.$("#create-event-btn");r&&e&&this.addListener(r,"click",()=>{e.open(new Date)}),this.addListener(this.shadowRoot,"day-click",i=>{e&&e.open(i.detail.date)}),e&&this.addListener(e,"save",i=>{const s=i.detail,n=window.crypto&&typeof window.crypto.randomUUID=="function"?window.crypto.randomUUID():Math.random().toString(36).substring(2,15);this.stateManager.addEvent({id:n,...s})}),this._hasRendered=!0}handleNavigation(t){switch(t.currentTarget.dataset.action){case"today":this.stateManager.today();break;case"previous":this.stateManager.previous();break;case"next":this.stateManager.next();break}}handleViewChange(t){const e=t.currentTarget.dataset.view;this.stateManager.setView(e)}getTitle(t,e){const r=this.stateManager.getState().config.locale;switch(e){case"month":return p.formatDate(t,"month",r);case"week":{const i=p.startOfWeek(t),s=p.endOfWeek(t);return p.formatDateRange(i,s,r)}case"day":return p.formatDate(t,"long",r);default:return p.formatDate(t,"month",r)}}getIcon(t){return{"chevron-left":`
1073
+ `}renderView(){return`<div id="calendar-view-container"></div>`}afterRender(){let t=this.$(`#calendar-view-container`);if(t&&this.stateManager&&this.currentView){if(this._currentViewInstance&&this._currentViewInstance._viewType===this.currentView&&t.children.length>0)return;this._currentViewInstance&&(this._currentViewInstance.cleanup&&this._currentViewInstance.cleanup(),this._viewUnsubscribe&&=(this._viewUnsubscribe(),null));try{let n=new(e.RENDERERS[this.currentView]||u)(t,this.stateManager);n._viewType=this.currentView,this._currentViewInstance=n,n.render()}catch(e){console.error(`[ForceCalendar] Error creating/rendering view:`,e)}}this.$$(`[data-action]`).forEach(e=>{this.addListener(e,`click`,this.handleNavigation)}),this.$$(`[data-view]`).forEach(e=>{this.addListener(e,`click`,this.handleViewChange)});let n=this.$(`#event-modal`),r=this.$(`#create-event-btn`);r&&n&&this.addListener(r,`click`,()=>{n.open(new Date)}),this.addListener(this.shadowRoot,`day-click`,e=>{n&&n.open(e.detail.date)}),n&&this.addListener(n,`save`,e=>{let t=e.detail,n=window.crypto&&typeof window.crypto.randomUUID==`function`?window.crypto.randomUUID():Math.random().toString(36).substring(2,15);this.stateManager.addEvent({id:n,...t})}),this._hasRendered=!0}handleNavigation(e){switch(e.currentTarget.dataset.action){case`today`:this.stateManager.today();break;case`previous`:this.stateManager.previous();break;case`next`:this.stateManager.next();break}}handleViewChange(e){let t=e.currentTarget.dataset.view;this.stateManager.setView(t)}getTitle(e,t){let n=this.stateManager.getState().config.locale;switch(t){case`month`:return o.formatDate(e,`month`,n);case`week`:{let t=o.startOfWeek(e),r=o.endOfWeek(e);return o.formatDateRange(t,r,n)}case`day`:return o.formatDate(e,`long`,n);default:return o.formatDate(e,`month`,n)}}getIcon(e){return{"chevron-left":`
1052
1074
  <svg class="fc-icon" viewBox="0 0 24 24">
1053
1075
  <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
1054
1076
  </svg>
@@ -1060,5 +1082,5 @@
1060
1082
  <svg class="fc-icon" viewBox="0 0 24 24">
1061
1083
  <path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"/>
1062
1084
  </svg>
1063
- `}[t]||""}addEvent(t){return this.stateManager.addEvent(t)}updateEvent(t,e){return this.stateManager.updateEvent(t,e)}deleteEvent(t){return this.stateManager.deleteEvent(t)}getEvents(){return this.stateManager.getEvents()}setView(t){this.stateManager.setView(t)}setDate(t){this.stateManager.setDate(t)}next(){this.stateManager.next()}previous(){this.stateManager.previous()}today(){this.stateManager.today()}unmount(){this.destroy()}destroy(){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()}};w(y,"RENDERERS",{month:k,week:C,day:H});let D=y;customElements.get("forcecal-main")||customElements.define("forcecal-main",D),d.BaseComponent=v,d.BaseViewRenderer=_,d.DOMUtils=m,d.DateUtils=p,d.DayViewRenderer=H,d.EventBus=M,d.ForceCalendar=D,d.MonthViewRenderer=k,d.StateManager=T,d.StyleUtils=u,d.WeekViewRenderer=C,d.eventBus=I,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
1064
- //# sourceMappingURL=force-calendar-interface.umd.js.map
1085
+ `}[e]||``}addEvent(e){return this.stateManager.addEvent(e)}updateEvent(e,t){return this.stateManager.updateEvent(e,t)}deleteEvent(e){return this.stateManager.deleteEvent(e)}getEvents(){return this.stateManager.getEvents()}setView(e){this.stateManager.setView(e)}setDate(e){this.stateManager.setDate(e)}next(){this.stateManager.next()}previous(){this.stateManager.previous()}today(){this.stateManager.today()}unmount(){this.destroy()}destroy(){this._busUnsubscribers.forEach(e=>e()),this._busUnsubscribers=[],this._stateUnsubscribe&&=(this._stateUnsubscribe(),null),this._currentViewInstance&&this._currentViewInstance.cleanup&&(this._currentViewInstance.cleanup(),this._currentViewInstance=null),this.stateManager&&this.stateManager.destroy(),super.cleanup()}};customElements.get(`forcecal-main`)||customElements.define(`forcecal-main`,m),e.BaseComponent=n,e.BaseViewRenderer=l,e.DOMUtils=s,e.DateUtils=o,e.DayViewRenderer=f,e.EventBus=r,e.ForceCalendar=m,e.MonthViewRenderer=u,e.StateManager=a,e.StyleUtils=c,e.WeekViewRenderer=d,e.eventBus=i});
1086
+ //# sourceMappingURL=force-calendar-interface.umd.js.map