advanced-filter-system 1.0.5 → 1.0.7
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.
- package/README.md +452 -194
- package/dist/AFS.esm.js +4542 -637
- package/dist/AFS.esm.js.map +1 -1
- package/dist/AFS.js +4543 -637
- package/dist/AFS.js.map +1 -1
- package/dist/AFS.min.js +1 -1
- package/dist/AFS.min.js.map +1 -1
- package/package.json +1 -1
package/dist/AFS.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).AFS={})}(this,(function(t){"use strict";function e(t,e){let s;return function(){for(var i=arguments.length,r=new Array(i),o=0;o<i;o++)r[o]=arguments[o];clearTimeout(s),s=setTimeout((()=>{clearTimeout(s),t(...r)}),e)}}t.AFS=class{constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.options={containerSelector:".filter-container",itemSelector:".filter-item",filterButtonSelector:".btn-filter",searchInputSelector:".filter-search",counterSelector:".filter-counter",activeClass:"active",hiddenClass:"hidden",animationDuration:300,filterMode:"OR",searchKeys:["title"],debounceTime:300,...t},this.container=document.querySelector(this.options.containerSelector),this.items=document.querySelectorAll(this.options.itemSelector),this.filterButtons=document.querySelectorAll(this.options.filterButtonSelector),this.searchInput=document.querySelector(this.options.searchInputSelector),this.counter=document.querySelector(this.options.counterSelector),this.currentFilters=new Set(["*"]),this.currentSearch="",this.visibleItems=new Set(this.items),this.filterGroups=new Map,this.groupMode="OR",this.init()}init(){this.addStyles(),this.bindEvents(),this.loadFromURL(),this.updateCounter()}addStyles(){const t=`\n .${this.options.hiddenClass} {\n display: none !important;\n }\n\n ${this.options.itemSelector} {\n opacity: 1;\n transform: scale(1);\n transition: opacity ${this.options.animationDuration}ms ease-out,\n transform ${this.options.animationDuration}ms ease-out;\n }\n\n ${this.options.filterButtonSelector} {\n opacity: 0.5;\n transition: opacity ${this.options.animationDuration}ms ease;\n }\n\n ${this.options.filterButtonSelector}.${this.options.activeClass} {\n opacity: 1;\n }\n `,e=document.createElement("style");e.textContent=t,document.head.appendChild(e)}bindEvents(){this.filterButtons.forEach((t=>{t.addEventListener("click",(()=>this.handleFilterClick(t)))})),this.searchInput&&this.searchInput.addEventListener("input",e((t=>{this.search(t.target.value)}),this.options.debounceTime)),window.addEventListener("popstate",(()=>this.loadFromURL()))}handleFilterClick(t){const e=t.dataset.filter;"*"===e?this.resetFilters():this.toggleFilter(e,t),this.filter(),this.updateURL()}resetFilters(){this.filterButtons.forEach((t=>t.classList.remove(this.options.activeClass))),this.currentFilters.clear(),this.currentFilters.add("*"),this.filterButtons[0].classList.add(this.options.activeClass),this.resetCounter()}resetCounter(){this.visibleItems=new Set(this.items),this.updateCounter()}toggleFilter(t,e){if(this.currentFilters.delete("*"),this.filterButtons[0].classList.remove(this.options.activeClass),e.classList.contains(this.options.activeClass)){if(e.classList.remove(this.options.activeClass),this.currentFilters.delete(t),0===this.currentFilters.size)return this.resetFilters(),void window.history.pushState({},"",window.location.pathname)}else e.classList.add(this.options.activeClass),this.currentFilters.add(t)}filter(){const t=()=>{this.visibleItems.clear(),this.items.forEach((t=>{if(this.currentFilters.has("*"))this.showItem(t),this.visibleItems.add(t);else{const e=new Set(t.dataset.categories?.split(" ")||[]);("OR"===this.options.filterMode?this.matchesAnyFilter(e):this.matchesAllFilters(e))?(this.showItem(t),this.visibleItems.add(t)):this.hideItem(t)}}))};0===this.filterGroups.size?t():(this.visibleItems.clear(),this.items.forEach((t=>{if(this.currentFilters.has("*"))this.showItem(t),this.visibleItems.add(t);else{const e=new Set(t.dataset.categories?.split(" ")||[]);this.matchesFilterGroups(e)?(this.showItem(t),this.visibleItems.add(t)):this.hideItem(t)}}))),setTimeout((()=>{this.updateCounter()}),this.options.animationDuration)}addFilterGroup(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"OR";try{if(!t||!Array.isArray(e))return console.warn("Invalid group parameters"),!1;const i=s.toUpperCase();return["AND","OR"].includes(i)||(console.warn('Invalid operator. Using default "OR"'),s="OR"),this.filterGroups.set(t,{filters:new Set(e),operator:i}),this.filterGroups.size>0&&(this.updateFiltersFromGroups(),this.filter(),this.updateURL()),!0}catch(t){return console.error("Error adding filter group:",t),!1}}setGroupMode(t){const e=t.toUpperCase();["AND","OR"].includes(e)&&(this.groupMode=e,this.filterGroups.size>0&&this.filter())}removeFilterGroup(t){return!!this.filterGroups.has(t)&&(this.filterGroups.delete(t),0===this.filterGroups.size?this.resetFilters():this.updateFiltersFromGroups(),this.filter(),this.updateURL(),!0)}updateFiltersFromGroups(){if(0!==this.filterGroups.size){this.currentFilters.has("*")||this.currentFilters.clear();for(const t of this.filterGroups.values())t.filters.forEach((t=>{"*"!==t&&this.currentFilters.add(t)}))}}matchesAnyFilter(t){return[...this.currentFilters].some((e=>{const[s,i]=e.split(":");return t.has(`${s}:${i}`)}))}matchesAllFilters(t){return[...this.currentFilters].every((e=>{const[s,i]=e.split(":");return t.has(`${s}:${i}`)}))}showItem(t){this.visibleItems.add(t),t.classList.remove(this.options.hiddenClass),t.style.opacity="0",t.style.transform="scale(0.95)",t.offsetHeight,requestAnimationFrame((()=>{t.style.opacity="1",t.style.transform="scale(1)"}))}hideItem(t){t.style.opacity="0",t.style.transform="scale(0.95)",setTimeout((()=>{"0"===t.style.opacity&&(t.classList.add(this.options.hiddenClass),this.visibleItems.delete(t))}),this.options.animationDuration)}search(t){this.currentSearch=t.toLowerCase().trim(),this.items.forEach((t=>{const e=this.options.searchKeys.map((e=>t.dataset[e]||"")).join(" ").toLowerCase();""===this.currentSearch||e.includes(this.currentSearch)?this.showItem(t):this.hideItem(t)})),this.updateURL(),setTimeout((()=>{this.updateCounter()}),this.options.animationDuration)}sortMultiple(t){const e=[...this.items];e.sort(((e,s)=>{for(const i of t){const t=e.dataset[i.key],r=s.dataset[i.key],o="asc"===i.direction?t.localeCompare(r):r.localeCompare(t);if(0!==o)return o}return 0})),e.forEach((t=>this.container.appendChild(t)))}addRangeFilter(t,e,s){this.items.forEach((i=>{const r=parseFloat(i.dataset[t]);r>=e&&r<=s?this.showItem(i):this.hideItem(i)})),setTimeout((()=>{this.updateCounter()}),this.options.animationDuration)}matchesFilterGroups(t){const e=[...this.filterGroups.values()].map((e=>{const s=[...e.filters];return 0===s.length||("OR"===e.operator?s.some((e=>t.has(e))):s.every((e=>t.has(e))))}));return"OR"===this.groupMode?e.some((t=>t)):e.every((t=>t))}updateURL(){if(0===this.currentFilters.size||1===this.currentFilters.size&&this.currentFilters.has("*"))return void window.history.pushState({},"",window.location.pathname);const t=new URLSearchParams(window.location.search);if(this.filterGroups.size>0){for(const[e,s]of this.filterGroups.entries())t.set(`group_${e}`,[...s.filters].join(",")),t.set(`groupOp_${e}`,s.operator.toLowerCase());t.set("groupMode",this.groupMode.toLowerCase())}const e={};for(const t of this.currentFilters)if("*"!==t){const[s,i]=t.split(":");e[s]||(e[s]=new Set),e[s].add(i)}Object.entries(e).forEach((e=>{let[s,i]=e;t.set(s,Array.from(i).join(","))})),this.currentSearch&&t.set("search",this.currentSearch);const s=`${window.location.pathname}${t.toString()?"?"+t.toString():""}`;window.history.pushState({},"",s)}loadFromURL(){const t=new URLSearchParams(window.location.search);this.filterGroups.clear();for(const[e,s]of t.entries())if(e.startsWith("group_")){const i=e.replace("group_",""),r=t.get(`groupOp_${i}`)?.toUpperCase()||"OR",o=s.split(",");this.addFilterGroup(i,o,r)}const e=t.get("groupMode")?.toUpperCase();e&&["AND","OR"].includes(e)&&(this.groupMode=e),this.currentFilters.clear();let s=!1;for(const[e,i]of t.entries())"search"!==e&&(s=!0,i.split(",").forEach((t=>{this.currentFilters.add(`${e}:${t}`)})));s||this.currentFilters.add("*"),this.filterButtons.forEach((t=>{const e=t.dataset.filter;this.currentFilters.has(e)||"*"===e&&this.currentFilters.has("*")?t.classList.add(this.options.activeClass):t.classList.remove(this.options.activeClass)}));const i=t.get("search")||"";this.searchInput&&(this.searchInput.value=i),this.filter(),i&&this.search(i)}updateCounter(){const t=this.items.length,e=this.visibleItems.size;return this.counter&&(this.counter.textContent=`Showing ${e} of ${t}`),{total:t,visible:e}}setAnimationOptions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.options.animationDuration=t.duration||this.options.animationDuration,this.options.animationType=t.type||"ease-out",this.addStyles()}addEventSystem(){this.events={},this.on=(t,e)=>{this.events[t]||(this.events[t]=[]),this.events[t].push(e)},this.emit=(t,e)=>{this.events[t]&&this.events[t].forEach((t=>t(e)))}}setPagination(t){this.pagination={currentPage:1,itemsPerPage:t,totalPages:Math.ceil(this.visibleItems.size/t)},this.updatePagination()}updatePagination(){const t=(this.pagination.currentPage-1)*this.pagination.itemsPerPage,e=t+this.pagination.itemsPerPage;[...this.visibleItems].forEach(((s,i)=>{i>=t&&i<e?this.showItem(s):this.hideItem(s)}))}enableAnalytics(t){this.analyticsCallback=t,this.on("filter",(t=>{this.analyticsCallback({type:"filter",filters:[...this.currentFilters],visibleItems:this.visibleItems.size,timestamp:(new Date).toISOString()})}))}sortWithComparator(t,e){const s=[...this.items];s.sort(((s,i)=>{const r=s.dataset[t],o=i.dataset[t];return e(r,o)})),s.forEach((t=>this.container.appendChild(t)))}setResponsiveOptions(t){window.addEventListener("resize",e((()=>{const e=window.innerWidth;for(const[s,i]of Object.entries(t))if(e<=parseInt(s)){Object.assign(this.options,i),this.filter();break}}),250))}enableKeyboardNavigation(){document.addEventListener("keydown",(t=>{"Enter"===t.key&&document.activeElement.classList.contains(this.options.filterButtonSelector.slice(1))&&document.activeElement.click()}))}exportState(){return{filters:[...this.currentFilters],search:this.currentSearch,mode:this.options.filterMode,timestamp:(new Date).toISOString()}}importState(t){t.filters&&(this.currentFilters=new Set(t.filters),this.currentSearch=t.search||"",this.options.filterMode=t.mode||"OR",this.filter(),this.updateURL())}savePreset(t){const e={filters:[...this.currentFilters],search:this.currentSearch,mode:this.options.filterMode};localStorage.setItem(`afs_preset_${t}`,JSON.stringify(e))}loadPreset(t){const e=JSON.parse(localStorage.getItem(`afs_preset_${t}`));e&&(this.currentFilters=new Set(e.filters),this.currentSearch=e.search,this.options.filterMode=e.mode,this.filter(),this.updateURL())}setLogic(t){if("boolean"==typeof t)return this.options.filterMode=t?"AND":"OR",void this.filter();const e=t.toUpperCase();["OR","AND"].includes(e)&&(this.options.filterMode=e,this.filter())}setFilterMode(t){["OR","AND"].includes(t.toUpperCase())&&(this.options.filterMode=t.toUpperCase(),this.filter())}addFilter(t,e){this.currentFilters.add(`${t}:${e}`),this.filter(),this.updateURL()}removeFilter(t,e){this.currentFilters.delete(`${t}:${e}`),0===this.currentFilters.size&&this.currentFilters.add("*"),this.filter(),this.updateURL()}getActiveFiltersByType(t){return[...this.currentFilters].filter((e=>e.startsWith(`${t}:`))).map((t=>t.split(":")[1]))}}}));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).AFS={})}(this,(function(t){"use strict";class e{constructor(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"info";this.enabled=t,this.level=e,this.levels={error:0,warn:1,info:2,debug:3}}_log(t){if(!this.enabled)return;const e=this.levels[this.level];if(this.levels[t]<=e){const e=(new Date).toISOString(),r=`[AFS ${t.toUpperCase()}] ${e}`;for(var s=arguments.length,i=new Array(s>1?s-1:0),a=1;a<s;a++)i[a-1]=arguments[a];switch(t){case"error":console.error(r,...i);break;case"warn":console.warn(r,...i);break;case"info":console.info(r,...i);break;case"debug":console.debug(r,...i)}}}error(){for(var t=arguments.length,e=new Array(t),s=0;s<t;s++)e[s]=arguments[s];this._log("error",...e)}warn(){for(var t=arguments.length,e=new Array(t),s=0;s<t;s++)e[s]=arguments[s];this._log("warn",...e)}info(){for(var t=arguments.length,e=new Array(t),s=0;s<t;s++)e[s]=arguments[s];this._log("info",...e)}debug(){for(var t=arguments.length,e=new Array(t),s=0;s<t;s++)e[s]=arguments[s];this._log("debug",...e)}setDebugMode(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"info";this.enabled=t,this.levels.hasOwnProperty(e)&&(this.level=e),this._log("info",`Debug mode ${t?"enabled":"disabled"} with level: ${e}`)}}class s{static defaults={containerSelector:".filter-container",itemSelector:".filter-item",filterButtonSelector:".btn-filter",searchInputSelector:".filter-search",counterSelector:".filter-counter",activeClass:"active",hiddenClass:"hidden",animationDuration:300,animationType:"fade",animationEasing:"ease-out",filterMode:"OR",searchKeys:["title"],debounceTime:300,debug:!1,logLevel:"info",dateFormat:"YYYY-MM-DD",counter:{template:"Showing {visible} of {total}",showFiltered:!0,filteredTemplate:"({filtered} filtered)",noResultsTemplate:"No items found",formatter:t=>t.toLocaleString()},styles:{slider:{class:"afs-range-slider",trackClass:"afs-range-track",thumbClass:"afs-range-thumb",valueClass:"afs-range-value",selectedClass:"afs-range-selected",ui:{showHistogram:!1,bins:10}},colors:{primary:"#000",background:"#e5e7eb",text:"#000",histogram:"#e5e7eb",histogramActive:"#000"}},pagination:{enabled:!1,itemsPerPage:10,container:".afs-pagination-container",pageButtonClass:"afs-page-button",activePageClass:"afs-page-active",containerClass:"afs-pagination",scrollToTop:!1,scrollOffset:50,scrollBehavior:"smooth"}};constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.options=this.mergeOptions(s.defaults,t),this.initializeStyles(),this.validate()}initializeStyles(){const t=s.defaults.styles,e=this.options.styles||{};this.options.styles=this.mergeOptions(t,e),this.options.styles.colors={...t.colors,...e.colors||{}}}mergeOptions(t,e){const s={...t};for(const i in e)null===e[i]||"object"!=typeof e[i]||Array.isArray(e[i])?void 0!==e[i]&&(s[i]=e[i]):(t[i]&&"object"==typeof t[i]||(s[i]={}),s[i]=this.mergeOptions(s[i],e[i]));return s}validate(){const t=["containerSelector","itemSelector"];for(const e of t)if("string"!=typeof this.options[e])throw new Error(`${e} must be a string`);if("number"!=typeof this.options.animationDuration||this.options.animationDuration<0)throw new Error("animationDuration must be a positive number");if(!["OR","AND"].includes(this.options.filterMode.toUpperCase()))throw new Error('filterMode must be either "OR" or "AND"');if(!Array.isArray(this.options.searchKeys)||0===this.options.searchKeys.length)throw new Error("searchKeys must be a non-empty array");if(this.options.counter){if("string"!=typeof this.options.counter.template)throw new Error("counter.template must be a string");"boolean"!=typeof this.options.counter.showFiltered&&(this.options.counter.showFiltered=!0),"function"!=typeof this.options.counter.formatter&&(this.options.counter.formatter=t=>t.toLocaleString())}else this.options.counter={...s.defaults.counter}}get(t){return t.split(".").reduce(((t,e)=>t?.[e]),this.options)}set(t,e){const s=t.split("."),i=s.pop();s.reduce(((t,e)=>(e in t||(t[e]={}),t[e])),this.options)[i]=e,this.validate()}update(t){this.options=this.mergeOptions(this.options,t),this.validate()}reset(){this.options={...s.defaults}}export(){return{...this.options}}}class i{constructor(){this.state={filters:{current:new Set(["*"]),groups:new Map,ranges:new Map,dateRanges:new Map,mode:"OR",groupMode:"OR"},search:{query:"",keys:["title"]},sort:{orders:{},current:null},items:{visible:new Set,total:0},pagination:{currentPage:1,itemsPerPage:10,totalPages:0}}}getState(){return this.state}setState(t,e){const s=t.split(".");let i=this.state;for(let t=0;t<s.length-1;t++)s[t]in i||(i[s[t]]={}),i=i[s[t]];i[s[s.length-1]]=e}export(){return{filters:{current:Array.from(this.state.filters.current),groups:Array.from(this.state.filters.groups.entries()),ranges:Array.from(this.state.filters.ranges.entries()),dateRanges:Array.from(this.state.filters.dateRanges.entries()),mode:this.state.filters.mode,groupMode:this.state.filters.groupMode},search:{...this.state.search},sort:{...this.state.sort},pagination:{...this.state.pagination}}}import(t){t.filters&&(this.state.filters.current=new Set(t.filters.current),this.state.filters.groups=new Map(t.filters.groups),this.state.filters.ranges=new Map(t.filters.ranges),this.state.filters.dateRanges=new Map(t.filters.dateRanges),this.state.filters.mode=t.filters.mode,this.state.filters.groupMode=t.filters.groupMode),t.search&&(this.state.search={...t.search}),t.sort&&(this.state.sort={...t.sort}),t.pagination&&(this.state.pagination={...t.pagination})}reset(){this.state={filters:{current:new Set(["*"]),groups:new Map,ranges:new Map,dateRanges:new Map,mode:"OR",groupMode:"OR"},search:{query:"",keys:["title"]},sort:{orders:{},current:null},items:{visible:new Set,total:0},pagination:{currentPage:1,itemsPerPage:10,totalPages:0}}}}class a{constructor(t){this.options=t,this.styleElement=null,this.defaultStyles={slider:{class:"afs-range-slider",trackClass:"afs-range-track",thumbClass:"afs-range-thumb",valueClass:"afs-range-value",selectedClass:"afs-range-selected"},colors:{primary:"#000",background:"#ddd",text:"#000"},animation:{duration:"300ms",type:"ease-out"}}}createBaseStyles(){const t=this.options.get("hiddenClass")||"hidden",e=this.options.get("itemSelector")||".filter-item",s=this.options.get("filterButtonSelector")||".btn-filter",i=this.options.get("activeClass")||"active",a=this.options.get("animationDuration")||"300ms",r=this.options.get("animationEasing")||"ease-out";return`\n .${t} {\n display: none !important;\n }\n\n ${e} {\n opacity: 1;\n transform: scale(1);\n filter: blur(0);\n transition: opacity ${a} ${r},\n transform ${a} ${r},\n filter ${a} ${r};\n }\n\n ${e}.${t} {\n opacity: 0;\n transform: scale(0.95);\n filter: blur(5px);\n }\n\n ${s} {\n opacity: 0.5;\n transition: opacity ${a} ${r};\n }\n\n ${s}.${i} {\n opacity: 1;\n }\n `}createRangeStyles(){const t=this.options.get("styles")||this.defaultStyles,e=t.slider||this.defaultStyles.slider,s=t.colors||this.defaultStyles.colors;return`\n /* Range Slider Styles */\n .${e.class} {\n position: relative;\n width: auto;\n height: 40px;\n margin: 10px 0;\n padding: 0 8px;\n }\n\n .${e.trackClass} {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 100%;\n height: 4px;\n background: ${s.background};\n border-radius: 2px;\n }\n\n .${e.thumbClass} {\n position: absolute;\n top: 50%;\n width: 16px;\n height: 16px;\n background: ${s.primary};\n border-radius: 50%;\n transform: translate(-50%, -50%);\n cursor: pointer;\n z-index: 2;\n }\n\n .${e.valueClass} {\n position: absolute;\n top: -20px;\n transform: translateX(-50%);\n font-size: 10px;\n color: ${s.text};\n }\n\n .${e.selectedClass} {\n position: absolute;\n height: 4px;\n background: ${s.primary};\n top: 50%;\n transform: translateY(-50%);\n }\n\n /* Histogram Styles */\n .afs-histogram {\n position: absolute;\n bottom: 22px;\n left: 8px;\n right: 8px;\n height: 20px;\n display: flex;\n align-items: flex-end;\n gap: 1px;\n opacity: 0.5;\n }\n\n .afs-histogram-bar {\n flex: 1;\n background-color: ${s.background};\n min-height: 4px;\n transition: background-color 0.2s ease;\n }\n\n .afs-histogram-bar.active {\n background-color: ${s.primary};\n }\n `}createDateStyles(){const t=(this.options.get("styles")||this.defaultStyles).colors;return`\n .afs-date-range-container {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n margin: 10px 0;\n }\n\n .afs-date-input-wrapper {\n flex: 1;\n }\n\n .afs-date-input-wrapper label {\n display: block;\n font-size: 0.875rem;\n color: ${t.text};\n margin-bottom: 0.5rem;\n }\n\n .afs-date-input {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid ${t.background};\n border-radius: 0.25rem;\n font-size: 0.875rem;\n color: ${t.text};\n transition: border-color 0.2s ease;\n }\n\n .afs-date-input:focus {\n outline: none;\n border-color: ${t.primary};\n }\n `}applyStyles(){try{const t=`\n /* Base styles */\n ${this.createBaseStyles()}\n\n /* Range slider styles */\n ${this.createRangeStyles()}\n\n /* Date filter styles */\n ${this.createDateStyles()}\n\n /* Pagination styles */\n ${this.createPaginationStyles()}\n\n /* Search styles */\n ${this.createSearchStyles()}\n `;this.styleElement?this.styleElement.textContent=t:(this.styleElement=document.createElement("style"),this.styleElement.textContent=t,document.head.appendChild(this.styleElement))}catch(t){console.error("Error applying styles:",t);const e=this.createBaseStyles();this.styleElement?this.styleElement.textContent=e:(this.styleElement=document.createElement("style"),this.styleElement.textContent=e,document.head.appendChild(this.styleElement))}}createPaginationStyles(){const t=this.options.get("pagination")||{},e=(this.options.get("styles")||this.defaultStyles).colors,s=t.containerClass||"afs-pagination",i=t.pageButtonClass||"afs-page-button",a=t.activePageClass||"afs-page-active";return`\n .${s} {\n display: flex;\n justify-content: center;\n gap: 8px;\n margin-top: 20px;\n }\n\n .${i} {\n padding: 8px 12px;\n border: 1px solid ${e.primary};\n border-radius: 4px;\n cursor: pointer;\n transition: all 200ms ease-out;\n background: transparent;\n color: ${e.primary};\n }\n\n .${i}:hover {\n background: ${e.primary};\n color: white;\n }\n\n .${i}.${a} {\n background: ${e.primary};\n color: white;\n }\n\n .${i}:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `}createSearchStyles(){const t=this.options.get("searchInputClass")||"afs-search",e=(this.options.get("styles")||this.defaultStyles).colors;return`\n .${t} {\n padding: 8px;\n border: 1px solid ${e.background};\n border-radius: 4px;\n width: 100%;\n max-width: 300px;\n transition: border-color 200ms ease-out;\n }\n\n .${t}:focus {\n outline: none;\n border-color: ${e.primary};\n }\n `}updateStyles(t){this.options=t,this.applyStyles()}removeStyles(){this.styleElement&&(this.styleElement.remove(),this.styleElement=null)}}class r{constructor(){this.events=new Map,this.onceEvents=new Map}on(t,e){return this.events.has(t)||this.events.set(t,new Set),this.events.get(t).add(e),()=>this.off(t,e)}once(t,e){var s=this;const i=function(){s.off(t,i);for(var a=arguments.length,r=new Array(a),n=0;n<a;n++)r[n]=arguments[n];e.apply(s,r)};return this.onceEvents.has(t)||this.onceEvents.set(t,new Map),this.onceEvents.get(t).set(e,i),this.on(t,i)}off(t,e){if(this.events.has(t)&&(this.events.get(t).delete(e),0===this.events.get(t).size&&this.events.delete(t)),this.onceEvents.has(t)){const s=this.onceEvents.get(t).get(e);s&&(this.events.get(t)?.delete(s),this.onceEvents.get(t).delete(e)),0===this.onceEvents.get(t).size&&this.onceEvents.delete(t)}}emit(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;i<e;i++)s[i-1]=arguments[i];this.events.has(t)&&this.events.get(t).forEach((e=>{try{e.apply(this,s)}catch(e){console.error(`Error in event handler for ${t}:`,e)}}))}removeAllListeners(t){t?(this.events.delete(t),this.onceEvents.delete(t)):(this.events.clear(),this.onceEvents.clear())}listenerCount(t){return(this.events.get(t)?.size||0)+(this.onceEvents.get(t)?.size||0)}}class n{constructor(t){this.afs=t,this.options=this.afs.options,this.animations={fade:{in:{opacity:1,transform:"scale(1)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"scale(0.95)",transitionTimingFunction:"ease-out"}},slide:{in:{opacity:1,transform:"translateY(0)",transitionTimingFunction:"ease-in-out"},out:{opacity:0,transform:"translateY(20px)",transitionTimingFunction:"ease-in-out"}},scale:{in:{opacity:1,transform:"scale(1)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"scale(0.8)",transitionTimingFunction:"ease-out"}},rotate:{in:{opacity:1,transform:"rotate(0deg) scale(1)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"rotate(90deg) scale(0.9)",transitionTimingFunction:"ease-out"}},flip:{in:{opacity:1,transform:"rotateY(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"rotateY(180deg)",transitionTimingFunction:"ease-out"}},zoom:{in:{opacity:1,transform:"scale(1.2)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"scale(0.8)",transitionTimingFunction:"ease-out"}},bounce:{in:{opacity:1,transform:"translateY(0)",animation:"bounce 1s cubic-bezier(0.68, -0.55, 0.27, 1.55)"},out:{opacity:0,transform:"translateY(-20px)",animation:"bounceOut 1s ease-out"}},blur:{in:{opacity:1,filter:"blur(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,filter:"blur(5px)",transitionTimingFunction:"ease-out"}},skew:{in:{opacity:1,transform:"skew(0deg)",transitionTimingFunction:"ease-in-out"},out:{opacity:0,transform:"skew(10deg)",transitionTimingFunction:"ease-in-out"}},slideInLeft:{in:{opacity:1,transform:"translateX(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateX(-100%)",transitionTimingFunction:"ease-out"}},slideInRight:{in:{opacity:1,transform:"translateX(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateX(100%)",transitionTimingFunction:"ease-out"}},fadeInUp:{in:{opacity:1,transform:"translateY(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateY(10px)",transitionTimingFunction:"ease-out"}},fadeInDown:{in:{opacity:1,transform:"translateY(0)",transitionTimingFunction:"ease-in"},out:{opacity:0,transform:"translateY(-10px)",transitionTimingFunction:"ease-out"}},bounceIn:{in:{opacity:1,transform:"scale(1.05)",transitionTimingFunction:"cubic-bezier(0.68, -0.55, 0.27, 1.55)"},out:{opacity:0,transform:"scale(0.9)",transitionTimingFunction:"ease-out"}}}}applyShowAnimation(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"fade";const s=this.options.get("animationDuration")||"300ms",i=this.animations[e]?.in||this.animations.fade.in;t.style.display="block",requestAnimationFrame((()=>{Object.assign(t.style,i,{transition:`opacity ${s} ${i.transitionTimingFunction}, transform ${s} ${i.transitionTimingFunction}`})}))}applyHideAnimation(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"fade";const s=this.options.get("animationDuration")||"300ms",i=this.animations[e]?.out||this.animations.fade.out;Object.assign(t.style,i,{transition:`opacity ${s} ${i.transitionTimingFunction}, transform ${s} ${i.transitionTimingFunction}`});const a=()=>{t.style.display="none",t.removeEventListener("transitionend",a)};t.addEventListener("transitionend",a)}setAnimation(t){this.afs.options.set("animationType",t)}}class o{constructor(t){this.afs=t,this.animation=new n(t),this.filterButtons=new Map,this.activeFilters=new Set(["*"]),this.currentFilters=new Set(["*"]),this.filterGroups=new Map,this.sortOrders=new Map,this.setupFilters()}setupFilters(){this.afs.logger.debug("Setting up filters");const t=this.afs.options.get("filterButtonSelector");t&&(document.querySelectorAll(t).forEach((t=>{const e=t.dataset.filter;e?(this.filterButtons.set(t,e),this.bindFilterEvent(t)):this.afs.logger.warn("Filter button missing data-filter attribute:",t)})),this.afs.logger.debug("Filters initialized"))}setLogic(t){if("boolean"==typeof t)this.afs.options.set("filterMode",t?"AND":"OR");else{const e=t.toUpperCase();if(!["OR","AND"].includes(e))return void this.afs.logger.warn(`Invalid filter mode: ${t}`);this.afs.options.set("filterMode",e)}this.afs.logger.debug(`Filter logic set to: ${this.afs.options.get("filterMode")}`),this.applyFilters()}clearAllFilters(){this.afs.logger.debug("Clearing all filters"),this.activeFilters.clear(),this.activeFilters.add("*"),this.filterButtons.forEach(((t,e)=>{e.classList.remove(this.afs.options.get("activeClass"))})),this.filterGroups.clear();const t=this.findAllButton();t&&t.classList.add(this.afs.options.get("activeClass")),this.sortOrders.clear(),this.applyFilters(),this.afs.urlManager.updateURL(),this.afs.emit("filtersCleared")}bindFilterEvent(t){this.afs.logger.debug("Binding filter event to button:",t),t.addEventListener("click",(()=>{const e=this.filterButtons.get(t);e&&("*"===e?this.resetFilters():this.toggleFilter(e,t),this.afs.urlManager.updateURL())}))}resetFilters(){this.afs.logger.debug("Resetting filters"),this.activeFilters.clear(),this.filterButtons.forEach(((t,e)=>{e.classList.remove(this.afs.options.get("activeClass"))})),this.activeFilters.add("*");const t=this.findAllButton();t&&t.classList.add(this.afs.options.get("activeClass")),this.filterGroups.clear();const e=new Set(this.afs.items);this.afs.state.setState("items.visible",e),this.afs.items.forEach((t=>{t.classList.remove(this.afs.options.get("hiddenClass")),requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.afs.options.get("animationType"))}))})),this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("filtersReset")}findAllButton(){for(const[t,e]of this.filterButtons.entries())if("*"===e)return t;return null}handleFilterClick(t){const e=t.dataset.filter;this.afs.logger.debug("Filter clicked:",e),"*"===e?this.resetFilters():this.toggleFilter(e,t),this.filter(),this.updateURL()}toggleFilter(t,e){this.activeFilters.delete("*");const s=this.findAllButton();if(s&&s.classList.remove(this.afs.options.get("activeClass")),e.classList.contains(this.afs.options.get("activeClass"))){if(e.classList.remove(this.afs.options.get("activeClass")),this.activeFilters.delete(t),0===this.activeFilters.size)return void this.resetFilters()}else e.classList.add(this.afs.options.get("activeClass")),this.activeFilters.add(t);this.applyFilters(),this.afs.emit("filterToggled",{filter:t,activeFilters:Array.from(this.activeFilters)}),this.afs.logger.debug("Filter toggled:",t)}applyFilters(){const t=Array.from(this.activeFilters);this.afs.logger.debug("Active filters:",t),this.afs.logger.debug("Applying filters");const e=new Set(this.afs.state.getState().items.visible),s=new Set;this.afs.items.forEach((t=>{(this.activeFilters.has("*")||this.itemMatchesFilters(t))&&s.add(t)})),this.afs.state.setState("items.visible",s),this.afs.items.forEach((t=>{s.has(t)?(t.classList.remove(this.afs.options.get("hiddenClass")),requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.afs.options.get("animationType"))}))):requestAnimationFrame((()=>{this.animation.applyHideAnimation(t,this.afs.options.get("animationType"))}))})),this.emitFilterEvents(e,s),requestAnimationFrame((()=>{this.afs.container.offsetHeight,this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("filtersApplied",{activeFilters:t,visibleItems:s.size})}))}itemMatchesFilters(t){if(this.activeFilters.has("*"))return!0;const e=new Set(t.dataset.categories?.split(" ")||[]);return this.filterGroups.size>0?this.itemMatchesFilterGroups(e):"OR"===this.afs.options.get("filterMode")?this.itemMatchesAnyFilter(e):this.itemMatchesAllFilters(e)}itemMatchesAnyFilter(t){return Array.from(this.activeFilters).some((e=>"*"===e||t.has(e)))}itemMatchesAllFilters(t){return Array.from(this.activeFilters).every((e=>"*"===e||t.has(e)))}itemMatchesFilterGroups(t){const e=Array.from(this.filterGroups.values()).map((e=>0===e.filters.size||("OR"===e.operator?Array.from(e.filters).some((e=>t.has(e))):Array.from(e.filters).every((e=>t.has(e))))));return"OR"===this.afs.options.get("groupMode")?e.some((t=>t)):e.every((t=>t))}emitFilterEvents(t,e){const s=new Set([...e].filter((e=>!t.has(e)))),i=new Set([...t].filter((t=>!e.has(t))));this.afs.emit("filter",{activeFilters:Array.from(this.activeFilters),visibleItems:e.size,added:s.size,removed:i.size}),s.size>0&&this.afs.emit("itemsShown",{items:s}),i.size>0&&this.afs.emit("itemsHidden",{items:i})}addFilterGroup(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"OR";if(this.afs.logger.debug(`Adding filter group: ${t}`),!Array.isArray(e))return void this.afs.logger.error("Filters must be an array");const i=s.toUpperCase();["AND","OR"].includes(i)||(this.afs.logger.warn(`Invalid operator: ${s}, defaulting to OR`),s="OR"),this.filterGroups.set(t,{filters:new Set(e),operator:i}),this.applyFilters()}removeFilterGroup(t){this.filterGroups.delete(t)&&(this.afs.logger.debug(`Removed filter group: ${t}`),0===this.filterGroups.size?this.resetFilters():this.applyFilters())}setGroupMode(t){const e=t.toUpperCase();["AND","OR"].includes(e)?(this.afs.options.set("groupMode",e),this.afs.logger.debug(`Set group mode to: ${e}`),this.applyFilters()):this.afs.logger.warn(`Invalid group mode: ${t}`)}addFilter(t){this.afs.logger.debug(`Adding filter: ${t}`),"*"!==t?(this.activeFilters.delete("*"),this.activeFilters.add(t),this.filterButtons.forEach(((e,s)=>{e===t?s.classList.add(this.afs.options.get("activeClass")):"*"===e&&s.classList.remove(this.afs.options.get("activeClass"))})),this.applyFilters()):this.resetFilters()}removeFilter(t){this.afs.logger.debug(`Removing filter: ${t}`),this.activeFilters.delete(t),this.filterButtons.forEach(((e,s)=>{e===t&&s.classList.remove(this.afs.options.get("activeClass"))})),0===this.activeFilters.size?this.resetFilters():this.applyFilters()}setFilterMode(t){this.afs.logger.debug(`Setting filter mode to: ${t}`);const e=t.toUpperCase();["AND","OR"].includes(e)?(this.afs.options.set("filterMode",e),this.afs.logger.debug(`Set filter mode to: ${e}`),this.applyFilters()):this.afs.logger.warn(`Invalid filter mode: ${t}`)}getActiveFilters(){return new Set(this.activeFilters)}getFilterGroups(){return new Map(this.filterGroups)}addFilterButton(t,e){e?(this.filterButtons.set(t,e),this.bindFilterEvent(t),this.afs.logger.debug(`Added filter button for: ${e}`)):this.afs.logger.warn("Filter value required for new filter button")}removeFilter(t){this.afs.logger.debug(`Removing filter: ${t}`),this.activeFilters.delete(t),this.filterButtons.forEach(((e,s)=>{e===t&&s.classList.remove(this.afs.options.get("activeClass"))})),0===this.activeFilters.size?this.resetFilters():this.applyFilters()}sortWithOrder(t){this.afs.logger.debug(`Sorting by ${t}`);try{const e=Array.from(this.afs.items),s="asc"===(this.sortOrders.get(t)||"asc")?"desc":"asc";this.sortOrders.set(t,s);const i=this.determineSortType(e[0],t);return e.sort(((e,a)=>{const r=this.getSortValue(e,t,i),n=this.getSortValue(a,t,i);return this.compareValues(r,n,s)})),this.reorderItems(e),this.afs.emit("sort",{key:t,order:s}),this.afs.logger.info(`Sorted items by ${t} in ${s} order`),s}catch(t){return this.afs.logger.error("Sort error:",t),null}}shuffle(){this.afs.logger.debug("Shuffling items");try{const t=Array.from(this.afs.items);for(let e=t.length-1;e>0;e--){const s=Math.floor(Math.random()*(e+1));[t[e],t[s]]=[t[s],t[e]]}this.reorderItems(t),this.sortOrders.clear(),this.afs.emit("shuffled",{itemCount:t.length}),this.afs.logger.debug("Items shuffled successfully")}catch(t){this.afs.logger.error("Shuffle error:",t)}}determineSortType(t,e){this.afs.logger.debug(`Determining sort type for ${e}`);const s=t.dataset[e];return s?isNaN(s)?/^\d{4}-\d{2}-\d{2}/.test(s)?"date":"string":"number":"string"}getSortValue(t,e,s){const i=t.dataset[e];switch(s){case"number":return parseFloat(i)||0;case"date":return new Date(i).getTime()||0;default:return(i||"").toLowerCase()}}compareValues(t,e,s){if(null==t)return"asc"===s?1:-1;if(null==e)return"asc"===s?-1:1;const i=t<e?-1:t>e?1:0;return"asc"===s?i:-i}reorderItems(t){const e=document.createDocumentFragment();t.forEach((t=>e.appendChild(t))),this.afs.container.appendChild(e)}getCurrentSortOrder(t){return this.sortOrders.get(t)||"asc"}clearSortOrders(){this.afs.logger.debug("Clearing all sort orders"),this.sortOrders.clear(),this.afs.emit("sortCleared")}clearAllFilters(){this.afs.logger.debug("Clearing all filters and search"),this.activeFilters.clear(),this.activeFilters.add("*"),this.filterButtons.forEach(((t,e)=>{e.classList.remove(this.afs.options.get("activeClass"))}));const t=this.findAllButton();t&&t.classList.add(this.afs.options.get("activeClass"));document.querySelectorAll('input[type="checkbox"]').forEach((t=>{t.classList.contains(this.afs.options.get("activeClass"))&&(t.checked=!1,t.classList.remove(this.afs.options.get("activeClass")))})),this.afs.search&&this.afs.search.setValue(""),this.filterGroups.clear(),this.sortOrders.clear(),this.applyFilters(),this.afs.urlManager&&this.afs.urlManager.updateURL(),this.afs.emit("filtersCleared"),this.afs.logger.info("All filters cleared")}refresh(){this.afs.logger.debug("Refreshing view"),this.applyFilters(),this.afs.updateCounter()}removeFilterButton(t){this.filterButtons.delete(t),t.removeEventListener("click",this.handleFilterClick)}destroy(){this.filterButtons.forEach(((t,e)=>{this.removeFilterButton(e)})),this.filterButtons.clear(),this.activeFilters.clear(),this.filterGroups.clear(),this.afs.logger.debug("Filter functionality destroyed")}}function l(t,e){let s,i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return function(){for(var a=arguments.length,r=new Array(a),n=0;n<a;n++)r[n]=arguments[n];const o=this,l=i&&!s;clearTimeout(s),s=setTimeout((()=>{s=null,i||t.apply(o,r)}),e),l&&t.apply(o,r)}}class h{constructor(t){this.afs=t,this.searchInput=null,this.searchKeys=["title"],this.minSearchLength=2,this.highlightClass="afs-highlight",this.setupSearch()}setupSearch(){const t=this.afs.options.get("searchInputSelector");t&&(this.searchInput=document.querySelector(t),this.searchInput?(this.searchKeys=this.afs.options.get("searchKeys")||this.searchKeys,this.minSearchLength=this.afs.options.get("minSearchLength")||this.minSearchLength,this.bindSearchEvents(),this.afs.logger.debug("Search functionality initialized")):this.afs.logger.warn(`Search input not found: ${t}`))}bindSearchEvents(){if(!this.searchInput)return;const t=l((t=>{this.search(t.target.value)}),this.afs.options.get("debounceTime")||300);this.searchInput.addEventListener("input",t),this.searchInput.addEventListener("search",(t=>{t.target.value||this.clearSearch()})),this.searchInput.addEventListener("keypress",(t=>{"Enter"===t.key&&(t.preventDefault(),this.search(t.target.value))}))}search(t){this.afs.logger.debug("Performing search:",t);const e=this.normalizeQuery(t);this.afs.state.setState("search.query",e);let s=0;if(e)if(e.length<this.minSearchLength)this.afs.logger.debug("Search query too short");else{try{const t=this.createSearchRegex(e);this.afs.items.forEach((e=>{const i=this.getItemSearchText(e);t.test(i)?(this.afs.showItem(e),this.highlightMatches(e,t),s++):(this.afs.hideItem(e),this.removeHighlights(e))})),this.afs.urlManager.updateURL(),this.afs.emit("search",{query:e,matches:s,total:this.afs.items.length}),this.afs.logger.info(`Search complete. Found ${s} matches`)}catch(t){this.afs.logger.error("Search error:",t)}setTimeout((()=>{this.afs.updateCounter()}),this.afs.options.get("animationDuration"))}else this.clearSearch()}normalizeQuery(t){return t.toLowerCase().trim().replace(/\s+/g," ")}createSearchRegex(t){const e=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").split(" ").filter(Boolean).map((t=>`(?=.*\\b${t})`)).join("");return new RegExp(e,"i")}getItemSearchText(t){return this.searchKeys.map((e=>t.dataset[e]||"")).join(" ").toLowerCase()}highlightMatches(t,e){this.afs.options.get("highlightMatches")&&this.searchKeys.forEach((e=>{const s=t.querySelector(`[data-search-key="${e}"]`);if(!s)return;const i=s.textContent,a=this.afs.state.getState().search.query.split(" ");let r=i;a.forEach((t=>{if(!t)return;const e=new RegExp(`(${t})`,"gi");r=r.replace(e,`<span class="${this.highlightClass}">$1</span>`)})),s.innerHTML=r}))}removeHighlights(t){this.afs.options.get("highlightMatches")&&this.searchKeys.forEach((e=>{const s=t.querySelector(`[data-search-key="${e}"]`);if(!s)return;s.querySelectorAll(`.${this.highlightClass}`).forEach((t=>{const e=t.textContent;t.replaceWith(e)}))}))}clearSearch(){this.afs.logger.debug("Clearing search"),this.searchInput&&(this.searchInput.value=""),this.afs.state.setState("search.query",""),this.afs.items.forEach((t=>{this.afs.showItem(t),this.removeHighlights(t)})),this.afs.urlManager.updateURL(),this.afs.emit("searchCleared"),setTimeout((()=>{this.afs.updateCounter()}),this.afs.options.get("animationDuration"))}setValue(t){this.searchInput&&(this.searchInput.value=t),this.search(t)}getValue(){return this.afs.state.getState().search.query}updateConfig(){let{searchKeys:t,minSearchLength:e,highlightClass:s,debounceTime:i}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};t&&(this.searchKeys=t),e&&(this.minSearchLength=e),s&&(this.highlightClass=s),i&&this.bindSearchEvents()}destroy(){this.searchInput&&(this.searchInput.removeEventListener("input",this.debouncedSearch),this.searchInput.removeEventListener("search",this.handleClear),this.searchInput.removeEventListener("keypress",this.handleEnter)),this.clearSearch()}}class c{constructor(t){this.afs=t,this.sortButtons=new Map,this.setupSort()}setupSort(){const t=this.afs.options.get("sortButtonSelector");t&&(document.querySelectorAll(t).forEach((t=>{const e=t.dataset.sortKey;e?(this.sortButtons.set(t,{key:e,direction:t.dataset.sortDirection||"asc"}),this.bindSortEvent(t)):this.afs.logger.warn("Sort button missing data-sort-key attribute:",t)})),this.afs.logger.debug("Sort functionality initialized"))}bindSortEvent(t){this.afs.logger.debug("Binding sort event to button:",t),t.addEventListener("click",(()=>{const e=this.sortButtons.get(t);e&&(e.direction="asc"===e.direction?"desc":"asc",this.sortButtons.set(t,e),this.updateSortButtonState(t,e),this.sort(e.key,e.direction))}))}updateSortButtonState(t,e){this.sortButtons.forEach(((t,e)=>{e.classList.remove(this.afs.options.get("activeSortClass"))})),t.classList.add(this.afs.options.get("activeSortClass"));const s=t.querySelector(".sort-direction");s&&(s.textContent="asc"===e.direction?"↑":"↓")}sort(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"asc";this.afs.logger.debug(`Sorting by ${t} in ${e} order`);try{this.afs.state.setState("sort.current",{key:t,direction:e});const s=Array.from(this.afs.items),i=this.determineSortType(s[0],t);s.sort(((s,a)=>{const r=this.getSortValue(s,t,i),n=this.getSortValue(a,t,i);return this.compareValues(r,n,e)})),this.reorderItems(s),this.afs.urlManager.updateURL(),this.afs.emit("sort",{key:t,direction:e}),this.afs.logger.info(`Sorted items by ${t} ${e}`)}catch(t){this.afs.logger.error("Sort error:",t)}}determineSortType(t,e){const s=t.dataset[e];return s?isNaN(s)?/^\d{4}-\d{2}-\d{2}/.test(s)?"date":"string":"number":"string"}getSortValue(t,e,s){const i=t.dataset[e];switch(s){case"number":return parseFloat(i);case"date":return new Date(i).getTime();default:return i.toLowerCase()}}compareValues(t,e,s){const i="asc"===s?1:-1;return t===e?0:null==t?1:null==e?-1:t>e?i:-i}reorderItems(t){const e=this.afs.options.get("container"),s=document.createDocumentFragment();t.forEach((t=>s.appendChild(t))),e.appendChild(s)}sortMultiple(t){this.afs.logger.debug("Sorting by multiple criteria:",t);try{const e=Array.from(this.afs.items);e.sort(((s,i)=>{for(const{key:a,direction:r}of t){const t=this.determineSortType(e[0],a),n=this.getSortValue(s,a,t),o=this.getSortValue(i,a,t),l=this.compareValues(n,o,r);if(0!==l)return l}return 0})),this.reorderItems(e),t.length>0&&this.afs.state.setState("sort.current",t[0]),this.afs.urlManager.updateURL(),this.afs.emit("multiSort",{criteria:t})}catch(t){this.afs.logger.error("Multiple sort error:",t)}}sortWithComparator(t,e){this.afs.logger.debug(`Sorting by ${t} with custom comparator`);try{const s=Array.from(this.afs.items);s.sort(((s,i)=>{const a=s.dataset[t],r=i.dataset[t];return e(a,r)})),this.reorderItems(s),this.afs.emit("customSort",{key:t,comparator:e})}catch(t){this.afs.logger.error("Custom sort error:",t)}}shuffle(){this.afs.logger.debug("Shuffling items");try{const t=Array.from(this.afs.items);for(let e=t.length-1;e>0;e--){const s=Math.floor(Math.random()*(e+1));[t[e],t[s]]=[t[s],t[e]]}this.reorderItems(t),this.afs.state.setState("sort.current",null),this.sortButtons.forEach(((t,e)=>{e.classList.remove(this.afs.options.get("activeSortClass"));const s=e.querySelector(".sort-direction");s&&(s.textContent="")})),this.afs.urlManager.updateURL(),this.afs.emit("shuffle")}catch(t){this.afs.logger.error("Shuffle error:",t)}}reset(){this.afs.logger.debug("Resetting sort"),this.afs.state.setState("sort.current",null),this.sortButtons.forEach(((t,e)=>{e.classList.remove(this.afs.options.get("activeSortClass"));const s=e.querySelector(".sort-direction");s&&(s.textContent="")})),this.sortButtons.forEach(((t,e)=>{t.direction="asc",this.sortButtons.set(e,t)})),this.afs.urlManager.updateURL(),this.afs.emit("sortReset")}getCurrentSort(){return this.afs.state.getState().sort.current}addSortButton(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"asc";e?(this.sortButtons.set(t,{key:e,direction:s}),this.bindSortEvent(t),this.afs.logger.debug(`Added sort button for ${e}`)):this.afs.logger.warn("Sort key required for new sort button")}removeSortButton(t){this.sortButtons.has(t)&&(t.removeEventListener("click",this.bindSortEvent),this.sortButtons.delete(t),this.afs.logger.debug("Removed sort button"))}destroy(){this.sortButtons.forEach(((t,e)=>{this.removeSortButton(e)})),this.sortButtons.clear(),this.afs.logger.debug("Sort functionality destroyed")}}class g{constructor(t){this.afs=t,this.container=null,this.animation=new n(t),this.options=this.afs.options.get("pagination"),this.setupPagination()}setupPagination(){if(this.afs.logger.debug("Setting up pagination"),!this.afs.options.get("pagination.enabled"))return;console.log("Pagination enabled"),this.container=document.createElement("div"),this.container.className=this.options.containerClass;const t=document.querySelector(this.afs.options.get("pagination.container"));t?(t.appendChild(this.container),this.afs.state.setState("pagination",{currentPage:1,itemsPerPage:this.options.itemsPerPage,totalPages:0}),this.bindEvents(),this.update(),this.afs.logger.debug("Pagination initialized")):this.afs.logger.error("Items container not found.")}bindEvents(){this.afs.on("filter",(()=>this.update())),this.afs.on("search",(()=>this.update())),this.afs.on("sort",(()=>this.update())),this.container.addEventListener("click",(t=>{const e=t.target.closest("button");if(!e)return;const s=e.dataset.page;s&&this.goToPage(parseInt(s,10))}))}update(){const t=Array.from(this.afs.state.getState().items.visible),e=this.afs.state.getState().pagination.itemsPerPage,s=Math.max(1,Math.ceil(t.length/e)),i=this.afs.state.getState().pagination;let a=i.currentPage;a>s&&(a=s),this.afs.state.setState("pagination",{...i,currentPage:a,totalPages:s}),this.updateVisibility(t),this.renderPagination(),this.afs.urlManager.updateURL(),this.afs.emit("pagination",{currentPage:a,totalPages:s,itemsPerPage:e,visibleItems:t.length})}updateVisibility(t){const{currentPage:e,itemsPerPage:s}=this.afs.state.getState().pagination,i=(e-1)*s,a=i+s;this.afs.items.forEach((t=>{t.style.display="none",t.classList.add(this.afs.options.get("hiddenClass"))}));const r=t.slice(i,a);0===r.length&&t.length>0?this.goToPage(1):requestAnimationFrame((()=>{r.forEach((t=>{t.style.display="",t.classList.remove(this.afs.options.get("hiddenClass")),requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.options.animationType||"fade")}))}))}))}renderPagination(){const{currentPage:t,totalPages:e}=this.afs.state.getState().pagination;if(this.container.innerHTML="",e<=1)return void(this.container.style.display="none");this.container.style.display="flex";const s=this.createPaginationControls(t,e);this.container.appendChild(s)}createPaginationControls(t,e){const s=document.createDocumentFragment();if(this.options.showPrevNext){const e=this.createPageButton("‹",t-1,{disabled:1===t,class:"afs-pagination-prev"});s.appendChild(e)}s.appendChild(this.createPageButton("1",1,{active:1===t}));const i=this.calculatePageRange(t,e);i.start>2&&s.appendChild(this.createEllipsis());for(let a=i.start;a<=i.end;a++)1!==a&&a!==e&&s.appendChild(this.createPageButton(a.toString(),a,{active:t===a}));if(i.end<e-1&&s.appendChild(this.createEllipsis()),e>1&&s.appendChild(this.createPageButton(e.toString(),e,{active:t===e})),this.options.showPrevNext){const i=this.createPageButton("›",t+1,{disabled:t===e,class:"afs-pagination-next"});s.appendChild(i)}return s}createPageButton(t,e){let{active:s=!1,disabled:i=!1,class:a=""}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=document.createElement("button");return r.textContent=t,r.dataset.page=e,r.classList.add(this.options.pageButtonClass||"afs-page-button"),a&&r.classList.add(a),s&&r.classList.add(this.options.activePageClass||"afs-page-active"),i&&(r.disabled=!0),r}createEllipsis(){const t=document.createElement("span");return t.textContent="...",t.classList.add("afs-pagination-ellipsis"),t}calculatePageRange(t,e){const s=this.options.maxButtons||7,i=Math.floor((s-3)/2);let a=Math.max(2,t-i),r=Math.min(e-1,a+s-3);return r-a<s-3&&(a=Math.max(2,r-(s-3))),{start:a,end:r}}goToPage(t){const e=this.afs.state.getState().pagination,s=Math.max(1,Math.min(t,e.totalPages));s!==e.currentPage&&(this.afs.state.setState("pagination.currentPage",s),this.afs.container.offsetHeight,this.update(),this.options.scrollToTop&&setTimeout((()=>this.scrollToTop()),100),this.afs.emit("pageChanged",{previousPage:e.currentPage,currentPage:s,totalPages:e.totalPages}))}scrollToTop(){const t=document.querySelector(this.afs.options.get("pagination.container"));t?window.scrollTo({top:t.offsetTop-this.options.scrollOffset,behavior:"smooth"}):this.afs.logger.warn("Scroll container not found.")}setPaginationMode(t){this.afs.logger.debug(`Setting pagination mode to: ${t}`),this.afs.options.set("pagination.enabled",t),t?this.setupPagination():(this.container.remove(),this.showAllItems()),this.afs.emit("paginationModeChanged",{enabled:t})}showAllItems(){const t=Array.from(this.afs.state.getState().items.visible);requestAnimationFrame((()=>{t.forEach((t=>{t.style.display="",t.classList.remove(this.afs.options.get("hiddenClass")),requestAnimationFrame((()=>{this.animation.applyShowAnimation(t,this.options.animationType||"fade")}))}))}))}}class d{constructor(t){this.afs=t,this.defaultParams=new URLSearchParams,this.setupPopStateHandler(),setTimeout((()=>{this.loadFromURL()}),0)}setupPopStateHandler(){window.addEventListener("popstate",(()=>{this.loadFromURL()}))}updateURL(){this.afs.logger.debug("Updating URL state");const t=new URLSearchParams,e=this.afs.state.getState(),s=this.afs.filter.getActiveFilters();e.filters.current=s,this.addFiltersToURL(t,e),this.addRangesToURL(t,e),this.addSearchToURL(t,e),this.addSortToURL(t,e),this.addPaginationToURL(t,e),this.pushState(t)}addFiltersToURL(t,e){const s=e.filters;if(0===s.current.size||1===s.current.size&&s.current.has("*"))return;const i={};for(const t of s.current)if("*"!==t){const[e,s]=t.split(":");i[e]||(i[e]=new Set),i[e].add(s)}Object.entries(i).forEach((e=>{let[s,i]=e;t.set(s,Array.from(i).join(","))})),"OR"!==s.mode&&t.set("filterMode",s.mode.toLowerCase()),s.groups.size>0&&"OR"!==s.groupMode&&t.set("groupMode",s.groupMode.toLowerCase()),s.groups.forEach(((e,s)=>{t.set(`group_${s}`,Array.from(e.filters).join(",")),"OR"!==e.operator&&t.set(`groupOp_${s}`,e.operator.toLowerCase())}))}addRangesToURL(t,e){e.filters.ranges.forEach(((e,s)=>{const{currentMin:i,currentMax:a}=e;i===e.min&&a===e.max||t.set(`range_${s}`,`${i},${a}`)})),e.filters.dateRanges.forEach(((e,s)=>{const{start:i,end:a}=e;t.set(`dateRange_${s}`,`${i.toISOString()},${a.toISOString()}`)}))}addSearchToURL(t,e){e.search.query&&t.set("search",e.search.query)}addSortToURL(t,e){if(e.sort.current){const{key:s,direction:i}=e.sort.current;t.set("sort",`${s},${i}`)}}addPaginationToURL(t,e){const{currentPage:s,itemsPerPage:i}=e.pagination;s>1&&t.set("page",s.toString()),i!==this.afs.options.get("pagination.itemsPerPage")&&t.set("perPage",i.toString())}pushState(t){const e=t.toString(),s=`${window.location.pathname}${e?"?"+e:""}`;s!==window.location.href&&(window.history.pushState({},"",s),this.afs.logger.debug("URL updated:",s))}loadFromURL(){this.afs.logger.debug("Loading state from URL");const t=new URLSearchParams(window.location.search);try{this.afs.filter&&this.afs.filter.clearAllFilters();const e=t.get("filterMode");e&&this.afs.filter&&this.afs.filter.setFilterMode(e.toUpperCase());const s=Array.from(t.entries()).filter((t=>{let[e]=t;return this.isRegularFilter(e)}));s.length>0&&this.afs.filter&&(this.afs.filter.activeFilters.clear(),s.forEach((t=>{let[e,s]=t;s.split(",").forEach((t=>{const s=`${e}:${t}`;this.afs.filter.activeFilters.add(s),this.afs.filter.filterButtons.forEach(((t,e)=>{t===s?e.classList.add(this.afs.options.get("activeClass")):"*"===t&&e.classList.remove(this.afs.options.get("activeClass"))}))}))}))),this.afs.filter&&this.afs.filter.applyFilters();const i=t.get("search");i&&this.afs.search&&this.afs.search.setValue(i);const a=t.get("sort");if(a&&this.afs.sort){const[t,e]=a.split(",");this.afs.sort.sort(t,e)}const r=parseInt(t.get("page"));!isNaN(r)&&this.afs.pagination&&this.afs.pagination.goToPage(r),this.afs.emit("urlStateLoaded",{params:Object.fromEntries(t)}),this.afs.logger.info("State loaded from URL")}catch(t){this.afs.logger.error("Error loading state from URL:",t),this.afs.filter&&this.afs.filter.clearAllFilters()}}processFiltersFromURL(t){const e=this.afs.state.getState();let s=!1;const i=t.get("filterMode");i&&(e.filters.mode=i.toUpperCase());const a=t.get("groupMode");a&&(e.filters.groupMode=a.toUpperCase());for(const[i,a]of t.entries())this.isRegularFilter(i)&&a.split(",").filter(Boolean).forEach((t=>{s=!0,e.filters.current.add(`${i}:${t}`)}));for(const[s,i]of t.entries())if(s.startsWith("group_")){const a=s.replace("group_",""),r=t.get(`groupOp_${a}`)?.toUpperCase()||"OR";e.filters.groups.set(a,{filters:new Set(i.split(",")),operator:r})}s||0!==e.filters.groups.size||e.filters.current.add("*")}processRangesFromURL(t){const e=this.afs.state.getState();for(const[s,i]of t.entries())if(s.startsWith("range_")){const t=s.replace("range_",""),[a,r]=i.split(",").map(Number);e.filters.ranges.set(t,{currentMin:a,currentMax:r})}for(const[s,i]of t.entries())if(s.startsWith("dateRange_")){const t=s.replace("dateRange_",""),[a,r]=i.split(",").map((t=>new Date(t)));e.filters.dateRanges.set(t,{start:a,end:r})}}processSearchFromURL(t){const e=t.get("search")||"";this.afs.state.setState("search.query",e),this.afs.options.get("searchInput")&&(this.afs.options.get("searchInput").value=e)}processSortFromURL(t){const e=t.get("sort");if(e){const[t,s]=e.split(",");this.afs.state.setState("sort.current",{key:t,direction:s})}}processPaginationFromURL(t){const e=parseInt(t.get("page"))||1,s=parseInt(t.get("perPage"))||this.afs.options.get("pagination.itemsPerPage");this.afs.state.setState("pagination",{currentPage:e,itemsPerPage:s})}isRegularFilter(t){return!(["search","sort","page","perPage","filterMode","groupMode"].includes(t)||t.startsWith("group_")||t.startsWith("groupOp_")||t.startsWith("range_")||t.startsWith("dateRange_"))}clearURL(){window.history.pushState({},"",window.location.pathname),this.afs.state.reset(),this.afs.filter&&this.afs.filter.clearAllFilters()}getURLParams(){return new URLSearchParams(window.location.search)}hasParams(){return window.location.search.length>1}getParam(t){return new URLSearchParams(window.location.search).get(t)}}class u{constructor(t){this.afs=t,this.activeRanges=new Map,this.afs.styleManager||(this.afs.styleManager=new a(this.afs.options)),this.afs.styleManager.applyStyles()}addRangeSlider(t){let{key:e,type:s,container:i,min:a,max:r,step:n=1,ui:o}=t;if(this.afs.logger.debug(`Adding range slider for ${e}`),!i)return void this.afs.logger.error("Container element required for range slider");const l=this.calculateMinMax(e,s);a=a??l.min,r=r??l.max;const h={...this.afs.options.get("styles.slider.ui")||{showHistogram:!1,bins:10},...o},c=h.showHistogram?this.calculateHistogramData(e,h.bins):{counts:[],binEdges:[],max:0},g=this.createSliderElements(c,h),d=this.initializeState(a,r,n,s);d.ui=h,h.showHistogram&&(d.histogram=c),this.appendElements(i,g),this.setupEventHandlers(g,d,e),this.activeRanges.set(e,{state:d,elements:g}),this.updateSliderUI(e),h.showHistogram&&this.setupHistogramHighlight(g,d,c.binEdges),this.afs.logger.info(`Range slider added for ${e}`)}calculateMinMax(t,e){const s=Array.from(this.afs.items).map((s=>{const i=s.dataset[t];return"date"===e?new Date(i).getTime():parseFloat(i)})).filter((t=>!isNaN(t)));return{min:Math.min(...s),max:Math.max(...s)}}createSliderElements(t,e){const s=this.afs.options.get("styles")||this.afs.styleManager.defaultStyles,i=s.slider||this.afs.styleManager.defaultStyles.slider,a=s.colors||this.afs.styleManager.defaultStyles.colors,r=document.createElement("div");r.className="price-range-container";const n=document.createElement("div");n.className=i.class;const o=document.createElement("div");if(o.className=i.trackClass,e?.showHistogram&&t?.counts?.length>0){const e=this.createHistogramBars(t,a);n.appendChild(e)}const l=document.createElement("div");l.className=i.selectedClass;const h=document.createElement("div");h.className=i.thumbClass;const c=document.createElement("div");c.className=i.thumbClass;const g=document.createElement("div");g.className=i.valueClass;const d=document.createElement("div");return d.className=i.valueClass,n.appendChild(o),n.appendChild(l),n.appendChild(h),n.appendChild(c),n.appendChild(g),n.appendChild(d),r.appendChild(n),{container:r,slider:n,track:o,selectedRange:l,minThumb:h,maxThumb:c,minValue:g,maxValue:d}}createHistogram(t,e){const s=document.createElement("div");return s.className="afs-histogram",t.forEach(((t,i)=>{const a=document.createElement("div");a.className="afs-histogram-bar",a.style.height=`${t}%`,a.style.backgroundColor=e.histogram,s.appendChild(a)})),s}calculateHistogramData(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10;try{const s=Array.from(this.afs.items).map((e=>parseFloat(e.dataset[t]))).filter((t=>!isNaN(t)));if(0===s.length)return{counts:[],binEdges:[],max:0};const i=Math.min(...s),a=Math.max(...s),r=(a-i)/e,n=new Array(e).fill(0),o=new Array(e+1);for(let t=0;t<=e;t++)o[t]=i+t*r;s.forEach((t=>{if(t===a)return void n[n.length-1]++;const e=Math.floor((t-i)/r);n[e]++}));const l=Math.max(...n);return{counts:n.map((t=>Math.max(20,Math.round(t/l*100)))),binEdges:o,max:l,min:i,max:a}}catch(t){return this.afs.logger.error("Error calculating histogram:",t),{counts:[],binEdges:[],max:0}}}setupHistogramHighlight(t,e,s){const i=t.slider.querySelectorAll(".afs-histogram-bar"),a=()=>{const t=e.currentMin,a=e.currentMax;i.forEach(((e,i)=>{const r=s[i],n=s[i+1];r>=t&&n<=a?e.classList.add("active"):e.classList.remove("active")}))};this.afs.on("rangeFilter",(()=>a())),a()}createHistogramBars(t,e){const{counts:s}=t,i=document.createElement("div");return i.className="afs-histogram",s.forEach((t=>{const e=document.createElement("div");e.className="afs-histogram-bar",e.style.height=`${t}%`,i.appendChild(e)})),i}initializeState(t,e,s,i){return{min:t,max:e,currentMin:t,currentMax:e,step:s,type:i,isDragging:!1}}appendElements(t,e){const{slider:s,track:i,selectedRange:a,minThumb:r,maxThumb:n,minValue:o,maxValue:l}=e;s.appendChild(i),s.appendChild(a),s.appendChild(r),s.appendChild(n),s.appendChild(o),s.appendChild(l),t.appendChild(s)}setupEventHandlers(t,e,s){const{minThumb:i,maxThumb:a}=t,r=i=>a=>{a.preventDefault(),e.isDragging=!0;const r=a=>{const r=(n=a).touches?n.touches[0]:n;var n;this.createMoveHandler(t,e,s,i)(r)},n=()=>{e.isDragging=!1,window.removeEventListener("mousemove",r),window.removeEventListener("mouseup",n),window.removeEventListener("touchmove",r),window.removeEventListener("touchend",n),window.removeEventListener("touchcancel",n),this.applyFilter(s)};window.addEventListener("mousemove",r),window.addEventListener("mouseup",n),window.addEventListener("touchmove",r,{passive:!1}),window.addEventListener("touchend",n),window.addEventListener("touchcancel",n)};i.addEventListener("mousedown",r(!0)),i.addEventListener("touchstart",r(!0),{passive:!1}),a.addEventListener("mousedown",r(!1)),a.addEventListener("touchstart",r(!1),{passive:!1})}updateSliderUI(t){const{state:e,elements:s}=this.activeRanges.get(t),{minThumb:i,maxThumb:a,selectedRange:r,minValue:n,maxValue:o}=s,l=e.max-e.min,h=(e.currentMin-e.min)/l*100,c=(e.currentMax-e.min)/l*100,g=Math.max(0,Math.min(h,100)),d=Math.max(0,Math.min(c,100));i.style.left=`${g}%`,a.style.left=`${d}%`,r.style.left=`${g}%`,r.style.width=d-g+"%";const u="date"===e.type?t=>new Date(t).toLocaleDateString():t=>t.toFixed(2);n.textContent=u(e.currentMin),o.textContent=u(e.currentMax),n.style.left=`${g}%`,o.style.left=`${d}%`,n.style.transform=g<5?"translateX(0)":g>95?"translateX(-100%)":"translateX(-50%)",o.style.transform=d<5?"translateX(0)":d>95?"translateX(-100%)":"translateX(-50%)"}createMoveHandler(t,e,s,i){this.afs.logger.debug(`Creating move handler for ${s}`);const{track:a}=t;return l((t=>{const r=t.touches?t.touches[0].clientX:t.clientX,n=a.getBoundingClientRect(),o=n.width,l=.05*o,h=(r-n.left-l)/(o-2*l),c=Math.min(Math.max(0,h),1),g=e.min+(e.max-e.min)*c,d=Math.round(g/e.step)*e.step;i?e.currentMin=Math.min(d,e.currentMax):e.currentMax=Math.max(d,e.currentMin),this.updateSliderUI(s)}),16)}applyFilter(t){this.afs.logger.debug(`Applying range filter for ${t}`);const{state:e}=this.activeRanges.get(t);this.afs.items.forEach((s=>{const i="date"===e.type?new Date(s.dataset[t]).getTime():parseFloat(s.dataset[t]);i>=e.currentMin&&i<=e.currentMax?this.afs.showItem(s):this.afs.hideItem(s)})),this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("rangeFilter",{key:t,min:e.currentMin,max:e.currentMax})}getRangeValues(t){const e=this.activeRanges.get(t);return e?{min:e.state.currentMin,max:e.state.currentMax,type:e.state.type}:null}setRangeValues(t,e,s){const i=this.activeRanges.get(t);i&&(i.state.currentMin=e,i.state.currentMax=s,this.updateSliderUI(t),this.applyFilter(t))}removeRangeSlider(t){const e=this.activeRanges.get(t);e&&(e.elements.slider.remove(),this.activeRanges.delete(t),this.afs.logger.info(`Range slider removed for ${t}`))}}class f{constructor(t){this.afs=t,this.activeDateRanges=new Map,this.defaultFormat=this.afs.options.get("dateFormat")||"YYYY-MM-DD"}addDateRange(t){let{key:e,container:s,minDate:i,maxDate:a,format:r=this.defaultFormat}=t;if(this.afs.logger.debug(`Adding date range for ${e}`),!s)return void this.afs.logger.error("Container element required for date range");const n=this.calculateMinMaxDates(e);i=i??n.min,a=a??n.max;const o=this.createDateElements(),l=this.initializeState(i,a,r);this.appendElements(s,o),this.setupEventHandlers(o,l,e),this.activeDateRanges.set(e,{state:l,elements:o}),this.updateDateUI(e),this.afs.logger.info(`Date range added for ${e}`)}calculateMinMaxDates(t){try{const e=Array.from(this.afs.items).map((e=>{if(!e||!e.dataset||!e.dataset[t])return null;const s=new Date(e.dataset[t]);return isNaN(s.getTime())?null:s})).filter((t=>null!==t));if(0===e.length){const t=new Date;return{min:new Date(t.getFullYear(),0,1),max:new Date(t.getFullYear(),11,31)}}return{min:new Date(Math.min(...e)),max:new Date(Math.max(...e))}}catch(t){this.afs.logger.error("Error calculating date range:",t);const e=new Date;return{min:new Date(e.getFullYear(),0,1),max:new Date(e.getFullYear(),11,31)}}}createDateElements(){this.afs.logger.debug("Creating date picker elements");const t=document.createElement("div");t.className="afs-date-range-container";const e=document.createElement("div");e.className="afs-date-input-wrapper";const s=document.createElement("label");s.textContent="Start Date";const i=document.createElement("input");i.type="date",i.className="afs-date-input start-date";const a=document.createElement("div");a.className="afs-date-input-wrapper";const r=document.createElement("label");r.textContent="End Date";const n=document.createElement("input");return n.type="date",n.className="afs-date-input end-date",e.appendChild(s),e.appendChild(i),a.appendChild(r),a.appendChild(n),t.appendChild(e),t.appendChild(a),{container:t,startInput:i,endInput:n}}initializeState(t,e,s){return{minDate:t,maxDate:e,currentStartDate:t,currentEndDate:e,format:s}}appendElements(t,e){t.appendChild(e.container)}setupEventHandlers(t,e,s){this.afs.logger.debug(`Setting up event handlers for date range ${s}`);const{startInput:i,endInput:a}=t,r=l((()=>{const t=new Date(i.value),r=new Date(a.value);isNaN(t.getTime())||isNaN(r.getTime())||(e.currentStartDate=t,e.currentEndDate=r,this.applyDateFilter(s))}),300);i.addEventListener("change",r),a.addEventListener("change",r)}updateDateUI(t){try{const{state:e,elements:s}=this.activeDateRanges.get(t),{startInput:i,endInput:a}=s,r=t=>{try{const e=new Date(t);if(isNaN(e.getTime()))throw new Error("Invalid date");return e.toISOString().split("T")[0]}catch(t){return this.afs.logger.error("Error formatting date:",t),""}};i.min=r(e.minDate),i.max=r(e.maxDate),a.min=r(e.minDate),a.max=r(e.maxDate),i.value=r(e.currentStartDate),a.value=r(e.currentEndDate)}catch(t){this.afs.logger.error("Error updating date UI:",t)}}applyDateFilter(t){this.afs.logger.info(`Applying date filter for ${t}`);const{state:e}=this.activeDateRanges.get(t);this.afs.items.forEach((s=>{try{if(!s||!s.dataset||!s.dataset[t])return void this.afs.hideItem(s);const i=new Date(s.dataset[t]);if(isNaN(i.getTime()))return void this.afs.hideItem(s);const a=new Date(e.currentStartDate);a.setHours(0,0,0,0);const r=new Date(e.currentEndDate);r.setHours(23,59,59,999);const n=new Date(i);n.setHours(0,0,0,0),n>=a&&n<=r?this.afs.showItem(s):this.afs.hideItem(s)}catch(t){this.afs.logger.error("Error filtering item by date:",t),this.afs.hideItem(s)}})),this.afs.updateCounter(),this.afs.urlManager.updateURL(),this.afs.emit("dateFilter",{key:t,startDate:e.currentStartDate,endDate:e.currentEndDate})}getDateRange(t){const e=this.activeDateRanges.get(t);return e?{startDate:e.state.currentStartDate,endDate:e.state.currentEndDate}:null}setDateRange(t,e,s){const i=this.activeDateRanges.get(t);i&&(i.state.currentStartDate=e,i.state.currentEndDate=s,this.updateDateUI(t),this.applyDateFilter(t))}removeDateRange(t){const e=this.activeDateRanges.get(t);e&&(e.elements.container.remove(),this.activeDateRanges.delete(t),this.afs.logger.info(`Date range removed for ${t}`))}}const p="1.0.7";t.AFS=class extends r{constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(),this.initializeCore(t)}initializeCore(t){try{this.options=new s(t),this.logger=new e(this.options.get("debug")||!1,this.options.get("logLevel")||"info"),this.state=new i,this.styleManager=new a(this.options),this.initializeDOM(),this.initializeFeatures(),this.setupLifecycle()}catch(t){throw console.error("AFS initialization error:",t),t}}initializeDOM(){if(this.logger.debug("Initializing DOM elements"),this.container=document.querySelector(this.options.get("containerSelector")),!this.container)throw new Error(`Container not found: ${this.options.get("containerSelector")}`);this.items=this.container.querySelectorAll(this.options.get("itemSelector")),0===this.items.length&&this.logger.warn("No items found in container"),this.state.setState("items.total",this.items.length),this.state.setState("items.visible",new Set(this.items))}initializeFeatures(){this.logger.debug("Initializing features"),this.filter=new o(this),this.search=new h(this),this.sort=new c(this),this.rangeFilter=new u(this),this.urlManager=new d(this),this.dateFilter=new f(this),this.pagination=new g(this),this.styleManager.applyStyles(),this.urlManager.loadFromURL()}setupLifecycle(){this.options.get("responsive")&&window.addEventListener("resize",this.handleResize.bind(this)),this.options.get("preserveState")&&document.addEventListener("visibilitychange",this.handleVisibilityChange.bind(this)),this.options.get("observeDOM")&&this.setupMutationObserver(),this.emit("initialized",{itemCount:this.items.length,options:this.options.export()})}showItem(t){const e=this.state.getState().items.visible;e.add(t),this.state.setState("items.visible",e),t.classList.remove(this.options.get("hiddenClass")),t.style.opacity="0",t.style.transform="scale(0.95)",t.style.display="",t.offsetHeight;const s=this.options.get("transitionClass")||"afs-transition";t.classList.contains(s)||t.classList.add(s),requestAnimationFrame((()=>{requestAnimationFrame((()=>{t.style.opacity="1",t.style.transform="scale(1)"}))}));const i=this.options.get("animationDuration")||300;setTimeout((()=>{e.has(t)&&(t.style.transform="",t.style.opacity="")}),i)}hideItem(t){const e=this.state.getState().items.visible;e.delete(t),this.state.setState("items.visible",e);const s=this.options.get("transitionClass")||"afs-transition";t.classList.contains(s)||t.classList.add(s),requestAnimationFrame((()=>{t.style.opacity="0",t.style.transform="scale(0.95)"}));const i=this.options.get("animationDuration")||300;setTimeout((()=>{e.has(t)||(t.classList.add(this.options.get("hiddenClass")),t.style.transform="",t.style.opacity="")}),i)}addItems(t){const e=Array.isArray(t)?t:[t],s=document.createDocumentFragment();e.forEach((t=>{s.appendChild(t),this.state.getState().items.visible.add(t)})),this.container.appendChild(s),this.items=this.container.querySelectorAll(this.options.get("itemSelector")),this.filter.applyFilters()}removeItems(t){const e=Array.isArray(t)?t:[t],s=this.state.getState().items.visible;e.forEach((t=>{s.delete(t),t.remove()})),this.items=this.container.querySelectorAll(this.options.get("itemSelector")),this.updateCounter()}saveState(){if(!this.options.get("preserveState"))return;const t={filters:Array.from(this.filter.getActiveFilters()),search:this.search.getValue(),sort:this.sort.getCurrentSort(),pagination:this.pagination.getPageInfo(),timestamp:Date.now()};localStorage.setItem("afs_state",JSON.stringify(t)),this.logger.debug("State saved")}restoreState(){if(this.options.get("preserveState"))try{const t=localStorage.getItem("afs_state");if(!t)return;const e=JSON.parse(t);if(Date.now()-e.timestamp>this.options.get("stateExpiry"))return void localStorage.removeItem("afs_state");this.setState(e),this.logger.debug("State restored")}catch(t){this.logger.error("Error restoring state:",t)}}getState(){return this.state.export()}setState(t){this.state.import(t),this.refresh()}updateCounter(){const t=document.querySelector(this.options.get("counterSelector"));if(t)try{const e=this.items.length,i=this.state.getState().items.visible.size,a=e-i,r=this.options.get("counter")||s.defaults.counter,n=r.template||"Showing {visible} of {total}",o=r.formatter||(t=>t.toLocaleString()),l=o(i),h=o(e),c=o(a);let g=n.replace("{visible}",l).replace("{total}",h).replace("{filtered}",c);if(a>0&&r.showFiltered){g+=" "+(r.filteredTemplate||"({filtered} filtered)").replace("{filtered}",c)}0===i&&r.noResultsTemplate&&(g=r.noResultsTemplate),t.textContent=g,this.emit("counterUpdated",{total:e,visible:i,filtered:a,formattedTotal:h,formattedVisible:l,formattedFiltered:c})}catch(e){this.logger.error("Error updating counter:",e),t.textContent=`${this.state.getState().items.visible.size}/${this.items.length}`}}updateOptions(t){this.options.update(t),this.styleManager.updateStyles(t),this.refresh()}refresh(){this.logger.debug("Refreshing AFS"),this.items=this.container.querySelectorAll(this.options.get("itemSelector")),this.state.setState("items.total",this.items.length),this.filter.applyFilters(),this.search.search(this.search.getValue()),this.pagination.update(),this.emit("refreshed",{itemCount:this.items.length})}handleResize=(()=>l((()=>{this.emit("resize"),this.refresh()}),250))();handleVisibilityChange(){document.hidden?(this.emit("hidden"),this.saveState()):(this.emit("visible"),this.restoreState())}setupMutationObserver(){new MutationObserver((t=>{t.some((t=>"childList"===t.type))&&this.refresh()})).observe(this.container,{childList:!0,subtree:!0})}getVersion(){return p}isFeatureSupported(t){return!!{search:!!this.search,pagination:!0,animation:void 0!==document.createElement("div").style.transition,urlState:"function"==typeof window.history.pushState,localStorage:(()=>{try{return localStorage.setItem("test","test"),localStorage.removeItem("test"),!0}catch(t){return!1}})()}[t]}destroy(){this.logger.debug("Destroying AFS instance"),window.removeEventListener("resize",this.handleResize),document.removeEventListener("visibilitychange",this.handleVisibilityChange),this.filter.destroy(),this.search.destroy(),this.sort.destroy(),this.pagination.destroy(),this.rangeFilter.destroy(),this.styleManager.removeStyles(),this.state.reset(),localStorage.removeItem("afs_state"),this.items.forEach((t=>{t.style="",t.classList.remove(this.options.get("hiddenClass"),this.options.get("activeClass"))})),this.emit("destroyed")}},t.VERSION=p}));
|
|
2
2
|
//# sourceMappingURL=AFS.min.js.map
|