UNPKG

persian-datepicker-element

Version:

A modern Jalali (Shamsi) Date Picker web component with shadcn-like styling

1 lines 54.5 kB
function t(t,e,i){const r=o.jalaliToGregorian(t,e,i);return new Date(r[0],r[1]-1,r[2]).toISOString()}var e,i,r,s={d(t,e){for(var i in e)s.o(e,i)&&!s.o(t,i)&&Object.defineProperty(t,i,{enumerable:1,get:e[i]})},o:(t,e)=>({}.hasOwnProperty.call(t,e))},a={};s.d(a,{tG:()=>u,ZP:()=>g,QA:()=>o});const o={g_days_in_month:[31,28,31,30,31,30,31,31,30,31,30,31],j_days_in_month:[31,31,31,31,31,31,30,30,30,30,30,29],jalaliToGregorian(t,e,i){const r=(t=parseInt(""+t))-979,s=(e=parseInt(""+e))-1,a=(i=parseInt(""+i))-1;let o=365*r+8*Math.floor(r/33)+Math.floor((r%33+3)/4);for(let t=0;s>t;++t)o+=this.j_days_in_month[t];o+=a;let n=o+79,d=1600+400*Math.floor(n/146097);n%=146097;let h=1;n>=36525&&(n--,d+=100*Math.floor(n/36524),n%=36524,365>n?h=0:n++),d+=4*Math.floor(n/1461),n%=1461,n>=366&&(h=0,n--,d+=Math.floor(n/365),n%=365);let c=0;for(;n>=this.g_days_in_month[c]+(1===c&&h?1:0);c++)n-=this.g_days_in_month[c]+(1===c&&h?1:0);return[d,c+1,n+1]},gregorianToJalali(t,e,i){const r=(t=parseInt(""+t))-1600,s=(e=parseInt(""+e))-1,a=(i=parseInt(""+i))-1;let o=365*r+Math.floor((r+3)/4)-Math.floor((r+99)/100)+Math.floor((r+399)/400);for(let t=0;s>t;++t)o+=this.g_days_in_month[t];s>1&&(r%4==0&&r%100!=0||r%400==0)&&o++,o+=a;let n=o-79;const d=Math.floor(n/12053);n%=12053;let h=979+33*d+4*Math.floor(n/1461);n%=1461,n>=366&&(h+=Math.floor((n-1)/365),n=(n-1)%365);let c=0;for(;11>c&&n>=this.j_days_in_month[c];++c)n-=this.j_days_in_month[c];return[h,c+1,n+1]},isLeapJalaliYear:t=>[1,5,9,13,17,22,26,30].includes(t%33),getDaysInMonth(t,e){return 1>e||e>12?0:e>6?11>=e||this.isLeapJalaliYear(t)?30:29:31},getMonthName:t=>["\u0641\u0631\u0648\u0631\u062f\u06cc\u0646","\u0627\u0631\u062f\u06cc\u0628\u0647\u0634\u062a","\u062e\u0631\u062f\u0627\u062f","\u062a\u06cc\u0631","\u0645\u0631\u062f\u0627\u062f","\u0634\u0647\u0631\u06cc\u0648\u0631","\u0645\u0647\u0631","\u0622\u0628\u0627\u0646","\u0622\u0630\u0631","\u062f\u06cc","\u0628\u0647\u0645\u0646","\u0627\u0633\u0641\u0646\u062f"][t-1],getDayOfWeek(t,e,i){const r=this.jalaliToGregorian(t,e,i);return new Date(r[0],r[1]-1,r[2]).getDay()},getDaysInYear(t){return this.isLeapJalaliYear(t)?366:365},isValidDate(t,e,i){return!(0>t||1>e||e>12||1>i||i>this.getDaysInMonth(t,e))}},n=new Date,d=o.gregorianToJalali(n.getFullYear(),n.getMonth()+1,n.getDate())[0],h=[];class c{constructor(){this.mappedEvents=[...h],this.persianCalendarData={"Persian Calendar":[],"Hijri Calendar":[],Source:{name:"Fallback Data",url:""}},this.isLoading=0,this.lastFetchYear=""[0],this.fetchPromise=""[0],this.isInitialized=0,this.CACHE_KEY="persian_calendar_events",this.CACHE_EXPIRY_DAYS=7}static getInstance(){return c.instance||(c.instance=new c),c.instance}static isInitialized(){return c.instance?.isInitialized??0}static async initialize(){if(c.initializationPromise)return c.initializationPromise;c.initializationPromise=c.getInstance().loadEventsData();try{await c.initializationPromise}finally{c.initializationPromise=""[0]}}mapPersianCalendarEvents(){try{let e=[];return this.persianCalendarData&&this.persianCalendarData["Persian Calendar"]&&Array.isArray(this.persianCalendarData["Persian Calendar"])&&(e=this.persianCalendarData["Persian Calendar"].map((e=>{const i=e.month||1,r=e.day||1;return{title:e.title||"",month:i,day:r,type:e.type||"Iran",holiday:e.holiday||0,isoString:t(d,i,r)}}))),e}catch(t){return[...h]}}saveToCache(t){try{const e={data:t,timestamp:(new Date).getTime(),year:this.lastFetchYear};localStorage.setItem(this.CACHE_KEY,JSON.stringify(e))}catch(t){}}getFromCache(){try{const t=localStorage.getItem(this.CACHE_KEY);if(!t)return""[0];const{data:e,timestamp:i,year:r}=JSON.parse(t);return(new Date).getTime()-i>864e5*this.CACHE_EXPIRY_DAYS||r!==this.lastFetchYear?(localStorage.removeItem(this.CACHE_KEY),""[0]):e}catch(t){return""[0]}}async loadEventsData(){if(this.fetchPromise)return void await this.fetchPromise;const t=new Date,e=o.gregorianToJalali(t.getFullYear(),t.getMonth()+1,t.getDate())[0],i=this.getFromCache();if(i)return this.persianCalendarData=i,this.mappedEvents=this.mapPersianCalendarEvents(),this.lastFetchYear=e,void(this.isInitialized=1);this.fetchPromise=(async()=>{this.isLoading=1;try{const t=await this.fetchWithRetry("data/events.json",3);if(!t.ok)throw Error("HTTP error! status:"+t.status);this.persianCalendarData=await t.json(),this.saveToCache(this.persianCalendarData);const i=this.mapPersianCalendarEvents();this.mappedEvents=[...i],this.lastFetchYear=e,this.isInitialized=1}catch(t){this.mappedEvents=[...h]}finally{this.isLoading=0}})();try{await this.fetchPromise}finally{this.fetchPromise=""[0]}}async fetchWithRetry(t,e){let i=""[0];for(let r=0;e>r;r++)try{const e=await fetch(t);if(e.ok)return e;throw Error("HTTP error! status:"+e.status)}catch(t){i=t,e-1>r&&await new Promise((t=>setTimeout(t,1e3*Math.pow(2,r))))}throw i||Error("Failed to fetch events data after multiple retries")}getEvents(e,i,r,s=0){return this.getAllEvents(r,s).filter((t=>t.month===e&&t.day===i)).map((e=>e.isoString?e:{...e,isoString:t(d,e.month,e.day)}))}getEvent(e,i){const r=this.mappedEvents.find((t=>t.month===e&&t.day===i));return r&&!r.isoString?{...r,isoString:t(d,r.month,r.day)}:r}getEventsForMonth(e){return this.mappedEvents.filter((t=>t.month===e)).map((e=>e.isoString?e:{...e,isoString:t(d,e.month,e.day)}))}getEventsForYear(){return this.mappedEvents.map((e=>e.isoString?e:{...e,isoString:t(d,e.month,e.day)}))}isHoliday(t,e,i,r=0){return this.getEvents(t,e,i,r).some((t=>1==t.holiday))}getHolidayTitles(t,e,i,r=0){return this.getEvents(t,e,i,r).filter((t=>1==t.holiday)).map((t=>t.title))}getAllEventTitles(t,e,i,r=0){return this.getEvents(t,e,i,r).map((t=>t.title))}getAllEvents(e,i=0){let r;return r=i?[...this.mappedEvents]:this.mappedEvents.filter((t=>e?.includes(t.type)??1)),r.map((e=>e.isoString?e:{...e,isoString:t(d,e.month,e.day)}))}getEventsByType(t,e=0,i=0){const r=e?this.mappedEvents:this.mappedEvents.filter((e=>e.type===t));return i?r.filter((t=>1==t.holiday)):r}getAllHolidays(t,e=0){return this.getAllEvents(t,e).filter((t=>1==t.holiday))}getEventTypes(){const t=new Set;return this.mappedEvents.forEach((e=>t.add(e.type))),Array.from(t)}getSourceMetadata(){return this.persianCalendarData.Source||{}}async refreshEvents(){if(!this.isLoading){this.fetchPromise=(async()=>{this.isLoading=1;try{const t=await this.fetchWithRetry("data/events.json",3);if(!t.ok)throw Error("HTTP error! status:"+t.status);this.persianCalendarData=await t.json(),this.saveToCache(this.persianCalendarData);const e=this.mapPersianCalendarEvents();this.mappedEvents=[...e];const i=new Date,r=o.gregorianToJalali(i.getFullYear(),i.getMonth()+1,i.getDate());this.lastFetchYear=r[0]}catch(t){}finally{this.isLoading=0}})();try{await this.fetchPromise}finally{this.fetchPromise=""[0]}}return[...this.mappedEvents]}}c.instance=""[0],c.initializationPromise=""[0];const l=c,p=["Iran","AncientIran","International"];class u extends HTMLElement{toPersianNum(t){const e=["\u06f0","\u06f1","\u06f2","\u06f3","\u06f4","\u06f5","\u06f6","\u06f7","\u06f8","\u06f9"];return(""+t).replace(/\d/g,(t=>e[parseInt(t)]))}static get observedAttributes(){return["placeholder","rtl","format","show-holidays","holiday-types","event-types","show-events","today-button-text","today-button-class","tomorrow-button-text","tomorrow-button-class","min-date","max-date","disabled-dates","range-mode","show-month-selector","show-year-selector","show-prev-button","show-next-button","show-today-button","show-tomorrow-button"]}constructor(t={}){if(super(),this.jalaliYear=0,this.jalaliMonth=0,this.jalaliDay=0,this.selectedDate=""[0],this.isRangeMode=0,this.rangeStart=""[0],this.rangeEnd=""[0],this.isSelectingRange=0,this.showEvents=1,this.eventTypes=[...p],this.includeAllTypes=0,this.isTransitioning=0,this.t=()=>{},this.persianMonths=["\u0641\u0631\u0648\u0631\u062f\u06cc\u0646","\u0627\u0631\u062f\u06cc\u0628\u0647\u0634\u062a","\u062e\u0631\u062f\u0627\u062f","\u062a\u06cc\u0631","\u0645\u0631\u062f\u0627\u062f","\u0634\u0647\u0631\u06cc\u0648\u0631","\u0645\u0647\u0631","\u0622\u0628\u0627\u0646","\u0622\u0630\u0631","\u062f\u06cc","\u0628\u0647\u0645\u0646","\u0627\u0633\u0641\u0646\u062f"],this.holidayTypeLabels={Iran:"\u0627\u06cc\u0631\u0627\u0646",Afghanistan:"\u0627\u0641\u063a\u0627\u0646\u0633\u062a\u0627\u0646",AncientIran:"\u0627\u06cc\u0631\u0627\u0646 \u0628\u0627\u0633\u062a\u0627\u0646",International:"\u0628\u06cc\u0646\u200c\u0627\u0644\u0645\u0644\u0644\u06cc"},this.format="YYYY/MM/DD",this.minDate=""[0],this.maxDate=""[0],this.disabledDatesFn=""[0],this.handleInputClick=t=>{t.stopPropagation(),this.toggleCalendar()},this.handleDocumentClick=t=>{this.calendar&&this.calendar.classList.contains("visible")&&(t.composedPath().includes(this)||(this.closeAllDropdowns(),this.toggleCalendar()))},this.i=0,this.h=0,this.l=0,this.p=0,this.options=t,this.eventUtils=l.getInstance(),void 0!==t.showEvents&&(this.showEvents=t.showEvents),t.format&&(this.format=t.format),void 0!==t.rtl&&this.style.setProperty("--jdp-direction",t.rtl?"rtl":"ltr"),void 0!==t.rangeMode&&(this.isRangeMode=t.rangeMode),t.rangeStart&&(this.rangeStart=t.rangeStart),t.rangeEnd&&(this.rangeEnd=t.rangeEnd),t.minDate&&(this.minDate=t.minDate),t.maxDate&&(this.maxDate=t.maxDate),t.disabledDates)if("function"==typeof t.disabledDates)this.disabledDatesFn=t.disabledDates;else if("string"==typeof t.disabledDates){const e=window[t.disabledDates];"function"==typeof e&&(this.disabledDatesFn=e)}t.defaultDate&&(this.selectedDate=t.defaultDate,this.jalaliYear=t.defaultDate[0],this.jalaliMonth=t.defaultDate[1],this.jalaliDay=t.defaultDate[2]);const e=this.attachShadow({mode:"open"});this.render(e),t.showEvents&&t.eventTypes&&this.seteventTypes(t.eventTypes)}async connectedCallback(){try{if(!this.shadowRoot)return;this.initializeDomReferences(),this.initializeCurrentDate(),l.isInitialized()||await l.initialize(),this.initializeUIComponents(),this.addEventListeners(),this.initTouchGestures(),this.renderCalendar()}catch(t){}}disconnectedCallback(){if(this.t&&document.removeEventListener("click",this.t),u.openCalendarInstance===this&&(u.openCalendarInstance=""[0]),this.shadowRoot){this.input&&this.input.removeEventListener("click",this.handleInputClick),this.calendar&&this.calendar.removeEventListener("click",(t=>t.stopPropagation())),this.daysContainer&&this.daysContainer.removeEventListener("click",this.handleDayClick.bind(this));const t=this.shadowRoot.getElementById("prev-month"),e=this.shadowRoot.getElementById("next-month"),i=this.shadowRoot.getElementById("today-button"),r=this.shadowRoot.getElementById("tomorrow-button");t&&(t.removeEventListener("click",(()=>this.changeMonth(-1))),t.removeEventListener("touchstart",(t=>t.stopPropagation()))),e&&(e.removeEventListener("click",(()=>this.changeMonth(1))),e.removeEventListener("touchstart",(t=>t.stopPropagation()))),i&&i.removeEventListener("click",(()=>this.goToToday())),r&&r.removeEventListener("click",(()=>this.goToTomorrow())),this.calendar&&(this.calendar.removeEventListener("touchstart",this.handleTouchStart),this.calendar.removeEventListener("touchmove",this.handleTouchMove),this.calendar.removeEventListener("touchend",this.handleTouchEnd),this.calendar.removeEventListener("touchcancel",this.handleTouchCancel))}}attributeChangedCallback(t,e,i){if(e!==i&&this.shadowRoot)switch(t){case"placeholder":this.input&&(this.input.placeholder=i||"");break;case"rtl":this.style.setProperty("--jdp-direction",i!==""[0]&&"!1"!==i?"rtl":"ltr");break;case"show-holidays":case"show-events":this.showEvents=i!==""[0]&&"!1"!==i,this.calendar&&this.renderCalendar();break;case"holiday-types":case"event-types":i?this.seteventTypes(i):(this.eventTypes=[...p],this.includeAllTypes=0),this.calendar&&this.renderCalendar();break;case"format":i&&this.isValidFormat(i)&&(this.format=i,this.selectedDate&&this.formatAndSetValue());break;case"min-date":if(i)try{const[t,e,r]=JSON.parse(i);this.setMinDate(t,e,r)}catch(t){}else this.minDate=""[0];this.calendar&&this.renderCalendar();break;case"max-date":if(i)try{const[t,e,r]=JSON.parse(i);this.setMaxDate(t,e,r)}catch(t){}else this.maxDate=""[0];this.calendar&&this.renderCalendar();break;case"disabled-dates":if(i){let e=""[0];try{e="function"==typeof i?i:"function"==typeof this[i]?this[i]:window[i]}catch(t){}"function"==typeof e&&(this.disabledDatesFn=e)}else this.disabledDatesFn=""[0];this.calendar&&this.renderCalendar();break;case"today-button-text":case"tomorrow-button-text":this.updateButtonText(t,i);break;case"today-button-class":case"tomorrow-button-class":this.updateButtonClass(t,i);break;case"range-mode":this.isRangeMode=i!==""[0]&&"!1"!==i,this.calendar&&this.renderCalendar();break;case"show-month-selector":case"show-year-selector":case"show-prev-button":case"show-next-button":case"show-today-button":case"show-tomorrow-button":this.shadowRoot&&(this.render(this.shadowRoot),this.initializeDomReferences(),this.initializeUIComponents(),this.addEventListeners(),this.renderCalendar())}}updateButtonText(t,e){if(!this.shadowRoot)return;const i="today-button-text"===t?"\u0627\u0645\u0631\u0648\u0632":"\u0641\u0631\u062f\u0627",r=this.shadowRoot.getElementById("today-button-text"===t?"today-button":"tomorrow-button");r&&(r.textContent=e||i)}updateButtonClass(t,e){if(!this.shadowRoot)return;const i="today-button-class"===t?"today-button":"tomorrow-button",r=this.shadowRoot.getElementById("today-button-class"===t?"today-button":"tomorrow-button");r&&(r.className="date-nav-button "+i,e&&e.split(" ").forEach((t=>{t.trim()&&r.classList.add(t.trim())})))}initializeDomReferences(){if(this.shadowRoot){if(this.input=this.shadowRoot.getElementById("date-input"),this.calendar=this.shadowRoot.getElementById("calendar"),this.daysContainer=this.shadowRoot.getElementById("days-container"),this.dayNamesContainer=this.shadowRoot.getElementById("day-names"),!(this.input&&this.calendar&&this.daysContainer&&this.dayNamesContainer))throw Error("Failed to initialize required elements");if(this.options.placeholder)this.input.placeholder=this.options.placeholder;else{const t=this.getAttribute("placeholder");t&&(this.input.placeholder=t)}}}initializeCurrentDate(){const t=new Date,e=o.gregorianToJalali(t.getFullYear(),t.getMonth()+1,t.getDate());this.jalaliYear=e[0],this.jalaliMonth=e[1],this.jalaliDay=e[2],this.selectedDate=""[0]}initializeUIComponents(){this.initializeDayNames(),this.setupMonthYearSelectors()}initializeDayNames(){this.dayNamesContainer&&(this.dayNamesContainer.innerHTML="",["\u0634","\u06cc","\u062f","\u0633","\u0686","\u067e","\u062c"].forEach((t=>{const e=document.createElement("div");e.classList.add("day-name"),e.textContent=t,this.dayNamesContainer.appendChild(e)})))}setupMonthYearSelectors(){if(!this.shadowRoot)return;const t=this.shadowRoot.getElementById("month-select-trigger"),e=this.shadowRoot.getElementById("year-select-trigger"),i=this.shadowRoot.getElementById("month-select-value"),r=this.shadowRoot.getElementById("year-select-value"),s=this.shadowRoot.getElementById("month-select-content"),a=this.shadowRoot.getElementById("year-select-content");if(!(t&&e&&i&&r&&s&&a))return;s.innerHTML="",a.innerHTML="";const n=document.createDocumentFragment(),d=document.createDocumentFragment();this.persianMonths.forEach(((t,e)=>{const r=e+1,s=document.createElement("div");s.classList.add("select-item"),s.textContent=t,s.dataset.value=""+r,r===this.jalaliMonth&&(s.classList.add("selected"),i.textContent=t),s.addEventListener("click",(e=>{e.stopPropagation(),this.handleMonthChange(r,t),this.closeAllDropdowns()})),n.appendChild(s)}));const h=new Date,c=o.gregorianToJalali(h.getFullYear(),h.getMonth()+1,h.getDate())[0],l=c+50;for(let t=c-100;l>=t;t++){const e=document.createElement("div");e.classList.add("select-item"),e.textContent=this.toPersianNum(t),e.dataset.value=""+t,t===this.jalaliYear&&(e.classList.add("selected"),r.textContent=this.toPersianNum(t)),e.addEventListener("click",(e=>{e.stopPropagation(),this.handleYearChange(t),this.closeAllDropdowns()})),d.appendChild(e)}s.appendChild(n),a.appendChild(d),t.addEventListener("click",(t=>{t.stopPropagation(),this.toggleDropdown(s)})),e.addEventListener("click",(t=>{t.stopPropagation(),this.toggleDropdown(a)})),s.addEventListener("click",(t=>{t.stopPropagation()})),a.addEventListener("click",(t=>{t.stopPropagation()}))}addEventListeners(){this.shadowRoot&&this.input&&this.calendar&&(this.input.addEventListener("click",this.handleInputClick),this.setupNavigationButtons(),this.calendar.addEventListener("click",(t=>t.stopPropagation())),this.daysContainer.addEventListener("click",this.handleDayClick.bind(this)),this.calendar.addEventListener("click",(t=>{const e=t.target;e.closest(".select-trigger")||e.closest(".select-content")||this.closeAllDropdowns()})),this.t=this.handleDocumentClick.bind(this),document.addEventListener("click",this.t))}handleDayClick(t){const e=t.target.closest(".day");if(!e||e.classList.contains("empty")||e.classList.contains("disabled")||this.isDateDisabled(this.jalaliYear,this.jalaliMonth,parseInt(e.textContent||"0")))return;t.stopPropagation();const i=e.textContent;if(!i)return;const r=this.fromPersianNum(i);isNaN(r)||this.handleRangeSelection(r)}fromPersianNum(t){const e=["\u06f0","\u06f1","\u06f2","\u06f3","\u06f4","\u06f5","\u06f6","\u06f7","\u06f8","\u06f9"];return parseInt(t.replace(/[\u06f0-\u06f9]/g,(t=>""+e.indexOf(t))))}setupNavigationButtons(){if(!this.shadowRoot)return;const t=this.shadowRoot.getElementById("prev-month"),e=this.shadowRoot.getElementById("next-month"),i=this.shadowRoot.getElementById("today-button"),r=this.shadowRoot.getElementById("tomorrow-button"),s=(t,e)=>{t&&t.addEventListener("click",(t=>{t.stopPropagation(),this.closeAllDropdowns(),e()}))};s(t,(()=>this.changeMonth(-1))),s(e,(()=>this.changeMonth(1))),s(i,(()=>this.goToToday())),s(r,(()=>this.goToTomorrow()))}seteventTypes(t){if("string"==typeof t){if("all"===t.toLowerCase())return this.includeAllTypes=1,void(this.eventTypes=[...this.eventUtils.getEventTypes()]);try{const e=JSON.parse(t);this.eventTypes=Array.isArray(e)?e:t.split(",").map((t=>t.trim())).filter(Boolean)}catch(e){this.eventTypes=t.split(",").map((t=>t.trim())).filter(Boolean)}}else this.eventTypes=Array.isArray(t)?[...t]:[...p];this.includeAllTypes=0,this.calendar&&this.renderCalendar()}geteventTypes(){return[...this.eventTypes]}isShowingAllTypes(){return this.includeAllTypes}render(t){const e=this.getAttribute("today-button-text")||"\u0627\u0645\u0631\u0648\u0632",i=this.getAttribute("today-button-class")||"",r=this.getAttribute("tomorrow-button-text")||"\u0641\u0631\u062f\u0627",s=this.getAttribute("tomorrow-button-class")||"",a="!1"!==this.getAttribute("show-month-selector"),o="!1"!==this.getAttribute("show-year-selector"),n="!1"!==this.getAttribute("show-prev-button"),d="!1"!==this.getAttribute("show-next-button"),h="!1"!==this.getAttribute("show-today-button"),c="!1"!==this.getAttribute("show-tomorrow-button"),l='<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>';t.innerHTML=`<style>:host{--jdp-primary:#0891b2;--jdp-primary-hover:#0e7490;--jdp-primary-foreground:#ffffff;--jdp-background:#ffffff;--jdp-foreground:#1e293b;--jdp-muted:#f1f5f9;--jdp-muted-foreground:#64748b;--jdp-border:#e2e8f0;--jdp-ring:#0284c7;--jdp-holiday-color:#ef4444;--jdp-holiday-bg:#fee2e2;--jdp-holiday-hover-bg:#fecaca;--jdp-range-bg:rgba(8, 145, 178, 0.1);--jdp-range-color:var(--jdp-foreground);--jdp-range-start-bg:var(--jdp-primary);--jdp-range-start-color:var(--jdp-primary-foreground);--jdp-range-end-bg:var(--jdp-primary);--jdp-range-end-color:var(--jdp-primary-foreground);--jdp-font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--jdp-font-size:14px;--jdp-line-height:1.5;--jdp-font-weight:400;--jdp-font-weight-medium:500;--jdp-day-name-font-size:12px;--jdp-day-name-font-weight:400;--jdp-day-font-size:13px;--jdp-day-font-weight:400;--jdp-month-year-font-size:14px;--jdp-month-year-font-weight:500;--jdp-spacing-xs:4px;--jdp-spacing-sm:8px;--jdp-spacing-md:16px;--jdp-spacing-lg:24px;--jdp-input-padding-x:14px;--jdp-input-padding-y:10px;--jdp-input-border-width:1px;--jdp-input-border-color:var(--jdp-border);--jdp-input-border-radius:var(--jdp-border-radius);--jdp-input-focus-ring-width:2px;--jdp-input-focus-ring-color:rgba(2, 132, 199, 0.25);--jdp-calendar-width:280px;--jdp-calendar-padding:var(--jdp-spacing-md);--jdp-calendar-border-width:1px;--jdp-calendar-border-color:var(--jdp-border);--jdp-calendar-border-radius:var(--jdp-border-radius);--jdp-calendar-shadow:0px 10px 38px-10px rgba(22, 23, 24, 0.35), 0px 10px 20px-15px rgba(22, 23, 24, 0.2);--jdp-calendar-z-index:10;--jdp-nav-button-size:30px;--jdp-nav-button-bg:var(--jdp-muted);--jdp-nav-button-bg-hover:var(--jdp-border);--jdp-nav-button-border-radius:var(--jdp-border-radius);--jdp-nav-arrow-size:8px;--jdp-nav-arrow-thickness:2px;--jdp-nav-arrow-color:var(--jdp-foreground);--jdp-day-cell-size:32px;--jdp-day-cell-margin:1px;--jdp-day-cell-border-radius:var(--jdp-border-radius);--jdp-day-hover-bg:var(--jdp-muted);--jdp-day-selected-bg:var(--jdp-primary);--jdp-day-selected-color:var(--jdp-primary-foreground);--jdp-day-today-border-color:var(--jdp-primary);--jdp-day-today-border-width:1px;--jdp-day-disabled-opacity:0.4;--jdp-transition-duration:0.2s;--jdp-fade-from-y:-4px;--jdp-fade-from-y-reverse:4px;--jdp-month-transition-duration:0.3s;--jdp-border-radius:0.5rem;--jdp-direction:rtl;--jdp-header-gap:var(--jdp-spacing-xs);--jdp-select-container-gap:8px;--jdp-select-trigger-height:var(--jdp-nav-button-size);--jdp-select-trigger-bg:var(--jdp-muted);--jdp-select-trigger-max-width:110px;--jdp-select-month-trigger-max-width:var(--jdp-select-trigger-max-width);--jdp-select-year-trigger-max-width:var(--jdp-select-trigger-max-width);--jdp-select-dropdown-width:auto;--jdp-select-text-overflow:ellipsis;--jdp-scrollbar-width:4px;--jdp-scrollbar-track:transparent;--jdp-scrollbar-thumb:rgba(0, 0, 0, 0.15);--jdp-scrollbar-thumb-hover:rgba(0, 0, 0, 0.25);--jdp-scrollbar-border-radius:4px}*{box-sizing:border-box;direction:var(--jdp-direction)}.picker-container{position:relative;display:inline-block;width:100%;font-family:var(--jdp-font-family);font-size:var(--jdp-font-size);line-height:var(--jdp-line-height);font-weight:var(--jdp-font-weight)}input{width:100%;padding:var(--jdp-input-padding-y) var(--jdp-input-padding-x);border-radius:var(--jdp-input-border-radius);border:var(--jdp-input-border-width) solid var(--jdp-input-border-color);font-size:var(--jdp-font-size);line-height:var(--jdp-line-height);font-family:inherit;background-color:var(--jdp-background);color:var(--jdp-foreground);cursor:pointer;outline:none;transition:all var(--jdp-transition-duration) ease;text-align:right}input:focus{border-color:var(--jdp-ring);box-shadow:0 0 0 var(--jdp-input-focus-ring-width) var(--jdp-input-focus-ring-color)}.calendar{display:none;position:absolute;right:0;width:var(--jdp-calendar-width);background:var(--jdp-background);border:var(--jdp-calendar-border-width) solid var(--jdp-calendar-border-color);border-radius:var(--jdp-calendar-border-radius);box-shadow:var(--jdp-calendar-shadow);padding:var(--jdp-calendar-padding);text-align:center;z-index:var(--jdp-calendar-z-index);touch-action:manipulation;-webkit-user-select:none;user-select:none;transform:translateZ(0);will-change:transform;backface-visibility:hidden;contain:layout style}.calendar.position-bottom{top:calc(100%+5px);animation:fadeInFromTop var(--jdp-transition-duration) ease}.calendar.position-top{bottom:calc(100%+5px);animation:fadeInFromBottom var(--jdp-transition-duration) ease}.calendar.visible{display:block}@keyframes fadeInFromTop{from{opacity:0;transform:translateY(var(--jdp-fade-from-y))}to{opacity:1;transform:translateY(0)}}@keyframes fadeInFromBottom{from{opacity:0;transform:translateY(var(--jdp-fade-from-y-reverse))}to{opacity:1;transform:translateY(0)}}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--jdp-spacing-md);gap:var(--jdp-header-gap, var(--jdp-spacing-xs))}.month-year{font-weight:var(--jdp-month-year-font-weight);font-size:var(--jdp-month-year-font-size);color:var(--jdp-foreground);transition:opacity var(--jdp-transition-duration) ease}.month-year.fade{opacity:0}.days-wrapper{position:relative;touch-action:pan-y;overflow:visible;z-index:1;contain:layout;isolation:isolate}.days{display:grid;grid-template-columns:repeat(7, 1fr);transition:transform var(--jdp-month-transition-duration) ease, opacity var(--jdp-month-transition-duration) ease;will-change:transform, opacity;transform:translateZ(0);backface-visibility:hidden;position:relative;contain:layout}.days.slide-left{animation:slideInLeft var(--jdp-month-transition-duration) ease}.days.slide-right{animation:slideInRight var(--jdp-month-transition-duration) ease}@keyframes slideInLeft{from{opacity:0;transform:translateX(-10%) translateZ(0);pointer-events:none}to{opacity:1;transform:translateX(0) translateZ(0);pointer-events:auto}}@keyframes slideInRight{from{opacity:0;transform:translateX(10%) translateZ(0);pointer-events:none}to{opacity:1;transform:translateX(0) translateZ(0);pointer-events:auto}}.day{position:relative;z-index:1;touch-action:manipulation;isolation:isolate}.day:hover{z-index:2}.nav-button{background:var(--jdp-nav-button-bg);border:none;border-radius:var(--jdp-nav-button-border-radius);width:var(--jdp-nav-button-size);height:var(--jdp-nav-button-size);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--jdp-transition-duration) ease;position:relative;touch-action:manipulation;will-change:transform, background-color}.nav-button:hover{background:var(--jdp-nav-button-bg-hover)}.nav-button:active{transform:translateY(1px)}.nav-button::before{content:'';display:block;width:var(--jdp-nav-arrow-size);height:var(--jdp-nav-arrow-size);border-top:var(--jdp-nav-arrow-thickness) solid var(--jdp-nav-arrow-color);border-right:var(--jdp-nav-arrow-thickness) solid var(--jdp-nav-arrow-color);position:absolute}.nav-button.prev::before{transform:rotate(45deg);right:11px;left:auto}.nav-button.next::before{transform:rotate(225deg);left:11px;right:auto}.day-names{display:grid;grid-template-columns:repeat(7, 1fr);margin-bottom:var(--jdp-spacing-sm)}.day-name{font-size:var(--jdp-day-name-font-size);font-weight:var(--jdp-day-name-font-weight);color:var(--jdp-muted-foreground);padding:var(--jdp-spacing-xs) 0;text-align:center}.day{aspect-ratio:1/1;display:flex;align-items:center;justify-content:center;border-radius:var(--jdp-day-cell-border-radius);font-size:var(--jdp-day-font-size);font-weight:var(--jdp-day-font-weight);cursor:pointer;transition:var(--jdp-transition-duration) ease;margin:var(--jdp-day-cell-margin);position:relative;touch-action:manipulation;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}.day:hover:not(.empty):not(.disabled){background:var(--jdp-day-hover-bg)}.day.selected{background:var(--jdp-day-selected-bg);color:var(--jdp-day-selected-color)}.day.today:not(.selected){border:var(--jdp-day-today-border-width) solid var(--jdp-day-today-border-color)}.day.empty{cursor:default}.day.disabled{opacity:var(--jdp-day-disabled-opacity);cursor:not-allowed} .day.holiday:not(.selected){color:var(--jdp-holiday-color);background-color:var(--jdp-holiday-bg);font-weight:var(--jdp-font-weight-medium)}.day.holiday:hover:not(.selected):not(.disabled){background-color:var(--jdp-holiday-hover-bg)} .day.holiday.in-range{background-color:var(--jdp-range-bg);color:var(--jdp-range-color)}.day.holiday.range-start, .day.holiday.range-end{background-color:var(--jdp-range-start-bg);color:var(--jdp-range-start-color)}.day.friday{color:var(--jdp-holiday-color)}.event-tooltip{position:absolute;background:var(--jdp-background);border:1px solid var(--jdp-border);border-radius:var(--jdp-border-radius);padding:var(--jdp-spacing-sm);width:200px;box-shadow:var(--jdp-calendar-shadow);text-align:right;font-size:12px;opacity:0;visibility:hidden;transition:opacity var(--jdp-transition-duration) ease, visibility var(--jdp-transition-duration) ease;pointer-events:none;bottom:120%;right:0;transform:translateY(-5px);z-index:9999}.event-tooltip.tooltip-visible{opacity:1;visibility:visible;pointer-events:auto;background:var(--jdp-background)} @media (max-width:768px){.event-tooltip{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:90%;max-width:300px;max-height:80vh;overflow-y:auto;bottom:auto;right:auto;background:var(--jdp-background);z-index:9999}.event-tooltip::before{content:'';position:fixed;top:0;left:0;right:0;bottom:0;z-index:-1}}.event-item{margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid var(--jdp-border);color:var(--jdp-foreground);background:var(--jdp-background)}.event-item:last-child{margin-bottom:0;padding-bottom:0;border-bottom:none}.event-item.holiday{color:var(--jdp-holiday-color)}.event-type-label{display:inline-block;font-size:10px;padding:1px 4px;border-radius:3px;margin-right:4px;background-color:var(--jdp-muted);color:var(--jdp-muted-foreground)} .footer{margin-top:var(--jdp-spacing-md);display:flex;justify-content:space-between}.date-nav-button{background:var(--jdp-muted);border:none;border-radius:var(--jdp-border-radius);padding:var(--jdp-spacing-xs) var(--jdp-spacing-md);font-family:inherit;font-size:var(--jdp-font-size);color:var(--jdp-foreground);cursor:pointer;transition:all var(--jdp-transition-duration) ease;touch-action:manipulation;-webkit-tap-highlight-color:transparent}.date-nav-button:hover{background:var(--jdp-nav-button-bg-hover)}.date-nav-button:active{transform:translateY(1px)} :host .selectors-container{display:flex;gap:var(--jdp-select-container-gap, 8px);position:relative;align-items:var(--jdp-select-container-align, center);justify-content:var(--jdp-select-container-justify, space-between);width:100%;max-width:calc(100%-var(--jdp-nav-button-size)*2-var(--jdp-spacing-sm));margin:0 var(--jdp-spacing-xs)}:host .custom-select{position:relative;user-select:none;width:100%;margin:0 var(--jdp-spacing-xs, 2px)}:host .month-select{margin-left:var(--jdp-month-select-margin-left, 0);margin-right:var(--jdp-month-select-margin-right, 0)}:host .year-select{margin-left:var(--jdp-year-select-margin-left, 0);margin-right:var(--jdp-year-select-margin-right, 0)}:host .select-trigger{display:flex;align-items:center;justify-content:var(--jdp-select-trigger-justify, center);gap:0 4px;width:100%;height:var(--jdp-select-trigger-height, var(--jdp-nav-button-size));min-height:var(--jdp-nav-button-size);background-color:var(--jdp-select-trigger-bg, var(--jdp-muted));border:var(--jdp-select-trigger-border-width, 1px) solid var(--jdp-select-trigger-border-color, var(--jdp-border));border-radius:var(--jdp-select-trigger-border-radius, var(--jdp-border-radius));color:var(--jdp-select-trigger-color, var(--jdp-foreground));font-family:inherit;font-size:var(--jdp-select-trigger-font-size, var(--jdp-font-size));line-height:1;padding:0 var(--jdp-select-trigger-padding-x, 0);cursor:pointer;transition:all var(--jdp-transition-duration) ease;text-align:var(--jdp-select-trigger-text-align, center);min-width:var(--jdp-select-trigger-min-width, initial);outline:none;font-weight:var(--jdp-select-trigger-font-weight, 500);box-sizing:border-box;max-width:var(--jdp-select-trigger-max-width, 110px)}:host .month-select .select-trigger{max-width:var(--jdp-select-month-trigger-max-width, var(--jdp-select-trigger-max-width))}:host .year-select .select-trigger{max-width:var(--jdp-select-year-trigger-max-width, var(--jdp-select-trigger-max-width))}:host .select-trigger span:first-child{white-space:nowrap;overflow:var(--jdp-select-trigger-overflow, visible);text-overflow:var(--jdp-select-text-overflow, ellipsis);max-width:calc(100%-24px);display:inline-block;text-align:center;flex:1}:host .select-trigger:hover{background-color:var(--jdp-select-trigger-bg-hover, rgba(0, 0, 0, 0.05));border-color:var(--jdp-select-trigger-border-hover, var(--jdp-border))}:host .select-trigger:focus-visible{outline:2px solid var(--jdp-select-trigger-focus-ring-color, var(--jdp-ring));outline-offset:var(--jdp-select-trigger-focus-ring-offset, 2px)}:host .select-icon{margin-left:var(--jdp-select-icon-margin, var(--jdp-spacing-xs));display:var(--jdp-select-icon-display, none);justify-content:center;align-items:center;transition:transform 0.2s ease;width:var(--jdp-select-icon-size, 12px);height:var(--jdp-select-icon-size, 12px);opacity:var(--jdp-select-icon-opacity, 0.7);flex-shrink:0}:host .select-icon svg{width:var(--jdp-select-icon-size, 12px);height:var(--jdp-select-icon-size, 12px)}:host .select-content.open .select-icon{transform:rotate(180deg)}:host .select-content{position:var(--jdp-select-content-position, absolute);top:calc(100%+var(--jdp-select-content-top-offset, 5px));left:0;width:var(--jdp-select-dropdown-width, 100%);min-width:100%;background-color:var(--jdp-select-content-bg, var(--jdp-background));border:var(--jdp-select-content-border-width, 1px) solid var(--jdp-select-content-border-color, var(--jdp-border));border-radius:var(--jdp-select-content-border-radius, var(--jdp-border-radius));box-shadow:var(--jdp-select-content-shadow, 0 4px 8px rgba(0,0,0,0.1));z-index:var(--jdp-select-content-z-index, 20);overflow-y:auto;max-height:var(--jdp-select-content-max-height, 200px);display:none;padding:var(--jdp-select-content-padding-y, 0.25rem) var(--jdp-select-content-padding-x, 0);scroll-behavior:smooth; scrollbar-width:var(--jdp-scrollbar-width-size, none);scrollbar-color:var(--jdp-scrollbar-thumb, rgba(0, 0, 0, 0.15)) var(--jdp-scrollbar-track, transparent)} :host .select-content::-webkit-scrollbar{width:var(--jdp-scrollbar-width, 4px)}:host .select-content::-webkit-scrollbar-track{background:var(--jdp-scrollbar-track, transparent);border-radius:var(--jdp-scrollbar-border-radius, 4px)}:host .select-content::-webkit-scrollbar-thumb{background-color:var(--jdp-scrollbar-thumb, rgba(0, 0, 0, 0.15));border-radius:var(--jdp-scrollbar-border-radius, 4px)}:host .select-content::-webkit-scrollbar-thumb:hover{background-color:var(--jdp-scrollbar-thumb-hover, rgba(0, 0, 0, 0.25))}:host .select-content.open{display:block;animation:fadeInSelect var(--jdp-select-content-animation-duration, var(--jdp-transition-duration)) ease}:host .month-select-content{width:var(--jdp-select-month-width, var(--jdp-select-dropdown-width, auto));min-width:100%}:host .year-select-content{width:var(--jdp-select-year-width, var(--jdp-select-dropdown-width, auto));min-width:100%}:host .select-item{padding:var(--jdp-select-item-padding-y, 0.5rem) var(--jdp-select-item-padding-x, 0.75rem);cursor:pointer;transition:background-color var(--jdp-transition-duration) ease;border-radius:var(--jdp-select-item-border-radius, var(--jdp-select-trigger-border-radius, var(--jdp-border-radius)));margin:var(--jdp-select-item-margin, 0 0.25rem);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:var(--jdp-select-item-max-width, 100%);box-sizing:border-box;text-align:var(--jdp-select-item-text-align, center)}:host .select-item:hover{background-color:var(--jdp-select-item-hover-bg, var(--jdp-day-hover-bg))}:host .select-item.selected{background-color:var(--jdp-select-item-selected-bg, var(--jdp-primary));color:var(--jdp-select-item-selected-color, var(--jdp-primary-foreground));font-weight:var(--jdp-select-item-selected-font-weight, var(--jdp-font-weight-medium));border-radius:var(--jdp-select-item-selected-border-radius, var(--jdp-select-trigger-border-radius, var(--jdp-border-radius)))}@keyframes fadeInSelect{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}} :host([rtl="!0"]) .select-icon, :host([dir="rtl"]) .select-icon{margin-left:0;margin-right:var(--jdp-select-icon-margin, var(--jdp-spacing-xs))}:host([rtl="!0"]) .select-item, :host([dir="rtl"]) .select-item{text-align:var(--jdp-select-item-text-align, right)} @media (prefers-color-scheme:dark){:host{--jdp-scrollbar-thumb:rgba(124, 124, 124, 0.15);--jdp-scrollbar-thumb-hover:rgba(41, 41, 41, 0.25)}} :host(.dark-theme){--jdp-scrollbar-thumb:rgba(124, 124, 124, 0.15);--jdp-scrollbar-thumb-hover:rgba(41, 41, 41, 0.25)} .day.in-range{background-color:var(--jdp-range-bg);color:var(--jdp-range-color);position:relative;z-index:1;border-radius:0}.day.range-start, .day.range-end{background-color:var(--jdp-range-start-bg);color:var(--jdp-range-start-color);position:relative;z-index:2}.day.range-start{border-radius:0 var(--jdp-border-radius) var(--jdp-border-radius) 0}.day.range-end{border-radius:var(--jdp-border-radius) 0 0 var(--jdp-border-radius)} :host([rtl="!0"]) .day.range-start, :host([dir="rtl"]) .day.range-start{border-radius:var(--jdp-border-radius) 0 0 var(--jdp-border-radius)}:host([rtl="!0"]) .day.range-end, :host([dir="rtl"]) .day.range-end{border-radius:0 var(--jdp-border-radius) var(--jdp-border-radius) 0} .day.range-start.range-end{border-radius:var(--jdp-border-radius)} .day.in-range:not(.range-start):not(.range-end){background-color:var(--jdp-range-bg);color:var(--jdp-range-color);border-radius:0} .day.disabled.in-range{opacity:0.4;background-color:var(--jdp-range-bg);color:var(--jdp-range-color);border-radius:0} .day.holiday.in-range:not(.range-start):not(.range-end){background-color:var(--jdp-range-bg);color:var(--jdp-range-color);border-radius:0}.day.holiday.range-start, .day.holiday.range-end{background-color:var(--jdp-range-start-bg);color:var(--jdp-range-start-color)}</style> <div class="picker-container"> <input type="text" id="date-input" readonly placeholder="\u0627\u0646\u062a\u062e\u0627\u0628 \u062a\u0627\u0631\u06cc\u062e"> <div class="calendar" id="calendar"> <div class="header"> ${n?'<button id="prev-month" type="button" class="nav-button prev"></button>':""}\n <div class="selectors-container">\n ${a?`\n <div class="custom-select month-select" id="month-select-container">\n <button type="button" class="select-trigger" id="month-select-trigger">\n <span id="month-select-value"></span>\n <span class="select-icon">${l}</span>\n </button>\n <div class="select-content month-select-content" id="month-select-content"></div>\n </div>\n `:""}\n ${o?`\n <div class="custom-select year-select" id="year-select-container">\n <button type="button" class="select-trigger" id="year-select-trigger">\n <span id="year-select-value"></span>\n <span class="select-icon">${l}</span>\n </button>\n <div class="select-content year-select-content" id="year-select-content"></div>\n </div>\n `:""}\n </div>\n ${d?'<button id="next-month" type="button" class="nav-button next"></button>':""}\n </div>\n <div class="day-names" id="day-names"></div>\n <div class="days-wrapper">\n <div class="days" id="days-container"></div>\n </div>\n <div class="footer">\n ${h?`<button id="today-button" type="button" class="date-nav-button today-button ${i}">${e}</button>`:""}\n ${c?`<button id="tomorrow-button" type="button" class="date-nav-button tomorrow-button ${s}">${r}</button>`:""}\n </div>\n </div>\n </div>\n `}toggleCalendar(){this.closeAllDropdowns(),this.calendar.classList.contains("visible")?(this.calendar.classList.remove("visible","position-bottom","position-top"),u.openCalendarInstance===this&&(u.openCalendarInstance=""[0])):(u.openCalendarInstance&&u.openCalendarInstance!==this&&u.openCalendarInstance.toggleCalendar(),this.positionCalendar(),this.calendar.classList.add("visible"),u.openCalendarInstance=this)}positionCalendar(){if(!this.input||!this.calendar)return;this.calendar.classList.remove("position-bottom","position-top");const t=this.input.getBoundingClientRect(),e=window.innerHeight;this.calendar.classList.add("position-bottom");const i=this.calendar.style.visibility,r=this.calendar.style.display;this.calendar.style.visibility="hidden",this.calendar.style.display="block";const s=this.calendar.offsetHeight,a=e-t.bottom;if(s>a){const e=t.top;(e>a||e>=s)&&(this.calendar.classList.remove("position-bottom"),this.calendar.classList.add("position-top"))}this.calendar.style.visibility=i,this.calendar.style.display=r}changeMonth(t){if(this.isTransitioning)return;this.isTransitioning=1;const e=this.daysContainer,i=t>0?"slide-left":"slide-right";e.classList.add(i),this.jalaliMonth=+this.jalaliMonth+t,1>this.jalaliMonth?(this.jalaliMonth=12,this.jalaliYear--):this.jalaliMonth>12&&(this.jalaliMonth=1,this.jalaliYear++),requestAnimationFrame((()=>{setTimeout((()=>{this.updateMonthYearSelectors(),e.innerHTML="",this.renderCalendarContent(),requestAnimationFrame((()=>{e.classList.remove(i),setTimeout((()=>{this.isTransitioning=0}),50)}))}),200)}))}updateMonthYearSelectors(){if(!this.shadowRoot)return;const t=this.shadowRoot.getElementById("month-select-value"),e=this.shadowRoot.getElementById("year-select-value");t&&(t.textContent=this.persianMonths[this.jalaliMonth-1]),e&&(e.textContent=this.toPersianNum(this.jalaliYear)),this.shadowRoot.querySelectorAll(".month-select-content .select-item").forEach((t=>{t.getAttribute("data-value")===""+this.jalaliMonth?t.classList.add("selected"):t.classList.remove("selected")})),this.shadowRoot.querySelectorAll(".year-select-content .select-item").forEach((t=>{t.getAttribute("data-value")===""+this.jalaliYear?t.classList.add("selected"):t.classList.remove("selected")}))}renderCalendar(){if(this.shadowRoot&&this.daysContainer&&(this.updateMonthYearSelectors(),this.daysContainer.innerHTML="",this.renderCalendarContent(),this.isRangeMode)){const t=this.shadowRoot.querySelector(".footer");t&&t.remove()}}renderCalendarContent(){if(!this.daysContainer)return;const t=o.getDayOfWeek(this.jalaliYear,this.jalaliMonth,1),e=o.getDaysInMonth(this.jalaliYear,this.jalaliMonth),i=new Date,r=o.gregorianToJalali(i.getFullYear(),i.getMonth()+1,i.getDate()),s=(t+1)%7,a=document.createDocumentFragment();for(let t=0;s>t;t++){const t=document.createElement("div");t.classList.add("day","empty"),a.appendChild(t)}for(let t=1;e>=t;t++){const e=document.createElement("div");e.classList.add("day"),e.textContent=this.toPersianNum(t),e.dataset.day=""+t;const i=this.isDateInRange(this.jalaliYear,this.jalaliMonth,t),s=this.isDateDisabled(this.jalaliYear,this.jalaliMonth,t);if(i&&!s||(e.classList.add("disabled"),e.style.opacity="0.4",e.style.cursor="not-allowed"),this.jalaliYear===r[0]&&this.jalaliMonth===r[1]&&t===r[2]&&e.classList.add("today"),this.isRangeMode){const i=[this.jalaliYear,this.jalaliMonth,t];if(e.classList.remove("in-range","range-start","range-end"),this.rangeStart&&this.rangeEnd){const t=this.compareDates(i,this.rangeStart)>=0&&0>=this.compareDates(i,this.rangeEnd);0===this.compareDates(i,this.rangeStart)?(e.classList.add("range-start"),0===this.compareDates(i,this.rangeEnd)&&e.classList.add("range-end")):0===this.compareDates(i,this.rangeEnd)?e.classList.add("range-end"):t&&e.classList.add("in-range")}else this.rangeStart&&!this.rangeEnd&&0===this.compareDates(i,this.rangeStart)&&e.classList.add("range-start")}else this.selectedDate&&this.jalaliYear===this.selectedDate[0]&&this.jalaliMonth===this.selectedDate[1]&&t===this.selectedDate[2]&&e.classList.add("selected");this.showEvents&&this.addHolidayInfo(e,t),this.setupDayTooltips(e),this.setupDayClickHandler(e,t),a.appendChild(e)}this.daysContainer.appendChild(a)}compareDates(t,e){return t[0]!==e[0]?t[0]-e[0]:t[1]!==e[1]?t[1]-e[1]:t[2]-e[2]}setupDayTooltips(t){t.addEventListener("mouseenter",(()=>{const e=t.querySelector(".event-tooltip");e&&e.classList.add("tooltip-visible")})),t.addEventListener("mouseleave",(()=>{const e=t.querySelector(".event-tooltip");e&&e.classList.remove("tooltip-visible")}))}setupDayClickHandler(t,e){let i=0;t.addEventListener("click",(r=>{r.preventDefault(),r.stopPropagation();const s=(new Date).getTime(),a=s-i;if("ontouchstart"in window||navigator.maxTouchPoints>0)if(500>a&&a>0){const e=t.querySelector(".event-tooltip");if(e){const t=this.shadowRoot?.querySelectorAll(".event-tooltip.tooltip-visible");t?.forEach((t=>t.classList.remove("tooltip-visible"))),e.classList.add("tooltip-visible")}}else this.handleRangeSelection(e);else this.handleRangeSelection(e);i=s}))}addHolidayInfo(t,e){let i=0;if(5===o.getDayOfWeek(this.jalaliYear,this.jalaliMonth,e)&&(t.classList.add("friday"),i=1),this.eventUtils.isHoliday(this.jalaliMonth,e,this.eventTypes,this.includeAllTypes)){t.classList.add("holiday"),i=1;const r=this.eventUtils.getEvents(this.jalaliMonth,e,this.eventTypes,this.includeAllTypes);if(r.length>0){const e=this.createEventTooltip(r);t.appendChild(e)}}return i}createEventTooltip(t){const e=document.createElement("div");return e.classList.add("event-tooltip"),t.forEach((t=>{const i=document.createElement("div");i.classList.add("event-item"),t.holiday&&i.classList.add("holiday");const r=document.createElement("span");r.classList.add("event-type-label"),r.textContent=this.holidayTypeLabels[t.type]||t.type,i.appendChild(r);const s=document.createElement("span");s.textContent=t.title,i.appendChild(s),e.appendChild(i)})),e}navigateToDate(t){const e=o.gregorianToJalali(t.getFullYear(),t.getMonth()+1,t.getDate()),i=this.jalaliYear;this.jalaliYear=e[0],this.jalaliMonth=e[1],i!==this.jalaliYear&&this.eventUtils.refreshEvents(),this.renderCalendar(),this.selectDate(e[2])}goToToday(){this.navigateToDate(new Date)}goToTomorrow(){const t=new Date;t.setDate(t.getDate()+1),this.navigateToDate(t)}selectDate(t){if(this.isDateDisabled(this.jalaliYear,this.jalaliMonth,t)||!this.isDateInRange(this.jalaliYear,this.jalaliMonth,t))return;this.jalaliDay=t,this.selectedDate=[this.jalaliYear,this.jalaliMonth,this.jalaliDay],this.formatAndSetValue();const e=this.eventUtils.getEvents(this.jalaliMonth,t,this.eventTypes,this.includeAllTypes),i=this.formatDate(this.selectedDate,this.format),r=o.jalaliToGregorian(this.jalaliYear,this.jalaliMonth,this.jalaliDay),s=this.jalaliToISOString(this.selectedDate);this.dispatchEvent(new CustomEvent("change",{detail:{jalali:this.selectedDate,gregorian:r,isHoliday:this.eventUtils.isHoliday(this.jalaliMonth,t,this.eventTypes,this.includeAllTypes),events:e,formattedDate:i,isoString:s},bubbles:1})),this.closeAllDropdowns(),this.toggleCalendar(),this.renderCalendar()}formatAndSetValue(){if(this.isRangeMode){if(!this.rangeStart||!this.rangeEnd)return void(this.input.value="");const t=t=>{const[e,i,r]=t;return this.formatDate(t,this.format)};this.input.value=`${t(this.rangeStart)}-${t(this.rangeEnd)}`}else this.input.value=this.selectedDate?this.formatDate(this.selectedDate,this.format):""}formatDate(t,e){if(!t)return"";const[i,r,s]=t,a=this.handleSpecialFormat(e,i,r,s);return a!==""[0]?a:this.handleGeneralFormat(e,i,r,s)}handleSpecialFormat(t,e,i,r){const s={"YYYY/MM/DD":()=>`${this.toPersianNum(e)}/${this.toPersianNum((""+i).padStart(2,"0"))}/${this.toPersianNum((""+r).padStart(2,"0"))}`,"YYYY-MM-DD":()=>`${this.toPersianNum(e)}-${this.toPersianNum((""+i).padStart(2,"0"))}-${this.toPersianNum((""+r).padStart(2,"0"))}`,"YYYY/MM/DDth":()=>`${this.toPersianNum(e)}/${this.toPersianNum((""+i).padStart(2,"0"))}/${this.toPersianNum(r)}\u0627\u0645`};return s[t]?.()||""[0]}handleGeneralFormat(t,e,i,r){const s=t.split(/(\s+)/),a=[];for(let t=0;s.length>t;t++){const o=s[t];if(!o.trim()){a.push(o);continue}let n=this.replaceFormatTokens(o,e,i,r);a.push(n),s.length-1>t&&s[t+1].trim()&&a.push(" ")}return a.join("")}replaceFormatTokens(t,e,i,r){let s=t;return s.includes("dddd")&&(s=s.replace("dddd",this.getWeekdayName(e,i,r))),s.includes("MMMM")?s=s.replace("MMMM",this.persianMonths[i-1]):s.includes("MMM")&&(s=s.replace("MMM",this.persianMonths[i-1].substring(0,3))),s=s.replace("YYYY",this.toPersianNum(e)),s=s.replace("MM",this.toPersianNum((""+i).padStart(2,"0"))),s=s.replace("DD",this.toPersianNum((""+r).padStart(2,"0"))),s.includes("th")&&(s=s.replace("th","\u0627\u0645")),s}isValidFormat(t){const e=t.includes("YYYY"),i=t.includes("MM"),r=t.includes("DD"),s=/[^YMD\/\-\. dth]/g.test(t);return"YYYY/MM"===t||"DD/MM"===t||"DD.MM.YYYY"===t||"YYYY/MM/DDth"===t||[e,i,r].filter(Boolean).length>=2&&!s}getWeekdayName(t,e,i){return["\u0634\u0646\u0628\u0647","\u06cc\u06a9\u0634\u0646\u0628\u0647","\u062f\u0648\u0634\u0646\u0628\u0647","\u0633\u0647\u200c\u0634\u0646\u0628\u0647","\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647","\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647","\u062c\u0645\u0639\u0647"][new Date(t,e-1,i).getDay()]}handleMonthChange(t,e){this.jalaliMonth!==t&&(this.jalaliMonth=t,this.renderCalendar())}handleYearChange(t){if(this.jalaliYear===t)return;const e=this.jalaliYear;this.jalaliYear=t,e!==t&&this.eventUtils.refreshEvents(),this.renderCalendar()}setValue(t,e,i){this.selectedDate=[t,e,i],this.jalaliYear=t,this.jalaliMonth=e,this.jalaliDay=i,this.formatAndSetValue(),this.renderCalendar()}getValue(){return this.selectedDate?[...this.selectedDate]:""[0]}isSelectedDateHoliday(){return!!this.selectedDate&&this.eventUtils.isHoliday(this.selectedDate[1],this.selectedDate[2],this.eventTypes,this.includeAllTypes)}getSelectedDateEvents(){return this.selectedDate?[...this.eventUtils.getEvents(this.selectedDate[1],this.selectedDate[2],this.eventTypes,this.includeAllTypes)]:[]}clear(){this.isRangeMode?(this.rangeStart=""[0],this.rangeEnd=""[0]):this.selectedDate=""[0],this.input.value="",this.renderCalendar()}initTouchGestures(){if(!this.calendar||!this.shadowRoot)return;let t=0,e=0,i=0,r=0,s=1;this.calendar.addEventListener("touchstart",(a=>{if(!this.calendar?.classList.contains("visible"))return;const o=a.touches[0];t=o.clientX,e=o.clientY,i=Date.now(),r=0