PageSourceSearch

https://ns-sesvete.hr/wp-content/plugins/eventON/assets/js/eventon_script.js?ver=5.0.8

js ns-sesvete.hr collected 2026-10-02 12:49:28 UTC 122,999 bytes, 3,432 lines download raw bytes

1/**
2 * Javascript code that is associated with the front end of the calendar
3 * @version 5.0.7
4 * @license EventON JavaScript Assets 
5 * Copyright (C) 2014-2026 Ashan Jay, AshanJay Designs LLC.
6 * 
7 * PROPRIETARY LICENSE - All Rights Reserved
8 * 
9 * Permission granted solely for personal use with valid EventON license.
10 * YOU MAY NOT: redistribute, resell, sublicense, or publish these Assets.
11 * 
12 * Trademark: "EventON" is a trademark of AshanJay Designs LLC.
13 * Contact: [email protected]
14 * 
15 * PROVIDED "AS IS" WITHOUT WARRANTY. VIOLATION MAY RESULT IN LEGAL ACTION.
16 */
17
18jQuery(document).ready(function($){
19
20	// restrict this only to frontend of the calendar
21	if ( evo_general_params != '' && evo_general_params !== undefined && evo_general_params.is_admin) return; 
22	
23	//return;
24	var BODY = $('body');
25	var BUS = ''; // initial eventon calendar data
26	var ajax_url = evo_general_params.ajaxurl;
27
28
29// EventON calendar main function
30	// Calendar processing 2.8.6 u 4.6
31	$.fn.evo_calendar = function (options) {
32
33		var el = this;
34		var cal = this;
35		var cal = {};
36		var calO = $.extend({
37			'SC': {},
38			'json':{},
39			'type':'init' ,
40			map_delay:0
41		}, options);
42		var SC = el.evo_shortcode_data();
43
44		
45		// load calendar eventcard and eventtop interactions
46		this.find('.eventon_list_event').each(function(){
47			evo_cal_eventcard_interactions( $(this) );
48		});
49
50		var init = function(){
51
52			// change IDs for map section for eventon widgets
53			if( $(el).hasClass('evcal_widget')){
54				$(el).find('.evcal_gmaps').each(function(){
55					var gmap_id = obj.attr('id');
56					var new_gmal_id =gmap_id+'_widget'; 
57					obj.attr({'id':new_gmal_id})
58				});
59			}
60
61			// load maps on calendar
62			_evo_run_eventcard_map_load();
63
64			// initial actions on calendar
65			$(el).evo_cal_filtering();
66
67			// localizing event time
68			$(el).evo_cal_localize_time();
69
70			// load lightbox events on page load
71			$(cal).evo_cal_oneevent_onload(calO.type);
72			
73			el.evo_cal_hide_data();	
74
75			live_now_cal();
76			counters();
77		};
78		
79		// support	
80			var live_now_cal = function(){
81				$(el).find('.evo_img_time').each(function(){
82					if( $(this).closest('a.desc_trig').find('em.evcal_time').length ){
83						_html = $(this).closest('a.desc_trig').find('em.evcal_time')[0].outerHTML;
84						$(this).html( _html );
85					}				
86				});
87			}
88
89			var counters = function(){
90				$(el).find('.evo_countdowner').each(function(){
91					$(this).evo_countdown();
92				});
93			}
94
95		init();	
96	};
97
98      
99// Event Card handling / Bind Event Listeners --- v4.6.1 @updated 5.0
100	var evo_eventcard_listeners = function(){
101
102		const EVO_Card_Listeners = {
103			E: {
104				B: $('body')
105			},
106			init(){
107				const { E } = this;
108				// Event listeners
109	            E.B.on('click.evoCard', '.evo_et_trigger', (e) => this.evo_handle_et_sidePanel(e));
110	            E.B.on('evo_ajax_success_evo_et_trigger.evoCard', (e, OO, data, el) => this.evo_handle_et_sp_content(e, OO, data, el));
111	            E.B.on('click.evoCard', '.tzo_trig', (e) => this.localizeTime(e));
112	            E.B.on('click.evoCard', '.evo_event_more_img', (e) => this.handle_event_more_img(e));
113	            E.B.on('click.evoCard', '.evo_img_triglb', (e) => this.handle_img_triglb(e));
114	            E.B.on('click.evoCard', '.evo_repeat_series_date', (e) => this.handle_repeat_series_date(e));
115	            E.B.on('click.evoCard', '.copy.evo_ss', (e) => this.handle_copy_event_link(e));
116	            E.B.on('click.evoCard', '.evo_copy_address', (e) => this.handle_copy_event_address(e));
117	            E.B.on('click.evoCard', '.evo_openmap_trig', (e) => this.handle_open_inmaps(e));
118	            E.B.on('click.evoCard', '.evo_locimg_more', (e) => this.handle_locimg_more(e));
119	            E.B.on('click.evoCard', '.evo_gal_icon', (e) => this.handle_gal_icon(e));
120	            E.B.on('click.evoCard', '.evobtn_details_show_more', (e) => this.handle_details_show_more(e));
121	            E.B.on('click.evoCard', '.evcal_close', (e) => this.handle_close_eventcard(e));
122	            E.B.on('click.evoCard', '.evocmd_button', (e) => this.handle_evocmd_button(e));
123	            E.B.on('click.evoCard', '.evo_org_clk_link', (e) => this.handle_org_clk_link(e));
124	            E.B.on('click.evoCard', '.editEventBtnET', (e) => this.handle_edit_event_button(e));
125	            E.B.on('click.evoCard', '.evo_organizer_more_trig', (e) => this.handle_organizer_more_details(e));
126			},
127
128			handle_organizer_more_details(e){
129				const { E } = this;
130		        const $el = $(e.currentTarget);
131		        $el.parent().hide();
132		        $el.parent().siblings('.evo_org_details_full').show().removeClass('evodni');
133			},
134
135			// actions
136				// Opens a side panel for event type triggers, adding a class and setting up data
137		        evo_handle_et_sidePanel(e) {
138		            const { E } = this;
139		            const $el = $(e.currentTarget);
140		            e.preventDefault();
141		            $el.addClass('evo_sp_trig_on');
142		            const aData = $el.data('d');
143		            aData.adata.data['nonce'] = evo_general_params.n;
144		            $el.evo_open_sidepanel(aData);
145		        },
146
147		        // Populates the side panel with content from an AJAX response and removes the loading bar
148		        evo_handle_et_sp_content(e, OO, data, el) {
149		            $(el).evo_populate_sidepanel(data.html);
150		            $('#evo_sp').find('.evo_loading_bar_holder').remove();
151		        },
152
153		        // Localizes the time display for elements with the tzo_trig class
154		        localizeTime(e) {
155		            e.preventDefault();
156		            e.stopPropagation();
157		            $(e.target).evo_localize_time();
158		        },
159
160		        // Changes the main event image when a thumbnail is clicked
161		        handle_event_more_img(e) {
162		            const $el = $(e.currentTarget);
163		            const box = $el.closest('.evcal_eventcard');
164		            const gal = $el.closest('.evocard_fti_in');
165
166		            if (box.length === 0) return;
167
168		            $el.siblings('span').removeClass('select');
169		            $el.addClass('select');
170
171		            const mainIMG = box.find('.evocard_main_image');
172		            mainIMG.data({
173		                h: $el.data('h'),
174		                w: $el.data('w'),
175		                f: $el.data('f')
176		            });
177
178		            if (mainIMG.hasClass('def')) {
179		                mainIMG.css('background-image', `url(${$el.data('f')})`);
180		            } else {
181		                mainIMG.html(`<span style="background-image:url(${$el.data('f')})"></span>`);
182		                mainIMG.eventon_process_main_ft_img();
183		            }
184		        },
185
186		        // Opens a lightbox to display a full-size event image when clicked
187		        handle_img_triglb(e) {
188		            const $el = $(e.currentTarget);
189
190		            if ($el.hasClass('inlb')) return;
191
192		            const __ac = parseInt($el.data('w')) >= parseInt($el.data('h')) ? 'iW' : 'iH';
193		            $el.evo_lightbox_open({
194		                uid: 'evocard_ft_img',
195		                lbc: 'evolb_ft_img',
196		                lbac: `within evocard_img ${__ac}`,
197		                content: `<img class='evocard_main_image inlb' src='${$el.data('f')}' data-w='${$el.data('w')}' data-h='${$el.data('h')}' style='max-width:100%; max-height:100%;'/>`,
198		                end: 'client',
199		                lb_padding: '',
200		                d: { event_id: $el.data('event_id'), ri: $el.data('ri') }
201		            });
202		        },
203
204		        // Navigates to a repeat event's date URL based on user interaction type
205		        handle_repeat_series_date(e) {
206		            const $el = $(e.currentTarget);
207		            if (!$el.parent().hasClass('clickable')) return;
208
209		            const ux = $el.data('ux');
210		            const URL = $el.data('l');
211		            if (ux === 'def') window.location = URL;
212		            if (ux === 'defA') window.open(URL, '_blank');
213		        },
214
215		        // Copies an event link to the clipboard and shows a temporary confirmation
216		        handle_copy_event_link(e) {
217		        	e.preventDefault();
218		            e.stopPropagation();
219		            const $el = $(e.currentTarget);
220		            const ROW = $el.closest('.evcal_evdata_row');
221		            const link = decodeURIComponent($el.data('l'));
222		            navigator.clipboard.writeText(link);
223
224		            const evo_card_socialshare_html = ROW.html();
225		            ROW.html(`<p style='display:flex'><i class='fa fa-check marr10'></i> ${$el.data('t')}</p>`);
226
227		            setTimeout(() => {
228		                ROW.html(evo_card_socialshare_html);
229		            }, 3000);
230		        },
231
232		        // copy event location address
233		        handle_copy_event_address(e){
234		        	e.preventDefault();
235		            e.stopPropagation();
236		        	const $el = $(e.currentTarget);
237		        	const content = decodeURIComponent($el.data('txt'));
238		        	navigator.clipboard.writeText(content);
239		        	$el.siblings('input').val( $el.data('t'));
240
241		        	setTimeout(() => {
242		                $el.siblings('input').val( content );
243		            }, 3000);
244		        },
245
246		        // open event location in maps
247		        handle_open_inmaps(e){
248		        	e.preventDefault();
249		            e.stopPropagation();
250		        	const $el = $(e.currentTarget);
251
252		        	const address = $el.data('d');
253		        	const ua = navigator.userAgent;
254				    // Mobile: try to open native app first
255				    if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('ipod')) {
256				        // Force Apple Maps APP
257				        window.location = 'maps://maps.apple.com/?q=' + address;
258				        // Fallback to web in new tab after 1 second if app didn't open
259				        setTimeout(() => {
260				            window.open('https://maps.apple.com/?q=' + address, '_blank');
261				        }, 1000);
262				    }
263				    else if (ua.includes('android')) {
264				        // Force Google Maps APP
265				        window.location = 'geo:0,0?q=' + address;
266				        setTimeout(() => {
267				            window.open('https://www.google.com/maps/search/?api=1&query=' + address, '_blank');
268				        }, 1000);
269				    }
270				    else {
271				        // Desktop or unknown → always open in new tab (your requirement)
272				        window.open('https://www.google.com/maps/search/?api=1&query=' + address, '_blank', 'noopener');
273				    }
274		        },
275
276		        // Toggles visibility of additional location images
277		        handle_locimg_more(e) {
278		            e.preventDefault();
279		            e.stopPropagation();
280		            $(e.currentTarget).closest('.evo_metarow_locImg').toggleClass('vis');
281		        },
282
283		        // Updates the gallery main image when a gallery icon is clicked
284		        handle_gal_icon(e) {
285		            e.preventDefault();
286		            e.stopPropagation();
287
288		            const $el = $(e.currentTarget);
289		            if ($el.hasClass('on')) return;
290		            $el.siblings('div').removeClass('on');
291		            $el.addClass('on');
292
293		            $el.closest('.evo_gal_box').find('.evo_gal_main_img')
294		                .css('background-image', `url(${$el.data('u')})`)
295		                .data('f', $el.data('u'))
296		                .data('h', $el.data('h'))
297		                .data('w', $el.data('w'));
298		        },
299
300		        // Toggles the display of additional event details
301		        handle_details_show_more(e) {
302		            e.preventDefault();
303		            this.control_more_less($(e.currentTarget));
304		        },
305
306		        // Closes the event card by sliding it up
307		        handle_close_eventcard(e) {
308		            e.preventDefault();
309		            $(e.currentTarget).closest('.evcal_eventcard').slide
309Up().removeClass('open');
310		        },
311
312		        // Redirects to a URL when an event command button is clicked
313		        handle_evocmd_button(e) {
314		            e.preventDefault();
315		            e.stopPropagation();
316
317		            const $el = $(e.currentTarget);
318		            const href = $el.data('href');
319		            if ($el.data('target') === 'yes') {
320		                window.open(href, '_blank');
321		            } else {
322		                window.location = href;
323		            }
324		        },
325
326		        // Opens an organizer's link in a new tab
327		        handle_org_clk_link(e) {
328		            window.open($(e.currentTarget).data('link'), '_blank');
329		        },
330
331		        // Redirects to the event edit page
332		        handle_edit_event_button(e) {
333		            e.stopPropagation();
334		            const href = $(e.currentTarget).attr('href');
335		            window.open(href);
336		        },
337
338		        // Controls the more/less toggle for event details display
339		        control_more_less(obj) {
340		            const content = obj.attr('content');
341		            const current_text = obj.find('.ev_more_text').html();
342		            const changeTo_text = obj.find('.ev_more_text').attr('data-txt');
343		            const cell = obj.closest('.evcal_evdata_cell');
344
345		            if (content === 'less') {
346		                cell.removeClass('shorter_desc');
347		                obj.attr('content', 'more');
348		                obj.find('.ev_more_arrow').removeClass('ard');
349		                obj.find('.ev_more_text').attr('data-txt', current_text).html(changeTo_text);
350		            } else {
351		                cell.addClass('shorter_desc');
352		                obj.attr('content', 'less');
353		                obj.find('.ev_more_arrow').addClass('ard');
354		                obj.find('.ev_more_text').attr('data-txt', current_text).html(changeTo_text);
355		            }
356		        }
357		};
358
359		EVO_Card_Listeners.init();		
360
361	}
362	var evo_cal_eventcard_interactions = function( EC , load_maps ){
363
364		// process featured image sizes
365		EC.find(".evocard_main_image").eventon_process_main_ft_img(  );		
366
367		// process content sliders
368		EC.find('.evo_elm_HCS').each(function(){
369			$(this).evoContentSlider();
370		});	
371
372		// countdown
373		EC.find('.evo_countdowner').each(function(){
374			var obj = $(this);
375			obj.removeClass('evo_cd_on');
376			obj.evo_countdown();
377		});
378		
379		$(window).on('resize',function(){
380			BODY.find(".evocard_main_image").each(function(){
381				$(this).eventon_process_main_ft_img();		
382			});
383			//EC.find(".evocard_main_image").eventon_process_main_ft_img();		
384		});
385	}
386	$.fn._evo_cal_eventcard_interactions = function( EC, load_maps){
387		evo_cal_eventcard_interactions( EC , load_maps);
388	}
389
390	// run all map waiting map @4.6.1
391	function _evo_run_eventcard_map_load(){
392		BODY.evo_run_eventcard_map_load();
393	}
394	$.fn.evo_run_eventcard_map_load = function(){
395
396		time = 600;
397
398		BODY.find('.evo_metarow_gmap').each(function(index){	
399			O = $(this);
400			if( !(O.is(":visible")) ) return;
401			O.evo_load_gmap({
402				map_canvas_id: O.attr('id'),
403				trigger_point:'evo_calendar',
404				delay: time
405			});
406			time += 600;
407		});			
408	}
409
410// EventTop Interactions v4.6
411	var evo_cal_eventtop_interactions = function( ET ){	}
412	
413// RUN on Page load
414	EVO_Global_Init();
415
416	function EVO_Global_Init(){
417
418		EVO_Interactions();
419
420		evo_eventcard_listeners();
421
422		// check if calendars are present in the page
423			var run_initload = false;
424
425			if( $('body').find('.ajde_evcal_calendar').length > 0 ) run_initload = true;
426			if( $('body').find('.ajax_loading_cal').length > 0 ) run_initload = true;
427			if( $('body').find('.eventon_single_event').length > 0 ) run_initload = true;
428
429			if(run_initload == false) return false;
430
431			var data_arg = {};	
432
433			BODY.trigger('evo_global_page_run');
434
435			data_arg['global'] = $('#evo_global_data').data('d');
436			data_arg['cals'] ={};	
437			data_arg['nonce'] = evo_general_params.n;				
438
439		// run through all the calendars on page
440			BODY.find('.ajde_evcal_calendar').each(function(){
441				const CAL = $(this);
442				var SC = CAL.evo_shortcode_data();
443
444				CAL.evo_pre_cal();
445
446				if( CAL.hasClass('ajax_loading_cal')){
447					data_arg['cals'][ CAL.attr('id')] = {};
448					data_arg['cals'][ CAL.attr('id')]['sc'] = SC;
449
450					BODY.trigger('evo_global_page_run_after', CAL , SC );// @4.6.1
451				}
452			});
453
454		BODY.evo_admin_get_ajax({
455			adata:{
456				data:data_arg,
457				a:'eventon_init_load',ajax_type:'endpoint',end:'client'
458			},
459			onSuccess:function( OO, data, LB){
460				$('#evo_global_data').data('d', data);
461
462				BUS = data;
463
464				// append html to calendars if present
465				if('cals' in data){
466					var time = 300;
467					$.each(data.cals, function(i,v){
468
469						setTimeout( function(){
470
471							CAL = BODY.find('#'+ i);
472							if(CAL.length === 0) return;
473							
474							if('html' in v){						
475								CAL.find('#evcal_list').html( v.html );
476								CAL.removeClass('ajax_loading_cal');
477								CAL.find('.evo_ajax_load_events').remove();
478							}	
479
480							// load SC and JSON to calendar
481							CAL.evo_cal_functions({action:'update_shortcodes',SC: v.sc});
482							CAL.evo_cal_functions({action:'update_json',json: v.json});
483							
484							$('body').trigger('evo_init_ajax_success_each_cal', [data, i, v, CAL]);
485
486						}, time);
487						time += 300;
488					});
489				}
490
491				$('body').trigger('evo_init_ajax_success', [data]);
492
493				// after timeout based cal loading, process all cals
494				setTimeout( function(){
495					BODY.find('.ajde_evcal_calendar').each(function(){
496						if( $(this).hasClass('.ajax_loading_cal') ) return;					
497						$(this).evo_calendar({'type':'complete'});
498					});
499				}, time );
500			},
501			onComplete:function( OO, data){
502				$('body').trigger('evo_init_ajax_completed', [data]);
503			}
504		});	
505
506		handlebar_additional_arguments();
507		
508		evo_cal_body_listeners();
509
510		// run basic countdown timers
511		BODY.find('.evo_countdowner').each(function(){
512			$(this).evo_countdown();
513		});
514	}
515
516
517
518// ELEMENTS u4.9
519	// tooltips
520		$('body').on('mouseover','.ajdeToolTip, .evotooltip, .evotooltipfree',function(event){
521			event.stopPropagation();
522			
523			const el = $(this);
524			if(el.hasClass('show')) return;
525
526			var free = el.hasClass('free') || el.hasClass('evotooltipfree');
527			var content =  el.data('d') || el.attr('title') || '';
528			if (!content) return;
529
530			var p = el.position();			
531			var cor = getCoords(event.target);
532
533			$('.evo_tooltip_box').removeClass('show').removeClass('L').html( content );
534			var box_height = $('.evo_tooltip_box').height();
535			var box_width = $('.evo_tooltip_box').width();
536			var top = cor.top - 55 - box_height + (free ? 20 : 0);
537
538			$('.evo_tooltip_box').css({'top': top, 'left': ( cor.left + 5 ) })
539				.addClass('show');
540
541			// left align
542			if( $(this).hasClass('L')){
543				$('.evo_tooltip_box').css({'left': (cor.left - box_width - 15) }).addClass('L');			
544			}
545		})
546		.on('mouseout','.ajdeToolTip, .evotooltip, .evotooltipfree',function(e){	
547			event.stopPropagation();
548			var relatedTarget = $(event.relatedTarget);
549			var target = $(this);
550
551			$('.evo_tooltip_box').removeClass('show');
552		});
553
554		function getCoords(elem) { // crossbrowser version
555		    var box = elem.getBoundingClientRect();
556		    //console.log(box);
557
558		    var body = document.body;
559		    var docEl = document.documentElement;
560
561		    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
562		    var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
563
564		    var clientTop = docEl.clientTop || body.clientTop || 0;
565		    var clientLeft = docEl.clientLeft || body.clientLeft || 0;
566
567		    var top  = box.top +  scrollTop - clientTop;
568		    var left = box.left + scrollLeft - clientLeft;
569
570		    return { top: Math.round(top), left: Math.round(left) };
571		}
572	// yes no button		
573		$('body').on('click','.ajde_yn_btn ', function(event){
574
575			// stop this code from working on wp-admin
576			if($('body').hasClass('wp-admin')) return false; 
577			
578			var obj = $(this);
579			var afterstatement = obj.attr('afterstatement');
580				afterstatement = (afterstatement === undefined)? obj.attr('data-afterstatement'): afterstatement;	
581			var uid = '';
582
583			// yes
584			if(obj.hasClass('NO')){					
585				obj.removeClass('NO');
586				obj.siblings('input').val('yes');
587
588				// afterstatment
589				if(afterstatement!=''){
590					var type = (obj.attr('as_type')=='class')? '.':'#';
591					if( obj.data('uid') !== undefined) uid = obj.data('uid');
592					$(type+ afterstatement).slideDown('fast');						
593				}
594
595			}else{//no
596				obj.addClass('NO');
597				obj.siblings('input').val('no');
598				
599				if(afterstatement!=''){
600					var type = (obj.attr('as_type')=='class')? '.':'#';
601					$(type+ afterstatement ).slideUp('fast');
602				}
603			}
604		});
605
606	// content slider v4.9.13
607		// jQuery plugin for content slider
608	    $.fn.evoContentSlider = function() {
609	        return this.each(function() {
610	            const $slider = $(this);
611	            const $inner = $slider.find('.evo_elm_HCS_in');
612	            const scrollAmount = 10; // Wheel scroll speed
613	            let scrollTimeout;
614
615	            // Initial button visibility
616	            updateButtonVisibility($slider);
617
618	            $slider.data('evo-slider-initialized', true);
619
620	            // Button click handler
621	            $slider.on('click', '.evo_elmHCS_nav.content_slide_trig', function() {
622	                const $button = $(this);
623	                const scrollDistance = parseInt($slider.width()) / 2;
624	                const currentScroll = $inner.scrollLeft();
625	                let newScroll;
626
627	                if ($button.hasClass('HCSnavR')) {
628	                    newScroll = currentScroll + scrollDistance;
629	                    $slider.find('.HCSnavL')[0].classList.add('vis');
630	                } else {
631	                    newScroll = Math.max(0, currentScroll - scrollDistance);
632	                }
633
634	                $inner.animate({ scrollLeft: newScroll }, 200, () => {
635	                    updateButtonVisibility($slider);
636	                });
637	            });
638
639	            // Wheel scrolling
640	            $inner[0].addEventListener('wheel', function(e) {
641	                e.preventDefault();
642	                const delta = e.deltaY;
643	                const scrollableLength = this.scrollWidth - parseInt($slider.width());
644	                const newScroll = Math.max(0, Math.min($inner.scrollLeft() + (delta > 0 ? scrollAmount : -scrollAmount), scrollableLength));
645	                $inner.scrollLeft(newScroll);
646	                updateButtonVisibility($slider);
647	            }, { passive: false });
648
649	            // Touch scrolling
650	            $inner[0].addEventListener('scroll', function() {
651	                clearTimeout(scrollTimeout);
652	                scrollTimeout = setTimeout(() => {
653	                    updateButtonVisibility($slider);
654	                }, 100);
655	            });
656	        });
657	    };
658
659	    // Add reload method
660	    $('body').on('evo_reload_slider', function(event, $slider){
661	    	updateButtonVisibility($slider);
662	    });
663		
664
665	    // Update button visibility
666	    function updateButtonVisibility($slider) {
667	    	const $inner = $slider.find('.evo_elm_HCS_in');
668	        const scrollableLength = $inner[0].scrollWidth - parseInt($slider.width());
669	        const currentScroll = $inner.scrollLeft();
670	        const leftButton = $slider.find('.HCSnavL')[0];
671	        const rightButton = $slider.find('.HCSnavR')[0];
672
673	        if (scrollableLength <= 0) {
674	            leftButton.classList.remove('vis');
675	            rightButton.classList.remove('vis');
676	            return;
677	        }
678
679	        leftButton.classList.toggle('vis', currentScroll >= 10);
680	        rightButton.classList.toggle('vis', currentScroll < scrollableLength - 5);
681	    }
682
683	    // Debounced resize handler
684	    let resizeTimeout;
685	    $(window).on('resize', function() {
686	        clearTimeout(resizeTimeout);
687	        resizeTimeout = setTimeout(() => {
688	            $('.evo_elm_HCS').each(function() {
689	                updateButtonVisibility($(this), $(this).find('.evo_elm_HCS_in'));
690	            });
691	        }, 100);
692	    });
693
694	    BODY.find('.evo_elm_HCS').each( function(event){
695			$(this).evoContentSlider();
696		});
697
698	// dynamic select @4.8.2
699		BODY.on('click', '.evo_elm_dynamic_select_trig',function(e){
700			e.preventDefault();
701			const btn = $(this);
702		    const row = btn.closest('.evo_elm_dynamic_select');
703		    const list = btn.find('.evoelm_ds_list');
704
705		    row.toggleClass('open');
706		    btn.toggleClass('open');
707
708			if (btn.hasClass('open')) {
709		        const options = btn.siblings('div').data('d');
710		        let html = `<div class="evoelm_ds_list evobr10 evodfx evofx_dr_c evobgcw evofz14 evoff_2 evo_ofh evoposa evoleft0 " role="listbox" aria-labelledby="selected-option">`;
711
712		        $.each(options, (index, value) => {
713		            html += `<span class="evoelm_ds_list_item evopad10 evocurp evoborderb" role="option" tabindex="-1" data-index="${index}">${value}</span>`;
714		        });
715
716		        html += '</div>';
717		        btn.append(html);
718		    } else {
719		        list.remove();
720		    }
721		});
722
723		$(document).click(function(event){
724			if( !$(event.target).closest('.evo_elm_dynamic_select').length){
725				const openBox = BODY.find('.evo_elm_dynamic_select.open');
726		        openBox.removeClass('open').find('button').removeClass('open');
727		        openBox.find('.evoelm_ds_list').remove();
728			}	
729		});
730
731		// item clicked from the list
732		BODY.on('click','.evoelm_ds_list_item',function(event){
733			const item = $(this);
734		    const box = item.closest('.evo_elm_dynamic_select');
735		    const value = item.data('index');
736
737		    // update focus item name
738		    box.find('.evoelm_ds_current').html( item.html() );
739
740		    // set new value to input
741		    box.find('input').val( value );
742
743		    // plug for others
744			BODY.trigger('evoelm_dynamic_select_clicked', [ item, value, box ]);
745
746			box.removeClass('open');
747            box.find('button').removeClass('open');
748            item.parent().remove();
749
750		});
751
752
753	// Image Select @added 4.9 @updated: 5.0.3	
754		var file_frame;	
755		var __img_index;
756		var __img_obj;
757		var __img_box;
758		var __img_type;
759	  
760	    BODY.on('click','.evolm_img_select_trig',function(event) {
761	    	event.preventDefault();
762	    	//console.log('ef');
763
764	    	const $trigger = $(this);
765	    	const __img_obj = $(this);
766	    	const $row = $trigger.closest('.evo_elm_row');
767	    	const __img_box = __img_obj.closest('.evo_metafield_image');
768	    	const __img_actions = __img_obj.closest('.evolm_img_actions');
769	    	const __img_type = __img_box.hasClass('multi')? 'multi': 'single';
770	    	const uploaderId = $row.data('id');
771
772	    	if( __img_type == 'single' &&  __img_box.hasClass('has_img') ) return;
773	    	if( __img_type == 'multi'){
774	    		__img_index = __img_obj.data('index');
775
776	    		// remove image
777				if( __img_obj.hasClass('on')){
778					__img_obj.css('background-image', '').removeClass('on');
779					__img_obj.find('input').val( '' );
780					return;
781				}
782	    	}
783
784	    	// Reset file_frame to avoid stale state
785	        if (file_frame) {     file_frame.close(); file_frame = null;   }
786
787			// Get user_id (0 for non-logged-in users)
788	        var user_id = __img_actions.data('userid') ? parseInt(__img_actions.data('userid')) : 0;
789	        var library_args = { type: 'image' };
790	        if (user_id > 0) { library_args.author = user_id; }
791
792	        //console.log(library_args);
793
794			// Create the media frame
795			file_frame = wp.media.frames.downloadable_file = wp.media({
796				title: 'Choose an Image', 
797				button: {text: 'Use Image'},	
798				multiple: false,
799				library: library_args,
800			});
801
802			// Attache unique ID
803			if( uploaderId != '' || uploaderId !== undefined){
804				//console.log(uploaderId);
805				file_frame.uploaderId = uploaderId;
806			}
807
808
809			// When an image is selected, run a callback.
810			file_frame.on( 'select', function() {
811				var selection = file_frame.state().get('selection');
812        		//console.log('Selection:', selection.toJSON());
813
814        		if (selection.length > 0) {
815	                var attachment = selection.first().toJSON();
816	                //console.log('Selected attachment:', attachment);
817
818	                if (__img_type == 'single') {
819	                    __img_box.addClass('has_img');
820	                    __img_box.find('input.evo_meta_img').val(attachment.id);
821	                    __img_box.find('.evoelm_img_holder').css('background-image', 'url(' + attachment.url + ')');
822	                    //console.log('Single image updated:', __img_box.find('.evoelm_img_holder').css('background-image'));
823	                } else {
824	                    __img_obj.css('background-image', 'url(' + attachment.url + ')').addClass('on');
825	                    __img_obj.find('input').val(attachment.id);
826	                    //console.log('Multi image updated:', __img_obj.css('background-image'));
827	                }
828	            } else {
829	                console.log('No image selected');
830	            }
831
832			});
833
834			// Handle errors
835	        file_frame.on('error', function(error) {
836	            console.error('Media Uploader Error:', error); alert('Error: ' + error.message);
837	        });
838
839			// Finally, open the modal.
840			file_frame.open();
841			
842	    });  
843		// remove image
844		BODY.on('click','.evoel_img_remove_trig',function(){
845
846			const field = $(this).closest('.evo_metafield_image');
847			if( !(field.hasClass('has_img') ) ) return;
848			
849			field.removeClass('has_img');
850			field.find('input').val('');
851			field.find('button').addClass('chooseimg');
852			field.find('.evoelm_img_holder').css('background-image', '' );
853		});
854
855	// plus minus changer @updated 4.9
856		$('body').on('click','.evo_plusminus_change', function(event){
857
858			// only run on frontend
859			if( evo_general_params.cal.is_admin ) return;
860
861	        OBJ = $(this);
862
863	        QTY = parseInt(OBJ.siblings('input').val());
864	        MAX = OBJ.siblings('input').data('max');        
865	        if(!MAX) MAX = OBJ.siblings('input').attr('max');           
866
867	        NEWQTY = (OBJ.hasClass('plu'))?  QTY+1: QTY-1;
868
869	        NEWQTY =(NEWQTY <= 0)? 0: NEWQTY;
870
871	        // can not go below 1
872	        if( NEWQTY == 0 && OBJ.hasClass('min') ){    return;    }
873
874	        NEWQTY = (MAX!='' && NEWQTY > MAX)? MAX: NEWQTY;
875	        if( isNaN( NEWQTY ) ) NEWQTY = 0;
876
877	        OBJ.siblings('input').val(NEWQTY).attr('value',NEWQTY);
878
879	        if( QTY != NEWQTY) $('body').trigger('evo_plusminus_changed',[NEWQTY, MAX, OBJ]);
880	       
881	        if(NEWQTY == MAX){
882	            PLU = OBJ.parent().find('b.plu');
883	            if(!PLU.hasClass('reached')) PLU.addClass('reached');   
884
885	            if(QTY == MAX)   $('body').trigger('evo_plusminus_max_reached',[NEWQTY, MAX, OBJ]);                 
886	        }else{            
887	            OBJ.parent().find('b.plu').removeClass('reached');
888	        } 
889	    });
890
891// CAL BODY Listeners
892	function evo_cal_body_listeners(){
893		BODY.evo_cal_lb_listeners();
894
895		const EVO_Listeners = {
896			E: {	
897				B: $('body')	
898			},
899			init(){
900				const { B } = this.E;
901
902				// FAQ toggle
903            	B.on('click.evoCal', '.evo_faq_toggle', (e) => this.handle_faq_toggle(e));
904				
905				// General AJAX trigger
906            	B.on('click.evoCal', '.evo_trig_ajax', (e) => this.handle_general_ajax(e));
907
908	            // Event anywhere lightbox trigger
909	            B.on('click.evoCal', '.eventon_anywhere.evoajax', (e) => this.handle_event_anywhere(e));
910
911	            // No events button click
912	            B.on('click.evoCal', '.evo_no_events_btn', (e) => this.handle_no_events_btn(e));
913
914	            // Month switch arrows
915	            B.on('click.evoCal', '.evcal_arrows', (e) => this.handle_month_switch(e));
916
917	            // Show more events
918	            B.on('click.evoCal', '.evoShow_more_events', (e) => this.handle_show_more_events(e));
919
920	            // Refresh event top (placeholder)
921	            B.on('runajax_refresh_eventtop.evoCal', (e, OBJ, nonce) => this.handle_refresh_eventtop(e, OBJ, nonce));
922
923	            // Event card slide down complete
924	            B.on('evo_slidedown_eventcard_complete.evoCal', (e, event_id, obj, is_slide_down) => this.handle_slidedown_complete(e, event_id, obj, is_slide_down));
925
926	            // Jumper month/year switch
927	            B.on('calendar_month_changed.evoCal', (e, CAL) => this.handle_calendar_month_changed(e, CAL));
928
929	            // Go to today button
930	            B.on('click.evoCal', '.evo-gototoday-btn', (e) => this.handle_gototoday_btn(e));
931
932	            // Refresh now calendar
933	            B.on('runajax_refresh_now_cal.evoCal', (e, OBJ, nonce) => this.handle_refresh_now_cal(e, OBJ, nonce));
934
935	            // Calendar header buttons
936	            this.handle_cal_head_interactions();	            
937	            B.on('show_cal_head_btn.evoCal', (e, obj) => this.handle_show_cal_head_btn(e, obj));
938	            B.on('hide_cal_head_btn.evoCal', (e, obj) => this.handle_hide_cal_head_btn(e, obj));
939
940	            // Tile box style 3 click
941	            B.on('click.evoCal', '.ajde_evcal_calendar.boxstyle3 .eventon_list_event', (e) => this.handle_tile_box_click(e));
942
943	            // Event card opening
944	           	B.on('click.evoCal', '.eventon_list_event .desc_trig', (e) => this.handle_desc_trig(e));
945	           		            
946			},
947			// Toggles FAQ answer visibility and updates icon
948	        handle_faq_toggle(e) {
949	            const toggle = $(e.currentTarget);
950	            const answer = toggle.next('.evo_faq_answer');
951	            const icon = toggle.find('i.fa');
952	            answer.toggle();
953	            icon.toggleClass('fa-plus fa-minus');
954	        },
955	        // Triggers general AJAX request with data from the clicked element
956	        handle_general_ajax(e) {
957	            const obj = $(e.target);
958	            let ajax_data = obj.data();
959	            $(document).data('evo_data', ajax_data);
960	            this.E.B.trigger('evo_before_trig_ajax', [obj]);
961	            const new_ajax_data = $(document).data('evo_data');
962	            new_ajax_data['nn'] = the_ajax_script.postnonce;
963	            $.ajax({
964	                beforeSend: () => {
965	                    this.E.B.trigger('evo_beforesend_trig_ajax', [obj, new_ajax_data]);
966	                },
967	                type: 'POST',
968	                url: get_ajax_url('eventon_gen_trig_ajax'),
969	                data: new_ajax_data,
970	                dataType: 'json',
971	                success: (return_data) => {
972	                    this.E.B.trigger('evo_success_trig_ajax', [obj, new_ajax_data, return_data]);
973	                },
974	                complete: () => {
975	                    this.E.B.trigger('evo_complete_trig_ajax', [obj, new_ajax_data]);
976	                }
977	            });
978	        },
979	        // Triggers lightbox for event anywhere links
980	        handle_event_anywhere(e) {
981	            e.preventDefault();
982	            const obj = $(e.currentTarget);
983	            const data = obj.data('sc');
984	            if (data.ev_uxval == '4') return;
985	            data['evortl'] = 'no';
986	            if ('id' in data) data['event_id'] = data.id;
987	            data['ux_val'] = '3a';
988	            data['ajax_eventtop_show_content'] = false;
989	            obj.evo_cal_lightbox_trigger(data, obj, false);
990	        },
991
992	        // Handles click on no events button
993	        handle_no_events_btn(e) {
994	            this.E.B.trigger('click_on_no_event_btn', [$(e.currentTarget)]);
995	        },
996
997	        // Switches calendar month on arrow click
998	        handle_month_switch(e) {
999	            e.preventDefault();
1000	            const CAL = $(e.currentTarget).closest('.ajde_evcal_calendar');
1001	            let dir = $(e.currentTarget).hasClass('evcal_btn_prev') ? 'prev' : 'next';
1002	            const cal_id = CAL.attr('id');
1003	            if (CAL.hasClass('evortl')) {
1004	                dir = dir == 'next' ? 'prev' : 'next';
1005	            }
1006	            if ($(e.currentTarget).closest('.evo_footer_nav').length > 0) {
1007	                const BOX = $(e.currentTarget).closest('.evo_footer_nav');
1008	                const offset = BOX.offset();
1009	                const scrolltop = $(window).scrollTop();
1010	                const viewport_top = offset.top - scrolltop;
1011	                CAL.addClass('nav_from_foot').data('viewport_top', viewport_top);
1012	            }
1013	            run_cal_ajax(cal_id, dir, 'switchmonth');
1014	        },
1015
1016	        // Shows more events in the calendar list
1017	        handle_show_more_events(e) {
1018	            const CAL = $(e.currentTarget).closest('.ajde_evcal_calendar');
1019	            const SC = CAL.evo_shortcode_data();
1020	            const OBJ = $(e.currentTarget);
1021	            if (SC.show_limit_redir !== '') {
1022	                window.location = SC.show_limit_redir;
1023	                return false;
1024	            }
1025	            if (SC.show_limit_ajax == 'yes') {
1026	                const CURRENT_PAGED = parseInt(SC.show_limit_paged);
1027	                CAL.evo_update_cal_sc({ F: 'show_limit_paged', V: CURRENT_PAGED + 1 });
1028	                run_cal_ajax(CAL.attr('id'), 'none', 'paged');
1029	            } else {
1030	                const event_count = parseInt(SC.event_count);
1031	                const eventList = OBJ.parent();
1032	                const allEvents = eventList.find('.eventon_list_event').length;
1033	                const currentShowing = eventList.find('.eventon_list_event:visible').length;
1034	                for (let x = 1; x <= event_count; x++) {
1035	                    const inde = currentShowing + x - 1;
1036	                    eventList.find(`.eventon_list_event:eq(${inde})`).slideDown();
1037	                }
1038	                if (allEvents >
1038= currentShowing && allEvents <= (currentShowing + event_count)) {
1039	                    OBJ.fadeOut();
1040	                }
1041	            }
1042	        },
1043
1044	        // Placeholder for refreshing event top
1045	        handle_refresh_eventtop(e, OBJ, nonce) {},
1046
1047	        // Processes event card interactions after slide down
1048	        handle_slidedown_complete(e, event_id, obj, is_slide_down) {
1049	            if (!is_slide_down) return;
1050	            setTimeout(() => {
1051	                const OO = obj.closest('.eventon_list_event');
1052	                evo_cal_eventcard_interactions(OO, true);
1053	            }, 300);
1054	        },
1055
1056	        // Updates jumper UI when calendar month changes
1057	        handle_calendar_month_changed(e, CAL) {
1058	            const SC = CAL.evo_shortcode_data();
1059	            const B = CAL.find('.evo-gototoday-btn');
1060	            const O = CAL.find('.evo_j_container');
1061	            O.find('.evo_j_months a').removeClass('set');
1062	            O.find(`.evo_j_months a[data-val="${SC.fixed_month}"]`).addClass('set');
1063	            O.find('.evo_j_years a').removeClass('set');
1064	            O.find(`.evo_j_years a[data-val="${SC.fixed_year}"]`).addClass('set');
1065	            if (SC.fixed_month != B.data('mo') || SC.fixed_year != B.data('yr')) {
1066	                this.E.B.trigger('show_cal_head_btn', [B]);
1067	            } else {
1068	                this.E.B.trigger('hide_cal_head_btn', [B]);
1069	            }
1070	        },
1071
1072	        // Navigates to today’s date on calendar
1073	        handle_gototoday_btn(e) {
1074	            const obj = $(e.currentTarget);
1075	            const CAL = obj.closest('.ajde_evcal_calendar');
1076	            const calid = CAL.attr('id');
1077	            CAL.evo_update_cal_sc({ F: 'fixed_month', V: obj.data('mo') });
1078	            CAL.evo_update_cal_sc({ F: 'fixed_year', V: obj.data('yr') });
1079	            run_cal_ajax(calid, 'none', 'today');
1080	            this.E.B.trigger('hide_cal_head_btn', [obj]);
1081	        },
1082
1083	        // Refreshes now calendar via AJAX
1084	        handle_refresh_now_cal(e, OBJ, nonce) {
1085	            const section = OBJ.closest('.evo_eventon_live_now_section');
1086	            const CAL = section.find('.ajde_evcal_calendar').eq(0);
1087	            const dataA = {
1088	                nonce: evo_general_params.n,
1089	                other: OBJ.data(),
1090	                SC: CAL.evo_shortcode_data()
1091	            };
1092	            $.ajax({
1093	                beforeSend: () => {
1094	                    section.addClass('evoloading');
1095	                },
1096	                type: 'POST',
1097	                url: get_ajax_url('eventon_refresh_now_cal'),
1098	                data: dataA,
1099	                dataType: 'json',
1100	                success: (data) => {
1101	                    if (data.status == 'good') {
1102	                        section.html(data.html);
1103	                        this.E.B.trigger('evo_refresh_designated_elm', [OBJ, 'evo_vir_data']);
1104	                    }
1105	                },
1106	                complete: () => {
1107	                    section.removeClass('evoloading');
1108	                    this.E.B.find('.evo_countdowner').each(function() {
1109	                        $(this).evo_countdown();
1110	                    });
1111	                }
1112	            });
1113	        },
1114
1115	        // Toggles visibility of calendar header buttons
1116	        handle_cal_head_interactions() {
1117	        	const { B } = this.E;
1118	        	B.on('click.evoCal', '.cal_head_btn', (e) => {
1119	        		const obj = $(e.currentTarget);
1120		            if (obj.hasClass('vis')) {
1121		                this.E.B.trigger('hide_cal_head_btn', [obj]);
1122		            } else {
1123		                this.E.B.trigger('show_cal_head_btn', [obj]);
1124		            }
1125	        	});
1126	        	// when a header button is clicked
1127				B.on('evo_cal_header_btn_clicked',function(event, O, CAL){
1128
1129					var SC = CAL.evo_shortcode_data();	
1130
1131					// if search is open on init > return
1132					if( evo_general_params.cal.search_openoninit ) return;
1133
1134					if( O.hasClass('evo-search')){
1135						if( O.hasClass('vis')){
1136							CAL.find('.evo_search_bar').show(1, function(){
1137								$(this).find('input').focus();
1138							});
1139						}else{
1140							CAL.find('.evo_search_bar').hide();
1141						}
1142					}
1143
1144					// hide the search
1145					if( O.hasClass('evo-sort-btn') || O.hasClass('evo-filter-btn')){
1146						CAL.find('.evo_search_bar').hide();
1147					}
1148				});
1149	            
1150	        },
1151
1152	        // Shows calendar header button
1153	        handle_show_cal_head_btn(e, obj) {
1154	            if (!obj.hasClass('evo-gototoday-btn')) {
1155	                obj.siblings(':not(.evo-gototoday-btn)').removeClass('show vis');
1156	            }
1157	            obj.addClass('show vis');
1158	            const CAL = obj.closest('.ajde_evcal_calendar');
1159	            this.E.B.trigger('evo_cal_header_btn_clicked', [obj, CAL, 'show']);
1160	        },
1161
1162	        // Hides calendar header button
1163	        handle_hide_cal_head_btn(e, obj) {
1164	            const CAL = obj.closest('.ajde_evcal_calendar');
1165	            obj.removeClass('show vis');
1166	            this.E.B.trigger('evo_cal_header_btn_clicked', [obj, CAL, 'hide']);
1167	        },
1168
1169	        // Triggers desc_trig click for tile box style 3
1170	        handle_tile_box_click(e) {
1171	            e.preventDefault();
1172	            e.stopPropagation();
1173	            $(e.currentTarget).find('.desc_trig').trigger('click');
1174	        },
1175
1176	        // Handles event card opening with various user interactions
1177	        handle_desc_trig(e) {
1178	        	e.preventDefault();
1179	            const $this = $(e.currentTarget);
1180	            const $eventBox = $this.closest('.eventon_list_event');
1181
1182	            /// stop this operation for single event box - it is controlled seperately
1183	            if( $this.closest('.eventon_single_event').length > 0 ) return;
1184
1185	            const $cal = $this.closest('.evo_lightbox').data('cal_id') ?
1186	                $('#' + $this.closest('.evo_lightbox').data('cal_id')) :
1187	                $this.closest('.ajde_evcal_calendar');
1188	            const SC = $cal.evo_shortcode_data();
1189	            const ux_val = $cal.evo_cal_event_get_uxval(SC, $this);
1190	            const event_id = $eventBox.data('event_id');
1191	            const exlk = $this.data('exlk');
1192	            const isSingleEventBox = $this.closest('.eventon_single_event').length > 0 && $cal.find('.evo-data').data('exturl');
1193
1194
1195	            const actions = {
1196	                '3': () => this.open_lightbox($this, $cal, SC, event_id, $eventBox, ux_val),
1197	                '3a': () => this.open_lightbox($this, $cal, SC, event_id, $eventBox, ux_val),
1198	                '4': () => this.open_url($this, $this.attr('href') || $this.parent().siblings('.evo_event_schema').find('a').attr('href'), '_self'),
1199	                '4a': () => this.open_url($this, $this.attr('href') || $this.parent().siblings('.evo_event_schema').find('a').attr('href'), '_blank'),
1200	                '2': () => this.handle_external_link($this, isSingleEventBox),
1201	                'X': () => false,
1202	                'none': () => false,
1203	                'default': () => exlk === '1' ? this.handle_external_link($this, isSingleEventBox) : this.slide_down_event_card($this, $eventBox, $cal, SC, event_id)
1204	            };
1205
1206	            return (actions[ux_val] || actions['default'])();
1207	        },
1208
1209	        // Opens lightbox for event content
1210	        open_lightbox($trigger, $cal, SC, event_id, $eventBox, ux_val) {
1211	            const repeat_interval = parseInt($eventBox.data('ri')) || 0;
1212	            const etttc_class = $cal.attr('class').split(' ').find(cls => cls.startsWith('etttc_')) || '';
1213	            const new_SC_data = {
1214	                ...SC,
1215	                repeat_interval,
1216	                event_id,
1217	                ux_val,
1218	                evortl: $trigger.closest('.eventon_events_list').hasClass('evortl') ? 'yes' : 'no',
1219	                ajax_eventtop_show_content: true,
1220	                additional_class: etttc_class
1221	            };
1222	            $cal.evo_cal_lightbox_trigger(new_SC_data, $trigger, $cal);
1223	            return false;
1224	        },
1225
1226	        // Opens a URL in specified target
1227	        open_url($this, url, target) {
1228	        	target = $this.attr('target') === '_blank' ? '_blank' : target;
1229			    if (url) window.open(url, target);
1230			    return target === '_blank';
1231	        },
1232
1233	        // Handles external link navigation
1234	        handle_external_link($trigger, isSingleEventBox) {
1235	            if (isSingleEventBox) return false;
1236	            const url = $trigger.attr('href');
1237	            if (url) {
1238	                window.open(url, $trigger.attr('target') === '_blank' ? '_blank' : '_self');
1239	            }
1240	            return !!url;
1241	        },
1242
1243	        // Slides down event card and loads map if present
1244	        slide_down_event_card($trigger, $eventBox, $cal, SC, event_id) {
1245	            const $content = $eventBox.find('.event_description');
1246	            const isOpen = $content.hasClass('open');
1247	            if (SC.accord === 'yes') {
1248	                $cal.find('.eventon_list_event').removeClass('open');
1249	                $cal.find('.event_description').slideUp().removeClass('open');
1250	            }
1251	            $eventBox.toggleClass('open', !isOpen);
1252	            $content[isOpen ? 'slideUp' : 'slideDown']().toggleClass('open', !isOpen);
1253	            if ($eventBox.find('.evo_metarow_gmap').length) {
1254	                $eventBox.find('.evo_metarow_gmap').evo_load_gmap({ trigger_point: 'slideDownCard' });
1255	            }
1256	            if ($trigger.data('runjs')) {
1257	                this.E.B.trigger('evo_load_single_event_content', [event_id, $trigger]);
1258	            }
1259	            this.E.B.trigger('evo_slidedown_eventcard_complete', [event_id, $trigger, !isOpen]);
1260	            return false;
1261	        }
1262		}
1263
1264		EVO_Listeners.init();		
1265	}
1266
1267// Global Calendar Listeners and Interactions
1268	function EVO_Interactions(){
1269		const interactions_class = {
1270			E:{ B: $('body')},
1271			run(){
1272				const { B } = this.E;
1273				this.evoLightboxEnd();
1274				this.evocardNavTrig();
1275				this.evoMapExpandTrig();
1276				this.handle_lightbox_processed();
1277				this.handle_calendar_interactions();
1278				this.handle_global_listners();
1279				this.handle_tabs();
1280				this.handle_aria_population();
1281			},
1282
1283			handle_aria_population() {
1284				const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1285			   	const gen = () => Array.from({length:9},()=>chars[Math.floor(Math.random()*62)]).join('');
1286			  	const used = new Set();
1287
1288			  	$('.evo_aria_ready').each(function() {
1289			  		const $label = $(this);
1290			  		let $unique_label = $label.text().trim();
1291
1292				    const $i = $label.siblings('.evo_aria_ready_match').first();
1293				    if (!$i.length) return;			    
1294
1295				    //$label.removeClass('evo_aria_ready');
1296				    let id;
1297				    do { id = gen(); } while (used.has(id));
1298				    used.add(id);
1299
1300				    $unique_label = $unique_label.replace(/\[[^\]]*\]/, '['+id+']');
1301				    $label.html( $unique_label );
1302				    $i.attr('aria-label', $unique_label );
1303
1304				    $(this).attr('for', id);
1305				    $i.attr('id', id).removeAttr('aria-label');
1306				});
1307			},
1308			evoLightboxEnd() {
1309		        this.E.B.on('evolightbox_end', (event, LB, CAL) => {
1310		            setTimeout(() => {
1311		                LB.find('.eventon_list_event').each(function() {
1312		                    evo_cal_eventcard_interactions($(this), true);
1313		                });
1314		                _evo_run_eventcard_map_load();
1315		                LB.evo_cal_localize_time();
1316		                this.handle_aria_population();
1317		            }, 1000);
1318		        });
1319
1320		        // eventcard lightbox event navigation @version 4.9.2
1321		        this.E.B.on('evolightbox_end', (e, LB, CAL, OO) => {
1322		            if (!evo_general_params.cal.lbnav) return;
1323		            if (evo_general_params.cal.lbnav === 'no') return;
1324		            if (OO === undefined || !('other_data' in OO)) return;
1325
1326		            const event = $(OO.other_data.obj).closest('.event');
1327		            const calId = (CAL ? CAL.attr('id') : '');
1328		            const buttons = [
1329		                { dir: 'prev', icon: 'left', sibling: event.prev('.event') },
1330		                { dir: 'next', icon: 'right', sibling: event.next('.event') }
1331		            ].filter(b => b.sibling.length)
1332		             .map(b => `
1333		                <div class='evocard_lb_navs'>
1334		                    <button class='evocard_nav_trig ${b.dir} evoposa evocurp evohoop7 evobr30 evobgcw evodfx evofxjcc evofxaic evo_transit_all evoboxbb' data-id='${b.sibling.attr('id')}' data-cid='${calId}'>
1335		                        <i class='fa fa-chevron-${b.icon}'></i>
1336		                    </button>
1337		                </div>
1338		            `).join('');
1339
1340		            LB.find('.evolb_box').append(buttons);
1341		            setTimeout(() => LB.find('.evocard_nav_trig').addClass('show'), 500);
1342		        });
1343		    },
1344		    evocardNavTrig(){
1345		    	this.E.B.on('click','.evocard_nav_trig',function(e){
1346					e.preventDefault();
1347				    const $el = $(e.currentTarget);
1348				    const CAL = $('#' + $el.data('cid'));
1349				    const SC = CAL.evo_shortcode_data();
1350				    const eventId = $el.data('id').split('_')[1];
1351				    const newEvent = CAL.find(`#${$el.data('id')}`);
1352				    const newEventTrigger = newEvent.find('.desc_trig');
1353				    const LB = $el.closest('.evo_lightbox');
1354
1355				    LB.find('.evocard_nav_trig').fadeOut().addClass('old');
1356				    setTimeout(() => LB.find('.evocard_lb_navs').has('.old').remove(), 500);
1357
1358				    LB.evo_lightbox_show_open_animation({ animation_type: 'saving' });
1359
1360				    const updatedSC = {
1361				        ...SC,
1362				        repeat_interval: parseInt(newEvent.data('ri')),
1363				        ux_val: CAL.evo_cal_event_get_uxval(SC, newEventTrigger),
1364				        event_id: eventId,
1365				        ajax_eventtop_show_content: true,
1366				        evortl: newEvent.find('.eventon_events_list').hasClass('evortl') ? 'yes' : 'no',			
1367				        additional_class: CAL.attr('class').match(/etttc_\w+/)?.[0] || '',
1368				    };
1369
1370				    const newLbClass = "evo_eventcard_"+eventId;
1371				    LB.removeClass(LB.data('lbc')).addClass(newLbClass).data('lbc', newLbClass);
1372
1373				    setTimeout(() => CAL.evo_cal_lightbox_trigger(updatedSC, newEventTrigger, CAL, LB), 1000);
1374				});
1375		    },
1376		    evoMapExpandTrig(){
1377		    	this.E.B.on('click','.evo_map_expand_trig',function(e){
1378					e.preventDefault();
1379
1380					const $gmapDiv = $(this).closest('.evo_map').find('.evo_metarow_gmap');
1381					const mapID = $gmapDiv.attr('id')+'_exp';
1382					const $newDiv = $('<div id="'+ mapID +'" class="evo_lb_map evobr15" style="min-height:calc(100vh - 120px);"></div>');
1383					const locationAdd = $gmapDiv.data('address');
1384					const locationName = $gmapDiv.data('name');
1385
1386					const extra = `<div class='evodfx evofxdrr evofxaic evogap10 evomarr50'>
1387							<input id="user-address-${mapID}" type="text" placeholder="Enter starting address"/>
1388							<button id="get-directions-${mapID}" class='evo_nonbtn'><i class='fa fa-circle-arrow-right'></i></button>
1389							<i class='fa fa-route evofz24i evocurp evoop5 evohoop7'></i>
1390							<button class='evo_nonbtn evoff_2 evocurp evohoop7 evoop5'><i class='fa fa-calendar evomarr10 evofz24i'></i>More Events</button>
1391						</div>`;
1392					const $topDiv = `<div class='evodfx evofxdrr evogap10 evofxjcsb evofxaic evomarb10'>
1393						<div class='evodfx evofxdrr evofxaic evogap10'>
1394							<p class='evoff_1i evomar0i evofz18i'>${locationName}</p>
1395							<p class='evomar0i evofz14i'>${locationAdd}</p>
1396						</div>
1397						</div>`;
1398					const $botDiv = ``;
1399
1400					// Copy only data attributes, not content
1401					$.each($gmapDiv.data(), function(key, value) {
1402					    $newDiv.data(key, value).attr('data-'+key, value);
1403					});
1404					const calID = $(this).closest('.ajde_evcal_calendar').attr('id');
1405					$(this).evo_lightbox_open({
1406						uid: 'evo_map_expand',calid: calID,
1407						lbdata:{ class:'evo_map_expand',content: $topDiv + $newDiv[0].outerHTML + $botDiv }
1408					});
1409				});
1410		    },
1411		    handle_lightbox_processed(){
1412		    	this.E.B.on('evo_lightbox_processed',function(e, OO, LB){
1413		    		if( OO.uid == 'evo_map_expand'){
1414						//console.log(OO);
1415						setTimeout(function(){
1416							LB.find('.evo_lb_map').evo_load_gmap({	cal: $('body').find('#'+ OO.calid)	});
1417						}, 500);						
1418					}
1419				}).on('evo_ajax_success_evo_open_eventcard_lightbox', function( e, OO, data, el){
1420					//console.log(OO);
1421					setTimeout(function(){
1422						LB.find('.evcal_gmaps').evo_load_gmap({	cal: $('body').find('#'+ OO.d.calid)	});
1423					}, 500);	
1424				});
1425		    },
1426
1427		    // Calendar
1428		    handle_calendar_interactions(){
1429		    	const { B } = this.E;
1430		    	B.find('.ajde_evcal_calendar').each( (index, calendar) => {
1431
1432		    		const $calendar = $(calendar);
1433		    		const $SC = $calendar.evo_shortcode_data();
1434
1435			        // Bubble tooltip for events in calendars with 'bub' class
1436			        if ($calendar.hasClass('bub')) {
1437			            $calendar.on('mouseover.evoCal', '.eventon_list_event', (e) => {
1438			                const $event = $(e.currentTarget);
1439			                const $list = $event.closest('.eventon_events_list');
1440			                const title = $event.find('.evoet_dayblock').data('bub');
1441			                const position = $event.position();
1442
1443			                $list.append(`<span class="evo_bub_box">${title}</span>`);
1444			                const $bubble = $list.find('.evo_bub_box');
1445
1446			                let left = position.left;
1447			                let top = position.top - $bubble.height() - 30;
1448
1449			                // Adjust bubble position if it exceeds list width
1450			                const listWidth = $list.width();
1451			                const totalWidth = position.left + $bubble.width() + $event.width();
1452			                if (totalWidth > listWidth) {
1453			                    left = position.left - $bubble.width() + $event.width() - 20;
1454			                }
1455
1456			                $bubble.css({ top, left }).addClass('show');
1457			            }).on('mouseout.evoCal', '.eventon_list_event', (e) => {
1458			                $(e.currentTarget).closest('.eventon_events_list').find('.evo_bub_box').remove();
1459			            });
1460			        }
1461
1462			        // Jumper button toggle
1463			        $calendar.on('click.evoCal', '.evo-jumper-btn', (e) => {
1464			            const $this = $(e.currentTarget);
1465			            $this.closest('.calendar_header').find('.evo_j_container').toggle();
1466			            $this.toggleClass('vis');
1467			        });
1468
1469			        // select a new time from jumper
1470			        $calendar.on('click','.evo_j_dates a',function(){
1471						var val = $(this).attr('data-val'),
1472							type = $(this).parent().parent().attr('data-val'),
1473							CAL = $calendar,
1474							SC = CAL.evo_shortcode_data();
1475
1476						if(type=='m'){ // change month
1477							CAL.evo_update_cal_sc({F:'fixed_month', V: val });
1478						}else{
1479							CAL.evo_update_cal_sc({F:'fixed_year', V: val });
1480						}
1481
1482						run_cal_ajax( CAL.attr('id') ,'none','jumper');
1483						
1484						// hide month jumper if not set to leave expanded
1485						if(SC.expj =='no')	container.delay(2000).slideUp();
1486					});
1487
1488					// view switcher
1489					$calendar.on('click', '.evo_vSW',function(){
1490						const O = elm = $(this);
1491						var DATA = O.data('d');
1492						if(O.hasClass('focusX')) return;
1493						CAL = $calendar;
1494
1495						// remove other additions from other views
1496						CAL.find('.evoADDS').hide().delay(200).queue(function(){
1497							$(this).remove();
1498						});
1499
1500						var SC = $SC;
1501						const cal_tz = CAL.evo_get_global({S1:'cal_def',S2:'cal_tz'});
1502						var reload_cal_data = false;
1503						
1504						// Create date object
1505							_M1 = moment().set({'year': SC.fixed_year, 'month': ( SC.fixed_month -1 ), 'date':SC.fixed_day}).tz( cal_tz );
1506							_M1.set('date',1).startOf('date');
1507							_start = _M1.unix();
1508							_M1.endOf('month').endOf('date'); // move to end of month
1509							_end = _M1.unix();
1510
1511						// DEP
1512							var DD = new Date(SC.fixed_year,SC.fixed_month -1 , SC.fixed_day, 0,0,0 );
1513							DD.setUTCHours(0);
1514							DD.setUTCFullYear( SC.fixed_year );
1515							DD.setUTCMonth( SC.fixed_month -1 );
1516							DD.setUTCDate( SC.fixed_day );
1517
1518						// switch to normal
1519							O.siblings('.evo_vSW').removeClass('focusX select');					
1520							O.addClass('focusX select');
1521							CAL.find('.evo-viewswitcher-btn em').html( O.html() );
1522							O.closest('.evo_cal_view_switcher').removeClass('show');
1523
1524						// ux_val for specific cal
1525							if( DATA && 'ux_val' in DATA)	CAL.evo_update_cal_sc({F:'ux_val', V: DATA.ux_val });
1526
1527						// calendar class toggling
1528							O.siblings('.evo_vSW').each(function(){
1529								var _d = $(this).data('d');
1530								if( _d && 'c' in _d )	CAL.removeClass( _d['c'] ); // remove other cls
1531							});
1532							if( DATA && 'c' in DATA)	CAL.addClass( DATA.c );
1533					
1534
1535						// process date times block
1536							CAL.find('.evoet_dayblock span').hide();
1537							CAL.find('.evoet_dayblock span.evo_start').show();
1538							CAL.find('.evoet_dayblock span.evo_end').show();
1539							CAL.find('.evoet_dayblock span.evo_end.only_time').hide();
1540
1541						// if current date range is not a month load those unix
1542						if( SC.focus_start_date_range != _start && SC.focus_end_date_range != _end ){
1543							reload_cal_data = true;
1544							CAL.evo_update_cal_sc({F:'focus_start_date_range',V: _start });
1545							CAL.evo_update_cal_sc({F:'focus_end_date_range', V: _end });
1546						}
1547
1548						// treating events list based on dif preferences--  vals el_visibility = hide_events, show_events
1549							if( 'el_visibility' in DATA){
1550								el_visibility = DATA.el_visibility;
1551
1552								if( el_visibility =='show_events') CAL.find('.eventon_list_event').show();
1553								if( el_visibility =='hide_events') CAL.find('.eventon_list_event').hide();
1554								if( el_visibility =='hide_list') CAL.find('#evcal_list').addClass('evo_hide').hide();
1555								if( el_visibility =='show_all'){
1556									CAL.find('#evcal_list').removeClass('evo_hide').show();
1557									CAL.find('.eventon_list_event').show();
1558								} 
1559							}				
1560
1561						CAL.evo_update_cal_sc({F:'calendar_type', V: 'default'});
1562						
1563						B.trigger('evo_vSW_clicked_before_ajax', [ O, CAL, DD, reload_cal_data ]);
1564
1565						// run ajax to load new events in the range
1566							if( reload_cal_data ){
1567								B.trigger('evo_run_cal_ajax',[CAL.attr('id'),'none','filering']);
1568							}else{
1569								B.trigger('evo_vSW_clicked_noajax', [ O, CAL ]); // @s4.6
1570							}
1571												
1572						B.trigger('evo_vSW_clicked', [ O, CAL, DD, reload_cal_data]);
1573
1574						// switching to and from tiles view
1575							if( elm.hasClass('evoti')){
1576								CAL.find('.eventon_list_event').each(function(){
1577									color = $(this).data('colr');
1578									$(this).find('a.desc_trig').css({'background-color': color});
1579								});
1580								CAL.addClass('color').removeClass('sev').data('oC', 'sev');
1581							}else{
1582								if( CAL.hasClass('esty_0') || CAL.hasClass('esty_4') ){
1583									CAL.removeClass('color');
1584									CAL.find('.eventon_list_event').each(function(){
1585										$(this).find('a.desc_trig').css({'background-color': ''});
1586									});
1587									if( CAL.data('oC') !== undefined) CAL.addClass( CAL.data('oC'));
1588								}
1589							}
1590
1591					});
1592		    	});
1593		    },		  
1594
1595		    // Global  
1596		    handle_global_listners(){
1597		    	const { B } = this.E;
1598		    	B.on('evo_trigger_cal_reset', function(event, cal){
1599					cal_resets( cal );
1600				});
1601				B.on('click', function(event) {
1602					BODY.trigger('clicked_on_page', [ $(event.target) , event ]);
1603				});
1604				B.find('.evo_location_map').each(function(){			
1605					$(this).evo_load_gmap();
1606				});
1607				// on event card lightbox load -> taxonomy details @since 4.2 u4.6
1608				B.on('evo_ajax_complete_eventon_get_tax_card_content', function(event,  OO){
1609			
1610					LB = B.find('.'+ OO.lightbox_key);
1611
1612					setTimeout(function(){
1613						// run map load
1614						if( LB.find('.evo_trigger_map').length > 0 ){
1615							map_id_elm = LB.find('.evo_trigger_map');			
1616							map_id_elm.evo_load_gmap();
1617							console.log('Loading Event Map');
1618						}
1619						
1620						// run countdown timers
1621						LB.find('.evo_countdowner').each(function(){
1622							$(this).evo_countdown();
1623						});
1624
1625						// run calendar filtering function
1626						CAL = LB.find('.ajde_evcal_calendar');
1627						if (CAL.length) CAL.evo_cal_filtering();
1628					},500);		
1629				});
1630		    },
1631		    // Tab view switcher
1632		    handle_tabs(){
1633		    	const { B } = this.E;
1634		    	B.find('.evo_tab_container').each(function(){
1635					$(this).find('.evo_tab_section').each(function(){
1636						if(!$(this).hasClass('visible')){
1637							$(this).addClass('hidden');
1638						}
1639					});
1640				});
1641				B.on('click','.evo_tab',function(){
1642					tab = $(this).data('tab');
1643					tabsection = $(this).closest('.evo_tab_view').find('.evo_tab_container');
1644					tabsection.find('.evo_tab_section').addClass('hidden').removeClass('visible');
1645					tabsection.find('.'+tab).addClass('visible').removeClass('hidden');
1646
1647					$(this).parent().find('.evo_tab').removeClass('selected');
1648					$(this).addClass('selected');
1649
1650					B.trigger('evo_tabs_newtab_selected',[ $(this)]);
1651				});
1652		    },
1653
1654		};
1655
1656		interactions_class.run();
1657	}
1658
1659// EVO ON
1660	const EVO = {
1661
1662		E:{
1663			B: $('body')
1664		},
1665		init(){
1666			this.Tools.init();
1667			this.Interactions.init();
1668			this.Virtual_Events.init();
1669			this.Search.init();
1670			this.Elements_Interactions.init();
1671			// Global event listeners (e.g., heartbeat, resize)
1672        	this.setupGlobalListeners();
1673        	this.schedule_view();
1674        	this.ajax_triggers();
1675		},
1676
1677		setupGlobalListeners(){
1678			const { B } = this.E;
1679			// Heartbeat hooks
1680	        $(document).on('heartbeat-send', (e, data) => {
1681	            if (this.BODY && this.BODY.find('.evo_refresh_on_heartbeat').length) {
1682	                this.BODY.find('.evo_refresh_on_heartbeat').each((i, el) => {
1683	                    if ($(el).closest('.eventon_list_event').length <= 0) return;
1684	                    if ($(el).data('refresh') !== undefined && !$(el).data('refresh')) return;
1685
1686	                    data['evo_data'] = EVO.Tools.build_elm_refresh_data($(el));
1687	                });
1688	            }
1689	        });
1690
1691	        $(document).on('heartbeat-tick', (e, data) => {
1692	            EVO.Tools.evo_apply_refresh_content(data);
1693	        });
1694
1695			// Other global events
1696	        B.on('evo_refresh_elements', (e, send_data) => {
1697	            if (!send_data || send_data.length <= 0) return;
1698
1699	            send_data['nonce'] = evo_general_params.n;
1700
1701	            $.ajax({
1702	                beforeSend: () => {
1703	                    if ('evo_data' in send_data) {
1704	                        $.each(send_data.evo_data, (ekey, eclasses) => {
1705	                            $.each(eclasses, (classnm, val) => {
1706	                                if (val && 'loader' in val && val.loader && 'loader_class' in val) {
1707	                                    $('#event_' + ekey).find('.' + val.loader_class).addClass('evoloading');
1708	                                }
1709	                            });
1710	                        });
1711	                    }
1712	                },
1713	                type: 'POST',
1714	                url: EVO.Tools.get_ajax_url('eventon_refresh_elm'),
1715	                data: send_data,
1716	                dataType: 'json',
1717	                success: (data) => {
1718	                    if (data.status === 'good') {
1719	                        EVO.Tools.evo_apply_refresh_content(data);
1720	                    }
1721	                },
1722	                complete: () => {
1723	                    if ('evo_data' in send_data) {
1724	                        $.each(send_data.evo_data, (ekey, eclasses) => {
1725	                            $.each(eclasses, (classnm, val) => {
1726	                                if (val && 'loader' in val && val.loader && 'loader_class' in val) {
1727	                                    $('#event_' + ekey).find('.' + val.loader_class).removeClass('evoloading');
1728	                                }
1729	                            });
1730	                        });
1731	                    }
1732	                }
1733	            });
1734	        });
1735	        // refresh the closest hearbeat run parent
1736			B.on('evo_refresh_designated_elm', function(ee, elm, elm_class, extra_data){
1737				//get closest event object
1738				const event = $(elm).closest('.eventon_list_event');
1739	            if (!event || event.find('.' + elm_class).length === 0) return;
1740
1741	            const refresh_elm = event.find('.' + elm_class);
1742	            let send_data = {};	
1743
1744				send_data['evo_data'] = EVO.Tools.build_elm_refresh_data( refresh_elm , extra_data);				
1745				B.trigger('evo_refresh_elements',[ send_data ]);
1746			});
1747
1748		},
1749		schedule_view(){
1750			EVO.E.B.on('evo_init_ajax_success_each_cal',function(event, data, i, v, CAL){
1751				$('body').find('.ajde_evcal_calendar.evoSV').each(function(){
1752					EVO.Tools.evosv_populate( $(this) );
1753				});
1754			})
1755			.on('evo_main_ajax_before_fnc', function(event, CAL,  ajaxtype, data_arg){
1756				SC = data_arg.shortcode;
1757				if( SC.calendar_type == 'schedule'){
1758					CAL.find('#evcal_list').removeClass('evo_hide').show();
1759				}
1760			}).on('evo_main_ajax_success', function(event, CAL,  ajaxtype, data , data_arg){
1761				SC = data_arg.shortcode;
1762				if( SC.calendar_type == 'schedule'){
1763					CAL.find('#evcal_list').addClass('evo_hide').hide();
1764				}
1765			}).on('evo_main_ajax_complete', function(event, CAL,  ajaxtype, data , data_arg){
1766				SC = data_arg.shortcode;
1767				if( SC.calendar_type == 'schedule'){
1768					EVO.Tools.evosv_populate( CAL );
1769				}
1770			})
1771			// view switching
1772			.on('evo_vSW_clicked_before_ajax',function(event, O, CAL, DD, reload_cal_data){
1773				if(!(O.hasClass('evosv'))) return;
1774				var SC = CAL.evo_shortcode_data();
1775
1776				CAL.evo_update_cal_sc({F:'calendar_type', V: 'schedule'});
1777				CAL.evo_update_cal_sc({F:'fixed_day', V: SC.fixed_day });
1778
1779			})
1780			.on('evo_vSW_clicked',function(event, OBJ, CAL, DD, reload_cal_data){
1781				if(!(OBJ.hasClass('evosv'))) return;						
1782				CAL.evo_update_cal_sc({F:'calendar_type', V: 'schedule'});
1783			})
1784			.on('evo_vSW_clicked_noajax',function(event, OBJ, CAL, DD, reload_cal_data){
1785				if(!(OBJ.hasClass('evosv'))) return;						
1786				EVO.Tools.evosv_populate( CAL );		
1787			})
1788			// open events from schedule view
1789			.on('click','.evosv_items',function(event, elm){
1790				O = $(this);
1791				CAL = O.closest('.ajde_evcal_calendar');
1792				var e_cl = 'event_'+O.data('id');
1793				
1794				const clicked_event_uxval = O.data('uxval');
1795
1796				// if event is set to slide down .. switch to lightbox
1797				if( clicked_event_uxval == '1' ){
1798					CAL.find('.'+e_cl).find('.desc_trig').data('ux_val', 3);
1799				}
1800
1801				CAL.find('.'+e_cl).find('.desc_trig').trigger('click');
1802			});
1803		},
1804		Interactions:{
1805			init(){
1806				const { B } = EVO.E;
1807			},
1808
1809		},
1810		Search:{
1811			init(){
1812				const { B } = EVO.E;
1813				B.on('click.evoSearch', '.evo_do_search', (event) => {
1814		            EVO.Tools.do_search_box($(event.target));
1815		        });
1816		        B.on('keypress.evoSearch', '.evo_search_field', (ev) => {
1817	                if ((ev.keyCode || ev.which) === 13) {
1818	                    EVO.Tools.do_search_box($(ev.target).siblings('.evo_do_search'));
1819	                }
1820	            });
1821	            B.on('keypress.evoSearch', '.evo_search_bar_in_field', (ev) => {
1822	                if ((ev.keyCode || ev.which) === 13) {
1823	                    EVO.Tools.search_within_calendar( $(ev.target) );
1824	                }
1825	            });
1826	            B.on('click', '.evosr_search_clear_btn', function(e) {
1827				    e.preventDefault(); EVO.Tools.reset_search($(this).siblings('input'), $(this));
1828				});
1829				B.on('evo_main_ajax_complete', function(e, CAL, ajaxtype, responseJSON, data) {
1830					if (ajaxtype === 'search' && data.shortcode['s']) {
1831				        CAL.find('.evosr_search_clear_btn').addClass('show');
1832				    }
1833				});
1834				// Handle search input interactions
1835				B.on({
1836					'click': function() { EVO.Tools.search_within_calendar($(this).siblings('input')); },
1837				    'keyup': function(e) {
1838				        const $input = $(this), $clearBtn = $input.siblings('.evosr_search_clear_btn');
1839				        if (e.which === 27) { e.preventDefault(); EVO.Tools.reset_search($input, $clearBtn); return; }
1840				        $clearBtn.toggleClass('show', $input.val().trim() !== '');
1841				    }		    
1842				}, '.evo_search_bar_in_field, .evosr_search_btn');
1843			}			
1844		},
1845		Elements_Interactions:{
1846			init(){
1847				const { B } = EVO.E;
1848				// increase and reduce quantity
1849			    B.on('click','.evo_qty_change', function(event){
1850			        var OBJ = $(this);
1851			        var QTY = oQTY = parseInt(OBJ.siblings('em').html());
1852			        var MAX = OBJ.siblings('input').attr('max');
1853			        var BOX = OBJ.closest('.evo_purchase_box');
1854
1855			        var pfd = BOX.find('.evo_purchase_box_data').data('pfd');			        
1856
1857			        (OBJ.hasClass('plu'))?  QTY++: QTY--;
1858
1859			        QTY =(QTY==0)? 1: QTY;
1860			        QTY = (MAX!='' && QTY > MAX)? MAX: QTY;
1861
1862			        // new total price
1863			        var sin_price = OBJ.parent().data('p');
1864			        new_price = sin_price * QTY;
1865
1866			        new_price = EVO.Tools.get_format_price( new_price, pfd);
1867
1868			        BOX.find('.total .value').html( new_price);
1869
1870			        OBJ.siblings('em').html(QTY);
1871			        OBJ.siblings('input').val(QTY);
1872
1873			        B.trigger('evo_qty_changed',[QTY,oQTY, new_price,OBJ ]);
1874			    });
1875			}
1876		},
1877		Virtual_Events:{
1878			init(){
1879				const { B } = EVO.E;
1880				this.jitsi();
1881				// record sign in - virtual plus // @+3.1
1882				B.on('click','.evo_vir_signin_btn',function(){
1883								
1884					let extra_data = {};
1885					extra_data['signin'] = 'y';
1886					extra_data['refresh_main'] = 'y';
1887					extra_data['loader'] = true;
1888					extra_data['loader_class'] = 'evo_vir_main_content';
1889
1890					B.trigger('evo_refresh_designated_elm',[ $(this) , 'evo_vir_data',extra_data]);
1891				});
1892			},
1893			jitsi( mod_refresh){
1894				const { B } = EVO.E;
1895				const domain = 'meet.jit.si';
1896			    let api = [];
1897
1898			    B.find('.evo-jitsi-wrapper').each(function(index, element) {
1899			    	const O = $(this);
1900			    	const eventO = O.closest('.eventon_list_event');
1901
1902			    	if( mod_refresh != '' && mod_refresh == 'mod_refresh_no' && O.hasClass('mod')) return;
1903
1904			        const roomName = $(element).data('n');
1905		            const width = $(element).data('width');
1906		            const height = $(element).data('height');
1907		            const audioMuted = $(element).data('audiomute');
1908		            const videoMuted = $(element).data('videomute');
1909		            const screenSharing = $(element).data('screen');
1910	           
1911			        const myOverwrite =
1912					{
1913					 	'TOOLBAR_BUTTONS': $(element).data('d'),
1914					    "DEFAULT_BACKGROUND": '#494a4e',
1915					    'MOBILE_APP_PROMO': false,
1916					    'SETTINGS_SECTIONS':['devices', 'language', 'profile', 'calendar'],
1917					};
1918			        const options = {
1919			            roomName,
1920			            width,
1921			            height,
1922			            parentNode: element,	            
1923			            configOverwrite: { 
1924			            	startWithAudioMuted: audioMuted,
1925			                startWithVideoMuted: videoMuted,
1926			                startScreenSharing: false,	  
1927			                disableInviteFunctions: false,             
1928			            },
1929			            interfaceConfigOverwrite: myOverwrite,     
1930			        };
1931
1932			       	api = new JitsiMeetExternalAPI(domain, options);      
1933
1934			        api.addEventListener('participantRoleChanged', function(event){
1935
1936			        	// record moderator joined
1937			        	if (event.role === "moderator"){	        		
1938			        		this._record_moderator_join( 'yes', eventO.data('event_id'), eventO.data('ri'));
1939			        	}
1940
1941			        	const pp = jQuery(element).data('p');
1942			        	if (event.role === "moderator" && pp != '__') {
1943			        		ppp = pp.replace('_','');
1944					        api.executeCommand('password', ppp);
1945					    }	        	
1946			        });	
1947
1948			        // moderator leave	        
1949			        api.addEventListener('videoConferenceLeft', function(event){
1950			        	if( eventO.find('.evo_vir_data').data('ismod') =='y'){
1951			        		this._record_moderator_join( 'no', eventO.data('event_id'), eventO.data('ri'));
1952			        		O.siblings('.evo_vir_mod_left').show();
1953			        		O.hide();
1954			        	}
1955			        });
1956			    });
1957			},
1958			// record moderator logins for jitsi
1959			_record_moderator_join(joined, eid, ri){
1960				var data_arg = {
1961					'action': 'eventon_record_mod_joined',
1962					'eid': eid,
1963					'ri': ri,
1964					'joined': joined,
1965					'nonce': evo_general_params.n,				
1966				};
1967
1968				$.ajax({
1969					beforeSend: function(){},
1970					type: 'POST',url: ajax_url,
1971					data: data_arg,dataType:'json',
1972					success:function(data){	}
1973				});
1974			}
1975		},
1976		ajax_triggers(){
1977			const { B } = EVO.E;
1978			B.on('evo_before_trig_ajax',function(event, obj){
1979				if(!obj.hasClass('evo_trig_vir_end')) return;
1980				
1981				var new_ajax_data = $(document).data( 'evo_data');
1982				new_ajax_data['fnct'] = 'mark_event_ended';
1983				$(document).data( 'evo_data', new_ajax_data );
1984				
1985			})
1986			.on('evo_beforesend_trig_ajax',function( event, obj, new_ajax_data){
1987				if(!obj.hasClass('evo_trig_vir_end')) return;
1988
1989				obj.closest('.evo_vir_mod_box').addClass('evoloading');
1990			})
1991			.on('evo_success_trig_ajax',function( event, obj, new_ajax_data, return_data){
1992				if(!obj.hasClass('evo_trig_vir_end')) return;
1993
1994				// if virtual events were marked as ended
1995				if(!('_vir_ended' in return_data)) return;
1996
1997				// refresh the virtual main content
1998				extra_data = {};
1999				extra_data['refresh_main'] = 'yy';
2000				extra_data['loader'] = true;
2001				extra_data['loader_class'] = 'evo_vir_main_content';
2002
2003				//console.log(extra_data);
2004
2005				B.trigger('evo_refresh_designated_elm',[ obj , 'evo_vir_data',extra_data]);
2006			})
2007			.on('evo_complete_trig_ajax',function( event, obj, new_ajax_data){
2008				if(!obj.hasClass('evo_trig_vir_end')) return;
2009				obj.closest('.evo_vir_mod_box').removeClass('evoloading');
2010			});
2011		},
2012		Tools:{
2013			init() {
2014				const { B } = EVO.E;  
2015				//const { B } = EVO.E;
2016	            // Bind AJAX listeners once
2017	            B.on('evo_ajax_beforesend_evo_get_search_results', (event, OO, el) => {
2018	            	$(el).find('.evo_search_results_count').hide();
2019	                $(el).addClass('searching');
2020	            }).on('evo_ajax_complete_evo_get_search_results', (event, OO, el) => {
2021	                $(el).removeClass('searching');
2022	            }).on('evo_ajax_success_evo_get_search_results', (event, OO, data, el) => {
2023	                $(el).find('.evo_search_results').html(data.content);
2024	                if ($(el).find('.no_events').length === 0) {
2025	                    const Events = $(el).find('.eventon_list_event').length;
2026	                    $(el).find('.evo_search_results_count span').html(Events);
2027	                    $(el).find('.evo_search_results_count').fadeIn();
2028	                }
2029	            });
2030			},
2031			do_search_box( OBJ ){
2032				const { B } = EVO.E;
2033				const SearchVal = OBJ.closest('.evosr_search_box').find('input').val();
2034				const Evosearch = OBJ.closest('.EVOSR_section');
2035				OBJ.closest('.evo_search_entry').find('.evosr_msg').toggle( !SearchVal );
2036
2037				if (!SearchVal) return false;			
2038
2039				var ajax_results = Evosearch.evo_admin_get_ajax({
2040					'ajaxdata': {
2041						//action: 		'eventon_search_evo_events',
2042						search: 		SearchVal,
2043						shortcode:  	Evosearch.find('span.data').data('sc'),
2044						nonce: 			evo_general_params.n				
2045					},
2046					ajax_type:'endpoint',
2047					ajax_action:'eventon_search_evo_events',
2048					uid:'evo_get_search_results',
2049					end: 'client',
2050				});
2051			},
2052			// Search function
2053			search_within_calendar($input) {
2054			    const ev_cal = $input.closest('.ajde_evcal_calendar');
2055			    ev_cal.evo_update_cal_sc({ F: 'show_limit_paged', V: '1' });
2056			    ev_cal.evo_update_cal_sc({ F: 's', V: $input.val() });
2057			    run_cal_ajax(ev_cal.attr('id'), 'none', 'search');
2058			    return false;
2059			},
2060
2061			// Reset search function
2062			reset_search($input, $clearBtn) {
2063			    const ev_cal = $input.closest('.ajde_evcal_calendar');
2064			    ev_cal.evo_update_cal_sc({ F: 's', V: '' });
2065			    run_cal_ajax(ev_cal.attr('id'), 'none', 'search');
2066			    $input.val('');
2067			    $clearBtn.removeClass('show');
2068			},
2069
2070			// Total formating
2071	        get_format_price(price, data){
2072
2073	            // price format data
2074	            PF = data;
2075	           
2076	            totalPrice = price.toFixed(PF.numDec); // number of decimals
2077	            htmlPrice = totalPrice.toString().replace('.', PF.decSep);
2078
2079	            if(PF.thoSep.length > 0) {
2080	                htmlPrice = EVO.Tools._addThousandSep(htmlPrice, PF.thoSep);
2081	            }
2082	            if(PF.curPos == 'right') {
2083	                htmlPrice = htmlPrice + PF.currencySymbol;
2084	            }
2085	            else if(PF.curPos == 'right_space') {
2086	                htmlPrice = htmlPrice + ' ' + PF.currencySymbol;
2087	            }
2088	            else if(PF.curPos == 'left_space') {
2089	                htmlPrice = PF.currencySymbol + ' ' + htmlPrice;
2090	            }
2091	            else {
2092	                htmlPrice = PF.currencySymbol + htmlPrice;
2093	            }
2094	            return htmlPrice;
2095	        },
2096	        _addThousandSep(n, thoSep){
2097	            var rx=  /(\d+)(\d{3})/;
2098	            return String(n).replace(/^\d+/, function(w){
2099	                while(rx.test(w)){
2100	                    w= w.replace(rx, '$1'+thoSep+'$2');
2101	                }
2102	                return w;
2103	            });
2104	        },
2105
2106	        // apply refresh event element content with matching data that is sent
2107			evo_apply_refresh_content(data){
2108				const { B } = EVO.E;          
2109				if (!('evo_data' in data)) return;
2110
2111				$.each(data.evo_data, function(eclass, boxes){
2112					// if event exists in the page
2113
2114					var vir_data_vals = false;
2115					if( 'evo_vir_data' in boxes) vir_data_vals = boxes.evo_vir_data.data;
2116
2117					B.find('.'+eclass).each(function(){
2118						const event_elm = $(this);
2119						$.each(boxes, (boxclass, boxdata) => {
2120							//console.log(boxdata);
2121							if( boxdata == '') return;
2122		                    if (!boxdata.html || event_elm.find('.' + boxclass).length <= 0) return;
2123		                    event_elm.find('.' + boxclass).html(boxdata.html);
2124		                });
2125
2126						// only for virtual event update
2127						if( vir_data_vals ){
2128
2129							// reload jitsi for main content - if main content html is sent it will refresh
2130								if( vir_data_vals && ('vir_type' in vir_data_vals) 
2131									&& vir_data_vals.vir_type == 'jitsi' 
2132									&& ('evo_vir_main_content' in boxes) 
2133									&& ('html' in boxes.evo_vir_main_content)  
2134									&& boxes.evo_vir_main_content.html != ''
2135								){
2136									EVO.Virtual_Events.jitsi('mod_refresh_no');
2137								}
2138
2139							// update data for sent object
2140								$.each(boxes, function(boxclass, boxdata){
2141									if( boxdata.data == '' || boxdata.data === undefined) return;
2142
2143									// for jitsi if mod left --> force refresh main
2144									if( boxdata !== undefined && vir_data_vals.vir_type == 'jitsi' && vir_data_vals.mod_joined =='left'){
2145										
2146										// force refresh main
2147										boxdata.data['refresh_main'] = 'yy';
2148									}	
2149
2150									event_elm.find( '.'+boxclass ).data( boxdata.data );
2151								});
2152						}
2153
2154					});
2155				});
2156			},
2157			// get refresh data for specified elem
2158			build_elm_refresh_data( elm , extra_data){
2159				const dataObj = {};
2160		        const event = $(elm).closest('.eventon_list_event');
2161		        const ekey = event.data('event_id') + '_' + parseInt(event.data('ri'));
2162		        dataObj[ekey] = {};
2163		        const key2 = elm.data('key');
2164		        dataObj[ekey][key2] = elm.data();
2165
2166		        if (elm.data('check_awaitmod')) {
2167		            if ((event.find('.evo_vir_jitsi_waitmod').length > 0)) dataObj[ekey][key2]['refresh_main'] = 'yy';
2168
2169		            if (event.find('.evo-jitsi-wrapper').length > 0 && dataObj[ekey][key2]['mod_joined'] !== 'left') 
2170		                dataObj[ekey][key2]['refresh_main'] = '';
2171		        }
2172
2173		        if (extra_data && extra_data !== undefined) {
2174		            $.each(extra_data, (index, val) => {
2175		                dataObj[ekey][key2][index] = val;
2176		            });
2177		        }
2178
2179		        return dataObj;
2180			},
2181
2182			// populate the schedule view data @4.5.8
2183			evosv_populate(CAL){
2184				//console.log('s');
2185				var SC = CAL.evo_shortcode_data();
2186				OD = CAL.evo_get_OD(); // calendar other data 
2187
2188				var cal_events = CAL.find('.eventon_list_event');
2189				days_in_month = CAL.evo_day_in_month({M: SC.fixed_month, Y: SC.fixed_year});
2190				time_format = CAL.evo_get_global({S1:'cal_def',S2:'wp_time_format'});
2191
2192				// text strings
2193					_txt = CAL.evo_get_txt({V:'no_events'});
2194					_txt2 = CAL.evo_get_txt({V:'until'});
2195					_txt3 = CAL.evo_get_txt({V:'from'});
2196					_txt4 = CAL.evo_get_txt({V:'all_day'});
2197				
2198				CAL.find('#evcal_list').addClass('evo_hide');
2199
2200				var has_events = false;
2201				var html = '';
2202				var template_data = {};
2203				var processed_ids = {};
2204
2205				// Set initial date - date values
2206					var SU = parseInt( SC.focus_start_date_range);	var EU = '';
2207					var M = moment.unix( SU ).tz( OD.cal_tz );
2208
2209				// go through each day in month
2210				for(var x=1; x<= days_in_month; x++){
2211					
2212					var month_name = CAL.evo_get_dms_vals({ V: (M.get('month') +1), type:'m3'});
2213					var day_name = CAL.evo_get_dms_vals({ V: M.day(), type:'d3'});
2214					
2215					// set event unix into moment
2216						SU = M.unix();	M.endOf('day');
2217						EU = M.unix();	M.startOf('day');
2218					
2219					// run through each event and get events in this date
2220						var events = {};
2221
2222						cal_events.each(function(index, elm){
2223							ED = $(elm).evo_cal_get_basic_eventdata();
2224							if( !ED) return;
2225
2226							processed_ids[ED.uID] = ED.uID;
2227							ESU = ED.unix_start; EEU = ED.unix_end;
2228
2229							// check for date range
2230								var inrange = CAL.evo_is_in_range({
2231									'S': SU,	'E': EU,	'start': ESU,	'end':EEU
2232								});
2233								if(!inrange) return; // skip if no in range
2234
2235							has_events = true;
2236
2237							// event time relative to calendar tz
2238							m = moment.unix( ESU ).tz( OD.cal_tz );
2239							me = moment.unix( end ).tz( OD.cal_tz );
2240
2241							var all_day = $(elm).find('a.desc_trig').hasClass('allday') ? true: false;
2242
2243							// get event time correct for all day
2244							if( all_day ){
2245								ED['t'] = _txt4;
2246							}else{
2247								if( ESU <= SU ){
2248									if( EEU >= EU) ED['t'] = _txt4;
2249									if( EEU < EU ) ED['t'] = _txt2+' ' + me.format( time_format);		
2250								}else if(ESU > SU){
2251									if( EEU >= EU)  ED['t'] = _txt3+' '+ m.format( time_format);
2252									if( EEU < EU ) ED['t'] = m.format( time_format) +' - '+ me.format( time_format);
2253								}	
2254							}						
2255
2256							// hide end time
2257							if( ED.hide_et == 'y')		ED['t'] = m.format( time_format);
2258
2259							events[index] = ED;
2260						});			
2261
2262					// if there are events in this date
2263						if( events && Object.keys(events).length > 0){
2264							
2265							template_data[ x ] = {};
2266							template_data[ x ]['date'] = '<b>' + M.get('date')+'</b> '+ month_name+' '+ day_name;
2267							template_data[ x ]['d'] =  M.format('YYYY-M-D');
2268							template_data[ x ]['SU'] = SU;
2269							template_data[ x ]['events'] = {}
2270
2271							$.each(events, function(index, item){		
2272
2273								location_data = organizer_data = event_tags = '';
2274
2275								// location 
2276								if( SC.show_location == 'yes' && 'location' in item){
2277									location_data = "<div class='evosv_subdata evosv_location'><i class='fa fa-location-pin marr5'></i>" +item.location+"</div>";
2278								}
2279
2280								// organizer					
2281								if( SC.show_organizer == 'yes' && 'organizer' in item){
2282									organizer_data = "<div class='evosv_subdata evosv_org'>" +item.organizer+"</div>";
2283								}
2284
2285								// event tags
2286								if( SC.show_tags == 'yes' && 'event_tags' in item){
2287									event_tags = "<div class='evosv_subdata evosv_tags'>";
2288									$.each( item.event_tags, function(index, val){
2289										event_tags += "<span class='evosv_tag " + index +"'>" + val+"</span>";
2290									});
2291									event_tags += "</div>";
2292								}
2293
2294								template_data[ x ]['events'][ item.uID ] = {
2295									'time': item.t,
2296									'ux_val': item.ux_val,
2297									'title': item.event_title,
2298									'color':item.hex_color,
2299									'tag': event_tags,
2300									'loc': location_data,
2301									'org': organizer_data,
2302									'i': item
2303								}
2304
2305							});					
2306						}
2307
2308					// next date
2309					M.add(1, 'd');
2310				}
2311
2312				var html_ = "<div class='evosv_grid evoADDS'>";
2313				
2314				// if no events
2315				if( !has_events){
2316					no_event_content = CAL.evo_get_global({S1: 'html', S2:'no_events'});			
2317					html_ += "<div class='date_row'><div class='row no_events evosv'>"+no_event_content+"</div></div>";
2318				}else{
2319					html_ += CAL.evo_HB_process_template({
2320						TD:template_data, part:'evosv_grid'
2321					});
2322				}
2323
2324				html_ += '</div>';
2325
2326				if( CAL.find('.evosv_grid').length > 0){
2327					CAL.find('.evosv_grid').replaceWith( html_ );
2328				}else{
2329					ELM = CAL.find('#eventon_loadbar_section');
2330					ELM.after( html_ );
2331				}
2332				
2333			},
2334
2335			// call ajax url
2336			get_ajax_url(action){
2337				var ajax_type = 'endpoint';
2338				if('ajax_method' in evo_general_params ) ajax_type = evo_general_params.ajax_method;
2339				return EVO.E.B.evo_get_ajax_url({a:action, type: 	ajax_type });
2340			},
2341		}
2342
2343	};
2344	EVO.init();
2345
2346
2347
2348// Other
2349	// RESET general calendar -- @U 2.8.9		
2350		function cal_resets(calOBJ){
2351			calargs = $(calOBJ).find('.cal_arguments');
2352			calargs.attr('data-show_limit_paged', 1 );
2353			calOBJ.evo_update_cal_sc({
2354				F:'show_limit_paged',V:'1'
2355			});
2356		}
2357	
2358	// layout view changer - legacy
2359		if($('body').find('.evo_layout_changer').length>0){
2360			// menu button focus adjust
2361			$('body').find('.evo_layout_changer').each(function(item){
2362				if($(this).parent().hasClass('boxy')){
2363					$(this).find('.fa-th-large').addClass('on');
2364				}else{
2365					$(this).find('.fa-reorder').addClass('on');
2366				}
2367			});
2368
2369			// interaction
2370			$('.evo_layout_changer').on('click','i',function(){
2371				const CAL = $(this).closest('.ajde_evcal_calendar');
2372				TYPE = $(this).data('type');
2373				$(this).parent().find('i').removeClass('on');
2374				$(this).addClass('on');
2375
2376				//console.log(TYPE);
2377				
2378				if(TYPE=='row'){
2379					CAL.attr('class','ajde_evcal_calendar');
2380					// set tile colors
2381					CAL.find('.eventon_list_event').each(function(){
2382						$(this).find('.desc_trig').css('background-color',  '');
2383						$(this).find('.desc_trig_outter').css('background-color',  '');
2384					});
2385				}else if(TYPE =='bar'){
2386					CAL.attr('class','ajde_evcal_calendar  box_2 sev cev');
2387					
2388					// set tile colors
2389					CAL.find('.eventon_list_event').each(function(){
2390						const color = $(this).data('colr');
2391						$(this).find('.desc_trig').css('background-color',  color);
2392					});
2393				}else{
2394
2395					// set tile colors
2396					CAL.find('.eventon_list_event').each(function(){
2397						const color = $(this).data('colr');
2398						$(this).find('.desc_trig_outter').css('background-color',  color);
2399					});
2400
2401					CAL.attr('class','ajde_evcal_calendar boxy boxstyle0 box_2');
2402				}				
2403			});
2404		}
2405	
2406	// SORTING & FILTERING		
2407		// Sorting	
2408			// update calendar based on the sorting selection
2409				$('body').on('click', '.evo_sort_option',function(){
2410					O = $(this);
2411					var CAL = O.closest('.ajde_evcal_calendar');
2412					var sort_by = O.data('val');
2413					
2414					// update new values everywhere
2415					CAL.evo_update_cal_sc({F:'sort_by',V:sort_by});
2416
2417					O.parent().find('p').removeClass('select');
2418					O.addClass('select');	
2419
2420					run_cal_ajax(CAL.attr('id'),'none','sorting');						
2421				});		
2422
2423		// close filter menus on click outside
2424			BODY.on('clicked_on_page',function( ev, obj, ee){
2425
2426				// hide filter menu when clicked outside 4.6.2
2427				if( !(obj.hasClass('eventon_filter')) && 
2428					!(obj.hasClass('filtering_set_val')) &&
2429					!(obj.hasClass('evo_filter_val')) &&
2430					!(obj.hasClass('evofp_filter_search_i')) &&
2431					obj.parents('.filtering_set_val').length == 0 
2432				){
2433					//console.log(obj);
2434					BODY.find('.evo_filter_menu').html('');
2435					BODY.find('.evo_filter_tax_box.vis').removeClass('vis');
2436				}
2437			});
2438
2439		// Filtering
2440			$.fn.evo_cal_filtering = function(O){
2441				
2442				var opt = $.extend({}, O);
2443
2444				var el = this; // cal
2445				const sortbox = el.find('.eventon_sorting_section'),
2446					filter_container = sortbox.find('.evo_filter_container_in'),
2447					filter_line = sortbox.find('.eventon_filter_line'),
2448					fmenu = sortbox.find('.evo_filter_menu'),
2449					all_cal_filter_data = el.evo_get_filter_data(),
2450					SC = el.evo_shortcode_data();
2451				var tterms = [];
2452
2453
2454				var init = function(){
2455
2456					if( SC == '' || SC === null ) return;
2457					if( el.hasClass('filters_go'))	return;
2458					el.addClass('filters_go');
2459					
2460					draw_filter_bar();
2461					filter_actions();
2462					run_filter_nav_check();
2463
2464				}
2465
2466				// draw the filter bar
2467				var draw_filter_bar = function(){
2468					//console.log(all_cal_filter_data);
2469
2470					BODY.trigger('evo_filter_before_draw', [ el ]);
2471
2472					html = '';
2473
2474					$.each( all_cal_filter_data , function( index, value){
2475
2476						// skip fast filter items
2477						if( SC && 'fast_filter' in SC && SC.fast_filter == 'yes' && SC.ff_tax != '' && SC.ff_tax !== undefined ){
2478							__t = SC.ff_tax.split(',');
2479							if( __t.includes( index ) ) return;
2480						}
2481
2482						html += "<div class='eventon_filter evo_filter_tax_box evo_hideshow_st "+index+"' data-tax='"+ value.__tax +"' data-filter_type='"+ value.__filter_type +"'>";
2483						html += "<div class='eventon_filter_selection'>";
2484							html += "<p class='filtering_set_val'><i class='fa fa-check'></i> "+ value.__name +"<em class='fa fa-caret-down'></em></p>";							
2485						html += "</div>";
2486						html += "</div>";
2487					});
2488
2489					filter_line.html( html );
2490
2491					BODY.trigger('evo_filter_drawn', [ el ]);
2492				}
2493
2494
2495				// filter all actions
2496				var filter_actions = function(){
2497
2498					el.off('click', '.evo-filter-btn');
2499
2500					// show/hide filter bar
2501						el.on('click','.evo-filter-btn',function(){
2502							const CAL = $(this).closest('.ajde_evcal_calendar');
2503							
2504							BODY.trigger('evo_filter_btn_trig', [ CAL , O ]);
2505							if( CAL.hasClass('fp_lb')) return; // PLUG 4.6.4
2506
2507							if( !( $(this).hasClass('vis') ) ){
2508								sortbox.addClass('vis');
2509								run_filter_nav_check();
2510							}else{
2511								sortbox.removeClass('vis');
2512							}
2513
2514						});
2515
2516						// close filter when other sibling buttons clicked 4.6.4
2517						BODY.on('evo_cal_header_btn_clicked',function(event, O){	
2518							if( O.hasClass('evo-sort-btn') || O.hasClass('evo-search')  ){
2519								const CAL = O.closest('.ajde_evcal_calendar');
2520								CAL.find('.eventon_sorting_section').removeClass('vis');								
2521							}
2522						});
2523						
2524						
2525					// show hide menu
2526					el.on('click','.filtering_set_val',function(){
2527
2528						O = $(this);
2529						const filterbox = O.closest('.evo_filter_tax_box'),
2530						filter_tax = filterbox.data('tax');
2531						selected_terms = el.evo_cal_get_filter_sub_data( filter_tax , 'tterms' );
2532
2533						// close sort menu
2534							el.find('.eventon_sort_line').hide();
2535
2536						// hide already opened menus
2537							if( filterbox.hasClass('vis')){
2538								filterbox.removeClass('vis');							
2539								close_filter_menu();
2540								return;
2541							}
2542							if( fmenu.data('tax') == filter_tax ){	
2543								filterbox.removeClass('vis');							
2544								close_filter_menu();
2545								return;
2546							}else{
2547								sortbox.find('.filtering_set_val').removeClass('show');
2548								sortbox.find('.evo_filter_tax_box').removeClass('vis');
2549								filterbox.addClass('vis');	
2550							}
2551
2552						// build the filter menu from data
2553							var filter_item_data = all_cal_filter_data[ filter_tax ].__list;
2554
2555							//console.log(all_cal_filter_data);
2556							//console.log(selected_terms);
2557							
2558							var __menu_html = '<div class="evo_filter_inside evo_filter_menu_in" data-tax="'+filter_tax+'"><div class="eventon_filter_dropdown">';
2559
2560
2561							// Sort the filter list alphabetically
2562							var sorted_data = Object.values(filter_item_data);  
2563							sorted_data.sort(function(a, b) {
2564							    // Natural sort by term label (a[1] and b[1]), case-insensitive
2565							    return a[1].localeCompare(b[1], 'en', {
2566							        numeric: true,      // Treat numbers properly (e.g., 2 before 11)
2567							        sensitivity: 'base' // Ignore case and accents for case-insensitive sort
2568							    });
2569							});
2570							
2571							// each term
2572							var menuInside = '';
2573							var AllHtml = '';
2574							$.each(sorted_data, function (index, val){
2575								var icon_html = '';
2576								var _class = filter_tax+'_'+ val[0] + ' '+ val[0];
2577								
2578								// parent or child term
2579								if( val[3] !== undefined && val[3] != '' && val[3] == 'n') _class += ' np';
2580
2581								//console.log(selected_terms);
2582								// select or not
2583								if( selected_terms == 'all' )  _class += ' select';
2584								if( selected_terms.includes( val[0] ) )  _class += ' select';
2585
2586								// icon
2587								if( val[2] != '' && val[2] !== undefined ){
2588									_class += ' has_icon'; icon_html = val[2];
2589								} 
2590
2591								// tax term color
2592								var _tax_color = '';
2593								if( val[4] != '' && val[4] !== undefined ){
2594									_tax_color = `style='background-color:#${val[4]};'`;
2595								}
2596
2597								const itemHTML = `<p class="evo_filter_val ${_class}" data-id="${val[0]}" ${_tax_color}>${icon_html} ${val[1]}</p>`;
2598
2599								// save all value
2600								if( val[0]=='all'){
2601									AllHtml = itemHTML;
2602								}else{
2603									menuInside += itemHTML;
2604								} 
2605								
2606							});
2607
2608							__menu_html += AllHtml + menuInside +"</div></div>";
2609
2610							// 4.6.4
2611							BODY.trigger('evo_filter_menu_html_ready', [ el , __menu_html , O , filterbox, filter_tax]);
2612
2613
2614							if( el.hasClass('fp_side')) return; // PLUG
2615							
2616
2617							
2618						// set new menu with correct location
2619							const scrolled_width = filter_container.scrollLeft();
2620							fmenu.html( __menu_html );
2621
2622							// pluggable
2623							BODY.trigger('evo_filter_menu_built', [ el , fmenu , filter_tax ]);
2624							
2625
2626							__left_margin = filterbox.position().left + 10 - scrolled_width;
2627							__menu_width = fmenu.find('.evo_filter_inside').width();
2628
2629							__cal_left_margin = el.position().left;
2630
2631							//console.log(__cal_left_margin + ' '+ __left_margin +' '+ __menu_width + ' '+ $(window).width());
2632
2633							if( __left_margin + __menu_width + __cal_left_margin > $(window).width()  ){
2634								
2635								if(  ( __left_margin + __menu_width ) > el.width() ){
2636									new_left = el.width() - __menu_width - 10;
2637								}else{
2638									new_left = ( el.width() - __menu_width ) / 2;
2639								}								
2640								fmenu.css('left', new_left );
2641							}else{
2642								fmenu.css('left', __left_margin);
2643							}
2644					});
2645
2646					// select a static filter menu item
2647						el.on('click','p.filtering_static_val',function(){
2648
2649							BODY.trigger('evo_filter_static_clicked', [ el , $(this) ]);
2650												
2651						});
2652
2653					// select terms in filter menu
2654						el.on('click','p.evo_filter_val',function (){
2655
2656							var O = $(this);
2657							const filter_menuIN = O.closest('.evo_filter_inside'),
2658								filter_tax = filter_menuIN.data('tax'),
2659								filterbox = sortbox.find('.evo_filter_tax_box.'+ filter_tax),
2660								all_terms_obj = filter_menuIN.find('p'),
2661								new_term_id = O.data('id'),
2662								old_terms = el.evo_cal_get_filter_sub_data( filter_tax , 'terms' )
2663								;
2664							var tterms = el.evo_cal_get_filter_sub_data( filter_tax , 'nterms' );
2665
2666							var new_terms = [];
2667
2668
2669							// select filter type
2670							if( SC.filter_type == 'select' ){
2671
2672								// all value
2673								if( new_term_id == 'all' ){
2674									if( O.hasClass('select') ){
2675										all_terms_obj.removeClass('select');
2676									}else{
2677										all_terms_obj.addClass('select');
2678										new_terms.push('all');
2679									}
2680								}else{
2681									// unselect all value
2682									filter_menuIN.find('p.all').removeClass('select');
2683									O.toggleClass('select');	
2684
2685									var unselect_count = 0;
2686									all_terms_obj.each(function(){
2687										if( $(this).hasClass('select')){
2688											new_terms.push( $(this).data('id') )
2689										}else{
2690											// not select
2691											if(!$(this).hasClass('all')) unselect_count++;
2692										}
2693									});	
2694
2695									// all selected
2696									if(unselect_count == 0){
2697										filter_menuIN.find('p.all').addClass('select');
2698										new_terms.push('all');
2699									}	
2700
2701									// if all field is not visible; nothing selected = all
2702									if( new_terms.length == 0 && O.parent().find('p.all').length == 0) 
2703										new_terms.push('all');
2704								}							
2705
2706							// non select type
2707							}else{ 
2708								// all value
2709								if( new_term_id == 'all' ){
2710									// if all is already selected
2711									if( O.hasClass('select')){
2712										new_terms.push('NOT-all');
2713										all_terms_obj.removeClass('select');
2714									}else{
2715										all_terms_obj.addClass('select');
2716										new_terms.push( new_term_id );
2717									}	
2718								}else{
2719									all_terms_obj.removeClass('select');
2720									O.addClass('select');
2721									new_terms.push( new_term_id );
2722								}
2723
2724								update_filter_data( filter_tax, new_terms );
2725
2726								// process selection @4.6.6
2727									if( tterms == new_terms ){
2728										close_filter_menu();
2729									}else{					
2730										cal_resets( el );
2731												
2732										el.evo_update_sc_from_filters();					
2733
2734										run_cal_ajax( el.attr('id') ,'none','filering');
2735																								
2736										close_filter_menu();
2737										O.removeClass('show');
2738									}
2739
2740								close_filter_menu();
2741								// mark hide of menu
2742								filterbox.removeClass('vis');
2743							}
2744							
2745							// show and hide apply filter button
2746								// if new terms = temp terms
2747									if( compare_terms( new_terms, tterms) ){
2748										filterbox.removeClass('chg');										
2749									}else{
2750										filterbox.addClass('chg');			
2751									}
2752									if( compare_terms( old_terms, new_terms) ){
2753										filterbox.removeClass('set');	
2754									}else{
2755										filterbox.addClass('set');
2756									}								
2757									
2758
2759								// changed filters
2760								var chg_filters = sortbox.find('.evo_filter_tax_box.chg').length;
2761								var set_count = sortbox.find('.evo_filter_tax_box.set').length;
2762								if( SC.filter_type == 'select' ) 
2763									( chg_filters > 0 ) ? show_apply_btns() : hide_apply_btns();
2764
2765
2766							// Filter highlighted indicator 
2767								if( !( el.hasClass('flhi') ) ){
2768
2769									const filter_btn = el.find('.evo-filter-btn');	
2770
2771									if( set_count > 0){
2772										filter_btn.find('em').html( set_count ).addClass('o');	
2773									}else{
2774										filter_btn.find('em').removeClass('o');			
2775									}			
2776								}
2777
2778
2779
2780							update_filter_data( filter_tax, new_terms , 'tterms');
2781
2782							run_filter_nav_check();
2783
2784						});
2785													
2786					// apply filters button
2787						el.on('click','.evo_filter_submit',function(){
2788
2789							el.evo_filters_update_from_temp( filter_line, el );
2790							
2791							cal_resets( el);
2792
2793							close_filter_menu(); // hide filter menu
2794
2795							// update filter item button
2796							sortbox.find('.filtering_set_val').removeClass('show');
2797
2798							el.evo_update_sc_from_filters();	// update shortcode from filters
2799							
2800							run_cal_ajax( el.attr('id'),'none','filering');
2801
2802							run_filter_nav_check();
2803						});
2804
2805					// clear filters
2806						el.on('click','.evo_filter_clear',function(){
2807								
2808							el.find('.evo_filter_tax_box').each(function(){
2809								const O = $(this),
2810									tax = O.data('tax'),
2811									terms = O.data('terms');
2812
2813								O.removeClass('set');
2814								O.find('.filtering_set_val').removeClass('set show');
2815								el.find('.evo-filter-btn em').removeClass('o');
2816
2817								close_filter_menu();
2818							});
2819
2820							// update all filters with default/ onload values @4.6.1
2821							$.each( all_cal_filter_data, function( tax, tdata){
2822								update_filter_data( tax, tdata.terms );
2823							} );
2824
2825
2826							hide_apply_btns(); // hide filter action buttons
2827							
2828							// update shortcode and run new ajax for events
2829							el.evo_update_sc_from_filters();					
2830							run_cal_ajax( el.attr('id'),'none','filering');
2831
2832							run_filter_nav_check();
2833						});
2834
2835					// click on filter navs
2836						el.on('click','.evo_filter_nav',function(){
2837							O = $(this);
2838
2839							_filter_bar = O.closest('.evo_filter_bar');
2840							_filter_container = _filter_bar.find('.evo_filter_container_in');
2841							_filter_line_width = _filter_bar.find('.eventon_filter_line')[0].scrollWidth;
2842							_filter_container_width = parseInt( _filter_container.width() ) + 0;
2843							_leftPos = _filter_container.scrollLeft();
2844							_scrollable_legth = _filter_line_width - _filter_container_width;
2845
2846							const scroll_length = _filter_container_width /2;
2847							
2848							// move right
2849							if( O.hasClass('evo_filter_r') ){
2850																		
2851								_filter_container.animate({scrollLeft:_leftPos + scroll_length},200);
2852								_filter_bar.find('.evo_filter_l').addClass('vis');
2853							// move left
2854							}else{
2855								sleft = (_leftPos - scroll_length < scroll_length) ? 0 :  _leftPos - scroll_length;
2856								_filter_container.animate({scrollLeft: sleft },200);											
2857							}
2858
2859							close_filter_menu();
2860
2861							setTimeout(function(){
2862								var _leftPos = _filter_container.scrollLeft();
2863								//console.log(_leftPos);
2864								if( _leftPos < 10){
2865									_filter_bar.find('.evo_filter_l').removeClass('vis');
2866									_filter_bar.find('.evo_filter_r').addClass('vis');
2867								}
2868
2869								if( _leftPos > ( _scrollable_legth - 5 ) ){
2870									_filter_bar.find('.evo_filter_r').removeClass('vis');
2871								}
2872							},200);
2873												
2874						});
2875
2876					// on window size change
2877					$(window).on('resize',function(){
2878						run_filter_nav_check();
2879					});
2880				}
2881
2882				var compare_terms = function(a, b){
2883					if (a === b) return true;
2884					if (a == null || b == null) return false;
2885					if (a.length !== b.length) return false;
2886
2887					for (var i = 0; i < a.length; ++i) {
2888					   if (a[i] !== b[i]) return false;
2889					}
2890					return true;
2891				}
2892				var close_filter_menu = function(){
2893					fmenu.html('').data('tax','');
2894				}
2895
2896				var show_apply_btns = function(){
2897					sortbox.find('.evo_filter_aply_btns').addClass('vis');	
2898				}
2899				var hide_apply_btns = function(){
2900					sortbox.find('.evo_filter_aply_btns').removeClass('vis');		
2901				}
2902
2903				var update_filter_data = function(tax, new_val, key){
2904
2905					el.evo_cal_update_filter_data( tax , new_val , key );					
2906				}
2907
2908
2909				// adjust and position filter nav buttons
2910				var run_filter_nav_check = function(){
2911
2912					$.each( el.find('.evo_filter_bar') , function(event){
2913						_filter_bar = $(this);
2914						_filter_container = _filter_bar.find('.evo_filter_container_in');
2915						_filter_line_width = _filter_bar.find('.eventon_filter_line')[0].scrollWidth;
2916						_filter_container_width = parseInt( _filter_container.width() ) + 3;
2917						var leftPos = _filter_container.scrollLeft();
2918
2919						//console.log(_filter_line_width +' '+ _filter_container_width +' '+leftPos);
2920
2921						// filter line is not showing full
2922						if( _filter_line_width > _filter_container_width ){
2923
2924							// if some of filter line is hidden on right
2925							if( ( _filter_container_width + leftPos  ) < _filter_line_width )
2926								_filter_bar.find('.evo_filter_r').addClass('vis');
2927
2928							// if filter has been scrolled
2929							if( leftPos > 0 ){
2930								_filter_bar.find('.evo_filter_l').addClass('vis');
2931							}else{
2932								_filter_bar.find('.evo_filter_r').addClass('vis');
2933							}
2934						}else{
2935							_filter_bar.find('.evo_filter_l').removeClass('vis');
2936							_filter_bar.find('.evo_filter_r').removeClass('vis');
2937						}
2938
2939					});
2940
2941					//console.log(filter_line_width +' '+ filter_container_width +' '+leftPos);					
2942				}
2943
2944				init();
2945			}
2946
2947			// for each tax move tterms value to nterms / before sending ajax
2948			$.fn.evo_filters_update_from_temp = function(filter_line, cal){
2949				// move temp term values into new terms
2950					filter_line.find('.evo_filter_tax_box').each(function(){
2951						var taxonomy = $(this).data('tax');
2952						const tterms = cal.evo_cal_get_filter_sub_data( taxonomy , 'tterms');
2953
2954						cal.evo_cal_update_filter_data( taxonomy , tterms, 'nterms');
2955
2956						$(this).removeClass('chg');
2957					});
2958			}
2959				
2960
2961	// PRIMARY hook to get content	 
2962		// MAIN AJAX for calendar events v2.8
2963		function run_cal_ajax( cal_id, direction, ajaxtype){
2964			
2965			// identify the calendar and its elements.
2966			var CAL = ev_cal = $('#'+cal_id); 
2967
2968			// check if ajax post content should run for this calendar or not			
2969			if(CAL.attr('data-runajax')!='0'){
2970
2971				const EVENTS_LIST = CAL.find('.eventon_events_list');
2972				const $showMoreBtn = EVENTS_LIST.find('.evoShow_more_events');
2973
2974				// category filtering for the calendar
2975				var cat = CAL.find('.evcal_sort').attr('cat');
2976
2977				// reset paged values for switching months
2978				if(ajaxtype=='switchmonth'){
2979					CAL.find('.cal_arguments').attr('data-show_limit_paged',1);
2980					CAL.evo_update_cal_sc({F:'show_limit_paged', V: '1'});
2981				}	
2982
2983				SC = CAL.evo_cal_functions({action:'load_shortcodes'});
2984
2985				$('body').trigger('evo_main_ajax_before', [CAL, ajaxtype, direction, SC]);		
2986
2987				var data_arg = {
2988					//action: 		'eventon_get_events',
2989					direction: 		direction,
2990					shortcode: 		SC,
2991					ajaxtype: 		ajaxtype,
2992					nonce: 			evo_general_params.n,
2993					nonceX: 		evo_general_params.nonce
2994				};	
2995
2996				
2997
2998				$.ajax({
2999					// preload actions
3000					beforeSend: function(xhr){
3001						xhr.setRequestHeader('X-WP-Nonce', evo_general_params.nonce );
3002
3003						CAL.addClass('evo_loading');
3004
3005						// paged -- adding events to end
3006						if(ajaxtype == 'paged'){							
3007							const currentContent = $showMoreBtn.html();
3008							$showMoreBtn.data('txt',currentContent);
3009							if( SC.tiles == 'yes'){
3010								$showMoreBtn.addClass('evoloading');
3011								$showMoreBtn.find('span').html('');
3012							}else{
3013								$showMoreBtn.find('span').addClass('evobtn_loader full');
3014							}
3015							
3016						}else{
3017
3018							html = evo_general_params.html.preload_events;
3019							if( SC.tiles == 'yes') html = evo_general_params.html.preload_event_tiles;
3020
3021							EVENTS_LIST.html( html );
3022							//EVENTS_LIST.slideUp('fast');
3023						}	
3024
3025						// maintain scrolltop location 4.6
3026						if( CAL.hasClass('nav_from_foot')){
3027							
3028							//scrolltop = (CAL.find('.evo_footer_nav').offset().top) - CAL.data('viewport_top');
3029							scrolltop = CAL.offset().top;
3030							$('html, body').animate({	scrollTop: scrolltop	},20);
3031						}	
3032
3033						$('body').trigger('evo_main_ajax_before_fnc',[CAL, ajaxtype, data_arg ]);	//s4.6			
3034					},
3035					type: 'POST', url: get_ajax_url('eventon_get_events'),data: data_arg,dataType:'json',
3036					success:function(data){
3037
3038						if(!data) return false;
3039
3040						// paged calendar
3041						if(ajaxtype == 'paged'){	
3042							$showMoreBtn.remove();
3043							EVENTS_LIST.find('.clear').remove();
3044							EVENTS_LIST.append( data.html + "<div class='clear'></div>");
3045
3046							// hide show more events if all events loaded
3047							var events_in_list = EVENTS_LIST.find('.eventon_list_event').length;
3048							if( 'total_events' in data && data.total_events == events_in_list){
3049								$showMoreBtn.hide();
3050							}	
3051
3052							// for month lists duplicate headers // @+2.8.1
3053							var T = {};
3054							EVENTS_LIST.find('.evcal_month_line').each(function(){
3055								d = $(this).data('d');
3056								if( T[d]) 
3057									$(this).remove();
3058								else
3059									T[d] = true;
3060							});
3061
3062							var T = {};
3063							EVENTS_LIST.find('.sep_month_events').each(function(){
3064								d = $(this).data('d');
3065								if( T[d]){
3066									var H = $(this).html();
3067									EVENTS_LIST.find('.sep_month_events[data-d="'+d+'"]').append( H );
3068									$(this).remove();
3069								}else{T[d] = true;}
3070							});
3071							
3072						}else{
3073							EVENTS_LIST.html(data.html);
3074						}
3075
3076						
3077						// update calendar data
3078						CAL.find('.evo_month_title').html( data.cal_month_title );
3079
3080						CAL.evo_cal_functions({action:'update_shortcodes',SC: data.SC});
3081						CAL.evo_cal_functions({action:'update_json',json: data.json});
3082
3083						// run cal process code
3084						CAL.evo_calendar({
3085							SC: data.SC,
3086							json: data.json
3087						});
3088							
3089
3090						$('body').trigger('calendar_month_changed',[CAL, data]);
3091						
3092						$('body').trigger('evo_main_ajax_success', [CAL, ajaxtype, data, data_arg]);
3093															
3094					},complete:function(data){
3095
3096						// show events list events if not set to hide on load
3097						if(! EVENTS_LIST.hasClass('evo_hide')) EVENTS_LIST.delay(300).slideDown('slow');
3098						
3099						// maintain scrolltop location 4.6
3100						if( CAL.hasClass('nav_from_foot')){
3101							
3102							setTimeout(function(){
3103								//scrolltop = (CAL.find('.evo_footer_nav').offset().top) - CAL.data('viewport_top');
3104								scrolltop = CAL.offset().top;
3105								$('html, body').animate({	scrollTop: scrolltop	},20);
3106								CAL.removeClass('nav_from_foot');
3107							},302);														
3108						}					
3109
3110						// pluggable
3111						$('body').trigger('evo_main_ajax_complete', [CAL, ajaxtype, data.responseJSON , data_arg]);
3112						CAL.removeClass('evo_loading');
3113					}
3114				});
3115			}			
3116		}
3117
3118		$('body').on('evo_run_cal_ajax',function(event,cal_id, direction, ajaxtype){
3119			run_cal_ajax( cal_id, direction, ajaxtype);
3120		});
3121
3122		// deprecated bridge function for sortby value 
3123		function ajax_post_content(sortby, cal_id, direction, ajaxtype){
3124			run_cal_ajax( cal_id, direction, ajaxtype);
3125		}
3126	
3127		
3128	// SINGLE EVENTS
3129		// Loading single event json based content
3130			$('body').on('evo_load_single_event_content', function(event, eid, obj){
3131				var ajaxdataa = {};
3132				ajaxdataa['eid'] = eid;
3133				ajaxdataa['nonce'] = the_ajax_script.postnonce;	
3134
3135				// pass on other event values
3136				if(obj.data('j')){
3137					$.each(obj.data('j'), function(index,val){
3138						ajaxdataa[ index] = val;
3139					});
3140				}			
3141				
3142				$.ajax({
3143					beforeSend: function(){ 	},	
3144					url:	get_ajax_url('eventon_load_event_content'),
3145					data: 	ajaxdataa,	dataType:'json', type: 	'POST',
3146					success:function(data){
3147						$('body').trigger('evo_single_event_content_loaded', [data, obj]);
3148					},complete:function(){ 	}
3149				});
3150			});
3151	
3152		if(BODY.evo_is_mobile()){
3153			if($('body').find('.fb.evo_ss').length != 0){
3154				$('body').find('.fb.evo_ss').each(function(){
3155					obj = $(this);
3156					obj.attr({'href':'http://m.facebook.com/sharer.php?u='+obj.attr('data-url')});
3157				});
3158			}
3159		}
3160
3161		// on single event page
3162		if($('body').find('.evo_sin_page').length>0){
3163			$('.evo_sin_page').each(function(){
3164				$('body').trigger('evo_load_single_event_content',[ $(this).data('eid'), $(this)]);
3165				$(this).find('.desc_trig ').attr({'data-ux_val':'none'});
3166			});
3167		}
3168		
3169		// Single events box
3170			// Click on single event box
3171				$('.eventon_single_event').on('click', '.evcal_list_a',function(event){
3172					var obj = $(this);	
3173					const $this = $(this);			
3174					var CAL = obj.closest('.ajde_evcal_calendar');
3175					var SC = CAL.evo_shortcode_data();
3176					var $trigger = '';
3177
3178					var uxVal = SC.ux_val;
3179
3180					event.preventDefault();
3181					
3182					// open in event page
3183					if(uxVal == 4){ 
3184						var url = obj.parent().siblings('.evo_event_schema').find('[itemprop=url]').attr('href');
3185						window.location.href= url;
3186					}else if(uxVal == '2'){ // External Link
3187						var url = SC.exturl;
3188						window.location.href= url;
3189					}else if(uxVal == '1'){ // Slide Down
3190						const $eventBox = $this.closest('.eventon_list_event');
3191						const $content = $eventBox.find('.event_description');
3192			            const isOpen = $content.hasClass('open');
3193			            const B = $('body');
3194			            $eventBox.toggleClass('open', !isOpen);
3195			            $content[isOpen ? 'slideUp' : 'slideDown']().toggleClass('open', !isOpen);
3196			            if ($eventBox.find('.evo_metarow_gmap').length) {
3197			                $eventBox.find('.evo_metarow_gmap').evo_load_gmap({ trigger_point: 'slideDownCard' });
3198			            }
3199			            if ($trigger && $trigger.data('runjs')) {
3200			                B.trigger('evo_load_single_event_content', [event_id, $trigger]);
3201			            }
3202			            B.trigger('evo_slidedown_eventcard_complete', [event_id, $trigger, !isOpen]);
3203			            return false;
3204
3205
3206
3207					}else if(uxVal == 'X'){ // do not do anything
3208						return false;
3209					}
3210				});
3211			// each single event box
3212				$('body').find('.eventon_single_event').each(function(){
3213					var _this = $(this);
3214
3215					var CAL = _this.closest('.ajde_evcal_calendar');
3216					var SC = CAL.evo_shortcode_data();	
3217					var evObj = CAL.find('.eventon_list_event');									
3218
3219					// show expanded eventCard
3220					if( SC.expanded =='yes'){
3221						_this.find('.evcal_eventcard').show();
3222						var idd = _this.find('.evcal_gmaps');						
3223
3224						// close button
3225						_this.find('.evcal_close').parent().css({'padding-right':0});
3226						_this.find('.evcal_close').hide();
3227
3228						//console.log(idd);
3229						var obj = _this.find('.desc_trig');
3230
3231						// Google Map
3232						_this.find('.evo_metarow_gmap').evo_load_gmap();
3233					
3234						// mark as eventcard open @since 4.4
3235						evObj.find('.event_description').addClass('open');
3236
3237					// open eventBox and lightbox	
3238					}else if(SC.uxval =='3'){
3239
3240						var obj = _this.find('.desc_trig');
3241						// remove other attr - that cause to redirect
3242						obj.removeAttr('data-exlk').attr({'data-ux_val':'3'});
3243					}
3244
3245					// show event excerpt
3246					var ev_excerpt = CAL.find('.event_excerpt').html();
3247					
3248					if(ev_excerpt!='' && ev_excerpt!== undefined && SC.excerpt =='yes' ){
3249						var appendation = '<div class="event_excerpt_in">'+ev_excerpt+'</div>'
3250						evObj.append(appendation);
3251					}
3252
3253					// trigger support @since 4.4
3254					var obj = evObj.find('.desc_trig');
3255					var event_id = evObj.data('event_id');
3256
3257
3258					$('body').trigger('evo_slidedown_eventcard_complete',[ event_id, obj]);	
3259				});
3260
3261// supportive
3262	// ajax url function  @u 4.5.5
3263		function get_ajax_url(action){
3264			var ajax_type = 'endpoint';
3265			if('ajax_method' in evo_general_params ) ajax_type = evo_general_params.ajax_method;
3266			return $('body').evo_get_ajax_url({a:action, type: 	ajax_type });
3267		}
3268	// handlebar additions
3269		function handlebar_additional_arguments(){
3270			Handlebars.registerHelper('ifE',function(v1, options){
3271				return (v1 !== undefined && v1 != '' && v1)
3272                    ? options.fn(this)
3273                    : options.inverse(this);
3274			});
3275
3276			Handlebars.registerHelper('ifEQ',function(v1, v2, options){
3277				return ( v1 == v2)? options.fn(this): options.inverse(this);
3278			});
3279			Handlebars.registerHelper('ifNEQ',function(v1, v2, options){
3280				return ( v1 != v2)? options.fn(this): options.inverse(this);
3281			});
3282			Handlebars.registerHelper('BUStxt',function(V, options){	
3283				if( !( V in BUS.txt) ) return V;
3284				return BUS.txt[V];
3285			});
3286			Handlebars.registerHelper('GetDMnames',function(V, U, options){				
3287				return BUS.dms[U][ V ];
3288			});
3289			// get total of increments
3290			Handlebars.registerHelper('forAdds',function(count, add_val, options){	
3291				O = '';
3292				for(x=1; x<= count; x++){	O += add_val;	}			
3293				return O;
3294			});
3295			Handlebars.registerHelper('GetEvProp',function(EID, PROP, CALID){
3296				EID = EID.split('-');	
3297				EV = $('#'+ CALID).find('.evo_cal_events').data('events');
3298				
3299				var O = '';
3300				$.each(EV, function(i,d){
3301					if( d.ID == EID[0] && d.ri == EID[1]){
3302						if( !(PROP in d.event_pmv)) return;
3303						O = d.event_pmv[PROP][0];
3304					}
3305				});
3306				return O;
3307			});
3308			Handlebars.registerHelper('GetEvV',function(EID, PROP, CALID){
3309				EID = EID.split('-');	
3310				EV = $('#'+ CALID).find('.evo_cal_events').data('events');
3311				
3312				var O = '';
3313				$.each(EV, function(i,d){
3314					if( d.ID == EID[0] && d.ri == EID[1]){
3315						O = d[PROP];
3316					}
3317				});
3318				return O;
3319			});
3320			Handlebars.registerHelper('COUNT',function( V){		
3321				return Object.keys(V).length;
3322			});
3323			Handlebars.registerHelper('CountlimitLess',function( AR, C,options){		
3324				var L= Object.keys(AR).length;
3325				return ( L < C)? options.inverse(this): options.fn(this);
3326			});
3327			Handlebars.registerHelper('ifCOND',function(v1, operator, v2, options){
3328				return checkCondition(v1, operator, v2)
3329	                ? options.fn(this)
3330	                : options.inverse(this);
3331			});
3332			Handlebars.registerHelper('toJSON', function(obj) {
3333			    return new Handlebars.SafeString(JSON.stringify(obj));
3334			});
3335			Handlebars.registerHelper('Cal_def_check',function(V, options){		
3336				if( BUS.cal_def && BUS.cal_def[V] ) return options.fn(this);
3337				return options.inverse(this);
3338			});
3339			Handlebars.registerHelper('TypeCheck',function(V, options){		
3340				if( options.type == V ) return options.fn(this);
3341				return options.inverse(this);
3342			});
3343		}
3344		function checkCondition(v1, operator, v2) {
3345	        switch(operator) {
3346	            case '==':
3347	                return (v1 == v2);
3348	            case '===':
3349	                return (v1 === v2);
3350	            case '!==':
3351	                return (v1 !== v2);
3352	            case '<':
3353	                return (v1 < v2);
3354	            case '<=':
3355	                return (v1 <= v2);
3356	            case '>':
3357	                return (v1 > v2);
3358	            case '>=':
3359	                return (v1 >= v2);
3360	            case '&&':
3361	                return (v1 && v2);
3362	            case '||':
3363	                return (v1 || v2);
3364	            default:
3365	                return false;
3366	        }
3367	    }
3368
3369
3370// DEPRECATING 
3371	// LIGHTBOX		
3372		// since 4.2 moving to functions
3373		// open lightbox @2.9
3374			BODY.on('evo_open_lightbox',function(event, lb_class, content){
3375				const LIGHTBOX = $('.evo_lightbox.'+lb_class).eq(0);
3376
3377				// if already open
3378				if(LIGHTBOX.is("visible")===true) return false;
3379
3380				if( content != ''){
3381					LIGHTBOX.find('.evo_lightbox_body').html( content );
3382				}
3383				BODY.trigger('evolightbox_show', [ lb_class ]);
3384			});
3385
3386		// click outside close LB
3387			BODY.on('clicked_on_page', function(event, obj, ev ){
3388				if( obj.hasClass('evo_content_inin')){
3389					closing_lightbox( obj.closest('.evo_lightbox') );
3390				}
3391			});
3392
3393		// close popup
3394			BODY.on('click','.evolbclose', function(){	
3395				if( $(this).hasClass('evolb_close_btn')) return;
3396				LIGHTBOX = 	$(this).closest('.evo_lightbox');
3397				closing_lightbox( LIGHTBOX );				
3398			});
3399
3400		// close with click outside popup box when pop is shown						
3401			function closing_lightbox( lightboxELM){
3402				
3403				if(! lightboxELM.hasClass('show')) return false;
3404				Close = (lightboxELM.parent().find('.evo_lightbox.show').length == 1)? true: false;
3405				lightboxELM.removeClass('show');
3406
3407				$('body').trigger('lightbox_before_event_closing', [lightboxELM]);
3408
3409				setTimeout( function(){ 
3410					lightboxELM.find('.evo_lightbox_body').html('');
3411					
3412					if(Close){
3413						$('body').removeClass('evo_overflow');
3414						$('html').removeClass('evo_overflow');
3415					}
3416					
3417					// trigger action to hook in at this stage
3418						$('body').trigger('lightbox_event_closing', [lightboxELM]);
3419				}, 100);
3420			}
3421
3422		// when lightbox open triggered
3423			$('body').on('evolightbox_show',function(event, lb_class){
3424				$('.evo_lightboxes').show();
3425				$('body').addClass('evo_overflow');
3426				$('html').addClass('evo_overflow');
3427
3428				$('body').trigger('evolightbox_opened',[ lb_class ]);
3429			});
3430
3431
3432});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.