@forcecalendar/interface 0.7.0 → 0.8.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,1486 +0,0 @@
1
- var Y=Object.defineProperty;var N=(u,e,t)=>e in u?Y(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var A=(u,e,t)=>N(u,typeof e!="symbol"?e+"":e,t);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))s(i);new MutationObserver(i=>{for(const a of i)if(a.type==="childList")for(const n of a.addedNodes)n.tagName==="LINK"&&n.rel==="modulepreload"&&s(n)}).observe(document,{childList:!0,subtree:!0});function t(i){const a={};return i.integrity&&(a.integrity=i.integrity),i.referrerPolicy&&(a.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?a.credentials="include":i.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function s(i){if(i.ep)return;i.ep=!0;const a=t(i);fetch(i.href,a)}})();class C extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._listeners=new Map,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()}initialize(){}mount(){this.render()}unmount(){}cleanup(){this._listeners.forEach((e,t)=>{t.removeEventListener(e.event,e.handler)}),this._listeners.clear()}setState(e){const 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){const s=this._props.get(e);this._props.set(e,t),this.propChanged(e,s,t)}getProp(e){return this._props.get(e)}propChanged(e,t,s){}addListener(e,t,s){if(!e||!t||!s){console.warn("addListener called with invalid parameters",{element:e,event:t,handler:s});return}const i=s.bind(this);e.addEventListener(t,i),this._listeners.set(e,{event:t,handler:i})}emit(e,t={}){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}getStyles(){return""}getBaseStyles(){return`
2
- :host {
3
- display: block;
4
- box-sizing: border-box;
5
- }
6
-
7
- *, *::before, *::after {
8
- box-sizing: inherit;
9
- }
10
- `}render(){const e=`
11
- <style>
12
- ${this.getBaseStyles()}
13
- ${this.getStyles()}
14
- </style>
15
- `,t=this.template();this.shadowRoot.innerHTML=e+t,this.afterRender()}template(){return""}afterRender(){}$(e){return this.shadowRoot.querySelector(e)}$$(e){return this.shadowRoot.querySelectorAll(e)}static get observedAttributes(){return[]}attributeChangedCallback(e,t,s){this.setProp(e,s),this._initialized&&this.render()}}class W{constructor(){this.timezones={UTC:{offset:0,dst:null},GMT:{offset:0,dst:null},"Africa/Abidjan":{offset:0,dst:null},"Africa/Accra":{offset:0,dst:null},"Africa/Addis_Ababa":{offset:180,dst:null},"Africa/Algiers":{offset:60,dst:null},"Africa/Cairo":{offset:120,dst:null},"Africa/Casablanca":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Africa/Johannesburg":{offset:120,dst:null},"Africa/Lagos":{offset:60,dst:null},"Africa/Nairobi":{offset:180,dst:null},"America/Anchorage":{offset:-540,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Argentina/Buenos_Aires":{offset:-180,dst:null},"America/Bogota":{offset:-300,dst:null},"America/Caracas":{offset:-240,dst:null},"America/Chicago":{offset:-360,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Denver":{offset:-420,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Detroit":{offset:-300,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Halifax":{offset:-240,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Los_Angeles":{offset:-480,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Mexico_City":{offset:-360,dst:{start:{month:4,week:1,day:0},end:{month:10,week:-1,day:0},offset:60}},"America/New_York":{offset:-300,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Phoenix":{offset:-420,dst:null},"America/Regina":{offset:-360,dst:null},"America/Santiago":{offset:-180,dst:{start:{month:9,week:1,day:0},end:{month:4,week:1,day:0},offset:60}},"America/Sao_Paulo":{offset:-180,dst:{start:{month:10,week:3,day:0},end:{month:2,week:3,day:0},offset:60}},"America/St_Johns":{offset:-210,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Toronto":{offset:-300,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"America/Vancouver":{offset:-480,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"Asia/Baghdad":{offset:180,dst:null},"Asia/Bangkok":{offset:420,dst:null},"Asia/Dubai":{offset:240,dst:null},"Asia/Hong_Kong":{offset:480,dst:null},"Asia/Jakarta":{offset:420,dst:null},"Asia/Jerusalem":{offset:120,dst:{start:{month:3,week:-1,day:5},end:{month:10,week:-1,day:0},offset:60}},"Asia/Karachi":{offset:300,dst:null},"Asia/Kolkata":{offset:330,dst:null},"Asia/Kuala_Lumpur":{offset:480,dst:null},"Asia/Manila":{offset:480,dst:null},"Asia/Seoul":{offset:540,dst:null},"Asia/Shanghai":{offset:480,dst:null},"Asia/Singapore":{offset:480,dst:null},"Asia/Taipei":{offset:480,dst:null},"Asia/Tehran":{offset:210,dst:{start:{month:3,week:4,day:0},end:{month:9,week:4,day:0},offset:60}},"Asia/Tokyo":{offset:540,dst:null},"Atlantic/Azores":{offset:-60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Atlantic/Bermuda":{offset:-240,dst:{start:{month:3,week:2,day:0},end:{month:11,week:1,day:0},offset:60}},"Atlantic/Reykjavik":{offset:0,dst:null},"Australia/Adelaide":{offset:570,dst:{start:{month:10,week:1,day:0},end:{month:4,week:1,day:0},offset:60}},"Australia/Brisbane":{offset:600,dst:null},"Australia/Darwin":{offset:570,dst:null},"Australia/Hobart":{offset:600,dst:{start:{month:10,week:1,day:0},end:{month:4,week:1,day:0},offset:60}},"Australia/Melbourne":{offset:600,dst:{start:{month:10,week:1,day:0},end:{month:4,week:1,day:0},offset:60}},"Australia/Perth":{offset:480,dst:null},"Australia/Sydney":{offset:600,dst:{start:{month:10,week:1,day:0},end:{month:4,week:1,day:0},offset:60}},"Europe/Amsterdam":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Athens":{offset:120,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Berlin":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Brussels":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Budapest":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Copenhagen":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Dublin":{offset:0,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Helsinki":{offset:120,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Istanbul":{offset:180,dst:null},"Europe/Kiev":{offset:120,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Lisbon":{offset:0,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/London":{offset:0,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Madrid":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Moscow":{offset:180,dst:null},"Europe/Oslo":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Paris":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Prague":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Rome":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Stockholm":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Vienna":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Warsaw":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Europe/Zurich":{offset:60,dst:{start:{month:3,week:-1,day:0},end:{month:10,week:-1,day:0},offset:60}},"Indian/Maldives":{offset:300,dst:null},"Indian/Mauritius":{offset:240,dst:null},"Pacific/Auckland":{offset:720,dst:{start:{month:9,week:-1,day:0},end:{month:4,week:1,day:0},offset:60}},"Pacific/Fiji":{offset:720,dst:{start:{month:11,week:1,day:0},end:{month:1,week:3,day:0},offset:60}},"Pacific/Guam":{offset:600,dst:null},"Pacific/Honolulu":{offset:-600,dst:null},"Pacific/Midway":{offset:-660,dst:null},"Pacific/Noumea":{offset:660,dst:null},"Pacific/Pago_Pago":{offset:-660,dst:null},"Pacific/Port_Moresby":{offset:600,dst:null},"Pacific/Tahiti":{offset:-600,dst:null}},this.aliases={EST:"America/New_York",EDT:"America/New_York",CST:"America/Chicago",CDT:"America/Chicago",MST:"America/Denver",MDT:"America/Denver",PST:"America/Los_Angeles",PDT:"America/Los_Angeles",AKST:"America/Anchorage",AKDT:"America/Anchorage",HST:"Pacific/Honolulu",AST:"America/Halifax",ADT:"America/Halifax",NST:"America/St_Johns",NDT:"America/St_Johns",BST:"Europe/London",IST:"Asia/Kolkata",WET:"Europe/Lisbon",WEST:"Europe/Lisbon",CET:"Europe/Paris",CEST:"Europe/Paris",EET:"Europe/Athens",EEST:"Europe/Athens",MSK:"Europe/Moscow",JST:"Asia/Tokyo",KST:"Asia/Seoul",CST_CN:"Asia/Shanghai",HKT:"Asia/Hong_Kong",SGT:"Asia/Singapore",AEST:"Australia/Sydney",AEDT:"Australia/Sydney",ACST:"Australia/Adelaide",ACDT:"Australia/Adelaide",AWST:"Australia/Perth",NZST:"Pacific/Auckland",NZDT:"Pacific/Auckland","US/Eastern":"America/New_York","US/Central":"America/Chicago","US/Mountain":"America/Denver","US/Pacific":"America/Los_Angeles","US/Alaska":"America/Anchorage","US/Hawaii":"Pacific/Honolulu","Canada/Eastern":"America/Toronto","Canada/Central":"America/Regina","Canada/Mountain":"America/Denver","Canada/Pacific":"America/Vancouver","Canada/Atlantic":"America/Halifax","Canada/Newfoundland":"America/St_Johns","Mexico/General":"America/Mexico_City","Brazil/East":"America/Sao_Paulo","Chile/Continental":"America/Santiago",GB:"Europe/London","GB-Eire":"Europe/London",Eire:"Europe/Dublin",Israel:"Asia/Jerusalem",Japan:"Asia/Tokyo",Singapore:"Asia/Singapore",Hongkong:"Asia/Hong_Kong",ROK:"Asia/Seoul",PRC:"Asia/Shanghai","Australia/NSW":"Australia/Sydney","Australia/Victoria":"Australia/Melbourne","Australia/Queensland":"Australia/Brisbane","Australia/South":"Australia/Adelaide","Australia/Tasmania":"Australia/Hobart","Australia/West":"Australia/Perth","Australia/North":"Australia/Darwin",NZ:"Pacific/Auckland"}}getTimezone(e){return this.aliases[e]&&(e=this.aliases[e]),this.timezones[e]||null}getAllTimezones(){return Object.keys(this.timezones)}isValidTimezone(e){return this.aliases[e]!==void 0||this.timezones[e]!==void 0}resolveAlias(e){return this.aliases[e]||e}getTimezonesByOffset(e){return Object.entries(this.timezones).filter(([t,s])=>s.offset===e).map(([t,s])=>t)}getCommonTimezones(){return{Americas:["America/New_York","America/Chicago","America/Denver","America/Los_Angeles","America/Toronto","America/Mexico_City","America/Sao_Paulo"],Europe:["Europe/London","Europe/Paris","Europe/Berlin","Europe/Moscow","Europe/Rome","Europe/Madrid","Europe/Amsterdam"],Asia:["Asia/Tokyo","Asia/Shanghai","Asia/Hong_Kong","Asia/Singapore","Asia/Kolkata","Asia/Dubai","Asia/Seoul"],"Australia/Pacific":["Australia/Sydney","Australia/Melbourne","Australia/Brisbane","Australia/Perth","Pacific/Auckland","Pacific/Honolulu"],Africa:["Africa/Cairo","Africa/Lagos","Africa/Johannesburg","Africa/Nairobi"]}}}class ${constructor(){this.database=new W,this.offsetCache=new Map,this.dstCache=new Map,this.maxCacheSize=1e3,this.cacheHits=0,this.cacheMisses=0}convertTimezone(e,t,s){if(!e)return null;if(t===s)return new Date(e);const i=this.getTimezoneOffset(e,t),n=(this.getTimezoneOffset(e,s)-i)*60*1e3;return new Date(e.getTime()+n)}toUTC(e,t){if(!e)return null;if(t==="UTC")return new Date(e);const s=this.getTimezoneOffset(e,t);return new Date(e.getTime()-s*60*1e3)}fromUTC(e,t){if(!e)return null;if(t==="UTC")return new Date(e);const s=this.getTimezoneOffset(e,t);return new Date(e.getTime()+s*60*1e3)}getTimezoneOffset(e,t){t=this.database.resolveAlias(t);const s=`${t}_${e.getFullYear()}_${e.getMonth()}_${e.getDate()}`;if(this.offsetCache.has(s))return this.cacheHits++,this._manageCacheSize(),this.offsetCache.get(s);if(this.cacheMisses++,typeof Intl<"u"&&Intl.DateTimeFormat)try{const r=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).formatToParts(e),c=(new Date(r.find(l=>l.type==="year").value,r.find(l=>l.type==="month").value-1,r.find(l=>l.type==="day").value,r.find(l=>l.type==="hour").value,r.find(l=>l.type==="minute").value,r.find(l=>l.type==="second").value).getTime()-e.getTime())/(1e3*60);return this.offsetCache.set(s,-c),this._manageCacheSize(),-c}catch{}const i=this.database.getTimezone(t);if(!i)throw new Error(`Unknown timezone: ${t}`);let a=i.offset;return i.dst&&this.isDST(e,t,i.dst)&&(a+=i.dst.offset),this.offsetCache.set(s,a),this._manageCacheSize(),a}isDST(e,t,s=null){if(!s){const r=this.database.getTimezone(t);if(!r||!r.dst)return!1;s=r.dst}const i=e.getFullYear(),a=this.getNthWeekdayOfMonth(i,s.start.month,s.start.week,s.start.day),n=this.getNthWeekdayOfMonth(i,s.end.month,s.end.week,s.end.day);return a>n?e>=a||e<n:e>=a&&e<n}getNthWeekdayOfMonth(e,t,s,i){const a=new Date(e,t,1),n=a.getDay();let r=i-n;if(r<0&&(r+=7),s>0)a.setDate(1+r+(s-1)*7);else{const o=new Date(e,t+1,0).getDate();a.setDate(o);let l=a.getDay()-i;l<0&&(l+=7),a.setDate(o-l+(s+1)*7)}return a}getCommonTimezones(){const e=new Date;return[{value:"America/New_York",label:"Eastern Time (New York)",region:"Americas"},{value:"America/Chicago",label:"Central Time (Chicago)",region:"Americas"},{value:"America/Denver",label:"Mountain Time (Denver)",region:"Americas"},{value:"America/Phoenix",label:"Mountain Time - Arizona (Phoenix)",region:"Americas"},{value:"America/Los_Angeles",label:"Pacific Time (Los Angeles)",region:"Americas"},{value:"America/Anchorage",label:"Alaska Time (Anchorage)",region:"Americas"},{value:"Pacific/Honolulu",label:"Hawaii Time (Honolulu)",region:"Pacific"},{value:"America/Toronto",label:"Eastern Time (Toronto)",region:"Americas"},{value:"America/Vancouver",label:"Pacific Time (Vancouver)",region:"Americas"},{value:"America/Mexico_City",label:"Central Time (Mexico City)",region:"Americas"},{value:"America/Sao_Paulo",label:"Brasilia Time (São Paulo)",region:"Americas"},{value:"Europe/London",label:"GMT/BST (London)",region:"Europe"},{value:"Europe/Paris",label:"Central European Time (Paris)",region:"Europe"},{value:"Europe/Berlin",label:"Central European Time (Berlin)",region:"Europe"},{value:"Europe/Moscow",label:"Moscow Time",region:"Europe"},{value:"Asia/Dubai",label:"Gulf Time (Dubai)",region:"Asia"},{value:"Asia/Kolkata",label:"India Time (Mumbai)",region:"Asia"},{value:"Asia/Shanghai",label:"China Time (Shanghai)",region:"Asia"},{value:"Asia/Tokyo",label:"Japan Time (Tokyo)",region:"Asia"},{value:"Asia/Seoul",label:"Korea Time (Seoul)",region:"Asia"},{value:"Asia/Singapore",label:"Singapore Time",region:"Asia"},{value:"Australia/Sydney",label:"Australian Eastern Time (Sydney)",region:"Oceania"},{value:"Australia/Melbourne",label:"Australian Eastern Time (Melbourne)",region:"Oceania"},{value:"Pacific/Auckland",label:"New Zealand Time (Auckland)",region:"Oceania"},{value:"UTC",label:"UTC",region:"UTC"}].map(s=>{const i=this.getTimezoneOffset(e,s.value),a=-i/60,n=Math.floor(Math.abs(a)),r=Math.round(Math.abs(a%1)*60),c=`UTC${a>=0?"+":"-"}${n.toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}`;return{...s,offset:c,offsetMinutes:-i}}).sort((s,i)=>s.offsetMinutes-i.offsetMinutes)}formatInTimezone(e,t,s={}){if(!e)return"";const a={...{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!0,timeZone:t},...s};try{return new Intl.DateTimeFormat("en-US",a).format(e)}catch{return this.fromUTC(this.toUTC(e,"UTC"),t).toLocaleString("en-US",s)}}getSystemTimezone(){if(typeof Intl<"u"&&Intl.DateTimeFormat)try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}const t=-new Date().getTimezoneOffset()/60;for(const[s,i]of Object.entries(this.database.timezones))if(i.offset/60===t)return s;return"UTC"}parseTimezone(e){if(!e)return"UTC";if(this.database.timezones.hasOwnProperty(e))return e;const t=e.toUpperCase();if(this.database.abbreviations&&this.database.abbreviations.hasOwnProperty(t))return this.database.abbreviations[t];const s=e.match(/^([+-])(\d{2}):?(\d{2})$/);if(s){const i=s[1]==="+"?1:-1,a=parseInt(s[2],10),n=parseInt(s[3],10),r=i*(a+n/60);for(const[o,c]of Object.entries(this.database.timezones))if(c.offset/60===r)return o}return"UTC"}getTimezoneDifference(e,t,s=new Date){const i=this.getTimezoneOffset(s,e);return(this.getTimezoneOffset(s,t)-i)/60}clearCache(){this.offsetCache.clear(),this.dstCache.clear(),this.cacheHits=0,this.cacheMisses=0}isValidTimezone(e){return this.database.isValidTimezone(e)}getCacheStats(){const e=this.cacheHits+this.cacheMisses>0?(this.cacheHits/(this.cacheHits+this.cacheMisses)*100).toFixed(2):0;return{offsetCacheSize:this.offsetCache.size,dstCacheSize:this.dstCache.size,maxCacheSize:this.maxCacheSize,cacheHits:this.cacheHits,cacheMisses:this.cacheMisses,hitRate:`${e}%`}}_manageCacheSize(){if(this.offsetCache.size>this.maxCacheSize){const e=Math.floor(this.offsetCache.size/2),t=Array.from(this.offsetCache.keys());for(let s=0;s<e;s++)this.offsetCache.delete(t[s])}if(this.dstCache.size>this.maxCacheSize/2){const e=Math.floor(this.dstCache.size/2),t=Array.from(this.dstCache.keys());for(let s=0;s<e;s++)this.dstCache.delete(t[s])}}}class x{static normalize(e){const t={...e};return t.start&&!(t.start instanceof Date)&&(t.start=new Date(t.start)),t.end&&!(t.end instanceof Date)&&(t.end=new Date(t.end)),t.end||(t.end=t.start?new Date(t.start):null),t.allDay&&t.start&&(t.start.setHours(0,0,0,0),t.end&&t.end.setHours(23,59,59,999)),t.id=String(t.id||"").trim(),t.title=String(t.title||"").trim(),t.description=String(t.description||"").trim(),t.location=String(t.location||"").trim(),t.attendees=Array.isArray(t.attendees)?t.attendees:[],t.reminders=Array.isArray(t.reminders)?t.reminders:[],e.category&&!e.categories?t.categories=[e.category]:t.categories?t.categories=Array.isArray(t.categories)?t.categories:[]:t.categories=[],t.attachments=Array.isArray(t.attachments)?t.attachments:[],["confirmed","tentative","cancelled"].includes(t.status)||(t.status="confirmed"),["public","private","confidential"].includes(t.visibility)||(t.visibility="public"),t.color&&!t.backgroundColor&&(t.backgroundColor=t.color),t.color&&!t.borderColor&&(t.borderColor=t.color),t}static validate(e){if(!e.id)throw new Error("Event must have an id");if(!e.title)throw new Error("Event must have a title");if(!e.start)throw new Error("Event must have a start date");if(!(e.start instanceof Date)||isNaN(e.start.getTime()))throw new Error("Invalid start date");if(e.end&&(!(e.end instanceof Date)||isNaN(e.end.getTime())))throw new Error("Invalid end date");if(e.end&&e.start&&e.end<e.start)throw new Error("Event end time cannot be before start time");if(e.recurring&&!e.recurrenceRule)throw new Error("Recurring events must have a recurrence rule");if(e.attendees&&e.attendees.length>0&&e.attendees.forEach((t,s)=>{if(!t.email||!t.name)throw new Error(`Attendee at index ${s} must have email and name`);if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.email))throw new Error(`Invalid email for attendee: ${t.email}`)}),e.reminders&&e.reminders.length>0&&e.reminders.forEach((t,s)=>{if(!t.method||t.minutesBefore==null)throw new Error(`Reminder at index ${s} must have method and minutesBefore`);if(t.minutesBefore<0)throw new Error("Reminder minutesBefore must be non-negative")}),e.timeZone)try{new Intl.DateTimeFormat("en-US",{timeZone:e.timeZone})}catch{throw new Error(`Invalid timezone: ${e.timeZone}`)}}constructor({id:e,title:t,start:s,end:i,allDay:a=!1,description:n="",location:r="",color:o=null,backgroundColor:c=null,borderColor:l=null,textColor:d=null,recurring:h=!1,recurrenceRule:y=null,timeZone:b=null,endTimeZone:w=null,status:E="confirmed",visibility:S="public",organizer:I=null,attendees:O=[],reminders:F=[],category:_,categories:B,attachments:H=[],conferenceData:R=null,metadata:U={},...P}){const m=x.normalize({id:e,title:t,start:s,end:i,allDay:a,description:n,location:r,color:o,backgroundColor:c,borderColor:l,textColor:d,recurring:h,recurrenceRule:y,timeZone:b,endTimeZone:w,status:E,visibility:S,organizer:I,attendees:O,reminders:F,category:_,categories:B,attachments:H,conferenceData:R,metadata:U,...P});x.validate(m),this.id=m.id,this.title=m.title,this._timezoneManager=new $,this.timeZone=m.timeZone||this._timezoneManager.getSystemTimezone(),this.endTimeZone=m.endTimeZone||this.timeZone,this.start=m.start,this.end=m.end,this.startUTC=this._timezoneManager.toUTC(this.start,this.timeZone),this.endUTC=this._timezoneManager.toUTC(this.end,this.endTimeZone),this.allDay=m.allDay,this.description=m.description,this.location=m.location,this.color=m.color,this.backgroundColor=m.backgroundColor,this.borderColor=m.borderColor,this.textColor=m.textColor,this.recurring=m.recurring,this.recurrenceRule=m.recurrenceRule,this._originalTimeZone=m.timeZone||null,this.status=m.status,this.visibility=m.visibility,this.organizer=m.organizer,this.attendees=[...m.attendees],this.reminders=[...m.reminders],this.categories=m.categories?[...m.categories]:[],this.attachments=[...m.attachments],this.conferenceData=m.conferenceData,this.metadata={...m.metadata},this._cache={},this._validateAttendees(),this._validateReminders()}get duration(){return this._cache.duration||(this._cache.duration=this.endUTC.getTime()-this.startUTC.getTime()),this._cache.duration}getStartInTimezone(e){return e===this.timeZone?new Date(this.start):this._timezoneManager.fromUTC(this.startUTC,e)}getEndInTimezone(e){return e===this.endTimeZone?new Date(this.end):this._timezoneManager.fromUTC(this.endUTC,e)}updateTimes(e,t,s){if(s||this.timeZone,this.start=e instanceof Date?e:new Date(e),this.end=t instanceof Date?t:new Date(t),s&&(this.timeZone=s,this.endTimeZone=s),this.startUTC=this._timezoneManager.toUTC(this.start,this.timeZone),this.endUTC=this._timezoneManager.toUTC(this.end,this.endTimeZone),this._cache={},this.endUTC<this.startUTC)throw new Error("Event end time cannot be before start time")}get durationMinutes(){return Math.floor(this.duration/(1e3*60))}get durationHours(){return this.duration/(1e3*60*60)}get isMultiDay(){if(!this._cache.hasOwnProperty("isMultiDay")){const e=this.start.toDateString(),t=this.end.toDateString();this._cache.isMultiDay=e!==t}return this._cache.isMultiDay}isRecurring(){return this.recurring&&this.recurrenceRule!==null}occursOn(e){e instanceof Date||(e=new Date(e));const t=e.toDateString(),s=this.start.toDateString(),i=this.end.toDateString();if(this.allDay)return e>=new Date(s)&&e<=new Date(i);if(this.isMultiDay){const a=new Date(t),n=new Date(t);return n.setHours(23,59,59,999),this.start<=n&&this.end>=a}else return s===t}overlaps(e){if(e instanceof x)return!(this.end<=e.start||this.start>=e.end);if(e&&e.start&&e.end)return!(this.end<=e.start||this.start>=e.end);throw new Error("Parameter must be an Event instance or have start/end properties")}contains(e){return e instanceof Date||(e=new Date(e)),e>=this.start&&e<=this.end}clone(e={}){return new x({id:this.id,title:this.title,start:new Date(this.start),end:new Date(this.end),allDay:this.allDay,description:this.description,location:this.location,color:this.color,backgroundColor:this.backgroundColor,borderColor:this.borderColor,textColor:this.textColor,recurring:this.recurring,recurrenceRule:this.recurrenceRule,timeZone:this.timeZone,status:this.status,visibility:this.visibility,organizer:this.organizer?{...this.organizer}:null,attendees:this.attendees.map(t=>({...t})),reminders:this.reminders.map(t=>({...t})),categories:[...this.categories],attachments:this.attachments.map(t=>({...t})),conferenceData:this.conferenceData?{...this.conferenceData}:null,metadata:{...this.metadata},...e})}toObject(){return{id:this.id,title:this.title,start:this.start.toISOString(),end:this.end.toISOString(),allDay:this.allDay,description:this.description,location:this.location,color:this.color,backgroundColor:this.backgroundColor,borderColor:this.borderColor,textColor:this.textColor,recurring:this.recurring,recurrenceRule:this.recurrenceRule,timeZone:this.timeZone,status:this.status,visibility:this.visibility,organizer:this.organizer,attendees:this.attendees,reminders:this.reminders,categories:this.categories,attachments:this.attachments,conferenceData:this.conferenceData,metadata:{...this.metadata}}}static fromObject(e){return new x(e)}equals(e){return e instanceof x?this.id===e.id&&this.title===e.title&&this.start.getTime()===e.start.getTime()&&this.end.getTime()===e.end.getTime()&&this.allDay===e.allDay&&this.description===e.description&&this.location===e.location&&this.recurring===e.recurring&&this.recurrenceRule===e.recurrenceRule&&this.status===e.status:!1}addAttendee(e){if(!e||!e.email)throw new Error("Attendee must have an email");return this.hasAttendee(e.email)?!1:(e.id||(e.id=`attendee_${Date.now()}_${Math.random().toString(36).substr(2,9)}`),e.responseStatus=e.responseStatus||"needs-action",e.role=e.role||"required",this.attendees.push(e),!0)}removeAttendee(e){const t=this.attendees.findIndex(s=>s.email===e||s.id===e);return t!==-1?(this.attendees.splice(t,1),!0):!1}updateAttendeeResponse(e,t){const s=this.getAttendee(e);return s?(s.responseStatus=t,s.responseTime=new Date,!0):!1}getAttendee(e){return this.attendees.find(t=>t.email===e)||null}hasAttendee(e){return this.attendees.some(t=>t.email===e)}getAttendeesByStatus(e){return this.attendees.filter(t=>t.responseStatus===e)}getAttendeeCounts(){return this.attendees.reduce((e,t)=>{const s=t.responseStatus||"needs-action";return e[s]=(e[s]||0)+1,e},{})}addReminder(e){if(!e||typeof e.minutesBefore!="number")throw new Error("Reminder must have minutesBefore property");return e.id||(e.id=`reminder_${Date.now()}_${Math.random().toString(36).substr(2,9)}`),e.method=e.method||"popup",e.enabled=e.enabled!==!1,this.reminders.some(s=>s.method===e.method&&s.minutesBefore===e.minutesBefore)?!1:(this.reminders.push(e),!0)}removeReminder(e){const t=this.reminders.findIndex(s=>s.id===e);return t!==-1?(this.reminders.splice(t,1),!0):!1}getActiveReminders(){return this.reminders.filter(e=>e.enabled!==!1)}getReminderTriggerTimes(){return this.getActiveReminders().map(e=>{const t=new Date(this.start);return t.setMinutes(t.getMinutes()-e.minutesBefore),t})}addCategory(e){if(!e||typeof e!="string")throw new Error("Category must be a non-empty string");const t=e.trim().toLowerCase();return this.hasCategory(t)?!1:(this.categories.push(t),!0)}removeCategory(e){const t=e.trim().toLowerCase(),s=this.categories.findIndex(i=>i.toLowerCase()===t);return s!==-1?(this.categories.splice(s,1),!0):!1}get category(){return this.categories&&this.categories.length>0?this.categories[0]:null}hasCategory(e){const t=e.trim().toLowerCase();return this.categories.some(s=>s.toLowerCase()===t)}hasAnyCategory(e){return e.some(t=>this.hasCategory(t))}hasAllCategories(e){return e.every(t=>this.hasCategory(t))}_validateAttendees(){for(const e of this.attendees){if(!e.email)throw new Error("All attendees must have an email address");if(e.name||(e.name=e.email),!this._isValidEmail(e.email))throw new Error(`Invalid attendee email: ${e.email}`)}}_validateReminders(){for(const e of this.reminders){if(typeof e.minutesBefore!="number"||e.minutesBefore<0)throw new Error("Reminder minutesBefore must be a positive number");if(!["email","popup","sms"].includes(e.method))throw new Error(`Invalid reminder method: ${e.method}`)}}_isValidEmail(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}get isCancelled(){return this.status==="cancelled"}get isTentative(){return this.status==="tentative"}get isConfirmed(){return this.status==="confirmed"}get isPrivate(){return this.visibility==="private"}get isPublic(){return this.visibility==="public"}get hasAttendees(){return this.attendees.length>0}get hasReminders(){return this.reminders.length>0}get isMeeting(){return this.hasAttendees||this.conferenceData!==null}get isVirtual(){return this.conferenceData!==null}}let f=class v{static startOfDay(e){const t=new Date(e);return t.setHours(0,0,0,0),t}static endOfDay(e){const t=new Date(e);return t.setHours(23,59,59,999),t}static startOfWeek(e,t=0){const s=new Date(e),i=s.getDay(),a=(i<t?7:0)+i-t;return s.setTime(s.getTime()-a*24*60*60*1e3),s.setHours(0,0,0,0),s}static endOfWeek(e,t=0){const s=v.startOfWeek(e,t);return s.setTime(s.getTime()+6*24*60*60*1e3),s.setHours(23,59,59,999),s}static startOfMonth(e){return new Date(e.getFullYear(),e.getMonth(),1,0,0,0,0)}static endOfMonth(e){return new Date(e.getFullYear(),e.getMonth()+1,0,23,59,59,999)}static startOfYear(e){return new Date(e.getFullYear(),0,1,0,0,0,0)}static endOfYear(e){return new Date(e.getFullYear(),11,31,23,59,59,999)}static addDays(e,t){const s=new Date(e);return s.setTime(s.getTime()+t*24*60*60*1e3),s}static addWeeks(e,t){return v.addDays(e,t*7)}static addMonths(e,t){const s=new Date(e),i=s.getDate();return s.setMonth(s.getMonth()+t),s.getDate()!==i&&s.setDate(0),s}static addYears(e,t){const s=new Date(e);return s.setFullYear(s.getFullYear()+t),s}static getUTCDateString(e){const t=e.getUTCFullYear(),s=String(e.getUTCMonth()+1).padStart(2,"0"),i=String(e.getUTCDate()).padStart(2,"0");return`${t}-${s}-${i}`}static getLocalDateString(e){const t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0");return`${t}-${s}-${i}`}static isToday(e){const t=new Date;return e.toDateString()===t.toDateString()}static isPast(e){return e<new Date}static isFuture(e){return e>new Date}static isSameDay(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}static isSameWeek(e,t,s=0){const i=v.startOfWeek(e,s),a=v.startOfWeek(t,s);return i.toDateString()===a.toDateString()}static isSameMonth(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()}static isSameYear(e,t){return e.getFullYear()===t.getFullYear()}static differenceInDays(e,t){const s=e.getTime()-t.getTime();return Math.floor(s/(1e3*60*60*24))}static differenceInWeeks(e,t){return Math.floor(v.differenceInDays(e,t)/7)}static differenceInMonths(e,t){const s=e.getFullYear()-t.getFullYear(),i=e.getMonth()-t.getMonth();return s*12+i}static getWeekNumber(e){const t=new Date(e.getFullYear(),0,1),s=(e-t)/864e5;return Math.ceil((s+t.getDay()+1)/7)}static getDayOfWeek(e,t=0){return(e.getDay()-t+7)%7}static getDaysInMonth(e){return new Date(e.getFullYear(),e.getMonth()+1,0).getDate()}static format(e,t="en-US",s={}){return new Intl.DateTimeFormat(t,s).format(e)}static getMonthName(e,t="en-US",s="long"){return v.format(e,t,{month:s})}static getDayName(e,t="en-US",s="long"){return v.format(e,t,{weekday:s})}static formatTime(e,t="en-US",s=!1){return v.format(e,t,{hour:"numeric",minute:"2-digit",hour12:!s})}static parseTime(e){const[t,s]=e.split(":").map(Number);return{hours:t,minutes:s}}static setTime(e,t){const s=new Date(e),{hours:i,minutes:a}=v.parseTime(t);return s.setHours(i,a,0,0),s}static isLeapYear(e){return e%4===0&&e%100!==0||e%400===0}static getDateRange(e,t){const s=[],i=new Date(e),a=t.getTime();for(;i.getTime()<=a;)s.push(new Date(i)),i.setTime(i.getTime()+24*60*60*1e3);return s}static clone(e){return new Date(e)}static isValidDate(e){return e instanceof Date&&!isNaN(e.getTime())}static toTimeZone(e,t){const i=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).formatToParts(e),a={};return i.forEach(n=>{n.type!=="literal"&&(a[n.type]=n.value)}),new Date(`${a.year}-${a.month}-${a.day}T${a.hour}:${a.minute}:${a.second}`)}static getTimezoneOffset(e,t){const s=new Date(e.toLocaleString("en-US",{timeZone:"UTC"})),i=new Date(e.toLocaleString("en-US",{timeZone:t}));return(s.getTime()-i.getTime())/6e4}static isDST(e,t){const s=new Date(e.getFullYear(),0,1),i=new Date(e.getFullYear(),6,1),a=v.getTimezoneOffset(s,t),n=v.getTimezoneOffset(i,t),r=v.getTimezoneOffset(e,t);return Math.max(a,n)===r}static addHoursWithDST(e,t,s){const i=new Date(e),a=v.getTimezoneOffset(e,s);i.setTime(i.getTime()+t*60*60*1e3);const n=v.getTimezoneOffset(i,s);if(a!==n){const r=(n-a)*6e4;i.setTime(i.getTime()+r)}return i}static createInTimeZone(e,t,s,i=0,a=0,n=0,r){const o=`${e}-${String(t+1).padStart(2,"0")}-${String(s).padStart(2,"0")}`,c=`${String(i).padStart(2,"0")}:${String(a).padStart(2,"0")}:${String(n).padStart(2,"0")}`,l=new Date(`${o}T${c}`),d=v.getTimezoneOffset(l,r),h=l.getTime()+d*6e4;return new Date(h)}};class V{static parse(e){if(typeof e=="object")return this.validateRule(e);const t={freq:null,interval:1,count:null,until:null,byDay:[],byWeekNo:[],byMonth:[],byMonthDay:[],byYearDay:[],bySetPos:[],byHour:[],byMinute:[],bySecond:[],wkst:"MO",exceptions:[],tzid:null},s=e.toUpperCase().split(";");for(const i of s){const[a,n]=i.split("=");switch(a){case"FREQ":t.freq=this.parseFrequency(n);break;case"INTERVAL":t.interval=parseInt(n,10),t.interval<1&&(t.interval=1);break;case"COUNT":t.count=parseInt(n,10);break;case"UNTIL":t.until=this.parseDateTime(n);break;case"BYDAY":t.byDay=this.parseByDay(n);break;case"BYWEEKNO":t.byWeekNo=this.parseIntList(n);break;case"BYMONTH":t.byMonth=this.parseIntList(n);break;case"BYMONTHDAY":t.byMonthDay=this.parseIntList(n);break;case"BYYEARDAY":t.byYearDay=this.parseIntList(n);break;case"BYSETPOS":t.bySetPos=this.parseIntList(n);break;case"BYHOUR":t.byHour=this.parseIntList(n);break;case"BYMINUTE":t.byMinute=this.parseIntList(n);break;case"BYSECOND":t.bySecond=this.parseIntList(n);break;case"WKST":t.wkst=n;break;case"EXDATE":t.exceptions=this.parseExceptionDates(n);break;case"TZID":t.tzid=n;break}}return this.validateRule(t)}static parseFrequency(e){return["SECONDLY","MINUTELY","HOURLY","DAILY","WEEKLY","MONTHLY","YEARLY"].includes(e)?e:"DAILY"}static parseByDay(e){const t=e.split(","),s=["SU","MO","TU","WE","TH","FR","SA"],i=[];for(const a of t){const n=a.match(/^([+-]?\d*)([A-Z]{2})$/);if(n){const[r,o,c]=n;s.includes(c)&&i.push({weekday:c,nth:o?parseInt(o,10):null})}}return i}static parseIntList(e){return e.split(",").map(t=>parseInt(t.trim(),10)).filter(t=>!isNaN(t))}static parseDateTime(e){if(e.length===8){const t=parseInt(e.substr(0,4),10),s=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10);return new Date(t,s,i)}if(e.length===15&&e[8]==="T"){const t=parseInt(e.substr(0,4),10),s=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10),a=parseInt(e.substr(9,2),10),n=parseInt(e.substr(11,2),10),r=parseInt(e.substr(13,2),10);return new Date(t,s,i,a,n,r)}if(e.length===16&&e[8]==="T"&&e[15]==="Z"){const t=parseInt(e.substr(0,4),10),s=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10),a=parseInt(e.substr(9,2),10),n=parseInt(e.substr(11,2),10),r=parseInt(e.substr(13,2),10);return new Date(Date.UTC(t,s,i,a,n,r))}return new Date(e)}static parseExceptionDates(e){return e.split(",").map(s=>this.parseDateTime(s.trim()))}static validateRule(e){if(e.freq||(e.freq="DAILY"),e.count&&e.until)throw new Error("RRULE cannot have both COUNT and UNTIL");e.interval<1&&(e.interval=1);const t=(s,i,a)=>s.filter(n=>n>=i&&n<=a);return e.byMonth=t(e.byMonth||[],1,12),e.byMonthDay=t(e.byMonthDay||[],-31,31).filter(s=>s!==0),e.byYearDay=t(e.byYearDay||[],-366,366).filter(s=>s!==0),e.byWeekNo=t(e.byWeekNo||[],-53,53).filter(s=>s!==0),e.byHour=t(e.byHour||[],0,23),e.byMinute=t(e.byMinute||[],0,59),e.bySecond=t(e.bySecond||[],0,59),e}static buildRRule(e){const t=[];if(t.push(`FREQ=${e.freq}`),e.interval&&e.interval>1&&t.push(`INTERVAL=${e.interval}`),e.count?t.push(`COUNT=${e.count}`):e.until&&t.push(`UNTIL=${this.formatDateTime(e.until)}`),e.byDay&&e.byDay.length>0){const s=e.byDay.map(i=>i.nth?`${i.nth}${i.weekday}`:i.weekday).join(",");t.push(`BYDAY=${s}`)}return e.byMonth&&e.byMonth.length>0&&t.push(`BYMONTH=${e.byMonth.join(",")}`),e.byMonthDay&&e.byMonthDay.length>0&&t.push(`BYMONTHDAY=${e.byMonthDay.join(",")}`),e.byYearDay&&e.byYearDay.length>0&&t.push(`BYYEARDAY=${e.byYearDay.join(",")}`),e.byWeekNo&&e.byWeekNo.length>0&&t.push(`BYWEEKNO=${e.byWeekNo.join(",")}`),e.bySetPos&&e.bySetPos.length>0&&t.push(`BYSETPOS=${e.bySetPos.join(",")}`),e.byHour&&e.byHour.length>0&&t.push(`BYHOUR=${e.byHour.join(",")}`),e.byMinute&&e.byMinute.length>0&&t.push(`BYMINUTE=${e.byMinute.join(",")}`),e.bySecond&&e.bySecond.length>0&&t.push(`BYSECOND=${e.bySecond.join(",")}`),e.wkst&&e.wkst!=="MO"&&t.push(`WKST=${e.wkst}`),t.join(";")}static formatDateTime(e){const t=e.getUTCFullYear(),s=String(e.getUTCMonth()+1).padStart(2,"0"),i=String(e.getUTCDate()).padStart(2,"0"),a=String(e.getUTCHours()).padStart(2,"0"),n=String(e.getUTCMinutes()).padStart(2,"0"),r=String(e.getUTCSeconds()).padStart(2,"0");return`${t}${s}${i}T${a}${n}${r}Z`}static getDescription(e){const t={SECONDLY:"second",MINUTELY:"minute",HOURLY:"hour",DAILY:"day",WEEKLY:"week",MONTHLY:"month",YEARLY:"year"},s={SU:"Sunday",MO:"Monday",TU:"Tuesday",WE:"Wednesday",TH:"Thursday",FR:"Friday",SA:"Saturday"},i={1:"first",2:"second",3:"third",4:"fourth",5:"fifth","-1":"last","-2":"second to last"};let a="Every";if(e.interval>1&&(a+=` ${e.interval}`),a+=` ${t[e.freq]}`,e.interval>1&&(a+="s"),e.byDay&&e.byDay.length>0){if(e.freq==="WEEKLY"){const n=e.byDay.map(r=>s[r.weekday]).join(", ");a+=` on ${n}`}else if(e.freq==="MONTHLY"||e.freq==="YEARLY"){const n=e.byDay.map(r=>r.nth?`the ${i[r.nth]||r.nth} ${s[r.weekday]}`:s[r.weekday]).join(", ");a+=` on ${n}`}}if(e.byMonthDay&&e.byMonthDay.length>0){const n=e.byMonthDay.map(r=>r<0?`${Math.abs(r)} day(s) from the end`:`day ${r}`).join(", ");a+=` on ${n}`}if(e.byMonth&&e.byMonth.length>0){const n=["January","February","March","April","May","June","July","August","September","October","November","December"],r=e.byMonth.map(o=>n[o-1]).join(", ");a+=` in ${r}`}return e.count?a+=`, ${e.count} time${e.count>1?"s":""}`:e.until&&(a+=`, until ${e.until.toLocaleDateString()}`),a}}class j{static expandEvent(e,t,s,i=365,a=null){if(!e.recurring||!e.recurrenceRule)return[{start:e.start,end:e.end,timezone:e.timeZone}];const n=this.parseRule(e.recurrenceRule),r=[],o=e.end-e.start,c=a||e.timeZone||"UTC",l=new $;let d=new Date(e.start),h=0;n.until&&n.until<s&&(s=n.until);let y=l.getTimezoneOffset(d,c);for(;d<=s&&h<i;){if(d>=t){const b=new Date(d),w=new Date(d.getTime()+o),E=l.getTimezoneOffset(b,c);if(E!==y){const S=y-E;b.setMinutes(b.getMinutes()+S),w.setMinutes(w.getMinutes()+S)}y=E,this.isException(b,n,e.id)||r.push({start:b,end:w,recurringEventId:e.id,timezone:c,originalStart:e.start})}if(d=this.getNextOccurrence(d,n,c),h++,n.count&&h>=n.count)break}return r}static parseRule(e){return V.parse(e)}static getNextOccurrence(e,t,s="UTC"){const i=new Date(e);switch(t.freq){case"DAILY":i.setDate(i.getDate()+t.interval);break;case"WEEKLY":if(t.byDay&&t.byDay.length>0)for(i.setDate(i.getDate()+1);!this.matchesByDay(i,t.byDay);)i.setDate(i.getDate()+1);else i.setDate(i.getDate()+7*t.interval);break;case"MONTHLY":if(t.byMonthDay&&t.byMonthDay.length>0){const a=i.getMonth();i.setMonth(a+t.interval),i.setDate(t.byMonthDay[0])}else t.byDay&&t.byDay.length>0?(i.setMonth(i.getMonth()+t.interval),this.setToWeekdayOfMonth(i,t.byDay[0],t.bySetPos[0]||1)):i.setMonth(i.getMonth()+t.interval);break;case"YEARLY":t.byMonth&&t.byMonth.length>0?(i.setFullYear(i.getFullYear()+t.interval),i.setMonth(t.byMonth[0]-1)):i.setFullYear(i.getFullYear()+t.interval);break;default:i.setTime(i.getTime()+24*60*60*1e3)}return i}static matchesByDay(e,t){const s={SU:0,MO:1,TU:2,WE:3,TH:4,FR:5,SA:6},i=e.getDay();return t.some(a=>{const n=a.match(/^(-?\d+)?([A-Z]{2})$/);if(n){const r=n[2];return s[r]===i}return!1})}static setToWeekdayOfMonth(e,t,s=1){const i={SU:0,MO:1,TU:2,WE:3,TH:4,FR:5,SA:6},a=t.match(/^(-?\d+)?([A-Z]{2})$/),n=a?a[2]:t,r=i[n];for(e.setDate(1);e.getDay()!==r;)e.setDate(e.getDate()+1);if(s>1)e.setDate(e.getDate()+7*(s-1));else if(s===-1){const o=new Date(e);for(o.setMonth(o.getMonth()+1),o.setDate(0);o.getDay()!==r;)o.setDate(o.getDate()-1);e.setTime(o.getTime())}}static isException(e,t,s=null){if(!t.exceptions||t.exceptions.length===0)return!1;const i=e.toDateString(),a=e.getTime();return t.exceptions.some(n=>{if(typeof n=="object"&&n.date){const r=n.date instanceof Date?n.date:new Date(n.date);return n.matchTime?Math.abs(r.getTime()-a)<1e3:r.toDateString()===i}else return(n instanceof Date?n:new Date(n)).toDateString()===i})}static addExceptions(e,t,s={}){return e.exceptions||(e.exceptions=[]),(Array.isArray(t)?t:[t]).forEach(a=>{s.reason||s.matchTime?e.exceptions.push({date:a,reason:s.reason,matchTime:s.matchTime||!1}):e.exceptions.push(a)}),e}static parseDate(e){if(e.length===8){const t=parseInt(e.substr(0,4),10),s=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10);return new Date(t,s,i)}else if(e.length===15||e.length===16){const t=parseInt(e.substr(0,4),10),s=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10),a=parseInt(e.substr(9,2),10),n=parseInt(e.substr(11,2),10),r=parseInt(e.substr(13,2),10);return e.endsWith("Z")?new Date(Date.UTC(t,s,i,a,n,r)):new Date(t,s,i,a,n,r)}return new Date(e)}static getDescription(e){typeof e=="string"&&(e=this.parseRule(e));let t="";const s=e.interval||1;switch(e.freq){case"DAILY":t=s===1?"Daily":`Every ${s} days`;break;case"WEEKLY":if(t=s===1?"Weekly":`Every ${s} weeks`,e.byDay&&e.byDay.length>0){const i=e.byDay.map(a=>this.getDayName(a)).join(", ");t+=` on ${i}`}break;case"MONTHLY":t=s===1?"Monthly":`Every ${s} months`,e.byMonthDay&&e.byMonthDay.length>0&&(t+=` on day ${e.byMonthDay.join(", ")}`);break;case"YEARLY":t=s===1?"Yearly":`Every ${s} years`;break}return e.count?t+=`, ${e.count} times`:e.until&&(t+=`, until ${e.until.toLocaleDateString()}`),t}static getDayName(e){const t={SU:"Sunday",MO:"Monday",TU:"Tuesday",WE:"Wednesday",TH:"Thursday",FR:"Friday",SA:"Saturday"},s=e.match(/^(-?\d+)?([A-Z]{2})$/),i=s?s[2]:e,a=s&&s[1]?parseInt(s[1],10):null;let n=t[i]||e;return a&&(n=`${a===-1?"Last":["","1st","2nd","3rd","4th","5th"][a]||`${a}th`} ${n}`),n}}class z{constructor(e=100){this.capacity=e,this.cache=new Map,this.hits=0,this.misses=0,this.evictions=0}get(e){if(!this.cache.has(e)){this.misses++;return}const t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),this.hits++,t}put(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.capacity){const s=this.cache.keys().next().value;this.cache.delete(s),this.evictions++}this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){return this.cache.delete(e)}clear(){this.cache.clear(),this.hits=0,this.misses=0,this.evictions=0}getStats(){const e=this.hits+this.misses>0?(this.hits/(this.hits+this.misses)*100).toFixed(2):0;return{size:this.cache.size,capacity:this.capacity,hits:this.hits,misses:this.misses,evictions:this.evictions,hitRate:`${e}%`}}keys(){return Array.from(this.cache.keys())}get size(){return this.cache.size}}class Z{constructor(e={}){this.config={checkInterval:3e4,memoryThreshold:.8,criticalThreshold:.95,minCacheSize:10,maxCacheSize:1e4,adaptiveScaling:!0,...e},this.caches=new Map,this.stats={adjustments:0,emergencyClears:0,lastMemoryUsage:0,lastCheckTime:null,cacheResizes:[]},this.monitoringInterval=null,this.config.adaptiveScaling&&this.startMonitoring()}registerCache(e,t,s={}){this.caches.set(e,{cache:t,priority:s.priority||1,currentCapacity:s.initialCapacity||100,minCapacity:s.minCapacity||this.config.minCacheSize,maxCapacity:s.maxCapacity||this.config.maxCacheSize,scaleFactor:s.scaleFactor||.5,lastAccess:Date.now()})}unregisterCache(e){this.caches.delete(e)}startMonitoring(){this.monitoringInterval||(this.monitoringInterval=setInterval(()=>{this.checkMemoryPressure()},this.config.checkInterval),this.checkMemoryPressure())}stopMonitoring(){this.monitoringInterval&&(clearInterval(this.monitoringInterval),this.monitoringInterval=null)}async checkMemoryPressure(){const e=await this.getMemoryUsage();this.stats.lastMemoryUsage=e,this.stats.lastCheckTime=new Date,e>this.config.criticalThreshold?this.emergencyClear():e>this.config.memoryThreshold?this.reduceCacheSizes(e):e<this.config.memoryThreshold-.2&&this.increaseCacheSizes()}async getMemoryUsage(){if(typeof performance<"u"&&performance.memory){const e=performance.memory;if(e.jsHeapSizeLimit&&e.usedJSHeapSize)return e.usedJSHeapSize/e.jsHeapSizeLimit}if(typeof process<"u"&&process.memoryUsage){const e=process.memoryUsage();return e.heapUsed/e.heapTotal}return this.estimateMemoryUsage()}estimateMemoryUsage(){let e=0,t=0;for(const[s,i]of this.caches)i.cache.size!==void 0&&(e+=i.cache.size,t+=i.maxCapacity);return t>0?e/t:.5}reduceCacheSizes(e){const t=(e-this.config.memoryThreshold)/(this.config.criticalThreshold-this.config.memoryThreshold),s=Array.from(this.caches.entries()).sort((i,a)=>i[1].priority-a[1].priority);for(const[i,a]of s){const n=Math.floor(a.currentCapacity*a.scaleFactor*t),r=Math.max(a.minCapacity,a.currentCapacity-n);r<a.currentCapacity&&this.resizeCache(i,a,r)}this.stats.adjustments++}increaseCacheSizes(){for(const[e,t]of this.caches)if(Date.now()-t.lastAccess<6e4){const i=Math.floor(t.currentCapacity*.2),a=Math.min(t.maxCapacity,t.currentCapacity+i);a>t.currentCapacity&&this.resizeCache(e,t,a)}}resizeCache(e,t,s){const i=t.currentCapacity;t.currentCapacity=s,t.cache.capacity!==void 0&&(t.cache.capacity=s),t.cache.size>s&&this.evictExcessItems(t.cache,s),this.stats.cacheResizes.push({cache:e,timestamp:new Date,oldCapacity:i,newCapacity:s,reason:s<i?"pressure":"available"}),this.stats.cacheResizes.length>100&&this.stats.cacheResizes.shift()}evictExcessItems(e,t){if(e.size<=t)return;const s=e.size-t;if(e.keys){const i=Array.from(e.keys());for(let a=0;a<s;a++)e.delete(i[a])}else e.clear&&e.clear()}emergencyClear(){for(const[e,t]of this.caches)t.cache.clear&&t.cache.clear(),t.currentCapacity=t.minCapacity;this.stats.emergencyClears++,console.warn("AdaptiveMemoryManager: Emergency cache clear triggered")}touchCache(e){const t=this.caches.get(e);t&&(t.lastAccess=Date.now())}getStats(){const e={};for(const[t,s]of this.caches)e[t]={size:s.cache.size||0,capacity:s.currentCapacity,priority:s.priority,lastAccess:new Date(s.lastAccess)};return{...this.stats,memoryUsagePercent:`${(this.stats.lastMemoryUsage*100).toFixed(2)}%`,totalCaches:this.caches.size,cacheStats:e,monitoring:this.monitoringInterval!==null}}async checkNow(){await this.checkMemoryPressure()}setThresholds(e){e.memoryThreshold!==void 0&&(this.config.memoryThreshold=Math.max(.5,Math.min(.95,e.memoryThreshold))),e.criticalThreshold!==void 0&&(this.config.criticalThreshold=Math.max(this.config.memoryThreshold+.05,Math.min(1,e.criticalThreshold)))}destroy(){this.stopMonitoring(),this.caches.clear()}}class q{constructor(e={}){this.config={enableCache:!0,cacheCapacity:500,maxIndexDays:365,batchSize:100,enableMetrics:!0,cleanupInterval:36e5,maxIndexAge:30*24*60*60*1e3,enableAdaptiveMemory:!0,...e},this.eventCache=new z(this.config.cacheCapacity),this.queryCache=new z(Math.floor(this.config.cacheCapacity/2)),this.dateRangeCache=new z(Math.floor(this.config.cacheCapacity/4)),this.config.enableAdaptiveMemory&&(this.memoryManager=new Z({checkInterval:3e4,memoryThreshold:.75,criticalThreshold:.9}),this.memoryManager.registerCache("events",this.eventCache,{priority:3,initialCapacity:this.config.cacheCapacity,minCapacity:50,maxCapacity:2e3}),this.memoryManager.registerCache("queries",this.queryCache,{priority:2,initialCapacity:Math.floor(this.config.cacheCapacity/2),minCapacity:25,maxCapacity:1e3}),this.memoryManager.registerCache("dateRanges",this.dateRangeCache,{priority:1,initialCapacity:Math.floor(this.config.cacheCapacity/4),minCapacity:10,maxCapacity:500})),this.lazyIndexes=new Map,this.pendingIndexes=new Map,this.batchQueue=[],this.batchTimer=null,this.batchCallbacks=[],this.metrics={operations:{},averageTimes:{},slowQueries:[]},this.cleanupTimer=null,this.config.cleanupInterval>0&&this.startCleanupTimer()}measure(e,t){if(!this.config.enableMetrics)return t();const s=performance.now();try{const i=t(),a=performance.now()-s;return this.recordMetric(e,a),i}catch(i){const a=performance.now()-s;throw this.recordMetric(e,a,!0),i}}async measureAsync(e,t){if(!this.config.enableMetrics)return await t();const s=performance.now();try{const i=await t(),a=performance.now()-s;return this.recordMetric(e,a),i}catch(i){const a=performance.now()-s;throw this.recordMetric(e,a,!0),i}}recordMetric(e,t,s=!1){this.metrics.operations[e]||(this.metrics.operations[e]={count:0,totalTime:0,errors:0,min:1/0,max:0});const i=this.metrics.operations[e];i.count++,i.totalTime+=t,i.min=Math.min(i.min,t),i.max=Math.max(i.max,t),s&&i.errors++,this.metrics.averageTimes[e]=i.totalTime/i.count,t>100&&(this.metrics.slowQueries.push({operation:e,duration:t,timestamp:new Date,isError:s}),this.metrics.slowQueries.length>100&&this.metrics.slowQueries.shift())}getMetrics(){const e={cacheStats:{event:this.eventCache.getStats(),query:this.queryCache.getStats(),dateRange:this.dateRangeCache.getStats()},operations:{},slowestOperations:[],recentSlowQueries:this.metrics.slowQueries.slice(-10),memoryManagement:this.memoryManager?this.memoryManager.getStats():null};for(const[t,s]of Object.entries(this.metrics.operations))e.operations[t]={count:s.count,avgTime:`${(s.totalTime/s.count).toFixed(2)}ms`,minTime:`${s.min.toFixed(2)}ms`,maxTime:`${s.max.toFixed(2)}ms`,totalTime:`${s.totalTime.toFixed(2)}ms`,errors:s.errors,errorRate:`${(s.errors/s.count*100).toFixed(2)}%`};return e.slowestOperations=Object.entries(this.metrics.averageTimes).sort((t,s)=>s[1]-t[1]).slice(0,5).map(([t,s])=>({operation:t,avgTime:`${s.toFixed(2)}ms`})),e}shouldUseLazyIndexing(e){return Math.ceil((e.end-e.start)/864e5)>this.config.maxIndexDays}createLazyIndexMarkers(e){const t={eventId:e.id,start:e.start,end:e.end,indexed:new Set,pending:!1},s=new Date(e.start.getFullYear(),e.start.getMonth(),1),i=new Date(e.end.getFullYear(),e.end.getMonth(),1);return t.indexed.add(this.getMonthKey(s)),this.getMonthKey(s)!==this.getMonthKey(i)&&t.indexed.add(this.getMonthKey(i)),this.lazyIndexes.set(e.id,t),t}async expandLazyIndex(e,t,s){const i=this.lazyIndexes.get(e);if(!i)return new Set;if(i.pending)return this.pendingIndexes.get(e);i.pending=!0;const a=new Promise(n=>{setTimeout(()=>{const r=new Set,o=new Date(t);for(;o<=s;){const c=o.toDateString();i.indexed.has(c)||(r.add(c),i.indexed.add(c)),o.setDate(o.getDate()+1)}i.pending=!1,this.pendingIndexes.delete(e),n(r)},0)});return this.pendingIndexes.set(e,a),a}getMonthKey(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}`}cache(e,t,s="event"){if(!this.config.enableCache)return;let i,a;switch(s){case"event":i=this.eventCache,a="events";break;case"query":i=this.queryCache,a="queries";break;case"dateRange":i=this.dateRangeCache,a="dateRanges";break;default:return}i.put(e,t),this.memoryManager&&this.memoryManager.touchCache(a)}getFromCache(e,t="event"){if(!this.config.enableCache)return;let s,i;switch(t){case"event":s=this.eventCache.get(e),i="events";break;case"query":s=this.queryCache.get(e),i="queries";break;case"dateRange":s=this.dateRangeCache.get(e),i="dateRanges";break;default:return}return s!==void 0&&this.memoryManager&&this.memoryManager.touchCache(i),s}invalidateEventCaches(e){this.eventCache.delete(e),this.queryCache.clear(),this.dateRangeCache.clear()}batch(e){return new Promise((t,s)=>{this.batchQueue.push(e),this.batchCallbacks.push({resolve:t,reject:s}),this.batchQueue.length>=this.config.batchSize?this.processBatch():this.batchTimer||(this.batchTimer=setTimeout(()=>this.processBatch(),10))})}processBatch(){if(this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.batchQueue.length===0)return;const e=this.batchQueue.splice(0),t=this.batchCallbacks.splice(0),s=[],i=[];e.forEach((a,n)=>{try{s[n]=a()}catch(r){i[n]=r}}),t.forEach((a,n)=>{i[n]?a.reject(i[n]):a.resolve(s[n])})}startCleanupTimer(){this.cleanupTimer=setInterval(()=>{this.cleanupOldIndexes()},this.config.cleanupInterval)}cleanupOldIndexes(){const e=Date.now(),t=this.config.maxIndexAge;for(const[s,i]of this.lazyIndexes)i.end.getTime()<e-t&&this.lazyIndexes.delete(s);this.metrics.slowQueries.length>100&&(this.metrics.slowQueries=this.metrics.slowQueries.slice(-100))}optimizeQuery(e,t){const s=this.getFromCache(e,"query");if(s!==void 0)return s;const i=this.measure(`query:${e}`,t);return this.cache(e,i,"query"),i}destroy(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null),this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.eventCache.clear(),this.queryCache.clear(),this.dateRangeCache.clear(),this.lazyIndexes.clear(),this.pendingIndexes.clear()}}class K{constructor(e){this.eventStore=e,this.conflictIdCounter=0}checkConflicts(e,t={}){const s={checkAttendees:!0,checkResources:!0,checkLocation:!0,ignoreAllDay:!1,excludeEventIds:[],includeStatuses:["confirmed","tentative"],bufferMinutes:0,...t};if(!e.start||!e.end)throw new Error("Event must have start and end dates");const i=[],a=new Set,n=new Set,r=new Date(e.start.getTime()-s.bufferMinutes*6e4),o=new Date(e.end.getTime()+s.bufferMinutes*6e4),c=this.eventStore.getEventsInRange(r,o,!1).filter(l=>!(l.id===e.id||s.excludeEventIds.includes(l.id)||!s.includeStatuses.includes(l.status)||s.ignoreAllDay&&(l.allDay||e.allDay)||l.status==="cancelled"));for(const l of c){const d=this._detectEventConflicts(e,l,s);d.length>0&&(i.push(...d),a.add(e.id),a.add(l.id),e.attendees&&e.attendees.forEach(h=>n.add(h.email)),l.attendees&&l.attendees.forEach(h=>n.add(h.email)))}return this._buildConflictSummary(i,a,n)}checkEventPairConflicts(e,t,s={}){const i={checkAttendees:!0,checkResources:!0,checkLocation:!0,bufferMinutes:0,...s};return this._detectEventConflicts(e,t,i)}getBusyPeriods(e,t,s,i={}){const a={includeStatuses:["confirmed","tentative"],mergePeriods:!0,...i},n=[];return this.eventStore.getEventsInRange(t,s,!1).filter(c=>!a.includeStatuses.includes(c.status)||c.status==="cancelled"?!1:c.attendees&&c.attendees.some(l=>e.includes(l.email))).forEach(c=>{n.push({start:c.start,end:c.end,eventIds:[c.id]})}),a.mergePeriods&&n.length>1?this._mergeBusyPeriods(n):n.sort((c,l)=>c.start-l.start)}getFreePeriods(e,t,s,i={}){const a={attendeeEmails:[],businessHoursOnly:!1,businessHours:{start:"09:00",end:"17:00"},excludeWeekends:!1,...i},n=[],r=a.attendeeEmails.length>0?this.getBusyPeriods(a.attendeeEmails,e,t):this._getAllBusyPeriods(e,t);let o=new Date(e);for(const c of r)o<c.start&&(c.start-o)/6e4>=s&&(!a.businessHoursOnly||this._isWithinBusinessHours(o,c.start,a))&&n.push({start:new Date(o),end:new Date(c.start)}),o=new Date(Math.max(o.getTime(),c.end.getTime()));return o<t&&(t-o)/6e4>=s&&(!a.businessHoursOnly||this._isWithinBusinessHours(o,t,a))&&n.push({start:new Date(o),end:new Date(t)}),n}_detectEventConflicts(e,t,s){const i=[];if(this._checkTimeOverlap(e,t,s.bufferMinutes)){const n=this._createTimeConflict(e,t);if(i.push(n),s.checkAttendees){const r=this._checkAttendeeConflicts(e,t);i.push(...r)}if(s.checkResources){const r=this._checkResourceConflicts(e,t);i.push(...r)}if(s.checkLocation){const r=this._checkLocationConflict(e,t);r&&i.push(r)}}return i}_checkTimeOverlap(e,t,s=0){const i=s*6e4,a=e.start.getTime()-i,n=e.end.getTime()+i,r=t.start.getTime(),o=t.end.getTime();return!(n<=r||o<=a)}_createTimeConflict(e,t){const s=new Date(Math.max(e.start.getTime(),t.start.getTime())),i=new Date(Math.min(e.end.getTime(),t.end.getTime())),a=(i-s)/6e4;let n="low";return a>=60?n="high":a>=30&&(n="medium"),e.status==="confirmed"&&t.status==="confirmed"&&(n=n==="low"?"medium":n==="medium"?"high":"critical"),{id:`conflict_${++this.conflictIdCounter}`,type:"time",severity:n,eventId:e.id,conflictingEventId:t.id,description:`Time overlap: ${e.title} conflicts with ${t.title}`,overlapStart:s,overlapEnd:i,overlapMinutes:a,metadata:{event1Title:e.title,event2Title:t.title,event1Status:e.status,event2Status:t.status}}}_checkAttendeeConflicts(e,t){const s=[];if(!e.attendees||!t.attendees)return s;const i=[];for(const a of e.attendees)for(const n of t.attendees)a.email===n.email&&i.push(a.email);if(i.length>0){let a="medium";i.some(r=>{const o=e.attendees.find(l=>l.email===r),c=t.attendees.find(l=>l.email===r);return(o==null?void 0:o.responseStatus)==="accepted"&&(c==null?void 0:c.responseStatus)==="accepted"})&&(a="critical"),s.push({id:`conflict_${++this.conflictIdCounter}`,type:"attendee",severity:a,eventId:e.id,conflictingEventId:t.id,description:`Attendee conflict: ${i.length} attendee(s) double-booked`,conflictingAttendees:i,metadata:{attendeeCount:i.length,attendeeEmails:i}})}return s}_checkResourceConflicts(e,t){var n,r;const s=[],i=((n=e.attendees)==null?void 0:n.filter(o=>o.resource))||[],a=((r=t.attendees)==null?void 0:r.filter(o=>o.resource))||[];for(const o of i)for(const c of a)o.email===c.email&&s.push({id:`conflict_${++this.conflictIdCounter}`,type:"resource",severity:"critical",eventId:e.id,conflictingEventId:t.id,description:`Resource conflict: ${o.name} is double-booked`,conflictingResource:o.email,metadata:{resourceName:o.name,resourceEmail:o.email}});return s}_checkLocationConflict(e,t){if(!e.location||!t.location)return null;const s=e.location.trim().toLowerCase(),i=t.location.trim().toLowerCase();return s===i?{id:`conflict_${++this.conflictIdCounter}`,type:"location",severity:"high",eventId:e.id,conflictingEventId:t.id,description:`Location conflict: ${e.location} is double-booked`,metadata:{location:e.location}}:null}_buildConflictSummary(e,t,s){const i={},a={};for(const n of e)i[n.type]=(i[n.type]||0)+1,a[n.severity]=(a[n.severity]||0)+1;return{hasConflicts:e.length>0,totalConflicts:e.length,conflicts:e,conflictsByType:i,conflictsBySeverity:a,affectedEventIds:Array.from(t),affectedAttendees:Array.from(s)}}_mergeBusyPeriods(e){if(e.length<=1)return e;e.sort((s,i)=>s.start-i.start);const t=[e[0]];for(let s=1;s<e.length;s++){const i=e[s],a=t[t.length-1];i.start<=a.end?(a.end=new Date(Math.max(a.end.getTime(),i.end.getTime())),a.eventIds.push(...i.eventIds)):t.push(i)}return t}_getAllBusyPeriods(e,t){return this.eventStore.getEventsInRange(e,t,!1).filter(i=>i.status!=="cancelled").map(i=>({start:i.start,end:i.end,eventIds:[i.id]})).sort((i,a)=>i.start-a.start)}_isWithinBusinessHours(e,t,s){const i=e.getHours(),a=t.getHours(),n=parseInt(s.businessHours.start.split(":")[0]),r=parseInt(s.businessHours.end.split(":")[0]);return i>=n&&a<=r}}class G{constructor(e={}){this.events=new Map,this.indices={byDate:new Map,byMonth:new Map,recurring:new Set,byCategory:new Map,byStatus:new Map},this.timezoneManager=new $,this.defaultTimezone=e.timezone||this.timezoneManager.getSystemTimezone(),this.optimizer=new q(e.performance),this.conflictDetector=new K(this),this.isBatchMode=!1,this.batchNotifications=[],this.batchBackup=null,this.version=0,this.listeners=new Set}addEvent(e){return this.optimizer.measure("addEvent",()=>{if(e instanceof x||(e=new x(e)),this.events.has(e.id))throw new Error(`Event with id ${e.id} already exists`);return this.events.set(e.id,e),this.optimizer.cache(e.id,e,"event"),this._indexEvent(e),this.isBatchMode?this.batchNotifications.push({type:"add",event:e,version:++this.version}):this._notifyChange({type:"add",event:e,version:++this.version}),e})}updateEvent(e,t){const s=this.events.get(e);if(!s)throw new Error(`Event with id ${e} not found`);this._unindexEvent(s);const i=s.clone(t);return this.events.set(e,i),this._indexEvent(i),this._notifyChange({type:"update",event:i,oldEvent:s,version:++this.version}),i}removeEvent(e){const t=this.events.get(e);return t?(this.events.delete(e),this._unindexEvent(t),this._notifyChange({type:"remove",event:t,version:++this.version}),!0):!1}getEvent(e){const t=this.optimizer.getFromCache(e,"event");if(t)return t;const s=this.events.get(e)||null;return s&&this.optimizer.cache(e,s,"event"),s}getAllEvents(){return Array.from(this.events.values())}queryEvents(e={}){let t=Array.from(this.events.values());if(e.start||e.end){const s=e.start?new Date(e.start):null,i=e.end?new Date(e.end):null;t=t.filter(a=>!(s&&a.end<s||i&&a.start>i))}if(e.date){const s=new Date(e.date);t=t.filter(i=>i.occursOn(s))}if(e.month&&e.year){const s=`${e.year}-${String(e.month).padStart(2,"0")}`,i=this.indices.byMonth.get(s)||new Set;t=t.filter(a=>i.has(a.id))}return e.hasOwnProperty("allDay")&&(t=t.filter(s=>s.allDay===e.allDay)),e.hasOwnProperty("recurring")&&(t=t.filter(s=>s.recurring===e.recurring)),e.status&&(t=t.filter(s=>s.status===e.status)),e.categories&&e.categories.length>0&&(t=t.filter(s=>e.matchAllCategories?s.hasAllCategories(e.categories):s.hasAnyCategory(e.categories))),e.hasOwnProperty("hasAttendees")&&(t=t.filter(s=>e.hasAttendees?s.hasAttendees:!s.hasAttendees)),e.organizerEmail&&(t=t.filter(s=>s.organizer&&s.organizer.email===e.organizerEmail)),e.sort&&t.sort((s,i)=>{switch(e.sort){case"start":return s.start-i.start;case"end":return s.end-i.end;case"duration":return s.duration-i.duration;case"title":return s.title.localeCompare(i.title);default:return 0}}),t}getEventsForDate(e,t=null){t=t||this.defaultTimezone,f.getLocalDateString(e);const s=[],i=new Date(e);for(let a=-1;a<=1;a++){const n=new Date(i);n.setDate(n.getDate()+a);const r=f.getLocalDateString(n),o=this.indices.byDate.get(r)||new Set;for(const c of o){const l=this.events.get(c);if(l&&!s.find(d=>d.id===l.id)){const d=l.getStartInTimezone(t),h=l.getEndInTimezone(t),y=new Date(e);y.setHours(0,0,0,0);const b=new Date(e);b.setHours(23,59,59,999),d<=b&&h>=y&&s.push(l)}}}return s.sort((a,n)=>{const r=a.getStartInTimezone(t),o=n.getStartInTimezone(t),c=r-o;return c!==0?c:n.duration-a.duration})}getOverlappingEvents(e,t,s=null){const i=[],a=f.startOfDay(e),n=f.endOfDay(t),r=f.getDateRange(a,n),o=new Set;return r.forEach(c=>{const l=c.toDateString();(this.indices.byDate.get(l)||new Set).forEach(h=>{if(!o.has(h)&&h!==s){o.add(h);const y=this.events.get(h);y&&y.overlaps({start:e,end:t})&&i.push(y)}})}),i.sort((c,l)=>c.start-l.start)}hasConflicts(e,t,s=null){return this.getOverlappingEvents(e,t,s).length>0}getOverlapGroups(e,t=!0){let s=this.getEventsForDate(e);t&&(s=s.filter(n=>!n.allDay));const i=[],a=new Set;return s.forEach(n=>{if(a.has(n.id))return;const r=[n];a.add(n.id);let o=0;for(;o<r.length;){const c=r[o];s.forEach(l=>{!a.has(l.id)&&c.overlaps(l)&&(r.push(l),a.add(l.id))}),o++}i.push(r)}),i}calculateEventPositions(e){const t=new Map;if(e.length===0)return t;e.sort((a,n)=>{const r=a.start-n.start;return r!==0?r:n.end-n.start-(a.end-a.start)});const s=[];e.forEach(a=>{let n=0;for(;n<s.length&&s[n].some(c=>c.overlaps(a));)n++;s[n]||(s[n]=[]),s[n].push(a),t.set(a.id,{column:n,totalColumns:0})});const i=s.length;return t.forEach(a=>{a.totalColumns=i}),t}getEventsInRange(e,t,s=!0,i=null){typeof s=="string"&&(i=s,s=!0),i=i||this.defaultTimezone;const a=this.timezoneManager.toUTC(e,i),n=this.timezoneManager.toUTC(t,i),r=this.queryEvents({start:a,end:n,sort:"start"});if(!s)return r;const o=[];return r.forEach(c=>{if(c.recurring&&c.recurrenceRule){const l=this.expandRecurringEvent(c,e,t,i);o.push(...l)}else o.push(c)}),o.sort((c,l)=>{const d=c.getStartInTimezone(i),h=l.getStartInTimezone(i);return d-h})}expandRecurringEvent(e,t,s,i=null){if(!e.recurring||!e.recurrenceRule)return[e];i=i||this.defaultTimezone;const a=e.timeZone||i;return j.expandEvent(e,t,s).map((r,o)=>e.clone({id:`${e.id}_occurrence_${o}`,start:r.start,end:r.end,timeZone:a,metadata:{...e.metadata,recurringEventId:e.id,occurrenceIndex:o}}))}clear(){const e=this.getAllEvents();this.events.clear(),this.indices.byDate.clear(),this.indices.byMonth.clear(),this.indices.recurring.clear(),this._notifyChange({type:"clear",oldEvents:e,version:++this.version})}loadEvents(e){this.clear();for(const t of e)this.addEvent(t)}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}_indexEvent(e){if(this.optimizer.shouldUseLazyIndexing(e)){this._indexEventLazy(e);return}const t=e.getStartInTimezone(e.timeZone),s=e.getEndInTimezone(e.endTimeZone||e.timeZone),i=f.startOfDay(t),a=f.endOfDay(s);f.getDateRange(i,a).forEach(o=>{const c=f.getLocalDateString(o);this.indices.byDate.has(c)||this.indices.byDate.set(c,new Set),this.indices.byDate.get(c).add(e.id)}),`${i.getFullYear()}${String(i.getMonth()+1).padStart(2,"0")}`,`${a.getFullYear()}${String(a.getMonth()+1).padStart(2,"0")}`;const r=new Date(i.getFullYear(),i.getMonth(),1);for(;r<=a;){const o=`${r.getFullYear()}-${String(r.getMonth()+1).padStart(2,"0")}`;this.indices.byMonth.has(o)||this.indices.byMonth.set(o,new Set),this.indices.byMonth.get(o).add(e.id),r.setMonth(r.getMonth()+1)}e.categories&&e.categories.length>0&&e.categories.forEach(o=>{this.indices.byCategory.has(o)||this.indices.byCategory.set(o,new Set),this.indices.byCategory.get(o).add(e.id)}),e.status&&(this.indices.byStatus.has(e.status)||this.indices.byStatus.set(e.status,new Set),this.indices.byStatus.get(e.status).add(e.id)),e.recurring&&this.indices.recurring.add(e.id)}_indexEventLazy(e){this.optimizer.createLazyIndexMarkers(e);const t=e.getStartInTimezone(e.timeZone),s=e.getEndInTimezone(e.endTimeZone||e.timeZone),i=f.startOfDay(t),a=f.endOfDay(s),n=new Date(i);if(n.setDate(n.getDate()+7),f.getDateRange(i,n<a?n:a).forEach(c=>{const l=f.getLocalDateString(c);this.indices.byDate.has(l)||this.indices.byDate.set(l,new Set),this.indices.byDate.get(l).add(e.id)}),a>n){const c=new Date(a);c.setDate(c.getDate()-7),f.getDateRange(c>i?c:i,a).forEach(d=>{const h=f.getLocalDateString(d);this.indices.byDate.has(h)||this.indices.byDate.set(h,new Set),this.indices.byDate.get(h).add(e.id)})}const o=new Date(i.getFullYear(),i.getMonth(),1);for(;o<=a;){const c=`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}`;this.indices.byMonth.has(c)||this.indices.byMonth.set(c,new Set),this.indices.byMonth.get(c).add(e.id),o.setMonth(o.getMonth()+1)}e.categories&&e.categories.length>0&&e.categories.forEach(c=>{this.indices.byCategory.has(c)||this.indices.byCategory.set(c,new Set),this.indices.byCategory.get(c).add(e.id)}),e.status&&(this.indices.byStatus.has(e.status)||this.indices.byStatus.set(e.status,new Set),this.indices.byStatus.get(e.status).add(e.id)),e.recurring&&this.indices.recurring.add(e.id)}_unindexEvent(e){for(const[t,s]of this.indices.byDate)s.delete(e.id),s.size===0&&this.indices.byDate.delete(t);for(const[t,s]of this.indices.byMonth)s.delete(e.id),s.size===0&&this.indices.byMonth.delete(t);this.indices.recurring.delete(e.id)}_notifyChange(e){for(const t of this.listeners)try{t(e)}catch(s){console.error("Error in EventStore listener:",s)}}getStats(){return{totalEvents:this.events.size,recurringEvents:this.indices.recurring.size,indexedDates:this.indices.byDate.size,indexedMonths:this.indices.byMonth.size,indexedCategories:this.indices.byCategory.size,indexedStatuses:this.indices.byStatus.size,version:this.version,performanceMetrics:this.optimizer.getMetrics()}}startBatch(e=!1){this.isBatchMode=!0,this.batchNotifications=[],e&&(this.batchBackup={events:new Map(this.events),indices:{byDate:new Map(Array.from(this.indices.byDate.entries()).map(([t,s])=>[t,new Set(s)])),byMonth:new Map(Array.from(this.indices.byMonth.entries()).map(([t,s])=>[t,new Set(s)])),recurring:new Set(this.indices.recurring),byCategory:new Map(Array.from(this.indices.byCategory.entries()).map(([t,s])=>[t,new Set(s)])),byStatus:new Map(Array.from(this.indices.byStatus.entries()).map(([t,s])=>[t,new Set(s)]))},version:this.version})}commitBatch(){this.isBatchMode&&(this.isBatchMode=!1,this.batchBackup=null,this.batchNotifications.length>0&&this._notifyChange({type:"batch",changes:this.batchNotifications,count:this.batchNotifications.length,version:++this.version}),this.batchNotifications=[])}rollbackBatch(){this.isBatchMode&&(this.isBatchMode=!1,this.batchBackup&&(this.events=this.batchBackup.events,this.indices=this.batchBackup.indices,this.version=this.batchBackup.version,this.batchBackup=null,this.optimizer.clearCache()),this.batchNotifications=[])}async executeBatch(e,t=!0){this.startBatch(t);try{const s=await e();return this.commitBatch(),s}catch(s){throw t&&this.rollbackBatch(),s}}addEvents(e){return this.optimizer.measure("addEvents",()=>{this.startBatch();const t=[],s=[];for(const i of e)try{t.push(this.addEvent(i))}catch(a){s.push({event:i,error:a.message})}return this.commitBatch(),s.length>0&&console.warn(`Failed to add ${s.length} events:`,s),t})}updateEvents(e){return this.optimizer.measure("updateEvents",()=>{this.startBatch();const t=[],s=[];for(const{id:i,updates:a}of e)try{t.push(this.updateEvent(i,a))}catch(n){s.push({id:i,error:n.message})}return this.commitBatch(),s.length>0&&console.warn(`Failed to update ${s.length} events:`,s),t})}removeEvents(e){return this.optimizer.measure("removeEvents",()=>{this.startBatch();let t=0;for(const s of e)this.removeEvent(s)&&t++;return this.commitBatch(),t})}getPerformanceMetrics(){return this.optimizer.getMetrics()}clearCaches(){this.optimizer.eventCache.clear(),this.optimizer.queryCache.clear(),this.optimizer.dateRangeCache.clear()}optimizeIndices(e){e||(e=new Date,e.setMonth(e.getMonth()-6)),e.toDateString();let t=0;for(const[s,i]of this.indices.byDate)if(new Date(s)<e){let n=!1;for(const r of i){const o=this.events.get(r);if(o&&o.end>=e){n=!0;break}}n||(this.indices.byDate.delete(s),t++)}return console.log(`Optimized indices: removed ${t} old date entries`),t}destroy(){this.clear(),this.optimizer.destroy(),this.listeners.clear()}checkConflicts(e,t={}){return this.conflictDetector.checkConflicts(e,t)}checkEventPairConflicts(e,t,s={}){const i=this.getEvent(e),a=this.getEvent(t);if(!i||!a)throw new Error("One or both events not found");return this.conflictDetector.checkEventPairConflicts(i,a,s)}getAllConflicts(e,t,s={}){const i=this.getEventsInRange(e,t,!1),a=[],n=new Set;for(let r=0;r<i.length;r++)for(let o=r+1;o<i.length;o++){const c=`${i[r].id}-${i[o].id}`;if(!n.has(c)){n.add(c);const l=this.conflictDetector.checkEventPairConflicts(i[r],i[o],s);a.push(...l)}}return this.conflictDetector._buildConflictSummary(a,new Set(i.map(r=>r.id)),new Set)}getBusyPeriods(e,t,s,i={}){return this.conflictDetector.getBusyPeriods(e,t,s,i)}getFreePeriods(e,t,s,i={}){return this.conflictDetector.getFreePeriods(e,t,s,i)}addEventWithConflictCheck(e,t=!0){const s=this.checkConflicts(e);if(!t&&s.hasConflicts)throw new Error(`Cannot add event: ${s.totalConflicts} conflicts detected`);return{event:this.addEvent(e),conflicts:s}}findEventsWithConflicts(e={}){const t=[],s=this.getAllEvents();for(const i of s){const a=this.checkConflicts(i,e);a.hasConflicts&&t.push({event:i,conflicts:a.conflicts})}return t}}let Q=class{constructor(e={}){this.state={view:"month",currentDate:new Date,selectedEventId:null,selectedDate:null,hoveredEventId:null,hoveredDate:null,weekStartsOn:0,showWeekNumbers:!1,showWeekends:!0,fixedWeekCount:!0,timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,locale:"en-US",hourFormat:"12h",businessHours:{start:"09:00",end:"17:00"},filters:{searchTerm:"",categories:[],showAllDay:!0,showTimed:!0},isDragging:!1,isResizing:!1,isCreating:!1,isLoading:!1,loadingMessage:"",error:null,metadata:{},...e},this.listeners=new Map,this.globalListeners=new Set,this.history=[],this.historyIndex=-1,this.maxHistorySize=50}getState(){return Object.freeze({...this.state})}get(e){return this.state[e]}setState(e){const t=this.state;typeof e=="function"&&(e=e(t));const s={...t,...e,filters:e.filters?{...t.filters,...e.filters}:t.filters,businessHours:e.businessHours?{...t.businessHours,...e.businessHours}:t.businessHours,metadata:e.metadata?{...t.metadata,...e.metadata}:t.metadata};this._hasChanged(t,s)&&(this.state=s,this._addToHistory(s),this._notifyListeners(t,s))}setView(e){const t=["month","week","day","list"];if(!t.includes(e))throw new Error(`Invalid view: ${e}. Must be one of: ${t.join(", ")}`);this.setState({view:e})}setCurrentDate(e){if(e instanceof Date||(e=new Date(e)),isNaN(e.getTime()))throw new Error("Invalid date");this.setState({currentDate:e})}navigateNext(){const{view:e,currentDate:t}=this.state,s=new Date(t);switch(e){case"month":s.setMonth(s.getMonth()+1);break;case"week":s.setDate(s.getDate()+7);break;case"day":s.setDate(s.getDate()+1);break}this.setCurrentDate(s)}navigatePrevious(){const{view:e,currentDate:t}=this.state,s=new Date(t);switch(e){case"month":s.setMonth(s.getMonth()-1);break;case"week":s.setDate(s.getDate()-7);break;case"day":s.setDate(s.getDate()-1);break}this.setCurrentDate(s)}navigateToday(){this.setCurrentDate(new Date)}selectEvent(e){this.setState({selectedEventId:e})}clearEventSelection(){this.setState({selectedEventId:null})}selectDate(e){e instanceof Date||(e=new Date(e)),this.setState({selectedDate:e})}clearDateSelection(){this.setState({selectedDate:null})}setLoading(e,t=""){this.setState({isLoading:e,loadingMessage:t})}setError(e){this.setState({error:e?e instanceof Error?e.message:e:null})}updateFilters(e){this.setState({filters:{...this.state.filters,...e}})}subscribe(e){return this.globalListeners.add(e),()=>{this.globalListeners.delete(e)}}watch(e,t){const s=Array.isArray(e)?e:[e];return s.forEach(i=>{this.listeners.has(i)||this.listeners.set(i,new Set),this.listeners.get(i).add(t)}),()=>{s.forEach(i=>{const a=this.listeners.get(i);a&&(a.delete(t),a.size===0&&this.listeners.delete(i))})}}canUndo(){return this.historyIndex>0}canRedo(){return this.historyIndex<this.history.length-1}getUndoCount(){return this.historyIndex}getRedoCount(){return this.history.length-1-this.historyIndex}undo(){if(!this.canUndo())return!1;this.historyIndex--;const e=this.history[this.historyIndex],t=this.state;return this.state={...e},this._notifyListeners(t,this.state),!0}redo(){if(!this.canRedo())return!1;this.historyIndex++;const e=this.history[this.historyIndex],t=this.state;return this.state={...e},this._notifyListeners(t,this.state),!0}reset(){const e=this.history[0]||{};this.setState(e),this.history=[e],this.historyIndex=0}_hasChanged(e,t){return!this._deepEqual(e,t)}_deepEqual(e,t,s=new Set){if(e===t)return!0;if(e==null||t==null)return e===t;if(typeof e!=typeof t)return!1;if(typeof e!="object")return e===t;if(s.has(e)||s.has(t))return!1;if(s.add(e),s.add(t),Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return s.delete(e),s.delete(t),!1;for(let n=0;n<e.length;n++)if(!this._deepEqual(e[n],t[n],s))return s.delete(e),s.delete(t),!1;return s.delete(e),s.delete(t),!0}if(e instanceof Date&&t instanceof Date){const n=e.getTime()===t.getTime();return s.delete(e),s.delete(t),n}const i=Object.keys(e),a=Object.keys(t);if(i.length!==a.length)return s.delete(e),s.delete(t),!1;i.sort(),a.sort();for(let n=0;n<i.length;n++)if(i[n]!==a[n])return s.delete(e),s.delete(t),!1;for(const n of i)if(!this._deepEqual(e[n],t[n],s))return s.delete(e),s.delete(t),!1;return s.delete(e),s.delete(t),!0}_addToHistory(e){this.historyIndex<this.history.length-1&&(this.history=this.history.slice(0,this.historyIndex+1)),this.history.push({...e}),this.historyIndex++,this.history.length>this.maxHistorySize&&(this.history.shift(),this.historyIndex--)}_notifyListeners(e,t){for(const s of this.globalListeners)try{s(t,e)}catch(i){console.error("Error in state listener:",i)}for(const[s,i]of this.listeners)if(e[s]!==t[s])for(const a of i)try{a(t[s],e[s],t,e)}catch(n){console.error(`Error in state listener for key "${s}":`,n)}}};class J{constructor(e={}){this.timezoneManager=new $,this.config={view:"month",date:new Date,weekStartsOn:0,locale:"en-US",timeZone:e.timeZone||this.timezoneManager.getSystemTimezone(),showWeekNumbers:!1,showWeekends:!0,fixedWeekCount:!0,businessHours:{start:"09:00",end:"17:00"},...e},this.eventStore=new G({timezone:this.config.timeZone}),this.state=new Q({view:this.config.view,currentDate:this.config.date,weekStartsOn:this.config.weekStartsOn,locale:this.config.locale,timeZone:this.config.timeZone,showWeekNumbers:this.config.showWeekNumbers,showWeekends:this.config.showWeekends,fixedWeekCount:this.config.fixedWeekCount,businessHours:this.config.businessHours}),this.listeners=new Map,this.plugins=new Set,this.views=new Map,this._setupInternalListeners(),e.events&&this.setEvents(e.events)}setView(e,t=null){this.state.setView(e),t&&this.state.setCurrentDate(t),this._emit("viewChange",{view:e,date:t||this.state.get("currentDate")})}getView(){return this.state.get("view")}next(){this.state.navigateNext(),this._emit("navigate",{direction:"next",date:this.state.get("currentDate"),view:this.state.get("view")})}previous(){this.state.navigatePrevious(),this._emit("navigate",{direction:"previous",date:this.state.get("currentDate"),view:this.state.get("view")})}today(){this.state.navigateToday(),this._emit("navigate",{direction:"today",date:this.state.get("currentDate"),view:this.state.get("view")})}goToDate(e){this.state.setCurrentDate(e),this._emit("navigate",{direction:"goto",date:e,view:this.state.get("view")})}setDate(e){this.goToDate(e)}getCurrentDate(){return new Date(this.state.get("currentDate"))}addEvent(e){!(e instanceof x)&&!e.timeZone&&(e={...e,timeZone:this.config.timeZone});const t=this.eventStore.addEvent(e);return this._emit("eventAdd",{event:t}),t}updateEvent(e,t){const s=this.eventStore.getEvent(e),i=this.eventStore.updateEvent(e,t);return this._emit("eventUpdate",{event:i,oldEvent:s}),i}removeEvent(e){const t=this.eventStore.getEvent(e),s=this.eventStore.removeEvent(e);return s&&this._emit("eventRemove",{event:t}),s}deleteEvent(e){return this.removeEvent(e)}getEvent(e){return this.eventStore.getEvent(e)}getEvents(){return this.eventStore.getAllEvents()}setEvents(e){this.eventStore.loadEvents(e),this._emit("eventsSet",{events:this.getEvents()})}queryEvents(e){return this.eventStore.queryEvents(e)}getEventsForDate(e,t=null){return this.eventStore.getEventsForDate(e,t||this.config.timeZone)}getEventsInRange(e,t,s=null){return this.eventStore.getEventsInRange(e,t,!0,s||this.config.timeZone)}setTimezone(e){const t=this.timezoneManager.parseTimezone(e),s=this.config.timeZone;this.config.timeZone=t,this.eventStore.defaultTimezone=t,this.state.setState({timeZone:t}),this._emit("timezoneChange",{timezone:t,previousTimezone:s})}getTimezone(){return this.config.timeZone}setLocale(e){this.config.locale=e,this.state.setState({locale:e}),this._emit("localeChange",{locale:e})}setWeekStartsOn(e){this.config.weekStartsOn=e,this.state.setState({weekStartsOn:e}),this._emit("weekStartsOnChange",{weekStartsOn:e})}convertTimezone(e,t,s){return this.timezoneManager.convertTimezone(e,t,s)}toCalendarTimezone(e,t){return this.timezoneManager.convertTimezone(e,t,this.config.timeZone)}fromCalendarTimezone(e,t){return this.timezoneManager.convertTimezone(e,this.config.timeZone,t)}formatInTimezone(e,t=null,s={}){return this.timezoneManager.formatInTimezone(e,t||this.config.timeZone,s)}getTimezones(){return this.timezoneManager.getCommonTimezones()}getOverlapGroups(e,t=!0){return this.eventStore.getOverlapGroups(e,t)}calculateEventPositions(e){return this.eventStore.calculateEventPositions(e)}getViewData(){const e=this.state.get("view"),t=this.state.get("currentDate");switch(e){case"month":return this._getMonthViewData(t);case"week":return this._getWeekViewData(t);case"day":return this._getDayViewData(t);case"list":return this._getListViewData(t);default:return null}}_getMonthViewData(e){const t=e.getFullYear(),s=e.getMonth(),i=this.state.get("weekStartsOn"),a=this.state.get("fixedWeekCount"),n=new Date(t,s,1),r=new Date(t,s+1,0),o=f.startOfWeek(n,i),c=[];let l=new Date(o);const d=a?6:Math.ceil((r.getDate()+f.getDayOfWeek(n,i))/7);for(let h=0;h<d;h++){const y={weekNumber:f.getWeekNumber(l),days:[]};for(let b=0;b<7;b++){const w=new Date(l),E=w.getMonth()===s,S=f.isToday(w),I=w.getDay()===0||w.getDay()===6;y.days.push({date:w,dayOfMonth:w.getDate(),isCurrentMonth:E,isToday:S,isWeekend:I,events:this.getEventsForDate(w)}),l=f.addDays(l,1)}c.push(y)}return{type:"month",year:t,month:s,monthName:f.getMonthName(e,this.state.get("locale")),weeks:c,startDate:o,endDate:new Date(l.getTime()-1)}}_getWeekViewData(e){const t=this.state.get("weekStartsOn"),s=f.startOfWeek(e,t),i=f.endOfWeek(e,t),a=[],n=new Date(s);for(let r=0;r<7;r++){const o=new Date(n);a.push({date:o,dayOfMonth:o.getDate(),dayOfWeek:o.getDay(),dayName:f.getDayName(o,this.state.get("locale")),isToday:f.isToday(o),isWeekend:o.getDay()===0||o.getDay()===6,events:this.getEventsForDate(o),overlapGroups:this.eventStore.getOverlapGroups(o,!0),getEventPositions:c=>this.eventStore.calculateEventPositions(c)}),n.setDate(n.getDate()+1)}return{type:"week",weekNumber:f.getWeekNumber(s),startDate:s,endDate:i,days:a}}_getDayViewData(e){const t=this.getEventsForDate(e),s=t.filter(n=>n.allDay),i=t.filter(n=>!n.allDay),a=[];for(let n=0;n<24;n++){const r=new Date(e);r.setHours(n,0,0,0);const o=new Date(e);o.setHours(n+1,0,0,0),a.push({hour:n,time:f.formatTime(r,this.state.get("locale")),events:i.filter(c=>c.start<o&&c.end>r)})}return{type:"day",date:e,dayName:f.getDayName(e,this.state.get("locale")),isToday:f.isToday(e),allDayEvents:s,hours:a}}_getListViewData(e){const t=new Date(e);t.setHours(0,0,0,0);const s=new Date(t);s.setDate(s.getDate()+30);const i=this.getEventsInRange(t,s),a=new Map;i.forEach(r=>{const o=r.start.toDateString();a.has(o)||a.set(o,{date:new Date(r.start),events:[]}),a.get(o).events.push(r)});const n=Array.from(a.values()).sort((r,o)=>r.date-o.date).map(r=>({...r,dayName:f.getDayName(r.date,this.state.get("locale")),isToday:f.isToday(r.date)}));return{type:"list",startDate:t,endDate:s,days:n,totalEvents:i.length}}selectEvent(e){const t=this.getEvent(e);t&&(this.state.selectEvent(e),this._emit("eventSelect",{event:t}))}clearEventSelection(){const e=this.state.get("selectedEventId");this.state.clearEventSelection(),e&&this._emit("eventDeselect",{eventId:e})}selectDate(e){this.state.selectDate(e),this._emit("dateSelect",{date:e})}clearDateSelection(){const e=this.state.get("selectedDate");this.state.clearDateSelection(),e&&this._emit("dateDeselect",{date:e})}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}off(e,t){const s=this.listeners.get(e);s&&(s.delete(t),s.size===0&&this.listeners.delete(e))}_emit(e,t){const s=this.listeners.get(e);s&&s.forEach(i=>{try{i(t)}catch(a){console.error(`Error in event listener for "${e}":`,a)}})}_setupInternalListeners(){this.state.subscribe((e,t)=>{this._emit("stateChange",{newState:e,oldState:t})}),this.eventStore.subscribe(e=>{this._emit("eventStoreChange",e)})}use(e){if(this.plugins.has(e)){console.warn("Plugin already installed");return}if(typeof e.install=="function")e.install(this),this.plugins.add(e);else throw new Error("Plugin must have an install method")}destroy(){this.listeners.clear(),this.eventStore.clear(),this.plugins.forEach(e=>{typeof e.uninstall=="function"&&e.uninstall(this)}),this.plugins.clear(),this._emit("destroy")}}class X{constructor(){this.events=new Map,this.wildcardHandlers=new Set}on(e,t,s={}){const{once:i=!1,priority:a=0}=s;if(e.includes("*")){const o={pattern:e,handler:t,once:i,priority:a};return this.wildcardHandlers.add(o),()=>this.wildcardHandlers.delete(o)}this.events.has(e)||this.events.set(e,[]);const n={handler:t,once:i,priority:a},r=this.events.get(e);return r.push(n),r.sort((o,c)=>c.priority-o.priority),()=>{const o=r.indexOf(n);o>-1&&r.splice(o,1)}}once(e,t,s={}){return this.on(e,t,{...s,once:!0})}off(e,t){if(!this.events.has(e))return;const s=this.events.get(e),i=s.findIndex(a=>a.handler===t);i>-1&&s.splice(i,1),s.length===0&&this.events.delete(e)}async emit(e,t){const s=[];if(this.events.has(e)){const i=[...this.events.get(e)];for(const a of i){const{handler:n,once:r}=a;r&&this.off(e,n);try{const o=n(t,e);o instanceof Promise&&s.push(o)}catch(o){console.error(`Error in event handler for ${e}:`,o)}}}for(const i of this.wildcardHandlers)if(this.matchesPattern(e,i.pattern)){const{handler:a,once:n}=i;n&&this.wildcardHandlers.delete(i);try{const r=a(t,e);r instanceof Promise&&s.push(r)}catch(r){console.error(`Error in wildcard handler for ${e}:`,r)}}return Promise.all(s)}matchesPattern(e,t){return new RegExp("^"+t.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}}const g=new X;class ee{constructor(e={}){this.calendar=new J({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)}getState(){return{...this.state}}setState(e,t={}){const{silent:s=!1}=t,i={...this.state};return this.state={...this.state,...e},s||(this.notifySubscribers(i,this.state),this.emitStateChange(i,this.state)),this.state}subscribe(e){return this.subscribers.add(e),()=>this.unsubscribe(e)}unsubscribe(e){this.subscribers.delete(e)}notifySubscribers(e,t){this.subscribers.forEach(s=>{try{s(t,e)}catch(i){console.error("Error in state subscriber:",i)}})}emitStateChange(e,t){const s=Object.keys(t).filter(i=>e[i]!==t[i]);s.forEach(i=>{g.emit(`state:${i}:changed`,{oldValue:e[i],newValue:t[i],state:t})}),s.length>0&&g.emit("state:changed",{oldState:e,newState:t,changedKeys:s})}setView(e){this.calendar.setView(e),this.setState({view:e}),g.emit("view:changed",{view:e})}getView(){return this.state.view}setDate(e){this.calendar.goToDate(e),this.setState({currentDate:this.calendar.getCurrentDate()}),g.emit("date:changed",{date:this.state.currentDate})}getCurrentDate(){return this.state.currentDate}next(){this.calendar.next(),this.setState({currentDate:this.calendar.getCurrentDate()}),g.emit("navigation:next",{date:this.state.currentDate})}previous(){this.calendar.previous(),this.setState({currentDate:this.calendar.getCurrentDate()}),g.emit("navigation:previous",{date:this.state.currentDate})}today(){this.calendar.today(),this.setState({currentDate:this.calendar.getCurrentDate()}),g.emit("navigation:today",{date:this.state.currentDate})}goToDate(e){this.calendar.goToDate(e),this.setState({currentDate:this.calendar.getCurrentDate()}),g.emit("navigation:goto",{date:this.state.currentDate})}addEvent(e){const t=this.calendar.addEvent(e);return this.state.events.push(t),this.setState({events:[...this.state.events]}),g.emit("event:added",{event:t}),t}updateEvent(e,t){const s=this.calendar.updateEvent(e,t);if(s){const i=this.state.events.findIndex(a=>a.id===e);i>-1&&(this.state.events[i]=s,this.setState({events:[...this.state.events]}),g.emit("event:updated",{event:s}))}return s}deleteEvent(e){const t=this.calendar.removeEvent(e);return t&&(this.state.events=this.state.events.filter(s=>s.id!==e),this.setState({events:[...this.state.events]}),g.emit("event:deleted",{eventId:e})),t}getEvents(){return this.calendar.getEvents()}getEventsForDate(e){return this.calendar.getEventsForDate(e)}getEventsInRange(e,t){return this.calendar.getEventsInRange(e,t)}getViewData(){const e=this.calendar.getViewData();return this.enrichViewData(e)}enrichViewData(e){var s;const t=(s=this.state.selectedDate)==null?void 0:s.toDateString();if(e.weeks&&(e.weeks=e.weeks.map(i=>({...i,days:i.days.map(a=>{const n=new Date(a.date);return{...a,isSelected:n.toDateString()===t,events:a.events||this.getEventsForDate(n)}})}))),e.days&&(e.days=e.days.map(i=>{const a=new Date(i.date);return{...i,isSelected:a.toDateString()===t,events:i.events||this.getEventsForDate(a)}})),e.date&&!e.days&&!e.weeks){const i=new Date(e.date);e.isSelected=i.toDateString()===t,e.events=e.events||this.getEventsForDate(i)}return e}selectEvent(e){this.setState({selectedEvent:e}),g.emit("event:selected",{event:e})}selectEventById(e){const t=this.state.events.find(s=>s.id===e);t&&this.selectEvent(t)}deselectEvent(){this.setState({selectedEvent:null}),g.emit("event:deselected",{})}selectDate(e){this.setState({selectedDate:e}),g.emit("date:selected",{date:e})}deselectDate(){this.setState({selectedDate:null}),g.emit("date:deselected",{})}isToday(e){const t=new Date;return e.toDateString()===t.toDateString()}isSelectedDate(e){return this.state.selectedDate&&e.toDateString()===this.state.selectedDate.toDateString()}isWeekend(e){const t=e.getDay();return t===0||t===6}setLoading(e){this.setState({loading:e})}setError(e){this.setState({error:e}),e&&g.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.state=null,this.calendar=null}}class p extends f{static formatDate(e,t="default",s="en-US"){if(!e)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"}},a=i[t]||i.default;return new Intl.DateTimeFormat(s,a).format(e)}static formatTime(e,t=!0,s=!1,i="en-US"){if(!e)return"";const a={hour:"numeric",minute:t?"2-digit":void 0,hour12:!s};return new Intl.DateTimeFormat(i,a).format(e)}static formatDateRange(e,t,s="en-US"){if(!e)return"";if(!t||this.isSameDay(e,t))return this.formatDate(e,"default",s);const i=this.isSameYear(e,t)?"short":"default";return`${this.formatDate(e,i,s)} - ${this.formatDate(t,"default",s)}`}static formatTimeRange(e,t,s="en-US"){if(!e)return"";const i=this.formatTime(e,!0,!1,s);if(!t)return i;const a=this.formatTime(t,!0,!1,s);return`${i} - ${a}`}static getRelativeTime(e,t=new Date,s="en-US"){const i=new Intl.RelativeTimeFormat(s,{numeric:"auto"}),a=e-t,n=Math.floor(a/1e3),r=Math.floor(n/60),o=Math.floor(r/60),c=Math.floor(o/24),l=Math.floor(c/7),d=Math.floor(c/30),h=Math.floor(c/365);return Math.abs(n)<60?i.format(n,"second"):Math.abs(r)<60?i.format(r,"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(d)<12?i.format(d,"month"):i.format(h,"year")}static isToday(e){const 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){const t=new Date(e.getFullYear(),0,1),s=(e-t)/864e5;return Math.ceil((s+t.getDay()+1)/7)}static getDayAbbreviation(e,t="en-US"){const s=new Date(2024,0,7+e);return new Intl.DateTimeFormat(t,{weekday:"short"}).format(s)}static getMonthName(e,t="long",s="en-US"){const i=new Date(2024,e,1);return new Intl.DateTimeFormat(s,{month:t}).format(i)}static parseTimeString(e,t=new Date){const s=new Date(t),[i,a]=e.split(/\s+/),[n,r]=i.split(":").map(Number);let o=n;return a&&(a.toLowerCase()==="pm"&&n<12?o=n+12:a.toLowerCase()==="am"&&n===12&&(o=0)),s.setHours(o,r||0,0,0),s}}class T{static createElement(e,t={},s=[]){const i=document.createElement(e);return Object.entries(t).forEach(([a,n])=>{if(a==="className")i.className=n;else if(a==="style"&&typeof n=="object")Object.assign(i.style,n);else if(a.startsWith("data-"))i.setAttribute(a,n);else if(a.startsWith("on")&&typeof n=="function"){const r=a.slice(2).toLowerCase();i.addEventListener(r,n)}else i[a]=n}),s.forEach(a=>{typeof a=="string"?i.appendChild(document.createTextNode(a)):a instanceof Node&&i.appendChild(a)}),i}static addEventListeners(e,t){return Object.entries(t).forEach(([s,i])=>{e.addEventListener(s,i)}),()=>{Object.entries(t).forEach(([s,i])=>{e.removeEventListener(s,i)})}}static delegate(e,t,s,i){const a=n=>{const r=n.target.closest(t);r&&e.contains(r)&&i.call(r,n)};return e.addEventListener(s,a),()=>e.removeEventListener(s,a)}static getPosition(e){const 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){const s=e.getBoundingClientRect();return s.top>=-t&&s.left>=-t&&s.bottom<=(window.innerHeight||document.documentElement.clientHeight)+t&&s.right<=(window.innerWidth||document.documentElement.clientWidth)+t}static scrollToElement(e,t={}){const{behavior:s="smooth",block:i="start",inline:a="nearest"}=t;e.scrollIntoView({behavior:s,block:i,inline:a})}static getStyle(e,t){return window.getComputedStyle(e).getPropertyValue(t)}static setStyles(e,t){Object.assign(e.style,t)}static async animateClass(e,t,s=300){e.classList.add(t),await this.wait(s),e.classList.remove(t)}static waitForAnimation(e,t="animationend"){return new Promise(s=>{const i=()=>{e.removeEventListener(t,i),s()};e.addEventListener(t,i)})}static wait(e){return new Promise(t=>setTimeout(t,e))}static parseHTML(e){const t=document.createElement("template");return t.innerHTML=e.trim(),t.content.firstChild}static escapeHTML(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}static debounce(e,t=250){let s;return function(...a){const n=()=>{clearTimeout(s),e(...a)};clearTimeout(s),s=setTimeout(n,t)}}static throttle(e,t=250){let s;return function(...i){s||(e.apply(this,i),s=!0,setTimeout(()=>s=!1,t))}}static closest(e,t){return e.closest(t)}static parents(e,t){const s=[];let i=e.parentElement;for(;i;)i.matches(t)&&s.push(i),i=i.parentElement;return s}static getOuterDimensions(e){const t=window.getComputedStyle(e),s={top:parseInt(t.marginTop),right:parseInt(t.marginRight),bottom:parseInt(t.marginBottom),left:parseInt(t.marginLeft)};return{width:e.offsetWidth+s.left+s.right,height:e.offsetHeight+s.top+s.bottom,margin:s}}static cloneWithEvents(e,t=!0){return e.cloneNode(t)}static trapFocus(e){const t=e.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'),s=t[0],i=t[t.length-1],a=n=>{n.key==="Tab"&&(n.shiftKey?document.activeElement===s&&(i.focus(),n.preventDefault()):document.activeElement===i&&(s.focus(),n.preventDefault()))};return e.addEventListener("keydown",a),s==null||s.focus(),()=>e.removeEventListener("keydown",a)}}class D{static getCSSVariable(e,t=document.documentElement){return getComputedStyle(t).getPropertyValue(e).trim()}static setCSSVariables(e,t=document.documentElement){Object.entries(e).forEach(([s,i])=>{t.style.setProperty(s,i)})}static getBaseStyles(){return`
16
- :host {
17
- /* Apply CSS variables */
18
- ${Object.entries(this.cssVariables).map(([e,t])=>`${e}: ${t};`).join(`
19
- `)}
20
-
21
- /* Base styles */
22
- display: block;
23
- box-sizing: border-box;
24
- font-family: var(--fc-font-family);
25
- font-size: var(--fc-font-size-base);
26
- line-height: var(--fc-line-height);
27
- color: var(--fc-text-color);
28
- -webkit-font-smoothing: antialiased;
29
- -moz-osx-font-smoothing: grayscale;
30
- }
31
-
32
- *, *::before, *::after {
33
- box-sizing: inherit;
34
- }
35
-
36
- /* Reset styles */
37
- h1, h2, h3, h4, h5, h6, p {
38
- margin: 0;
39
- font-weight: normal;
40
- }
41
-
42
- button {
43
- font-family: inherit;
44
- font-size: inherit;
45
- line-height: inherit;
46
- margin: 0;
47
- }
48
-
49
- /* Accessibility */
50
- .visually-hidden {
51
- position: absolute;
52
- width: 1px;
53
- height: 1px;
54
- padding: 0;
55
- margin: -1px;
56
- overflow: hidden;
57
- clip: rect(0, 0, 0, 0);
58
- white-space: nowrap;
59
- border: 0;
60
- }
61
-
62
- /* Focus styles */
63
- :focus-visible {
64
- outline: 2px solid var(--fc-primary-color);
65
- outline-offset: 2px;
66
- }
67
- `}static getButtonStyles(){return`
68
- .fc-btn {
69
- display: inline-flex;
70
- align-items: center;
71
- justify-content: center;
72
- padding: 8px 16px;
73
- font-size: var(--fc-font-size-sm);
74
- font-weight: var(--fc-font-weight-medium);
75
- line-height: 1.25rem;
76
- border-radius: var(--fc-border-radius);
77
- border: 1px solid transparent;
78
- cursor: pointer;
79
- transition: all var(--fc-transition-fast);
80
- outline: none;
81
- user-select: none;
82
- gap: var(--fc-spacing-sm);
83
- white-space: nowrap;
84
- }
85
-
86
- .fc-btn:disabled {
87
- opacity: 0.5;
88
- cursor: not-allowed;
89
- }
90
-
91
- .fc-btn-primary {
92
- background: var(--fc-primary-color);
93
- color: white;
94
- box-shadow: var(--fc-shadow-sm);
95
- }
96
-
97
- .fc-btn-primary:hover:not(:disabled) {
98
- background: var(--fc-primary-hover);
99
- box-shadow: var(--fc-shadow);
100
- }
101
-
102
- .fc-btn-secondary {
103
- background: white;
104
- border-color: var(--fc-border-color);
105
- color: var(--fc-text-color);
106
- box-shadow: var(--fc-shadow-sm);
107
- }
108
-
109
- .fc-btn-secondary:hover:not(:disabled) {
110
- background: var(--fc-background-hover);
111
- border-color: var(--fc-border-color-hover);
112
- }
113
-
114
- .fc-btn-outline {
115
- background: transparent;
116
- border-color: var(--fc-border-color);
117
- color: var(--fc-text-secondary);
118
- }
119
-
120
- .fc-btn-outline:hover:not(:disabled) {
121
- background: var(--fc-background-hover);
122
- color: var(--fc-text-color);
123
- border-color: var(--fc-border-color-hover);
124
- }
125
-
126
- .fc-btn-ghost {
127
- background: transparent;
128
- color: var(--fc-text-secondary);
129
- }
130
-
131
- .fc-btn-ghost:hover:not(:disabled) {
132
- background: var(--fc-background-hover);
133
- color: var(--fc-text-color);
134
- }
135
-
136
- .fc-btn-sm {
137
- padding: 6px 12px;
138
- font-size: var(--fc-font-size-xs);
139
- }
140
-
141
- .fc-btn-lg {
142
- padding: 10px 20px;
143
- font-size: var(--fc-font-size-base);
144
- }
145
-
146
- .fc-btn-icon {
147
- width: 32px;
148
- height: 32px;
149
- padding: 0;
150
- border-radius: var(--fc-border-radius-full);
151
- }
152
- `}static darken(e,t){const s=parseInt(e.replace("#",""),16),i=Math.round(2.55*t),a=(s>>16)-i,n=(s>>8&255)-i,r=(s&255)-i;return"#"+(16777216+(a<255?a<1?0:a:255)*65536+(n<255?n<1?0:n:255)*256+(r<255?r<1?0:r:255)).toString(16).slice(1)}static lighten(e,t){const s=parseInt(e.replace("#",""),16),i=Math.round(2.55*t),a=(s>>16)+i,n=(s>>8&255)+i,r=(s&255)+i;return"#"+(16777216+(a<255?a<1?0:a:255)*65536+(n<255?n<1?0:n:255)*256+(r<255?r<1?0:r:255)).toString(16).slice(1)}static getContrastColor(e){const t=e.replace("#",""),s=parseInt(t.substr(0,2),16),i=parseInt(t.substr(2,2),16),a=parseInt(t.substr(4,2),16);return(s*299+i*587+a*114)/1e3>=128?"#000000":"#FFFFFF"}static hexToRgba(e,t=1){const s=e.replace("#",""),i=parseInt(s.substr(0,2),16),a=parseInt(s.substr(2,2),16),n=parseInt(s.substr(4,2),16);return`rgba(${i}, ${a}, ${n}, ${t})`}static getGridStyles(){return`
153
- .fc-grid {
154
- display: grid;
155
- gap: 1px;
156
- background: var(--fc-border-color);
157
- border: 1px solid var(--fc-border-color);
158
- border-radius: var(--fc-border-radius);
159
- overflow: hidden;
160
- }
161
-
162
- .fc-grid-cell {
163
- background: var(--fc-background);
164
- padding: var(--fc-spacing-sm);
165
- min-height: 100px;
166
- position: relative;
167
- }
168
-
169
- .fc-grid-cell:hover {
170
- background: var(--fc-background-hover);
171
- }
172
-
173
- .fc-grid-header {
174
- background: var(--fc-background-alt);
175
- padding: var(--fc-spacing-sm);
176
- font-weight: var(--fc-font-weight-semibold);
177
- text-align: center;
178
- color: var(--fc-text-secondary);
179
- font-size: var(--fc-font-size-xs);
180
- text-transform: uppercase;
181
- letter-spacing: 0.5px;
182
- }
183
- `}static mediaQuery(e,t){const s=this.breakpoints[e];return s?`@media (min-width: ${s}) { ${t} }`:""}static getAnimations(){return`
184
- @keyframes fc-fade-in {
185
- from { opacity: 0; }
186
- to { opacity: 1; }
187
- }
188
-
189
- @keyframes fc-slide-in-up {
190
- from {
191
- opacity: 0;
192
- transform: translateY(10px);
193
- }
194
- to {
195
- opacity: 1;
196
- transform: translateY(0);
197
- }
198
- }
199
-
200
- @keyframes fc-slide-in-down {
201
- from {
202
- opacity: 0;
203
- transform: translateY(-10px);
204
- }
205
- to {
206
- opacity: 1;
207
- transform: translateY(0);
208
- }
209
- }
210
-
211
- @keyframes fc-scale-in {
212
- from {
213
- opacity: 0;
214
- transform: scale(0.95);
215
- }
216
- to {
217
- opacity: 1;
218
- transform: scale(1);
219
- }
220
- }
221
-
222
- @keyframes fc-spin {
223
- from { transform: rotate(0deg); }
224
- to { transform: rotate(360deg); }
225
- }
226
-
227
- .fc-fade-in {
228
- animation: fc-fade-in var(--fc-transition);
229
- }
230
-
231
- .fc-slide-in-up {
232
- animation: fc-slide-in-up var(--fc-transition);
233
- }
234
-
235
- .fc-scale-in {
236
- animation: fc-scale-in var(--fc-transition);
237
- }
238
- `}}A(D,"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"}}),A(D,"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"}),A(D,"breakpoints",{xs:"320px",sm:"576px",md:"768px",lg:"992px",xl:"1200px","2xl":"1400px"});class te extends C{constructor(){super(),this._stateManager=null,this.viewData=null,this.config={maxEventsToShow:3}}set stateManager(e){this._stateManager=e,e&&(this.unsubscribe=e.subscribe(this.handleStateUpdate.bind(this)),this.loadViewData())}get stateManager(){return this._stateManager}handleStateUpdate(e,t){if(e.currentDate!==t.currentDate){this.loadViewData();return}e.events!==t.events&&this.updateEvents(),e.selectedDate!==t.selectedDate&&this.updateSelection(e.selectedDate,t.selectedDate)}updateEvents(){this.loadViewData()}updateSelection(e,t){if(t){const s=this.shadowRoot.querySelector(`[data-date^="${t.toISOString().split("T")[0]}"]`);s&&s.classList.remove("selected")}if(e){const s=this.shadowRoot.querySelector(`[data-date^="${e.toISOString().split("T")[0]}"]`);s&&s.classList.add("selected")}}loadViewData(){if(!this.stateManager)return;const e=this.stateManager.getViewData();this.viewData=this.processViewData(e),this.render()}processViewData(e){var i,a;if(!e||!e.weeks)return null;const t=(a=(i=this.stateManager)==null?void 0:i.getState())==null?void 0:a.selectedDate,s=e.weeks.map(n=>n.days.map(r=>{const o=new Date(r.date),c=t&&o.toDateString()===t.toDateString(),l=r.events.map(d=>({...d,textColor:this.getContrastingTextColor(d.backgroundColor)}));return{...r,date:o,isOtherMonth:!r.isCurrentMonth,isSelected:c,events:l}}));return{...e,weeks:s,month:e.month,year:e.year}}getContrastingTextColor(e){if(!e)return"white";const t=e.charAt(0)==="#"?e.substring(1,7):e,s=parseInt(t.substring(0,2),16),i=parseInt(t.substring(2,4),16),a=parseInt(t.substring(4,6),16),r=[s/255,i/255,a/255].map(c=>c<=.03928?c/12.92:Math.pow((c+.055)/1.055,2.4));return .2126*r[0]+.7152*r[1]+.0722*r[2]>.179?"black":"white"}isSelectedDate(e){var s,i;const t=(i=(s=this.stateManager)==null?void 0:s.getState())==null?void 0:i.selectedDate;return t&&e.toDateString()===t.toDateString()}getStyles(){return`
239
- :host {
240
- display: block;
241
- height: 100%;
242
- }
243
-
244
- .month-view {
245
- display: flex;
246
- flex-direction: column;
247
- height: 100%;
248
- background: var(--fc-background);
249
- }
250
-
251
- .month-header {
252
- display: grid;
253
- grid-template-columns: repeat(7, 1fr);
254
- background: var(--fc-background);
255
- border-bottom: 1px solid var(--fc-border-color);
256
- z-index: 5;
257
- }
258
-
259
- .month-header-cell {
260
- padding: var(--fc-spacing-sm);
261
- text-align: left; /* Align with dates */
262
- font-weight: var(--fc-font-weight-bold);
263
- font-size: 10px;
264
- color: var(--fc-text-light);
265
- text-transform: uppercase;
266
- letter-spacing: 0.1em;
267
- border-left: 1px solid transparent; /* Alignment hack */
268
- padding-left: 8px;
269
- }
270
-
271
- .month-body {
272
- flex: 1;
273
- display: flex;
274
- flex-direction: column;
275
- overflow: hidden;
276
- }
277
-
278
- .month-week {
279
- flex: 1;
280
- display: grid;
281
- grid-template-columns: repeat(7, 1fr);
282
- border-bottom: 1px solid var(--fc-border-color);
283
- }
284
-
285
- .month-week:last-child {
286
- border-bottom: none;
287
- }
288
-
289
- .month-day {
290
- background: var(--fc-background);
291
- padding: 4px;
292
- position: relative;
293
- cursor: default;
294
- overflow: hidden;
295
- min-height: 80px;
296
- border-right: 1px solid var(--fc-border-color);
297
- display: flex;
298
- flex-direction: column;
299
- min-width: 0; /* Critical for Grid Item shrinking */
300
- }
301
-
302
- .month-day:last-child {
303
- border-right: none;
304
- }
305
-
306
- .month-day:hover {
307
- background: var(--fc-background-alt);
308
- }
309
-
310
- .month-day.other-month {
311
- background: var(--fc-background-alt);
312
- background-image: linear-gradient(45deg, #f9fafb 25%, transparent 25%, transparent 50%, #f9fafb 50%, #f9fafb 75%, transparent 75%, transparent);
313
- background-size: 10px 10px;
314
- }
315
-
316
- .month-day.other-month .day-number {
317
- color: var(--fc-text-light);
318
- opacity: 0.5;
319
- }
320
-
321
- .month-day.selected {
322
- background: var(--fc-background-hover);
323
- }
324
-
325
- .day-header {
326
- display: flex;
327
- align-items: center;
328
- justify-content: space-between;
329
- padding: 4px;
330
- margin-bottom: 2px;
331
- }
332
-
333
- .day-number {
334
- font-size: 12px;
335
- font-family: var(--fc-font-family); /* Ensure monospaced feel if available */
336
- font-weight: var(--fc-font-weight-medium);
337
- color: var(--fc-text-color);
338
- line-height: 1;
339
- }
340
-
341
- .month-day.today .day-number {
342
- color: white;
343
- background: var(--fc-danger-color); /* Red for Today (Calendar standard) */
344
- width: 20px;
345
- height: 20px;
346
- display: flex;
347
- align-items: center;
348
- justify-content: center;
349
- border-radius: 50%;
350
- margin-left: -4px; /* Optical adjustment */
351
- }
352
-
353
- .day-events {
354
- display: flex;
355
- flex-direction: column;
356
- gap: 2px;
357
- flex: 1;
358
- overflow: hidden;
359
- }
360
-
361
- /* Precision Event Style */
362
- .event-item {
363
- font-size: 11px;
364
- padding: 2px 6px;
365
- border-radius: 2px; /* Micro rounding */
366
-
367
- /* High Contrast */
368
- background: var(--fc-primary-color);
369
- color: white;
370
-
371
- overflow: hidden;
372
- text-overflow: ellipsis;
373
- white-space: nowrap;
374
- cursor: pointer;
375
- line-height: 1.3;
376
- font-weight: var(--fc-font-weight-medium);
377
- margin: 0 1px;
378
- border: 1px solid rgba(0,0,0,0.05); /* Subtle border for definition */
379
- }
380
-
381
- .event-item:hover {
382
- opacity: 0.9;
383
- }
384
-
385
- .event-time {
386
- font-weight: var(--fc-font-weight-bold);
387
- margin-right: 4px;
388
- opacity: 0.9;
389
- font-size: 10px;
390
- }
391
-
392
- .more-events {
393
- font-size: 10px;
394
- color: var(--fc-text-secondary);
395
- cursor: pointer;
396
- padding: 1px 4px;
397
- font-weight: var(--fc-font-weight-medium);
398
- text-align: right;
399
- }
400
-
401
- .more-events:hover {
402
- color: var(--fc-text-color);
403
- text-decoration: underline;
404
- }
405
-
406
- /* Responsive adjustments */
407
- @media (max-width: 768px) {
408
- .month-day {
409
- min-height: 60px;
410
- padding: 2px;
411
- }
412
-
413
- .day-number {
414
- font-size: 11px;
415
- }
416
-
417
- .event-item {
418
- font-size: 10px;
419
- padding: 1px 3px;
420
- }
421
-
422
- .month-header-cell {
423
- font-size: 9px;
424
- padding: 4px;
425
- }
426
- }
427
-
428
- /* Loading state */
429
- .month-loading {
430
- display: flex;
431
- align-items: center;
432
- justify-content: center;
433
- height: 100%;
434
- color: var(--fc-text-secondary);
435
- font-weight: var(--fc-font-weight-medium);
436
- }
437
-
438
- /* Empty state */
439
- .month-empty {
440
- display: flex;
441
- flex-direction: column;
442
- align-items: center;
443
- justify-content: center;
444
- height: 100%;
445
- color: var(--fc-text-secondary);
446
- gap: var(--fc-spacing-md);
447
- }
448
-
449
- .empty-icon {
450
- width: 48px;
451
- height: 48px;
452
- opacity: 0.3;
453
- }
454
- `}template(){return this.viewData?`
455
- <div class="month-view">
456
- ${this.renderHeader()}
457
- ${this.renderBody()}
458
- </div>
459
- `:`
460
- <div class="month-view">
461
- <div class="month-loading">Loading calendar...</div>
462
- </div>
463
- `}renderHeader(){const{config:e}=this.stateManager.getState(),t=[],s=e.weekStartsOn||0;for(let i=0;i<7;i++){const a=(s+i)%7,n=p.getDayAbbreviation(a,e.locale);t.push(`<div class="month-header-cell">${n}</div>`)}return`
464
- <div class="month-header">
465
- ${t.join("")}
466
- </div>
467
- `}renderBody(){return!this.viewData.weeks||this.viewData.weeks.length===0?`
468
- <div class="month-body">
469
- <div class="month-empty">
470
- <svg class="empty-icon" viewBox="0 0 24 24">
471
- <path fill="currentColor" 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 16H5V8h14v11z"/>
472
- </svg>
473
- <p>No calendar data available</p>
474
- </div>
475
- </div>
476
- `:`
477
- <div class="month-body">
478
- ${this.viewData.weeks.map(t=>this.renderWeek(t)).join("")}
479
- </div>
480
- `}renderWeek(e){return`
481
- <div class="month-week">
482
- ${e.map(s=>this.renderDay(s)).join("")}
483
- </div>
484
- `}renderDay(e){const{date:t,dayOfMonth:s,isOtherMonth:i,isToday:a,isSelected:n,isWeekend:r,events:o=[]}=e,c=s,l=["month-day"];i&&l.push("other-month"),a&&l.push("today"),n&&l.push("selected"),r&&l.push("weekend");const d=o.slice(0,this.config.maxEventsToShow),h=o.length-this.config.maxEventsToShow,y=d.map(w=>this.renderEvent(w)).join(""),b=h>0?`<div class="more-events">+${h} more</div>`:"";return`
485
- <div class="${l.join(" ")}"
486
- data-date="${t.toISOString()}"
487
- data-day="${c}">
488
- <div class="day-header">
489
- <span class="day-number">${c}</span>
490
- </div>
491
- <div class="day-events">
492
- ${y}
493
- ${b}
494
- </div>
495
- </div>
496
- `}renderEvent(e){const{title:t,start:s,allDay:i,backgroundColor:a,textColor:n}=e;let r="";a&&(r+=`background-color: ${a}; color: ${n};`);let o="";!i&&s&&(o=p.formatTime(new Date(s),!1,!1));const c=["event-item"];return i&&c.push("all-day"),`
497
- <div class="${c.join(" ")}"
498
- style="${r}"
499
- data-event-id="${e.id}"
500
- title="${T.escapeHTML(t)}">
501
- ${o?`<span class="event-time">${o}</span>`:""}
502
- <span class="event-title">${T.escapeHTML(t)}</span>
503
- </div>
504
- `}afterRender(){this.$$(".month-day").forEach(e=>{this.addListener(e,"click",this.handleDayClick)}),this.$$(".event-item").forEach(e=>{this.addListener(e,"click",this.handleEventClick)}),this.$$(".more-events").forEach(e=>{this.addListener(e,"click",this.handleMoreClick)})}handleDayClick(e){e.stopPropagation();const t=e.currentTarget,s=new Date(t.dataset.date);this.stateManager.selectDate(s),this.emit("day-click",{date:s})}handleEventClick(e){e.stopPropagation();const s=e.currentTarget.dataset.eventId,i=this.stateManager.getEvents().find(a=>a.id===s);i&&(this.stateManager.selectEvent(i),this.emit("event-click",{event:i}))}handleMoreClick(e){e.stopPropagation();const t=e.currentTarget.closest(".month-day"),s=new Date(t.dataset.date),i=this.stateManager.getEventsForDate(s);this.emit("more-events-click",{date:s,events:i})}unmount(){this.unsubscribe&&this.unsubscribe()}}class se extends C{constructor(){super(),this._stateManager=null,this.viewData=null,this.hours=Array.from({length:24},(e,t)=>t)}set stateManager(e){this._stateManager=e,e&&(this.unsubscribe=e.subscribe(this.handleStateUpdate.bind(this)),this.loadViewData())}get stateManager(){return this._stateManager}handleStateUpdate(e,t){if(e.currentDate!==(t==null?void 0:t.currentDate)||e.view!==(t==null?void 0:t.view)){this.loadViewData();return}e.events!==(t==null?void 0:t.events)&&this.loadViewData(),e.selectedDate!==(t==null?void 0:t.selectedDate)&&this.updateSelection(e.selectedDate,t==null?void 0:t.selectedDate)}updateSelection(e,t){if(t){const s=this.shadowRoot.querySelector(`[data-date^="${t.toISOString().split("T")[0]}"]`);s&&s.classList.remove("selected")}if(e){const s=this.shadowRoot.querySelector(`[data-date^="${e.toISOString().split("T")[0]}"]`);s&&s.classList.add("selected")}}loadViewData(){if(!this.stateManager)return;const e=this.stateManager.getViewData();this.viewData=this.processViewData(e),this.render()}processViewData(e){if(!e)return null;let t=[];return e.weeks&&e.weeks.length>0?t=e.weeks[0].days:e.days&&(t=e.days),!t||t.length===0?null:{...e,days:t.map(s=>{const i=new Date(s.date);return{...s,date:i,isToday:p.isToday(i),timedEvents:(s.events||[]).filter(a=>!a.allDay),allDayEvents:(s.events||[]).filter(a=>a.allDay)}})}}getStyles(){return`
505
- :host {
506
- display: flex;
507
- flex-direction: column;
508
- height: 100%;
509
- min-height: 0;
510
- }
511
-
512
- .week-view {
513
- display: flex;
514
- flex-direction: column;
515
- height: 100%;
516
- background: var(--fc-background);
517
- min-height: 0;
518
- overflow: hidden;
519
- }
520
-
521
- /* Header Section */
522
- .week-header {
523
- display: grid;
524
- grid-template-columns: 60px repeat(7, 1fr);
525
- border-bottom: 1px solid var(--fc-border-color);
526
- background: var(--fc-background);
527
- z-index: 20;
528
- flex-shrink: 0;
529
- }
530
-
531
- .day-column-header {
532
- padding: 12px 8px;
533
- text-align: center;
534
- border-right: 1px solid var(--fc-border-color);
535
- display: flex;
536
- flex-direction: column;
537
- align-items: center;
538
- gap: 4px;
539
- }
540
-
541
- .day-name {
542
- font-size: 10px;
543
- font-weight: 700;
544
- color: var(--fc-text-light);
545
- text-transform: uppercase;
546
- letter-spacing: 0.1em;
547
- }
548
-
549
- .day-number {
550
- font-size: 16px;
551
- font-weight: 500;
552
- width: 28px;
553
- height: 28px;
554
- display: flex;
555
- align-items: center;
556
- justify-content: center;
557
- border-radius: 50%;
558
- color: var(--fc-text-color);
559
- }
560
-
561
- .is-today .day-number {
562
- background: var(--fc-danger-color);
563
- color: white;
564
- font-weight: 700;
565
- }
566
-
567
- /* All Day Events Row */
568
- .all-day-row {
569
- display: grid;
570
- grid-template-columns: 60px repeat(7, 1fr);
571
- border-bottom: 1px solid var(--fc-border-color);
572
- background: var(--fc-background-alt);
573
- min-height: 32px;
574
- flex-shrink: 0;
575
- }
576
-
577
- .all-day-label {
578
- font-size: 9px;
579
- color: var(--fc-text-light);
580
- display: flex;
581
- align-items: center;
582
- justify-content: center;
583
- border-right: 1px solid var(--fc-border-color);
584
- text-transform: uppercase;
585
- font-weight: 700;
586
- }
587
-
588
- .all-day-cell {
589
- border-right: 1px solid var(--fc-border-color);
590
- padding: 4px;
591
- display: flex;
592
- flex-direction: column;
593
- gap: 2px;
594
- }
595
-
596
- /* Body Section */
597
- .week-body {
598
- flex: 1;
599
- overflow-y: auto;
600
- overflow-x: hidden;
601
- position: relative;
602
- display: grid;
603
- grid-template-columns: 60px repeat(7, 1fr);
604
- background: var(--fc-background);
605
- }
606
-
607
- .time-gutter {
608
- border-right: 1px solid var(--fc-border-color);
609
- background: var(--fc-background-alt);
610
- height: 1440px;
611
- }
612
-
613
- .time-slot-label {
614
- height: 60px;
615
- font-size: 10px;
616
- color: var(--fc-text-light);
617
- text-align: right;
618
- padding-right: 8px;
619
- font-weight: 500;
620
- }
621
-
622
- .day-column {
623
- border-right: 1px solid var(--fc-border-color);
624
- position: relative;
625
- height: 1440px;
626
- }
627
-
628
- .day-column.selected {
629
- background: var(--fc-background-hover);
630
- }
631
-
632
- /* Grid Lines Layer */
633
- .grid-lines {
634
- position: absolute;
635
- top: 0;
636
- left: 60px;
637
- right: 0;
638
- bottom: 0;
639
- pointer-events: none;
640
- }
641
-
642
- .grid-line {
643
- height: 60px;
644
- border-bottom: 1px solid var(--fc-border-color);
645
- width: 100%;
646
- }
647
-
648
- .grid-line:last-child {
649
- border-bottom: none;
650
- }
651
-
652
- .event-container {
653
- position: absolute;
654
- left: 2px;
655
- right: 2px;
656
- border-radius: 4px;
657
- padding: 4px 8px;
658
- font-size: 11px;
659
- font-weight: 500;
660
- color: white;
661
- background: var(--fc-primary-color);
662
- border: 1px solid rgba(0,0,0,0.1);
663
- overflow: hidden;
664
- box-shadow: var(--fc-shadow-sm);
665
- cursor: pointer;
666
- transition: transform 0.1s;
667
- z-index: 5;
668
- }
669
-
670
- .event-container:hover {
671
- z-index: 10;
672
- transform: scale(1.02);
673
- }
674
-
675
- .now-indicator {
676
- position: absolute;
677
- left: 0;
678
- right: 0;
679
- height: 2px;
680
- background: var(--fc-danger-color);
681
- z-index: 15;
682
- pointer-events: none;
683
- }
684
- `}template(){return this.viewData?`
685
- <div class="week-view">
686
- <div class="week-header">
687
- <div class="time-gutter-header"></div>
688
- ${this.viewData.days.map(e=>`
689
- <div class="day-column-header ${e.isToday?"is-today":""}">
690
- <span class="day-name">${p.getDayAbbreviation(e.date.getDay())}</span>
691
- <span class="day-number">${e.date.getDate()}</span>
692
- </div>
693
- `).join("")}
694
- </div>
695
-
696
- <div class="all-day-row">
697
- <div class="all-day-label">All day</div>
698
- ${this.viewData.days.map(e=>`
699
- <div class="all-day-cell">
700
- ${e.allDayEvents.map(t=>this.renderAllDayEvent(t)).join("")}
701
- </div>
702
- `).join("")}
703
- </div>
704
-
705
- <div class="week-body" id="scroll-container">
706
- <div class="grid-lines">
707
- ${this.hours.map(()=>'<div class="grid-line"></div>').join("")}
708
- </div>
709
-
710
- <div class="time-gutter">
711
- ${this.hours.map(e=>`
712
- <div class="time-slot-label">
713
- ${e===0?"":p.formatTime(new Date().setHours(e,0),!1)}
714
- </div>
715
- `).join("")}
716
- </div>
717
-
718
- ${this.viewData.days.map(e=>`
719
- <div class="day-column" data-date="${e.date.toISOString()}">
720
- ${e.isToday?this.renderNowIndicator():""}
721
- ${e.timedEvents.map(t=>this.renderTimedEvent(t)).join("")}
722
- </div>
723
- `).join("")}
724
- </div>
725
- </div>
726
- `:'<div class="week-view">Loading...</div>'}renderTimedEvent(e){const t=new Date(e.start),s=new Date(e.end),i=t.getHours()*60+t.getMinutes(),a=(s-t)/(1e3*60),n=i,r=Math.max(a,20),o=e.backgroundColor||"var(--fc-primary-color)",c=D.getContrastColor(o);return`
727
- <div class="event-container"
728
- style="top: ${n}px; height: ${r}px; background-color: ${o}; color: ${c};"
729
- data-event-id="${e.id}">
730
- <span class="event-title">${T.escapeHTML(e.title)}</span>
731
- <span class="event-time">${p.formatTime(t)}</span>
732
- </div>
733
- `}renderAllDayEvent(e){const t=e.backgroundColor||"var(--fc-primary-color)",s=D.getContrastColor(t);return`
734
- <div class="event-item"
735
- style="background-color: ${t}; color: ${s}; font-size: 10px; padding: 2px 4px; border-radius: 2px; cursor: pointer; margin-bottom: 2px;"
736
- data-event-id="${e.id}">
737
- ${T.escapeHTML(e.title)}
738
- </div>
739
- `}renderNowIndicator(){const e=new Date;return`<div class="now-indicator" style="top: ${e.getHours()*60+e.getMinutes()}px"></div>`}afterRender(){const e=this.$("#scroll-container");e&&!this._scrolled&&(e.scrollTop=8*60-50,this._scrolled=!0),this.$$("[data-event-id]").forEach(t=>{this.addListener(t,"click",s=>{s.stopPropagation();const i=s.currentTarget.dataset.eventId,a=this.stateManager.getEvents().find(n=>n.id===i);a&&this.emit("event-click",{event:a})})}),this.$$(".day-column").forEach(t=>{this.addListener(t,"click",s=>{const i=s.currentTarget,a=this.$("#scroll-container"),n=i.getBoundingClientRect(),r=s.clientY-n.top+(a?a.scrollTop:0),o=new Date(i.dataset.date);o.setHours(Math.floor(r/60),Math.floor(r%60),0,0),this.stateManager.selectDate(o),this.emit("day-click",{date:o})})})}unmount(){this.unsubscribe&&this.unsubscribe()}}class ie extends C{constructor(){super(),this._stateManager=null,this.viewData=null,this.hours=Array.from({length:24},(e,t)=>t)}set stateManager(e){this._stateManager=e,e&&(this.unsubscribe=e.subscribe(this.handleStateUpdate.bind(this)),this.loadViewData())}get stateManager(){return this._stateManager}handleStateUpdate(e,t){if(e.currentDate!==(t==null?void 0:t.currentDate)||e.view!==(t==null?void 0:t.view)){this.loadViewData();return}e.events!==(t==null?void 0:t.events)&&this.loadViewData(),e.selectedDate!==(t==null?void 0:t.selectedDate)&&this.updateSelection(e.selectedDate,t==null?void 0:t.selectedDate)}updateSelection(e,t){const s=this.shadowRoot.querySelector(".day-column");if(!s)return;(a=>a&&p.isSameDay(a,new Date(s.dataset.date)))(e)?s.classList.add("selected"):s.classList.remove("selected")}loadViewData(){if(!this.stateManager)return;const e=this.stateManager.getViewData();this.viewData=this.processViewData(e),this.render()}processViewData(e){var n;if(!e)return null;let t=null;const s=(n=this.stateManager)==null?void 0:n.getState(),i=(s==null?void 0:s.currentDate)||new Date;if(e.days&&Array.isArray(e.days)&&e.days.length>0)t=e.days.find(r=>p.isSameDay(new Date(r.date),i))||e.days[0];else if(e.weeks&&Array.isArray(e.weeks)&&e.weeks.length>0){const r=e.weeks.flatMap(o=>o.days||[]);t=r.find(o=>p.isSameDay(new Date(o.date),i))||r[0]}else e.date&&(t=e);if(!t)return null;const a=new Date(t.date);return{...e,day:{...t,date:a,isToday:p.isToday(a),timedEvents:(t.events||[]).filter(r=>!r.allDay),allDayEvents:(t.events||[]).filter(r=>r.allDay)}}}getStyles(){return`
740
- :host {
741
- display: flex;
742
- flex-direction: column;
743
- height: 100%;
744
- min-height: 0;
745
- }
746
-
747
- .day-view {
748
- display: flex;
749
- flex-direction: column;
750
- height: 100%;
751
- background: var(--fc-background);
752
- min-height: 0;
753
- overflow: hidden;
754
- }
755
-
756
- /* Header */
757
- .day-header {
758
- display: grid;
759
- grid-template-columns: 60px 1fr;
760
- border-bottom: 1px solid var(--fc-border-color);
761
- background: var(--fc-background);
762
- z-index: 20;
763
- flex-shrink: 0;
764
- }
765
-
766
- .day-column-header {
767
- padding: 16px 24px;
768
- text-align: left;
769
- display: flex;
770
- flex-direction: column;
771
- gap: 4px;
772
- }
773
-
774
- .day-name {
775
- font-size: 12px;
776
- font-weight: 700;
777
- color: var(--fc-text-light);
778
- text-transform: uppercase;
779
- letter-spacing: 0.1em;
780
- }
781
-
782
- .day-number {
783
- font-size: 24px;
784
- font-weight: 600;
785
- color: var(--fc-text-color);
786
- }
787
-
788
- .is-today .day-number {
789
- color: var(--fc-danger-color);
790
- }
791
-
792
- /* All Day Events */
793
- .all-day-row {
794
- display: grid;
795
- grid-template-columns: 60px 1fr;
796
- border-bottom: 1px solid var(--fc-border-color);
797
- background: var(--fc-background-alt);
798
- min-height: 36px;
799
- flex-shrink: 0;
800
- }
801
-
802
- .all-day-label {
803
- font-size: 9px;
804
- color: var(--fc-text-light);
805
- display: flex;
806
- align-items: center;
807
- justify-content: center;
808
- border-right: 1px solid var(--fc-border-color);
809
- text-transform: uppercase;
810
- font-weight: 700;
811
- }
812
-
813
- .all-day-cell {
814
- padding: 6px 12px;
815
- display: flex;
816
- flex-wrap: wrap;
817
- gap: 4px;
818
- }
819
-
820
- /* Body */
821
- .day-body {
822
- flex: 1;
823
- overflow-y: auto;
824
- overflow-x: hidden;
825
- position: relative;
826
- display: grid;
827
- grid-template-columns: 60px 1fr;
828
- background: var(--fc-background);
829
- }
830
-
831
- .time-gutter {
832
- border-right: 1px solid var(--fc-border-color);
833
- background: var(--fc-background-alt);
834
- height: 1440px;
835
- }
836
-
837
- .time-slot-label {
838
- height: 60px;
839
- font-size: 11px;
840
- color: var(--fc-text-light);
841
- text-align: right;
842
- padding-right: 12px;
843
- font-weight: 500;
844
- }
845
-
846
- .day-column {
847
- position: relative;
848
- height: 1440px;
849
- }
850
-
851
- .day-column.selected {
852
- background: var(--fc-background-hover);
853
- }
854
-
855
- /* Grid Lines */
856
- .grid-lines {
857
- position: absolute;
858
- top: 0;
859
- left: 60px;
860
- right: 0;
861
- bottom: 0;
862
- pointer-events: none;
863
- }
864
-
865
- .grid-line {
866
- height: 60px;
867
- border-bottom: 1px solid var(--fc-border-color);
868
- width: 100%;
869
- }
870
-
871
- /* Event Style */
872
- .event-container {
873
- position: absolute;
874
- left: 12px;
875
- right: 24px;
876
- border-radius: 6px;
877
- padding: 8px 12px;
878
- font-size: 13px;
879
- font-weight: 500;
880
- color: white;
881
- background: var(--fc-primary-color);
882
- border: 1px solid rgba(0,0,0,0.1);
883
- overflow: hidden;
884
- box-shadow: var(--fc-shadow);
885
- cursor: pointer;
886
- transition: all 0.15s ease;
887
- z-index: 5;
888
- }
889
-
890
- .event-container:hover {
891
- z-index: 10;
892
- transform: translateX(4px);
893
- }
894
-
895
- .now-indicator {
896
- position: absolute;
897
- left: 0;
898
- right: 0;
899
- height: 2px;
900
- background: var(--fc-danger-color);
901
- z-index: 15;
902
- pointer-events: none;
903
- }
904
- `}template(){var i,a,n;if(!this.viewData||!this.viewData.day)return'<div class="day-view" style="padding: 20px; color: var(--fc-text-light);">No data available.</div>';const{day:e}=this.viewData,t=((n=(a=(i=this.stateManager)==null?void 0:i.state)==null?void 0:a.config)==null?void 0:n.locale)||"en-US",s=p.formatDate(e.date,"day",t).split(" ")[0];return`
905
- <div class="day-view">
906
- <div class="day-header">
907
- <div class="time-gutter-header"></div>
908
- <div class="day-column-header ${e.isToday?"is-today":""}">
909
- <span class="day-name">${s}</span>
910
- <span class="day-number">${e.date.getDate()}</span>
911
- </div>
912
- </div>
913
-
914
- <div class="all-day-row">
915
- <div class="all-day-label">All day</div>
916
- <div class="all-day-cell">
917
- ${e.allDayEvents.map(r=>this.renderAllDayEvent(r)).join("")}
918
- </div>
919
- </div>
920
-
921
- <div class="day-body" id="scroll-container">
922
- <div class="grid-lines">
923
- ${this.hours.map(()=>'<div class="grid-line"></div>').join("")}
924
- </div>
925
-
926
- <div class="time-gutter">
927
- ${this.hours.map(r=>`
928
- <div class="time-slot-label">
929
- ${r===0?"":p.formatTime(new Date().setHours(r,0),!1)}
930
- </div>
931
- `).join("")}
932
- </div>
933
-
934
- <div class="day-column" data-date="${e.date.toISOString()}">
935
- ${e.isToday?this.renderNowIndicator():""}
936
- ${e.timedEvents.map(r=>this.renderTimedEvent(r)).join("")}
937
- </div>
938
- </div>
939
- </div>
940
- `}renderTimedEvent(e){const t=new Date(e.start),s=new Date(e.end),i=t.getHours()*60+t.getMinutes(),a=(s-t)/(1e3*60),n=i,r=Math.max(a,30),o=e.backgroundColor||"var(--fc-primary-color)",c=D.getContrastColor(o);return`
941
- <div class="event-container"
942
- style="top: ${n}px; height: ${r}px; background-color: ${o}; color: ${c};"
943
- data-event-id="${e.id}">
944
- <span class="event-title">${T.escapeHTML(e.title)}</span>
945
- <span class="event-time">${p.formatTime(t)} - ${p.formatTime(s)}</span>
946
- </div>
947
- `}renderAllDayEvent(e){const t=e.backgroundColor||"var(--fc-primary-color)",s=D.getContrastColor(t);return`
948
- <div class="event-item"
949
- style="background-color: ${t}; color: ${s}; font-size: 12px; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-weight: 500; margin-bottom: 2px;"
950
- data-event-id="${e.id}">
951
- ${T.escapeHTML(e.title)}
952
- </div>
953
- `}renderNowIndicator(){const e=new Date;return`<div class="now-indicator" style="top: ${e.getHours()*60+e.getMinutes()}px"></div>`}afterRender(){const e=this.$("#scroll-container");e&&!this._scrolled&&(e.scrollTop=8*60-50,this._scrolled=!0),this.$$("[data-event-id]").forEach(s=>{this.addListener(s,"click",i=>{i.stopPropagation();const a=i.currentTarget.dataset.eventId,n=this.stateManager.getEvents().find(r=>r.id===a);n&&this.emit("event-click",{event:n})})});const t=this.$(".day-column");t&&this.addListener(t,"click",s=>{const i=s.currentTarget,a=this.$("#scroll-container"),n=i.getBoundingClientRect(),r=s.clientY-n.top+(a?a.scrollTop:0),o=new Date(i.dataset.date);o.setHours(Math.floor(r/60),Math.floor(r%60),0,0),this.stateManager.selectDate(o),this.emit("day-click",{date:o})})}unmount(){this.unsubscribe&&this.unsubscribe()}}class ae extends C{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,s){e==="open"&&(s!==null?this.open():this.close())}getStyles(){return`
954
- ${D.getBaseStyles()}
955
- ${D.getButtonStyles()}
956
-
957
- :host {
958
- display: none;
959
- position: fixed;
960
- top: 0;
961
- left: 0;
962
- width: 100%;
963
- height: 100%;
964
- z-index: var(--fc-z-modal);
965
- align-items: center;
966
- justify-content: center;
967
- background: rgba(0, 0, 0, 0.5);
968
- backdrop-filter: blur(2px);
969
- }
970
-
971
- :host([open]) {
972
- display: flex;
973
- }
974
-
975
- .modal-content {
976
- background: var(--fc-background);
977
- width: 400px;
978
- max-width: 90vw;
979
- border-radius: var(--fc-border-radius-lg);
980
- box-shadow: var(--fc-shadow-lg);
981
- border: 1px solid var(--fc-border-color);
982
- display: flex;
983
- flex-direction: column;
984
- animation: fc-scale-in var(--fc-transition);
985
- }
986
-
987
- .modal-header {
988
- padding: var(--fc-spacing-lg);
989
- border-bottom: 1px solid var(--fc-border-color);
990
- display: flex;
991
- align-items: center;
992
- justify-content: space-between;
993
- }
994
-
995
- .modal-title {
996
- font-size: var(--fc-font-size-lg);
997
- font-weight: var(--fc-font-weight-semibold);
998
- color: var(--fc-text-color);
999
- }
1000
-
1001
- .close-btn {
1002
- background: transparent;
1003
- border: none;
1004
- color: var(--fc-text-secondary);
1005
- cursor: pointer;
1006
- padding: 4px;
1007
- border-radius: var(--fc-border-radius-sm);
1008
- display: flex;
1009
- align-items: center;
1010
- justify-content: center;
1011
- }
1012
-
1013
- .close-btn:hover {
1014
- background: var(--fc-background-hover);
1015
- color: var(--fc-text-color);
1016
- }
1017
-
1018
- .modal-body {
1019
- padding: var(--fc-spacing-lg);
1020
- display: flex;
1021
- flex-direction: column;
1022
- gap: var(--fc-spacing-md);
1023
- }
1024
-
1025
- .form-group {
1026
- display: flex;
1027
- flex-direction: column;
1028
- gap: 4px;
1029
- }
1030
-
1031
- label {
1032
- font-size: var(--fc-font-size-sm);
1033
- font-weight: var(--fc-font-weight-medium);
1034
- color: var(--fc-text-secondary);
1035
- }
1036
-
1037
- input[type="text"],
1038
- input[type="datetime-local"],
1039
- select {
1040
- padding: 8px 12px;
1041
- border: 1px solid var(--fc-border-color);
1042
- border-radius: var(--fc-border-radius);
1043
- font-family: var(--fc-font-family);
1044
- font-size: var(--fc-font-size-base);
1045
- color: var(--fc-text-color);
1046
- background: var(--fc-background);
1047
- transition: border-color var(--fc-transition-fast);
1048
- }
1049
-
1050
- input:focus,
1051
- select:focus {
1052
- outline: none;
1053
- border-color: var(--fc-primary-color);
1054
- box-shadow: 0 0 0 2px var(--fc-primary-light);
1055
- }
1056
-
1057
- .row {
1058
- display: flex;
1059
- gap: var(--fc-spacing-md);
1060
- }
1061
-
1062
- .row .form-group {
1063
- flex: 1;
1064
- }
1065
-
1066
- .modal-footer {
1067
- padding: var(--fc-spacing-lg);
1068
- border-top: 1px solid var(--fc-border-color);
1069
- display: flex;
1070
- justify-content: flex-end;
1071
- gap: var(--fc-spacing-md);
1072
- background: var(--fc-background-alt);
1073
- border-bottom-left-radius: var(--fc-border-radius-lg);
1074
- border-bottom-right-radius: var(--fc-border-radius-lg);
1075
- }
1076
-
1077
- /* Color picker style */
1078
- .color-options {
1079
- display: flex;
1080
- gap: 8px;
1081
- margin-top: 4px;
1082
- }
1083
-
1084
- .color-btn {
1085
- width: 28px;
1086
- height: 28px;
1087
- border-radius: 50%;
1088
- cursor: pointer;
1089
- border: 2px solid transparent;
1090
- transition: transform var(--fc-transition-fast), border-color var(--fc-transition-fast);
1091
- padding: 0;
1092
- position: relative;
1093
- }
1094
-
1095
- .color-btn:hover {
1096
- transform: scale(1.1);
1097
- }
1098
-
1099
- .color-btn.selected {
1100
- border-color: var(--fc-text-color);
1101
- box-shadow: 0 0 0 2px var(--fc-background), 0 0 0 4px var(--fc-primary-color);
1102
- }
1103
-
1104
- .color-btn:focus {
1105
- outline: none;
1106
- box-shadow: 0 0 0 2px var(--fc-background), 0 0 0 4px var(--fc-primary-color);
1107
- }
1108
-
1109
- .error-message {
1110
- color: var(--fc-danger-color);
1111
- font-size: 11px;
1112
- margin-top: 2px;
1113
- display: none;
1114
- }
1115
-
1116
- .form-group.has-error .error-message {
1117
- display: block;
1118
- }
1119
-
1120
- .form-group.has-error input {
1121
- border-color: var(--fc-danger-color);
1122
- }
1123
- `}template(){return`
1124
- <div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="modal-title">
1125
- <header class="modal-header">
1126
- <h3 class="modal-title" id="modal-title">${this.config.title}</h3>
1127
- <button class="close-btn" id="close-x" aria-label="Close modal">
1128
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1129
- <path d="M18 6L6 18M6 6l12 12"></path>
1130
- </svg>
1131
- </button>
1132
- </header>
1133
-
1134
- <div class="modal-body">
1135
- <div class="form-group" id="title-group">
1136
- <label for="event-title">Title</label>
1137
- <input type="text" id="event-title" placeholder="Event name" autofocus required>
1138
- <span class="error-message">Title is required</span>
1139
- </div>
1140
-
1141
- <div class="row">
1142
- <div class="form-group" id="start-group">
1143
- <label for="event-start">Start</label>
1144
- <input type="datetime-local" id="event-start" required>
1145
- </div>
1146
- <div class="form-group" id="end-group">
1147
- <label for="event-end">End</label>
1148
- <input type="datetime-local" id="event-end" required>
1149
- <span class="error-message">End time must be after start time</span>
1150
- </div>
1151
- </div>
1152
-
1153
- <div class="form-group">
1154
- <label id="color-label">Color</label>
1155
- <div class="color-options" id="color-picker" role="radiogroup" aria-labelledby="color-label">
1156
- ${this.config.colors.map(e=>`
1157
- <button type="button"
1158
- class="color-btn ${e.color===this._formData.color?"selected":""}"
1159
- style="background-color: ${e.color}"
1160
- data-color="${e.color}"
1161
- title="${e.label}"
1162
- aria-label="${e.label}"
1163
- aria-checked="${e.color===this._formData.color?"true":"false"}"
1164
- role="radio"></button>
1165
- `).join("")}
1166
- </div>
1167
- </div>
1168
- </div>
1169
-
1170
- <footer class="modal-footer">
1171
- <button class="fc-btn fc-btn-secondary" id="cancel-btn">Cancel</button>
1172
- <button class="fc-btn fc-btn-primary" id="save-btn">Save Event</button>
1173
- </footer>
1174
- </div>
1175
- `}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",t=>{this._formData.color=t.currentTarget.dataset.color,this.updateColorSelection()})}),this.addListener(this,"click",e=>{e.target===this&&this.close()}),this._handleKeyDown=e=>{e.key==="Escape"&&this.hasAttribute("open")&&this.close()},window.addEventListener("keydown",this._handleKeyDown)}updateColorSelection(){this.colorContainer.querySelectorAll(".color-btn").forEach(t=>{const s=t.dataset.color===this._formData.color;t.classList.toggle("selected",s),t.setAttribute("aria-checked",s?"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=T.trapFocus(this.modalContent))}close(){this.removeAttribute("open"),this._cleanupFocusTrap&&(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);const 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;const 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){const t=o=>String(o).padStart(2,"0"),s=e.getFullYear(),i=t(e.getMonth()+1),a=t(e.getDate()),n=t(e.getHours()),r=t(e.getMinutes());return`${s}-${i}-${a}T${n}:${r}`}unmount(){this._cleanupFocusTrap&&this._cleanupFocusTrap(),window.removeEventListener("keydown",this._handleKeyDown)}}customElements.get("force-calendar-event-form")||customElements.define("force-calendar-event-form",ae);customElements.get("force-calendar-month")||customElements.define("force-calendar-month",te);customElements.get("force-calendar-week")||customElements.define("force-calendar-week",se);customElements.get("force-calendar-day")||customElements.define("force-calendar-day",ie);class ne extends C{static get observedAttributes(){return["view","date","locale","timezone","week-starts-on","height"]}constructor(){super(),this.stateManager=null,this.currentView=null}initialize(){const 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 ee(e),this.stateManager.subscribe(this.handleStateChange.bind(this)),this.setupEventListeners()}setupEventListeners(){g.on("navigation:*",(e,t)=>{this.emit("calendar-navigate",{action:t.split(":")[1],...e})}),g.on("view:changed",e=>{this.emit("calendar-view-change",e)}),g.on("event:*",(e,t)=>{this.emit(`calendar-event-${t.split(":")[1]}`,e)}),g.on("date:selected",e=>{this.emit("calendar-date-select",e)})}handleStateChange(e,t){e.view!==(t==null?void 0:t.view)&&(this.currentView=e.view),this.render()}mount(){super.mount(),this.loadView(this.stateManager.getView())}loadView(e){this.currentView=e,this.render()}getStyles(){const e=this.getAttribute("height")||"800px";return`
1176
- ${D.getBaseStyles()}
1177
- ${D.getButtonStyles()}
1178
- ${D.getGridStyles()}
1179
- ${D.getAnimations()}
1180
-
1181
- :host {
1182
- --calendar-height: ${e};
1183
- display: block;
1184
- font-family: var(--fc-font-family);
1185
- }
1186
-
1187
- .force-calendar {
1188
- display: flex;
1189
- flex-direction: column;
1190
- height: var(--calendar-height);
1191
- background: var(--fc-background);
1192
- border: 1px solid var(--fc-border-color);
1193
- border-radius: var(--fc-border-radius-lg);
1194
- overflow: hidden;
1195
- box-shadow: var(--fc-shadow);
1196
- }
1197
-
1198
- .fc-header {
1199
- display: grid;
1200
- grid-template-columns: 1fr auto 1fr;
1201
- align-items: center;
1202
- padding: var(--fc-spacing-md) var(--fc-spacing-lg);
1203
- background: rgba(255, 255, 255, 0.95);
1204
- -webkit-backdrop-filter: blur(8px); /* Safari support */
1205
- backdrop-filter: blur(8px);
1206
- border-bottom: 1px solid var(--fc-border-color);
1207
- z-index: 10;
1208
- position: sticky;
1209
- top: 0;
1210
- }
1211
-
1212
- .fc-header-left {
1213
- display: flex;
1214
- align-items: center;
1215
- gap: var(--fc-spacing-md);
1216
- justify-self: start;
1217
- flex-basis: 0; /* Force Safari to distribute space */
1218
- }
1219
-
1220
- .fc-header-center {
1221
- display: flex;
1222
- align-items: center;
1223
- gap: var(--fc-spacing-lg);
1224
- justify-self: center;
1225
- }
1226
-
1227
- .fc-header-right {
1228
- display: flex;
1229
- align-items: center;
1230
- gap: var(--fc-spacing-md);
1231
- justify-self: end;
1232
- flex-basis: 0; /* Force Safari to distribute space */
1233
- }
1234
-
1235
- .fc-title {
1236
- font-size: 14px;
1237
- font-weight: var(--fc-font-weight-semibold);
1238
- color: var(--fc-text-color);
1239
- white-space: nowrap;
1240
- letter-spacing: -0.01em;
1241
- min-width: 140px;
1242
- text-align: center;
1243
- }
1244
-
1245
- .fc-btn-today {
1246
- border-radius: var(--fc-border-radius-sm);
1247
- padding: 0 12px;
1248
- font-size: 12px;
1249
- font-weight: var(--fc-font-weight-medium);
1250
- border: 1px solid var(--fc-border-color);
1251
- background: var(--fc-background);
1252
- color: var(--fc-text-color);
1253
- height: 28px;
1254
- transition: all var(--fc-transition-fast);
1255
- cursor: pointer;
1256
- display: flex;
1257
- align-items: center;
1258
- }
1259
-
1260
- .fc-btn-today:hover {
1261
- background: var(--fc-background-hover);
1262
- border-color: var(--fc-border-color-hover);
1263
- }
1264
-
1265
- .fc-nav-arrow {
1266
- border: 1px solid var(--fc-border-color);
1267
- background: var(--fc-background);
1268
- height: 28px;
1269
- width: 28px;
1270
- display: flex;
1271
- align-items: center;
1272
- justify-content: center;
1273
- border-radius: var(--fc-border-radius-sm);
1274
- color: var(--fc-text-secondary);
1275
- cursor: pointer;
1276
- transition: all var(--fc-transition-fast);
1277
- padding: 0;
1278
- }
1279
-
1280
- .fc-nav-arrow:hover {
1281
- background: var(--fc-background-hover);
1282
- color: var(--fc-text-color);
1283
- border-color: var(--fc-border-color-hover);
1284
- }
1285
-
1286
- /* View Switcher - Fused Button Group */
1287
- .fc-view-buttons {
1288
- display: flex;
1289
- border: 1px solid var(--fc-border-color);
1290
- border-radius: var(--fc-border-radius-sm);
1291
- overflow: hidden;
1292
- }
1293
-
1294
- .fc-view-button {
1295
- background: var(--fc-background);
1296
- border: none;
1297
- border-right: 1px solid var(--fc-border-color);
1298
- color: var(--fc-text-secondary);
1299
- padding: 0 12px;
1300
- font-size: var(--fc-font-size-sm);
1301
- font-weight: var(--fc-font-weight-medium);
1302
- transition: background-color var(--fc-transition-fast);
1303
- cursor: pointer;
1304
- height: 28px;
1305
- display: flex;
1306
- align-items: center;
1307
- }
1308
-
1309
- .fc-view-button:last-child {
1310
- border-right: none;
1311
- }
1312
-
1313
- .fc-view-button:hover:not(.active) {
1314
- background: var(--fc-background-hover);
1315
- color: var(--fc-text-color);
1316
- }
1317
-
1318
- .fc-view-button.active {
1319
- background: var(--fc-background-alt);
1320
- color: var(--fc-text-color);
1321
- font-weight: var(--fc-font-weight-semibold);
1322
- box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);
1323
- }
1324
-
1325
- .fc-body {
1326
- flex: 1;
1327
- position: relative;
1328
- background: var(--fc-background);
1329
- min-height: 0;
1330
- display: flex;
1331
- flex-direction: column;
1332
- }
1333
-
1334
- .fc-view-container {
1335
- flex: 1;
1336
- position: relative;
1337
- min-height: 0;
1338
- display: flex;
1339
- flex-direction: column;
1340
- }
1341
-
1342
- /* Ensure view components have proper dimensions */
1343
- force-calendar-month,
1344
- force-calendar-week,
1345
- force-calendar-day {
1346
- display: block;
1347
- width: 100%;
1348
- height: 100%;
1349
- }
1350
-
1351
- /* Loading state */
1352
- .fc-loading {
1353
- position: absolute;
1354
- top: 50%;
1355
- left: 50%;
1356
- transform: translate(-50%, -50%);
1357
- display: flex;
1358
- flex-direction: column;
1359
- align-items: center;
1360
- gap: var(--fc-spacing-md);
1361
- color: var(--fc-text-secondary);
1362
- }
1363
-
1364
- .fc-spinner {
1365
- width: 24px;
1366
- height: 24px;
1367
- border: 3px solid var(--fc-border-color);
1368
- border-top-color: var(--fc-primary-color);
1369
- border-radius: 50%;
1370
- animation: fc-spin 1s linear infinite;
1371
- }
1372
-
1373
- /* Error state */
1374
- .fc-error {
1375
- padding: var(--fc-spacing-xl);
1376
- text-align: center;
1377
- color: var(--fc-danger-color);
1378
- background: #FEF2F2;
1379
- border-radius: var(--fc-border-radius);
1380
- margin: var(--fc-spacing-xl);
1381
- }
1382
-
1383
- /* Icons */
1384
- .fc-icon {
1385
- width: 18px;
1386
- height: 18px;
1387
- fill: currentColor;
1388
- }
1389
-
1390
- /* Responsive Adjustments */
1391
- @media (max-width: 850px) {
1392
- .fc-header {
1393
- display: flex;
1394
- flex-direction: column;
1395
- align-items: stretch;
1396
- gap: var(--fc-spacing-md);
1397
- height: auto;
1398
- position: static;
1399
- padding: var(--fc-spacing-md);
1400
- }
1401
-
1402
- .fc-header-center {
1403
- order: -1;
1404
- text-align: center;
1405
- width: 100%;
1406
- padding: var(--fc-spacing-xs) 0;
1407
- }
1408
-
1409
- .fc-header-left,
1410
- .fc-header-right {
1411
- justify-content: space-between;
1412
- width: 100%;
1413
- }
1414
-
1415
- #create-event-btn {
1416
- flex: 1;
1417
- }
1418
- }
1419
- `}template(){const e=this.stateManager.getState(),{currentDate:t,view:s,loading:i,error:a}=e;if(a)return`
1420
- <div class="force-calendar">
1421
- <div class="fc-error">
1422
- <p><strong>Error:</strong> ${a.message||"An error occurred"}</p>
1423
- </div>
1424
- </div>
1425
- `;const n=this.getTitle(t,s);return`
1426
- <div class="force-calendar">
1427
- <header class="fc-header">
1428
- <div class="fc-header-left">
1429
- <button class="fc-btn-today" data-action="today">
1430
- Today
1431
- </button>
1432
- </div>
1433
-
1434
- <div class="fc-header-center">
1435
- <button class="fc-nav-arrow" data-action="previous" title="Previous">
1436
- ${this.getIcon("chevron-left")}
1437
- </button>
1438
- <h2 class="fc-title">${n}</h2>
1439
- <button class="fc-nav-arrow" data-action="next" title="Next">
1440
- ${this.getIcon("chevron-right")}
1441
- </button>
1442
- </div>
1443
-
1444
- <div class="fc-header-right">
1445
- <button class="fc-btn fc-btn-primary" id="create-event-btn" style="height: 28px; padding: 0 12px; font-size: 12px;">
1446
- + New Event
1447
- </button>
1448
- <div class="fc-view-buttons" role="group">
1449
- <button class="fc-view-button ${s==="month"?"active":""}"
1450
- data-view="month">Month</button>
1451
- <button class="fc-view-button ${s==="week"?"active":""}"
1452
- data-view="week">Week</button>
1453
- <button class="fc-view-button ${s==="day"?"active":""}"
1454
- data-view="day">Day</button>
1455
- </div>
1456
- </div>
1457
- </header>
1458
-
1459
- <div class="fc-body">
1460
- ${i?`
1461
- <div class="fc-loading">
1462
- <div class="fc-spinner"></div>
1463
- <span>Loading...</span>
1464
- </div>
1465
- `:`
1466
- <div class="fc-view-container">
1467
- ${this.renderView()}
1468
- </div>
1469
- `}
1470
- </div>
1471
-
1472
- <force-calendar-event-form id="event-modal"></force-calendar-event-form>
1473
- </div>
1474
- `}renderView(){if(!this.currentView)return"<div>Loading view...</div>";const e=`force-calendar-${this.currentView}`;return`<${e} id="calendar-view"></${e}>`}afterRender(){const e=this.$("#calendar-view");e&&this.stateManager&&(e.stateManager=this.stateManager),this.$$("[data-action]").forEach(i=>{i.addEventListener("click",this.handleNavigation.bind(this))}),this.$$("[data-view]").forEach(i=>{i.addEventListener("click",this.handleViewChange.bind(this))});const t=this.$("#event-modal"),s=this.$("#create-event-btn");s&&t&&s.addEventListener("click",()=>{t.open(new Date)}),this.shadowRoot.addEventListener("day-click",i=>{t&&t.open(i.detail.date)}),t&&t.addEventListener("save",i=>{const a=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,...a})})}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){const t=e.currentTarget.dataset.view;this.stateManager.setView(t)}getTitle(e,t){const s=this.stateManager.state.config.locale;switch(t){case"month":return p.formatDate(e,"month",s);case"week":const i=p.startOfWeek(e),a=p.endOfWeek(e);return p.formatDateRange(i,a,s);case"day":return p.formatDate(e,"long",s);default:return p.formatDate(e,"month",s)}}getIcon(e){return{"chevron-left":`
1475
- <svg class="fc-icon" viewBox="0 0 24 24">
1476
- <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
1477
- </svg>
1478
- `,"chevron-right":`
1479
- <svg class="fc-icon" viewBox="0 0 24 24">
1480
- <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
1481
- </svg>
1482
- `,calendar:`
1483
- <svg class="fc-icon" viewBox="0 0 24 24">
1484
- <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"/>
1485
- </svg>
1486
- `}[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()}destroy(){this.stateManager&&this.stateManager.destroy(),g.clear(),super.cleanup()}}customElements.get("force-calendar")||customElements.define("force-calendar",ne);typeof window<"u"&&typeof customElements<"u"&&console.log("Force Calendar Interface loading...");const k=document.getElementById("main-calendar"),L=document.getElementById("log-entries");function M(u,e){const t=new Date().toLocaleTimeString("en-GB",{hour12:!1}),s=document.createElement("div");s.className="log-entry",s.innerHTML=`<span class="log-time">${t}</span> <span class="log-tag">[${u}]</span> ${e}`,L.insertBefore(s,L.firstChild)}customElements.whenDefined("force-calendar").then(()=>{M("System","Calendar component ready"),[{id:"1",title:"Project Kickoff",start:new Date().setHours(10,0),end:new Date().setHours(11,30),backgroundColor:"#3B82F6"},{id:"2",title:"Strategic Planning",start:new Date().setHours(14,0),end:new Date().setHours(16,0),backgroundColor:"#8B5CF6"}].forEach(e=>k.addEvent(e)),M("System","Loaded sample events"),k.addEventListener("calendar-navigate",e=>{M("Nav",`Navigated: ${e.detail.action}`)}),k.addEventListener("calendar-view-change",e=>{M("View",`Changed to: ${e.detail.view}`)}),k.addEventListener("calendar-event-added",e=>{M("Event",`Added: "${e.detail.event.title}"`)}),k.addEventListener("calendar-date-select",e=>{M("Select",`Date selected: ${e.detail.date.toLocaleDateString()}`)}),document.getElementById("add-random-event").addEventListener("click",()=>{const e=["Coffee Break","Sync Meeting","Code Review","Deep Work","Lunch"],t=["#EF4444","#10B981","#F59E0B","#3B82F6","#8B5CF6"],s=new Date;s.setDate(s.getDate()+(Math.floor(Math.random()*10)-5)),s.setHours(Math.floor(Math.random()*8)+9,0,0);const i={id:Math.random().toString(36).substr(2,9),title:e[Math.floor(Math.random()*e.length)],start:s,end:new Date(s.getTime()+60*60*1e3),backgroundColor:t[Math.floor(Math.random()*t.length)]};k.addEvent(i)}),document.getElementById("go-to-today").addEventListener("click",()=>{k.today()}),document.querySelectorAll("[data-view]").forEach(e=>{e.addEventListener("click",t=>{k.setView(t.target.dataset.view)})})});