PageSourceSearch

https://buildingperformancecenter.org/wp-content/plugins/eventON/assets/js/eventon_functions.js?ver=5.1

js buildingperformancecenter.org collected 2026-10-06 08:04:38 UTC 86,018 bytes, 2,525 lines download raw bytes

1/**
2 * Javascript: EventON functions for all calendars
3 * @version: 5.1
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	const BB = $('body');
21
22	// Basics
23		// Calendar function s
24			$.fn.evo_cal_functions = function(O){
25				const el = this;
26				switch(O.action){
27					// load shortcodes inside calendar data
28					case 'load_shortcodes':
29						return el.find('.evo_cal_data').data('sc');		
30					break;
31					case 'update_json':
32						//console.log(O.json);
33						el.find('.evo_cal_events').data('events', O.json);		
34					break;
35					case 'update_shortcodes':
36						//console.log(O.SC);
37						el.find('.evo_cal_data').data( 'sc', O.SC );
38					break;
39				}
40			};
41
42		// access page GLOBALS
43			$.fn.evo_get_global = function(opt){
44				var defaults = { S1:'', S2:''};
45				var OPT = $.extend({}, defaults, opt);
46
47				var BUS = $('#evo_global_data').data('d');
48
49				if(!(OPT.S1 in BUS)) return false;
50				if(!(OPT.S2 in BUS[OPT.S1])) return false;
51				return BUS[OPT.S1][OPT.S2];
52			}
53			$.fn.evo_get_txt = function(opt){
54				var defaults = { V:''}
55				var OPT = $.extend({}, defaults, opt);
56
57				var BUS = $('#evo_global_data').data('d');
58				//console.log(BUS);
59				if(!('txt' in BUS)) return false;
60				if(!(OPT.V in BUS.txt)) return false;
61				return BUS.txt[OPT.V];
62			}
63
64			// get translated text strings from ajax loaded data @4.6.4
65			$.fn.evo_lang = function(text){
66				var t = text.toLowerCase()
67				    .replace(/ /g, "_")
68				    .replace(/[^\w-]+/g, "");
69
70
71				var BUS = $('#evo_global_data').data('d');
72
73				if(!('txt' in BUS)) return text;
74				if(!(t in BUS.txt)) return text;
75				return BUS.txt[ t ];
76
77			}
78			$.fn.evo_get_cal_def = function(opt){
79				var defaults = { V:''}
80				var OPT = $.extend({}, defaults, opt);
81
82				var BUS = $('#evo_global_data').data('d');
83				if(!('cal_def' in BUS)) return false;
84				if(!(OPT.V in BUS.cal_def)) return false;
85				return BUS.cal_def[OPT.V];
86			}
87
88			// return dms translates values from global data
89			// added 4.0
90			$.fn.evo_get_dms_vals = function(opt){
91				// type = d, d1,d3, m, m3
92				// V = 0-x
93				var defaults = { type:'d', V:''}
94				var OPT = $.extend({}, defaults, opt);
95
96				var BUS = $('#evo_global_data').data('d');			
97				if(!('dms' in BUS)) return false;
98				if(!(OPT.type in BUS.dms)) return false;
99
100				return BUS.dms[ OPT.type ][ OPT.V ];
101				
102			}
103
104	// GENERAL AJAX ACCESS @4.7.2 updated @5.1
105		$.fn.evo_admin_get_ajax = function(opt){
106
107			var el = $(this);
108
109  			var OO = this.evo_process_ajax_params( opt );
110
111
112  			var _lbdata = OO.lbdata;
113			var _adata = OO.adata;	
114			var _populate_id = OO._populate_id;	
115
116			// Allow custom success callback to be passed in opt -- 4.9.2    		
117    		var customBefore = typeof opt.onBefore === 'function' ? opt.onBefore : null;   // New onBefore callback
118		    var customSuccess = typeof opt.onSuccess === 'function' ? opt.onSuccess : (typeof opt.success === 'function' ? opt.success : null); 
119		    	// Rename to onSuccess, keep backward compatibility with 'success'
120		    var customSuccess_Extra = typeof opt.successExtra === 'function' ? opt.successExtra : null; // this will run with default ajax
121		    var customComplete = typeof opt.onComplete === 'function' ? opt.onComplete : null; // New onComplete callback
122		    var customError = typeof opt.onError === 'function' ? opt.onError : null; // New onError callback
123
124			var ajax_url = el.evo_get_ajax_url({a: _adata.a, e: _adata.end, type: _adata.ajax_type});
125
126			// for lightbox
127				var LB = false;
128	  			if( _lbdata.class != '') LB = $('body').find('.evo_lightbox.'+ _lbdata.class );
129
130	  			//console.log(OO);
131	  		// Run AJAX
132	  		let ajaxResponse = '';
133  			$.ajax({
134				beforeSend: function(){
135					if (customBefore) {   customBefore.call(el, OO, LB); } // Call with onBefore:function(OO, LB){}
136					el.evo_perform_ajax_run_loader( OO, LB, 'start'  );
137				},
138				type: 'POST', url: ajax_url, data: _adata.data,	dataType:'json',
139				success:function(data){	
140					ajaxResponse = data;
141					//console.log(data);
142					// If a custom success callback is provided, use it
143		            if (customSuccess) {
144		                customSuccess.call(el, OO, data, LB); // Call with onSuccess:function( OO, data, LB){} 
145		                // call data with data.data
146		                // Trigger a custom event for onSuccess - 4.9.11
147		                $('body').trigger('evo_ajax_success_' + OO.uid,[ OO, data , el]);	
148		            } else {
149		                // Otherwise, use the default success behavior
150		                el.evo_perform_ajax_success(OO, data, LB);
151		                if( customSuccess_Extra ) customSuccess_Extra.call( el, OO, data, LB );
152		            }
153
154				},complete:function(){
155					if (customComplete) {     customComplete.call(el, OO, ajaxResponse, LB);  } // Call with onComplete:function( OO, data, LB){} 
156					el.evo_perform_ajax_run_loader( OO, LB, 'end'  );					
157				},
158				error: function(xhr, status, error) {
159					if (customError) {     customError(xhr, status, error, OO, LB);  } // Call with onError:function( xhr, status, error, OO, LB){} 
160					
161			        // Trigger the global error event so our Promise can catch it
162			        $('body').trigger('evo_ajax_error_' + OO.uid, [OO,  xhr, error ]);
163			    }
164			});				
165		}
166
167		// @5.1
168		$.fn.evo_show_ajax_error_snackbar = (xhr, err) =>{
169			let errorMessage = 'An error occurred';
170
171		    // If the server returned a JSON response body even with the 404 status
172		    if (xhr.responseJSON && xhr.responseJSON.data) {
173		        errorMessage = xhr.responseJSON.data;
174		    } else if (xhr.responseText) {
175		        // Fallback: try to parse the raw text if it's JSON
176		        try {
177		            const parsed = JSON.parse(xhr.responseText);
178		            if (parsed.data) errorMessage = parsed.data;
179		        } catch (e) {
180		            // If not JSON, use the HTTP status text (e.g., "Not Found")
181		            errorMessage = xhr.statusText || errorMessage;
182		        }
183		    }
184
185		    $(this).evo_snackbar({ msg: errorMessage });
186		}
187
188		// submit forms via ligtbox
189		// @since 4.2.2		@updated 4.8
190		$.fn.evo_ajax_form_submit = function( opt , boxtype , formObj){
191			const el = this;	
192
193
194  			var OO = this.evo_process_ajax_params( opt );
195
196  			console.log(OO);
197
198  			var _lbdata = OO.lbdata;
199  			var _spdata = OO.spdata;
200			var _adata = OO.adata;	
201			var _populate_id = OO._populate_id;	
202  			  			
203  			// get parent element
204  			var parent = '';
205  			if( boxtype == 'sp') parent = el.closest('.evosp_in');
206  			if( boxtype == 'lb'){
207  				parent = el.closest('.evo_lightbox');
208  				if( _lbdata.class != '') parent = $('body').find('.evo_lightbox.'+ _lbdata.class );
209  			} 
210
211  			var form = parent.find('form');
212  			if( formObj !== undefined ) form = formObj;
213
214  			if( form.length == 0){ console.log('No Fom object found'); return;}
215
216  			// form required fields validation - @4.9
217			if( el.hasClass('validate')){
218
219				var hasError = false;
220				$('body').trigger('evo_elm_form_presubmit_validation', [form, function(isValid) {
221				    hasError =  isValid ? false: true;
222				}]);
223			    if( hasError){
224			    	el.evo_snackbar({message: 'Required fields missing' });
225			    	//LB.evo_lightbox_show_msg({message:'Required fields missing'});
226			    	return;
227			    }	
228			}
229
230
231  			// reset LB message
232  			if( boxtype == 'lb') parent.evo_lightbox_hide_msg();
233
234  			var ajax_url = el.evo_get_ajax_url({a: _adata.a, e: _adata.end, type: _adata.ajax_type});
235
236
237  			// Add passed on data from ajax object @4.8.2
238			var extra_ajax_data = ('data' in _adata ) ? _adata.data : null;
239
240			let ajaxResponse = '';
241	  			
242  			// Submit form
243				form.ajaxSubmit({
244					beforeSubmit: function(opt, xhr){
245						el.evo_perform_ajax_run_loader( OO, parent, 'start', boxtype  );
246					},
247					dataType: 	'json',	
248					url: ajax_url,	type: 	'POST',
249					data: extra_ajax_data,
250					success:function(data){
251						//console.log(data);
252						ajaxResponse = data;
253						el.evo_perform_ajax_success( OO, data, parent , boxtype);
254					},
255					complete:function(){	
256						el.evo_perform_ajax_run_loader( OO, parent, 'end' , boxtype , aja
256xResponse);
257					}
258				});
259		}
260		$.fn.evo_ajax_lightbox_form_submit = function(opt , formObj ){			
261  			this.evo_ajax_form_submit( opt, 'lb', formObj );
262		}
263
264	// perform ajax functions / type = start/end
265		$.fn.evo_perform_ajax_run_loader = function( OO , LB, type , boxtype, ajaxResponse){
266			var el = this;
267			var _lbdata = OO.lbdata;
268			var _adata = OO.adata;	
269			var _spdata = OO.spdata;	
270
271			var customer_loader_elm = false;
272			var loader_btn_el = false;
273			var loader_in_icon = false;
274
275  			if( _adata.loader_el !='')	customer_loader_elm = _adata.loader_el;
276  			if( 'loader_class' in _adata && _adata.loader_class != '') 
277  				customer_loader_elm = $('.' + _adata.loader_class);
278  			if( _adata.loader_btn_el != '' && _adata.loader_btn_el !== undefined ) loader_btn_el = el;
279  			if( _adata.loader_in_icon != '' && _adata.loader_in_icon !== undefined ) loader_in_icon = el;
280  			
281  			var LB_loader = false;
282  			if( LB && 'loader' in _lbdata && _lbdata.loader ) LB_loader = true;
283
284  			if( type == 'start'){
285
286  				var trigger_id = ( 'uid' in OO && OO.uid != '' ) ? OO.uid : OO.ajax_action; // @4.8
287  				$('body').trigger('evo_ajax_beforesend_' + trigger_id ,[ OO, el ]);
288
289				if( LB_loader ){
290					LB.find('.ajde_popup_text').addClass( 'evoloading'); // legacy
291					LB.evo_lightbox_start_inloading();
292				}
293				if( customer_loader_elm ) $( customer_loader_elm ).addClass('evoloading ');
294				if( loader_btn_el ) el.addClass('evobtn_loader'); // loader on button
295				if( loader_in_icon ) el.addClass('evoloader_icon'); // Loader in Icon (replace i.fa child with loader elm) @5.0.3
296  			
297			// COMPLETE
298  			}else{
299
300  				var trigger_id = ( 'uid' in OO && OO.uid != '' ) ? OO.uid : OO.ajax_action; // @4.8
301  				if( trigger_id === undefined ) trigger_id = OO.adata.a;
302  				//console.log(OO);
303
304  				$('body').trigger('evo_ajax_complete_' + trigger_id ,[ OO , el ]);
305			
306				if( LB_loader ){
307					LB.find('.ajde_popup_text').removeClass( 'evoloading');
308					LB.evo_lightbox_stop_inloading();	
309				}
310				if( customer_loader_elm ) $( customer_loader_elm ).removeClass('evoloading');
311				if( loader_btn_el ) el.removeClass('evobtn_loader'); // loader on button
312				if( 'loader_btn_el_done' in _adata && _adata.loader_btn_el_done ){
313					if( ajaxResponse.success ) el.removeClass('evobtn_loader success' );
314				} 
315				if( loader_in_icon ) el.removeClass('evoloader_icon'); // Loader in Icon (replace i.fa child with loader elm) @5.0.3				
316  			}
317
318			return {
319				'l1': customer_loader_elm,
320				'l2':LB_loader
321			};
322		}
323
324		$.fn.evo_perform_ajax_success = function ( OO, data, LB , boxtype){
325			var el = this;
326			var _lbdata = OO.lbdata;
327			var _adata = OO.adata;	
328			var _spdata = OO.spdata;	
329
330			var _populate_id = OO._populate_id;	
331			if( '_populate_id' in _adata ) 	_populate_id = _adata._populate_id;
332
333			if( !data || data === undefined ) return;
334
335
336			// if json is passing data object @4.9
337			var _success = ('success' in data) ? data.success : (data.status === 'good');
338
339			var extractedContent = 'content' in data ? data.content: '';
340			if( 'data' in data && 'content' in data.data) extractedContent = data.data.content;
341			var extractedData = ('data' in data) ? data.data : data;
342			extractedData['content'] = extractedContent;
343
344			// Ensure extractedData is an object for property checks; if it’s a string, wrap it
345		    if (typeof extractedData !== 'object' || extractedData === null) {
346		        extractedData = { msg: extractedData }; // Convert string to object
347		    }
348
349		    // Assign success and status to the extracted data
350		    extractedData.success = _success;
351		    extractedData.status = ('status' in extractedData) ? extractedData.status : (_success ? 'good' : 'bad');
352
353		    // Replace original data with processed data
354		    data = extractedData;
355
356		    //console.log(data);
357			//console.log( OO);
358
359			// if inside lightbox
360			if( LB.length > 0 && boxtype != 'sp'){
361				//console.log('show lb msg');
362				// show message
363					if (data && typeof data === 'object' && !Array.isArray(data) && 'msg' in data && data.msg !== '') {
364						LB.evo_lightbox_show_msg({
365							'type': ( _success ? 'good':'bad'), 
366							'message': ( data.msg ? data.msg : (data.data.msg ? data.data.msg : '') ), 
367							hide_lightbox: (  _success ? _lbdata.hide : false ),	
368							hide_message: _lbdata.hide_msg
369						});
370					}	
371
372				// populate lightbox
373				if( data && _lbdata.new_content && 'content' in data && data.content != '' ){
374
375					// populate a specific dom element with content
376					if( _populate_id ){
377						$('body').find('#'+_populate_id ).replaceWith( data.content );					
378					}else{
379						LB.evo_lightbox_populate_content({content: data.content});
380					}
381				}	
382								
383			}else{
384				// populate content
385				if( data && _populate_id && extractedContent != ''){
386					$('body').find('#'+_populate_id ).html( extractedContent );
387				}						
388			}
389
390			// Show snackbar message
391				if( 'show_snackbar' in  _adata && ('msg' in data)  && data.msg != '' ) {
392					el.evo_snackbar({message: data.msg});
393				}
394
395			// populate content with matching DOM class names, will set new html @4.7.2
396				if( data && 'populate_dom_classes' in data){
397					$.each( data.populate_dom_classes, function( domclass, content){
398						$('body').find('.'+ domclass).html( content );
399					} );
400				}
401
402			// Replace Content with new content DOM class match @since 5.0.9
403				if( data && 'replace_dom_classes' in data){
404					$.each( data.replace_dom_classes, function( domclass, content){
405						$('body').find('.'+ domclass).replaceWith( content );
406					} );
407				}
408
409			// if ajax data pass dom content to be replaced with run through each and replace - @4.2.3
410				if(data &&  'refresh_dom_content' in data ){
411					$.each(data.refresh_dom_content, function(domid, content){
412						$('body').find('#'+ domid).replaceWith( content);
413					});
414				}
415
416			// Trigger success actions @5.0.3
417			// call like 'trig_success'=> [ ['evosp_trig_close', ['delay'=> 2000] ] ]
418				if( _success &&  'trig_success' in _adata ){
419					$.each( _adata.trig_success, function(i, item) {
420						 var event_name = item[0];
421				        var extra_data = item[1] || {};   // parameters object (or {} if none)
422				        $('body').trigger( event_name, [ extra_data ] );
423				    });
424				}
425
426			// SIDE PANEL ACTIONS
427				// for SP content @since 4.5.2
428					if(data &&  'sp_content' in data){
429						if( 'load_new_content_id' in OO){
430							BB.find('#'+ OO.load_new_content_id).html( data.sp_content );
431						}else{
432							$("body").find('.evops_content').html( data.sp_content);
433						}
434						
435					}
436				// SP footer content @since 4.5.2
437					if( data && 'sp_content_foot' in data){
438						$("body").find('.evosp_foot_in').html( data.sp_content_foot);
439					}
440
441				// SP Show message @ since 5.0.13
442					if( data && 'sp_show_msg' in data){
443						BB.evo_showmsg_sidepanel( data.sp_show_msg , _spdata);
444					}
445			// process trumbowyg editors
446				$('body').trigger('evo_elm_load_interactivity');
447
448
449			// assign dynamic vals to DOM element
450				setTimeout(function(){
451					if( 'evoelms' in data ){
452						$.each( data.evoelms , function( uniqueid, elm_data ){
453
454							$('body').find('.has_dynamic_vals').each(function(){
455
456								if( $(this).attr('id') != uniqueid ) return;
457								var dynamic_elm = $(this);
458
459								$.each( elm_data , function( elm_key, elmv){
460									dynamic_elm.data( elm_key, elmv );
461								});
462							});
463						});
464					}
465				},200);
466
467
468			// call like $('body').on('evo_ajax_success_X', function(event, OO, data, el){
469			$('body').trigger('evo_ajax_success_' + OO.uid,[ OO, data , el]);	
470		}
471
472	// Process ajax and lightbox values @4.7.2 @updated 5.0.13
473		$.fn.evo_process_ajax_params = function ( opt ){
474			// defaults
475			var defz = { 
476				'uid':'',
477
478				// @since 4.7.2
479				'adata':{}, // @4.7.2 include all ajax data in here, type (ajax,rest,endpoint),action/a, other data
480				'lbdata':{},// @4.7.2 lightbox data all in one place, class, title, size, padding
481				'spdata':{},// @5.0.3 side panel data all in one place, class, title, size, padding, ajax_data
482				'_populate_id':'', // loading new content into matching elements outside of lightbox
483				
484				// legacy values
485				'content':'',// passed on dynamic content
486				'content_id' :'',// id to get dynamic content from page		
487								
488				't':'', //title
489				'lbc':'',// * lightbox class - REQUIRED
490				'lbac':'',// ligthbox additional class 4.6
491				'lbsz':'',// lightbox size = mid small, s400, s500, s700, s800
492				'lightbox_loader': true,
493				'preload_temp_key': 'init', // 4.6
494				'load_new_content': true, // @since 4.3.5
495				'lb_padding': '', // @4.3.5
496				'load_new_content_id':'',
497
498				'ajax':'no',// use ajax to load content yes no
499				'ajax_url':'',// load content from ajax file
500				'end':'admin',// admin or client end
501				'ajax_action':'', // @4.4 pass on ajax endpoint action key
502				'a':'',
503				'ajax_type':'ajax', // @4.4 ajax type, ajax, rest or endpoint
504				'd':'', // data object for ajax
505				'other_data':'',
506				'ajaxdata':'',				
507			};
508
509
510			// extend passed with defaults
511			var OO = $.extend({}, defz, opt);
512
513			// Build processed object
514				var processed = {};
515				processed['uid'] = OO.uid;
516
517
518			// Ajax	
519				var _adata = ( OO.adata == '') ? {}: OO.adata;
520
521				// type passed value fix
522				var passed_type_val = false;
523				if( 'type' in _adata && _adata.type != '' &&
524					!['ajax', 'rest', 'endpoint'].includes(_adata.type)
525				){
526					passed_type_val = _adata.type;
527					_adata.type = '';
528				}
529
530				// set default needed values
531				var def_avals = { 
532					'a':'',
533					'type':'ajax',
534					'end':'admin',
535					'data': '',
536					'loader_el':'',
537					'loader_btn_el':'',//4.8
538					'loader_btn_el_done':'', // 5.0.9
539					'loader_class':'',
540					'url':'',
541					'trig_success':[], // @5.0.3 trigger actions to run on success
542				}
543				
544				// set default values
545				$.each( def_avals, function(key, value) {					
546					if( key == 'data' && !( 'a' in _adata ) && ('data' in _adata ) && 'a' in _adata.data ) return;
547					if( !(key in _adata ) && value != '' ) _adata[ key ] = value;
548				});	
549
550				//console.log( _adata );
551
552				// map old to new
553				var def_adata_mapping = { 
554					'a' : 'a',
555					'ajax_action' : 'a',
556					'ajax_type':'type',
557					'end': 'end',
558					'ajax_url': 'url',
559					'ajaxdata':'data',
560					'ajax_data':'data',
561					'd':'data',
562				}
563				$.each( def_adata_mapping, function(oldV, newV) {					
564					if( newV in _adata && _adata[ newV ] != '' ) return;
565
566					if(  oldV in OO && OO[oldV] !== '' ) {
567						_adata[newV] = OO[oldV];
568					}  
569				});	
570
571				if( _adata.data === undefined ) _adata.data = {};
572
573				//console.log( _adata );			
574
575				// Move additional values in _adata to _adata.data
576					$.each(_adata, function(key, value) {
577						if ( !(key in def_avals)) {
578							//_adata.data[key] = value; // Move any extra values to _adata.data
579							//delete _adata[key]; // Remove them from the main _adata object
580						}
581					});
582
583				if( 'data' in _adata ){
584					//_adata['data']['nn'] = ( _adata.end == 'client' ) ? evo_general_params.n : evo_admin_ajax_handle.postnonce; 
585										
586					_adata['data']['nn'] = (typeof evo_admin_ajax_handle !== 'undefined' && evo_admin_ajax_handle !== null) 
587					    ? evo_admin_ajax_handle.postnonce 
588					    : evo_general_params.n;
589
590
591					_adata['data']['uid'] = processed['uid'];
592					if( passed_type_val ) _adata['data']['type'] = passed_type_val;
593					if( 'action' in _adata.data ) _adata['a'] =  _adata.data.action;
594					if( 'a' in _adata.data ) _adata['a'] =  _adata.data.a;
595					if( 'ajaxdata' in OO ) processed['ajaxdata'] = _adata.data;
596				}		
597
598				processed['adata'] = _adata;
599				
600
601			// lightbox
602				var _lbdata = ( OO.lbdata == '') ? {}: OO.lbdata;
603
604				// if legacy values exists > convert them to new
605				var def_lbdata_mapping = {
606					'lbc':'class',
607				    'lbsz':'size',
608				    'lbac' :'additional_class',
609				    't':'title',
610				    'lb_padding': 'padding',
611				    'load_new_content':'new_content',
612				    'lightbox_loader': 'loader',
613				    'content_id':'content_id',
614				    'content':'content',
615				    'hide_lightbox':'hide',
616				    'hide_message':'hide_msg',
617				    'lightbox_key': 'class',
618				}
619				$.each( def_lbdata_mapping, function(oldV, newV) {
620					// if _lbdata has new value > skip
621					if (newV in _lbdata && _lbdata[newV] !== '' && _lbdata[newV] !== null && _lbdata[newV] !== undefined) {
622				        return; 
623				    }
624					if(  oldV in OO && OO[oldV] !== '' ) {
625						_lbdata[newV] = OO[oldV];
626					} 
627				});	
628
629				// set default needed values
630				var def_lbvals = {
631					'padding':'evopad15',
632					'loader': false,
633					'preload_temp_key':'init',
634					'new_content': true,
635					'additional_class':'',
636					'lbcontentid': '',
637					'title':'',
638					'title_icon':'',
639					'hide':false,
640					'hide_msg':2000,
641					'content':'', // content for lightbox
642					'content_id':'', // content id in DOM to grab content for lightbox
643				}
644				// set default values
645				$.each( def_lbvals, function(key, value) {
646					if(  key in _lbdata )  return;
647					if( value == '') return;
648					_lbdata[ key ] = value;
649				});
650
651
652				//console.log( _lbdata.new_content ) ;
653
654				// load lightbox content legacy
655				if( OO.ajaxdata.load_lbcontent ) _lbdata['new_content'] = true;
656				if( OO.ajaxdata.load_new_content ) _lbdata['new_content'] = true;
657
658				// populate new content @4.7.3
659					processed['_populate_id'] =  false;
660					if( OO._populate_id != '')  processed['_populate_id'] = OO._populate_id;
661					if( OO.load_new_content_id != '')  processed['_populate_id'] = OO.load_new_content_id;
662					if( 'new_content_id' in _lbdata && _lbdata.new_content_id != '')  processed['_populate_id'] = _lbdata.new_content_id;
663					if( 'content_id' in _lbdata && _lbdata.content_id != '') processed['_populate_id'] = _lbdata.content_id;
664
665				processed['lbdata'] = _lbdata;
666
667			// make sure uid is moved to main level
668				if( processed.uid == '' && 'uid' in processed['lbdata'] ) processed['uid'] = processed['lbdata']['uid'];
669
670			// add legacy variables for backward compatibility
671				$.each(opt, function(oldkey, oldval){
672					if( oldkey in processed ) return;
673					processed[ oldkey ] = oldval;
674				});
675
676			// Side Panel
677				var _spdata = ( OO.spdata == '' ) ? {} : OO.spdata;
678				// set default needed values
679				var def_spvals = {
680					'class':'',
681					'loader': false,
682					'new_content': true,
683					'additional_class':'',
684					'title':'',
685					'hide':false,
686					'hide_msg':2000,
687					'content':'', // content for sp
688					'content_id':'', // content id in DOM to grab content for sp
689					'size':'',
690				}
691				// set default values
692				$.each( def_spvals, function(key, value) {
693					if(  key in _lbdata )  return;
694					if( value == '') return;
695					_lbdata[ key ] = value;
696				});
697
698			//console.log( processed );
699
700			return processed;
701		}
702
703	// LIGHTBOX triggers
704		// @version 4.2
705		$('body').on('click','.evolb_trigger', function(event){
706			if( event !== undefined ){
707				event.preventDefault();
708				event.stopPropagation();
709			}
710				
711			$(this).evo_lightbox_open(
712				$(this).data('lbvals') ?? $(this).data('d')
713			);
714		});
715		$('body').on('click','.evolb_close_btn', function (){
716			const LB = $(this).closest('.evo_lightbox');
717			LB.evo_lightbox_close();
718		});
719
720		// save form content - @since 4.2.2
721		$('body').on('click','.evolb_trigger_save, .evo_submit_form', function(event){
722			if( event !== undefined ){	event.preventDefault();	event.stopPropagation();	}
723
724			$(this).evo_ajax_form_submit( $(this).data('d') , ( $(this).closest('.evo_lightbox').length ? 'lb':'') );
725		});
726
727		$('body').on('click','.evo_trigger_ajax_run', function(event){
728			if( event !== undefined ){
729				event.preventDefault();
730				event.stopPropagation();
731			}
732
733			//console.log($(this).data('d') );
734			$(this).evo_admin_get_ajax( $(this).data('d') );
735		});
736		// @since 4.3.3
737		$('body').on('evo_lightbox_trigger', function(event, data){
738			event.preventDefault();
739			//console.log( data );
740			$('body').evo_lightbox_open(data);
741		});
742
743	// Lightbox opening	
744	// @updated 4.9.11	
745		$.fn.evo_alert = function(opt){ // @since 4.9.2
746			var defz = { 
747		        'title': 'Confirmation Action',
748		        'message': '',
749		        'yes_text': 'Proceed',
750		        'no_text': 'No',
751		        'on_yes': function() {}, // Callback for Yes
752		        'on_no': function() {}   // Callback for No
753		    };	
754
755		    // Extend passed options with defaults
756		    var options = $.extend({}, defz, opt);
757
758		    // Create alert HTML content
759		    var alertHtml = '<div class="evo_alert_box">' +
760		        '<p class="evotal evopad10i">' + options.message + '</p>' +
761		        '<div class="evo_alert_buttons evotar">' +		            
762		            '<button class="evo_alert_no evoboxsn evobrn evooln evocurp evohoop7 evopad10-20 evobr20 evobgclt">
762' + options.no_text + '</button>' +
763		            '<button class="evo_alert_yes evoboxsn evobrn evooln evocurp evoHbgc1 evopad10-20 evobr20 evomarr10 evobgclp evoclw">' + options.yes_text + '</button>' +
764		        '</div></div>';
765
766		    // Define lightbox options with the alert content
767		    var lightboxOptions = {
768		        lbdata: {
769		            class: 'evo_alert_lightbox',
770		            title: options.title || 'Alert',
771		            content: alertHtml, // Set the alert HTML as the lightbox content
772		            padding: 'pad20', // Optional: Add padding class if needed
773		            size:'small',
774		        },
775		    };
776
777		    // Open the lightbox with the alert content
778		    $(this).evo_lightbox_open(lightboxOptions);
779
780		    // After the lightbox is opened, attach event handlers
781		    setTimeout(function() {
782		        var LIGHTBOX = $('.evo_lightbox.evo_alert_lightbox');
783		        
784		        LIGHTBOX.find('.evo_alert_yes').on('click', function() {
785		        	var shouldClose = options.on_yes(LIGHTBOX);// Execute Yes callback
786		        	console.log(shouldClose);
787		        	if (shouldClose !== false) {
788		        		LIGHTBOX.evo_lightbox_close(); // Close the lightbox
789		        	}
790		            removeKeyListeners(); // Remove key listeners
791		        });
792
793		        LIGHTBOX.find('.evo_alert_no').on('click', function() {
794		            options.on_no(LIGHTBOX); // Execute No callback
795		            LIGHTBOX.evo_lightbox_close(); // Close the lightbox
796		            removeKeyListeners(); // Remove key listeners
797		        });
798
799		        // Keypress handler function
800		        function handleKeyPress(event) {
801		            if (event.key === 'Escape') { // Esc key
802		                options.on_no(LIGHTBOX); // Execute No callback
803		                LIGHTBOX.remove(); // Close the lightbox
804		                removeKeyListeners(); // Remove key listeners
805		            } else if (event.key === 'Enter') { // Enter key
806		                options.on_yes(LIGHTBOX); // Execute Yes callback
807		                LIGHTBOX.remove(); // Close the lightbox
808		                removeKeyListeners(); // Remove key listeners
809		            }
810		        }
811
812		        // Add keypress listener
813		        $(document).on('keydown', handleKeyPress);
814
815		        // Function to remove key listeners
816		        function removeKeyListeners() {
817		            $(document).off('keydown', handleKeyPress);
818		        }
819
820		        // Ensure key listeners are removed when lightbox is closed manually (e.g., via close button)
821		        LIGHTBOX.find('.evolb_close_btn').on('click', function() {
822		            removeKeyListeners();
823		        });
824		    }, 350); // Delay to ensure lightbox is fully rendered
825		}
826		$.fn.evo_lightbox_open = function (opt ){
827
828			var OO = this.evo_process_ajax_params( opt );
829			
830			var _lbdata = OO.lbdata;
831			var _adata = OO.adata;
832			var _populate_id = OO._populate_id;
833
834			//console.log(opt);
835			//console.log(_lbdata);
836			
837
838			// check if required values missing for lightbox
839			if( !('class' in _lbdata) || _lbdata.class == '' ) return;
840
841
842			const fl_footer = _adata.end == 'client' ? '<div class="evolb_footer"></div>' :'';
843
844			// create lightbox HTML
845				var __lb_size = _lbdata.size === undefined ? '' : _lbdata.size;
846
847				// zindex
848				let openBoxes = 0;
849				openBoxes = $('.evo_lightbox.show, .evosp_one.show').length;
850				zIndex = 950000+ openBoxes;
851				let titleIcon = '';
852				if( _lbdata.title_icon ) titleIcon = `<i class='${_lbdata.title_icon} evomarr10'></i>`;
853				let evolb_content_id = _lbdata.lbcontentid ?? '';
854
855				var html = '<div class="evo_lightbox '+_lbdata.class+' '+_adata.end+' '+ ( _lbdata.additional_class !== undefined ? _lbdata.additional_class :'') +'" data-lbc="'+_lbdata.class+'" style="z-index:'+ zIndex + '"><div class="evolb_content_in"><div class="evolb_content_inin"><div class="evolb_box '+_lbdata.class+' '+ __lb_size +'"><div class="evolb_header"><a class="evolb_backbtn" style="display:none"><i class="fa fa-angle-left"></i></a>';
856				if( _lbdata.title !== undefined ) html += `<p class="evolb_title">${titleIcon} ${_lbdata.title}</p>`;
857				html += `<span class="evolb_close_btn evolbclose "><i class="fa fa-xmark"><i></span></div><div id="${evolb_content_id}" class="evolb_content ${_lbdata.padding}"></div><p class="message"></p>${fl_footer}</div></div></div></div>`;
858
859			$('#evo_lightboxes').append( html );	
860			const lbCount = $('#evo_lightboxes').find('.evo_lightbox').length;
861
862			var LIGHTBOX = $('.evo_lightbox.'+ _lbdata.class );		
863			if( $('.evo_sp').hasClass('show')) LIGHTBOX.addClass('aboveSP');
864
865			
866			// Open lightbox on page
867				setTimeout( function(){ 
868					$('#evo_lightboxes').show();
869					LIGHTBOX.addClass('show');	
870					$('body').addClass('evo_overflow');
871					$('html').addClass('evo_overflow');
872				},300);
873
874				// show loading animation
875				LIGHTBOX.evo_lightbox_show_open_animation(OO);
876
877
878			// Load content locally from DOM
879			    if (_lbdata.content_id != '') {
880			        var content = $('#' + _lbdata.content_id).html();
881			        LIGHTBOX.find('.evolb_content').html(content);
882			    }
883			    if (_lbdata.content != '') {
884			        LIGHTBOX.find('.evolb_content').html(_lbdata.content);
885			    }
886
887			// run ajax to load content for the lightbox inside
888				if( 'a' in _adata  && _adata.a != ''){ // @4.7.2
889					LB.evo_admin_get_ajax( OO );
890				}
891				
892			// load content from a AJAX file			
893				if( 'url' in _adata && _adata.url != '' ){
894					$.ajax({
895						beforeSend: function(){},
896						url:	OO.ajax_url,
897						success:function(data){
898							LIGHTBOX.find('.evolb_content').html( data);							
899						},complete:function(){}
900					});
901				}
902			
903			$('body').trigger('evo_lightbox_processed', [ OO, LIGHTBOX]);
904		}
905
906		// support close lightbox with click outside @since 5.0.10
907		let isMouseDownInside = false;
908		$(document).on('mousedown', '.evo_lightbox', function(e) {
909		    // Check if mousedown happened inside the actual lightbox content
910		    isMouseDownInside = $(e.target).closest('.evolb_box, .evo_lightbox_body').length > 0;
911		});
912		$(document).on('click', '.evo_lightbox', function(e) {
913
914			let close = false;
915		    if (!isMouseDownInside && 
916		        !$(e.target).closest('.evolb_box').length && 
917		        !$(e.target).closest('.evo_lightbox_body').length) {		        
918		        close = true;
919		    }
920
921		    let remove_from_dom = true;
922		    if( $(this).closest('.ajde_admin_lightboxes').length > 0 ) remove_from_dom = false;
923		    if( close )   $(this).closest('.evo_lightbox').evo_lightbox_close({ delay: 300 , remove_from_dom });
924
925		    //console.log(isMouseDownInside);
926		    isMouseDownInside = false;
927		});
928		
929		$.fn.evo_lightbox_close = function(opt) {
930		    if (!this.hasClass('show')) return;
931
932		    const defaults = { delay: 500, remove_from_dom: true };
933		    const OO = $.extend({}, defaults, opt);
934		    const hideDelay = parseInt(OO.delay);
935		    const completeClose = this.parent().find('.evo_lightbox.show').length === 1;
936
937		    // Remove 'show' class with delay if needed
938		    hideDelay > 500 ? setTimeout(() => this.removeClass('show'), hideDelay - 500) : this.removeClass('show');
939
940		    // Final cleanup after delay
941		    setTimeout(() => {
942			    completeClose && $('body, html').removeClass('evo_overflow');
943			    OO.remove_from_dom && this.remove();
944			}, hideDelay);
945		};
946
947
948		// Other LB functions
949			$.fn.evo_lightbox_populate_content = function(opt){
950				LB = this;
951				var defaults = { 
952					'content':'',
953				}; var OO = $.extend({}, defaults, opt);
954
955				LB.find('.evolb_content').html( OO.content );
956			}
957			
958			$.fn.evo_lightbox_show_msg = function(opt){
959				LB = this;
960				var defaults = { 
961					'type':'good',
962					'message':'',
963					'hide_message': false,// hide message after some time pass time or false
964					'hide_lightbox': false, // hide lightbox after some time of false
965				}; var OO = $.extend({}, defaults, opt);
966				LB.find('.message').removeClass('bad good').addClass( OO.type ).html( OO.message ).fadeIn();
967				//console.log('showing LB msg');
968
969				if( OO.hide_message ) setTimeout(function(){  LB.evo_lightbox_hide_msg() }, OO.hide_message );
970
971				if( OO.hide_lightbox ) LB.evo_lightbox_close({ delay: OO.hide_lightbox });
972			}
973			$.fn.evo_lightbox_hide_msg = function(opt){
974				LB = this;
975				LB.find('p.message').hide();
976			}
977
978
979			// add preload animations to lightbox u4.6
980			$.fn.evo_lightbox_show_open_animation = function(opt){
981				LB = this;
982				var defaults = { 
983					'animation_type':'initial', // animation type initial or saving
984					'preload_temp_key': 'init', // 4.6 passed on preload template key
985					'end':'admin',
986				};
987				var OO = $.extend({}, defaults, opt);
988
989				if( OO.animation_type == 'initial'){
990
991					passed_data = (  typeof evo_admin_ajax_handle !== 'undefined') ? evo_admin_ajax_handle: evo_general_params;
992
993					//console.log( passed_data);
994
995					html = passed_data.html.preload_general;
996					if( OO.preload_temp_key != 'init') html = passed_data.html[ OO.preload_temp_key ];
997					LB.find('.evolb_content').html( html );
998				}
999
1000				if( OO.animation_type == 'saving')
1001					LB.find('.evolb_content').addClass('evoloading');
1002			}
1003
1004		// eventcard Lightbox function v4.6
1005			$.fn.evo_cal_lightbox_trigger = function( SC_data , obj, CAL , LB = null){
1006				
1007				const event = obj.closest('.eventon_list_event');
1008			    const classes = ['cancel_event', SC_data.additional_class, SC_data.calendar_type]
1009			        .filter(cls => cls && (cls !== 'cancel_event' || obj.hasClass('cancel_event')))
1010			        .join(' ');
1011
1012			    //console.log( SC_data);
1013
1014				const other_data = {
1015			        extra_classes: `evo_lightbox_body eventon_list_event evo_pop_body evcal_eventcard event_${SC_data.event_id}_${SC_data.repeat_interval} ${classes}`,
1016			        CAL,
1017			        obj,
1018			        et_data: obj.find('.evoet_data').data(),
1019			        SC: SC_data
1020			    };
1021				
1022				const randomId = `evo_eventcard_${Math.floor(Math.random() * 90) + 10}`;
1023				const lbac = { 'sc1': 'within', 'sc2': 'within ecSCR' }[evo_general_params.cal.lbs] || '';
1024
1025				const openLightbox = (content,  ajaxData = null) => {
1026			        const config = {
1027			            //uid: ajaxData?.uid || 'evo_open_eventcard_lightbox',
1028			            uid: 'evo_open_eventcard_lightbox',
1029			            lbc: randomId,
1030			            lbc: LB ? LB.data('lbc') || randomId : randomId,
1031			            lbac,
1032			            end: 'client',
1033			            content,
1034			            other_data
1035			        };
1036			        if (ajaxData) {
1037			            Object.assign(config, {
1038			                ajax: 'yes',
1039			                ajax_type: 'endpoint',
1040			                ajax_action: 'eventon_load_single_eventcard_content',
1041			                d: ajaxData
1042			            });
1043			        }
1044
1045			        console.log(config);
1046
1047			        // if LB is passed populate that LB @4.9
1048			        if( LB  ){
1049			        	if( ajaxData){			        		
1050
1051			        		var OO = this.evo_process_ajax_params( config );
1052			        		LB.evo_admin_get_ajax( OO );
1053			        		$('body').trigger('evo_lightbox_processed', [ config, LB]);
1054			        		return;
1055			        	}
1056			        	LB.evo_lightbox_populate_content({content: content}); 
1057			        	$('body').trigger('evo_lightbox_processed', [ config, LB]);
1058			        	return;
1059			        }
1060
1061			        $('body').evo_lightbox_open(config);
1062			    };
1063
1064				if (SC_data.ux_val === '3a') {
1065			        const placeholder = `
1066			            <div class="evo_cardlb" style="padding:10px 10px 0 10px">
1067			                <div style="margin-bottom:20px; width:100%; height:200px" class="evo_preloading"></div>
1068			                ${Array(3).fill('<div style="display:flex;justify-content:space-between;margin-bottom:10px"><div style="width:40px;height:40px;margin-right:20px" class="evo_preloading"></div><div style="flex:1 0 auto"><div class="evo_preloading" style="width:70%;height:20px;margin-bottom:10px"></div><div class="evo_preloading" style="width:100%;height:80px;margin-bottom:10px"></div></div></div>').join('')}
1069			            </div>
1070			        `;
1071
1072			        
1073			        const ajaxData = {
1074			            event_id: SC_data.event_id,
1075			            ri: SC_data.repeat_interval,
1076			            SC: { ...SC_data, tile_style: '0', tile_bg: '0', tiles: 'no', eventtop_style: SC_data.tile_style == '2' ? '0' : SC_data.eventtop_style },
1077			            load_lbcontent: true,
1078			            action: 'eventon_load_single_eventcard_content',
1079			            uid: 'load_single_eventcard_content_3a',
1080			            calid: ( CAL ? CAL.attr('id') : '' ), 
1081			        };
1082
1083			        openLightbox(placeholder, ajaxData);
1084			    } else {
1085			        const content = event.find('.event_description').html();
1086			        const clrW = event.hasClass('clrW') ? 'clrW' : 'clrD';
1087			        openLightbox(`<div class="evopop_top ${clrW}">${obj.html()}</div><div class="evopop_body">${content}</div>`);
1088			    }
1089			}
1090
1091			// listerners for lightbox on eventcard
1092			$.fn.evo_cal_lb_listeners = function(){
1093				// Listerners
1094				// process various lightbox types
1095				$('body')
1096				.on('evo_lightbox_processed', function(event, OO, LIGHTBOX){
1097					if( OO.uid != 'evo_open_eventcard_lightbox') return false;
1098
1099					var CAL = OO.other_data.CAL;
1100
1101					LIGHTBOX.addClass('eventcard eventon_events_list');
1102					LIGHTBOX_content = LIGHTBOX.find('.evolb_content');
1103					LIGHTBOX_content.attr('class', 'evolb_content '+ OO.other_data.extra_classes );
1104					
1105					var SC = OO.other_data.SC;
1106					var obj = OO.other_data.obj;
1107
1108					//console.log(SC);
1109
1110					// update border color and eventtop color
1111						const evoet_data = OO.other_data.et_data;
1112						
1113						bgcolor = bggrad ='';
1114						if( evoet_data ){
1115							bgcolor = evoet_data.bgc;
1116							bggrad = evoet_data.bggrad;
1117						}
1118						
1119
1120						// if tiles and eventtop style set to clean
1121						var show_lightbox_color = ( SC.eventtop_style == '0' || SC.eventtop_style == '4') ? false: true;
1122						
1123						if( (CAL && CAL.hasClass('color') && show_lightbox_color) ||
1124							(!CAL && show_lightbox_color)
1125
1126						){
1127							LIGHTBOX_content.addClass('color');
1128							LIGHTBOX_content.find('.evopop_top').css({
1129								'background-color':bgcolor,
1130								'background-image': bggrad,
1131							});
1132						}else{
1133							LIGHTBOX_content.addClass('clean');
1134							LIGHTBOX_content.find('.evopop_top').css({'border-left':'3px solid '+bgcolor});
1135						}
1136
1137					// trigger 
1138					if( obj.data('runjs')){
1139						$('body').trigger('evo_load_single_event_content',[ SC.event_id, OO.other_data.obj]);
1140					}
1141									
1142					
1143					// RTL
1144					if( SC.evortl =='yes')	LIGHTBOX.addClass('evortl');
1145
1146					$('body').trigger('evolightbox_end', [ LIGHTBOX , CAL, OO]);	// @s4.6
1147
1148				})
1149
1150				// after eventcard content is loaded to lightbox via 3a - @since 4.2.3
1151					.on('evo_ajax_success_evo_open_eventcard_lightbox', function (event, OO, data){
1152						
1153						if( OO.ajaxdata.uid != "load_single_eventcard_content_3a") return false;
1154						
1155						LIGHTBOX = $('.evo_lightbox.'+ OO.lightbox_key);
1156
1157						CAL = $('body').find('#'+ OO.ajaxdata.calid);
1158						
1159						$('body').trigger('evolightbox_end', [ LIGHTBOX , CAL, OO]);	// @s4.6	
1160					})
1161				;			
1162			}
1163
1164	// Side Panel for admin
1165	// @since 4.5.2 @updated 5.0
1166		BB
1167		.on('click', '.evosp_trigger', function(e){ 
1168			e.preventDefault(); e.stopPropagation();
1169			const $el = $(this);
1170			$el.addClass('evo_sp_trig_on');
1171			$el.evo_open_sidepanel($el.data('d'), $el.data('spv'));
1172		 })
1173		.on('click', '.evosp_close', function(e){ e.preventDefault(); e.stopPropagation(); $(this).evo_close_sidepanel() })
1174		.on('click', '.evosp_trigger_save', function(e){ e.preventDefault(); e.stopPropagation(); $(this).evo_ajax_form_submit( $(this).data('d'), 'sp');  })
1175		.on('evosp_trig_close', function(e, opt){ 
1176			$(this).evo_close_sidepanel( opt ); 
1177		});
1178		
1179
1180		/**
1181		 * Side panel for eventON 
1182		 * @version 4.9
1183		 */ 		
1184		$.fn.evo_open_sidepanel = function(opt, spv){
1185			var defs = {
1186				'uid':'',
1187				'end':'admin', // admin or client
1188				'hide_sp':false,
1189				'hide_message':false,
1190				'title':'',
1191				'sp_title':'',
1192				'sp_class':'',
1193				'sp_body_class': '', // @5.1
1194				'sp_id':'',// identifier for side panel @5.0.3
1195				'content_id':'',  // only to load dynamic content
1196				'content':'',// @5.0.3 populate passed on content with delay
1197				'content_footer':'',// @5.0.9 footer content
1198				'content_load_delay':0,// 1000
1199				'ajax':'no',
1200				'ajax_data':'',		
1201				'adata':{},
1202				'other_data':{},	
1203				'spdata':{}, // in progress pass all sidepanel data in one			
1204				'size': 'sm', // sm | med | lar
1205				'movepage': false,// in complete -- idea to move the entire page
1206				'fresh_content': false, // if fresh content stream is loading
1207				end:'admin'
1208			}
1209			var OO = $.extend({}, defs, opt);
1210			//console.log(OO);
1211
1212			const SP = $('body').find('.evo_sp');
1213			let sp_has_content = SP.length > 0 && SP.html()?.trim() !== '';
1214			
1215			let SP_uid = OO.sp_id || 'evosp_' + Math.random().toString(36).substr(2, 9);
1216			if( $('#'+ SP_uid).length > 0 ) SP_uid = SP_uid + '_' + ($('#'+ SP_uid).length); 
1217
1218			// get zindex value
1219			let openBoxes = 0;
1220			openBoxes = $('.evo_lightbox.show, .evosp_one.show').length;
1221			zIndex = 950000+ openBoxes;
1222
1223			//console.log(OO);
1224
1225			// structure
1226				const load_html = "<div class='evo_loading_bar_holder h100'><div class='evo_loading_bar wid_50 hi_50'></div><div class='evo_loading_bar hi_100'></div><div class='evo_loading_bar'></div><div class='evo_loading_bar'></div><div class='evo_loading_bar hi_50'></div></div>";
1227
1228				const footer_html = `<div class='evosp_foot evo_bordert evodfx evofxdrr evofxaic evofxww evogap10'><div class='evosp_foot_in evofx_1 evogap10'>
1229				<div class='evo_loading_bar_holder h100 evopad0i'><div class='evo_loading_bar wid_50 hi_50'></div></div>
1230				</div><p class='evosp_message message evomar0i'></p></div>`;
1231
1232				SP_back_btn = ( sp_has_content && !OO.fresh_content) ? `<button class='evonobtn evosp_back_trig'><i class='fa fa-chevron-left'></i></button>`: '';
1233
1234				let sp_header = OO.sp_title !== '' ? `<div class='evosp_head evoff_1'>${OO.sp_title}</div>` : '';
1235
1236				SP_HTML = `<div id='${SP_uid}' class='evosp_one ${OO.sp_class} ${OO.size}' style='z-index:${zIndex}'><div class='evosp_in'>${SP_back_btn}<span class='evosp_close'><i class='fa fa-multiply'></i></span>${sp_header}<div id='evops_content_${SP_uid}' class='evosp_body evops_content ${OO.sp_body_class}'>${load_html}</div>${footer_html}</div></div>`;
1237
1238				
1239				SP.append( SP_HTML );
1240
1241				SP_one = SP.find('#'+ SP_uid);
1242				setTimeout(() => { 
1243				  SP_one.addClass('show'); 
1244				}, 300);
1245				//SP.removeClass('med lar sm').addClass( OO.size );
1246
1247				// if move page as well
1248				//if( OO.movepage ) $('body').find('.editor-editor-interface').addClass('evotrans pagemoved').css('right', '400px');
1249
1250				const SP_body = SP.find('.evosp_body');
1251				const SP_head = SP.find('.evosp_head');
1252				const SP_foot = SP.find('.evosp_foot');		
1253
1254			// load using content
1255				if( OO.content_id != ''){
1256					if( OO.content_load_delay > 0){
1257						setTimeout(function(){
1258							SP.evo_populate_sidepanel( BB.find('#'+ OO.content_id ).html() );
1259						}, OO.content_load_delay );
1260					}else{
1261						SP.evo_populate_sidepanel( BB.find('#'+ OO.content_id ).html() );
1262					}				
1263				}
1264
1265			// run ajax to load content for the lightbox inside
1266				if( ( OO.ajax == 'yes' && OO.ajax_data != '') || ( OO.adata != '' && 'a' in OO.adata) ){
1267					var passing_data = {
1268						adata: OO.adata,
1269						ajaxdata: OO.ajax_data, 
1270						uid: OO.uid ,
1271						end: OO.end,
1272						load_new_content: true,
1273						load_new_content_id: 'evops_content_'+ SP_uid,
1274						lightbox_loader:false,
1275						end: OO.end,
1276						spdata:{
1277							spid: SP_uid,
1278						}
1279					};
1280
1281					SP.evo_admin_get_ajax( passing_data );
1282				}else{
1283					setTimeout(()=> BB.trigger('evo_sp_stop_loading'),OO.content_load_delay);
1284				}
1285
1286			// populate with passed on content with delay @5.0.3
1287				if( OO.content != ''){
1288					setTimeout(()=> SP.evo_populate_sidepanel( OO.content ),OO.content_load_delay);
1289					if( OO.content_footer ) setTimeout(()=> SP.evo_populate_sidepanel_footer( OO.content_footer ), (OO.content_load_delay + 500) );
1290				}
1291			// populate new content with spv values
1292				if( spv != ''){
1293					BB.on('evo_ajax_success_'+ OO.uid , function(){
1294						$('#evops_content').find('input, select').each(function(){
1295							var fel = $(this);
1296							$.each(spv,function(index, val){
1297								if( fel.attr('name') == index){
1298
1299									if( val == 'no' || val == 'yes') fel.evo_elm_change_yn_btn( val );
1300									fel.val( val );
1301								}
1302							});					
1303						});
1304					});
1305				}
1306	  		
1307	  		BB.trigger('evo_sp_opened_'+OO.uid, OO);
1308	  		BB.trigger('evo_sp_opened', OO);
1309	  		
1310	  	}
1311	  	// back from side panel
1312	  	BB.on('click','.evosp_back_trig',function(){
1313	  		const $el = $(this);
1314	  		const thisSPone = $el.closest('.evosp_one');
1315	  		let prevSPone = thisSPone.prev();
1316	  		thisSPone.remove();
1317	  		//prevSPone.removeClass('sp_hide');
1318	  	});
1319	  	BB.on('evo_sp_stop_loading',function(){
1320	  		$('body').find('.evo_sp').find('.evo_loading_bar_holder').remove();
1321	  	});
1322	  	$.fn.evo_savevals_sidepanel = function(spv){
1323	  		const el = BB.find('.evo_sp_trig_on');
1324
1325	  		el.data('spv', spv);
1326	  		el.removeClass('evo_sp_trig_on');
1327	  	}
1328
1329	  	$.fn.evo_populate_sidepanel = function(content){
1330	  		const SP = $('body').find('.evo_sp');
1331	  		SP.find('.evosp_body').html( content );
1332	  	}
1333
1334	  	// populate sidepanel footer @5.0.3
1335	  	$.fn.evo_populate_sidepanel_footer = function(content ){
1336	  		const SP = $('body').find('.evo_sp');
1337	  		SP.find('.evosp_foot_in').html( content );
1338	  	}
1339	  	// CLOSE sidepanel
1340	  	$.fn.evo_close_sidepanel = function(opt){
1341	  		$el = $(this);
1342	  		SP = BB.find('.evo_sp');
1343
1344	  		var defaults = { 
1345	  			'sp_id':'',
1346	  			'delay':200
1347	  		};
1348	  		var OO = $.extend({}, defaults, opt);
1349
1350	  		let SPone = OO.sp_id ? SP.find('#' + OO.sp_id) : SP.find('.evosp_one').last();
1351			if( !(SPone.hasClass('show')) ) return;
1352			
1353						
1354	  		setTimeout(function(){	
1355	  			BB.trigger('evo_sp_closed',[ SP, SPone ]);
1356	  			SPone.removeClass('show');
1357	  			//$('body').find('.editor-editor-interface.pagemoved').removeClass('pagemoved').css('right', 'auto');
1358	  			BB.find('.evo_sp_trig_on').removeClass('evo_sp_trig_on');
1359	  		}, OO.delay );
1360	  		setTimeout(function(){
1361	  			SPone.remove();	
1362	  			if( SP.find('.evosp_one').length < 0 ) SP.html('');	
1363	  		}, ( OO.delay + 100 ) );
1364	  	}
1365
1366	  	$.fn.evo_showmsg_sidepanel = function(opt, spdata){
1367	  		var defaults = { 
1368	  			'sp_id':'',
1369				'type':'good',
1370				'message':'',
1371				'hide_message': false,// hide message after some time pass time or false
1372				'hide_sp': false, // hide lightbox after some time of false
1373			}; var OO = $.extend({}, defaults, opt);
1374
1375			//console.log('showing sp msg');
1376			const SP = BB.find('#evo_sp');
1377
1378			// SP ID
1379			if( spdata && 'sp_id' in spdata ) OO.sp_id = spdata.sp_id;
1380			let SPone = OO.sp_id ? SP.find('#' + OO.sp_id) : SP.find('.evosp_one').last();
1381
1382			SPone.find('.evosp_message').removeClass('bad good').addClass( OO.type ).html( OO.message ).fadeIn();
1383			if( OO.hide_message ) setTimeout(function(){  SPone.evo_hidemsg_sidepanel() }, OO.hide_message );
1384			if( OO.hide_sp ) SPone.evo_close_sidepanel({ delay: OO.hide_sp });
1385	  	}
1386	  	$.fn.evo_hidemsg_sidepanel = function(opt){
1387			SP = this;
1388			SP.find('p.evosp_message').hide();
1389		}
1390
1391
1392
1393	// Get Ajax url @since 4.4 @u 4.5.5
1394		$.fn.evo_get_ajax_url = function(opt){
1395			var defaults = { 
1396				a:'', // action key
1397				e:'client', // end
1398				type: 'ajax'};
1399			var OO = $.extend({}, defaults, opt);
1400
1401			
1402
1403			// end point url
1404			if( OO.type == 'endpoint'){
1405				var evo_ajax_url = ( OO.e == 'client' || typeof evo_general_params !== 'undefined' )? 
1406					evo_general_params.evo_ajax_url : evo_admin_ajax_handle.evo_ajax_url;
1407				return  evo_ajax_url.toString().replace( '%%endpoint%%', OO.a );
1408			// rest api url
1409			}else if( OO.type == 'rest' ){
1410				var evo_ajax_url = ( OO.e == 'client' || typeof evo_general_params !== 'undefined')? 
1411					evo_general_params.rest_url : evo_admin_ajax_handle.rest_url;
1412					//console.log(evo_ajax_url);
1413					//console.log(OO);
1414				return  evo_ajax_url.toString().replace( '%%endpoint%%', OO.a );
1415			}else{
1416				action_add = OO.a != '' ? '?action='+ OO.a: '';
1417				return ( OO.e == 'client' || typeof evo_general_params !== 'undefined') ? 
1418					evo_general_params.ajaxurl + action_add : evo_admin_ajax_handle.ajaxurl + action_add;
1419			}	
1420		}
1421
1422	// loading animations @4.7.2
1423		$.fn.evo_start_loading = function( opt ){
1424			var defaults = { type:'1'};
1425			var OPT = $.extend({}, defaults, opt);
1426			var el = this;
1427
1428			if( OPT.type == '1') el.addClass('evoloading loading');
1429			if( OPT.type == '2') el.addClass('evoloading_2');
1430		}
1431		$.fn.evo_stop_loading = function( opt ){
1432			var el = this;
1433			var defaults = { type:'1'};
1434			var OPT = $.extend({}, defaults, opt);
1435
1436			if( OPT.type == '1') el.removeClass('evoloading loading');
1437			if( OPT.type == '2') el.removeClass('evoloading_2');
1438		}
1439		$.fn.evo_lightbox_start_inloading = function(opt){
1440			LB = this;
1441			LB.find('.evolb_content').addClass('loading evoloading');
1442		}
1443		$.fn.evo_lightbox_stop_inloading = function(opt){
1444			LB = this;
1445			LB.find('.evolb_content').removeClass('loading evoloading');
1446		}
1447	
1448	// Count down	// @+ 4.5
1449		$.fn.evo_countdown_get = function(opt){
1450			var defaults = { gap:'', endutc: ''};
1451			var OPT = $.extend({}, defaults, opt);
1452			var gap = OPT.gap;
1453
1454			// if gap not provided use endutc
1455			if( gap == '' ){				
1456				var Mnow = moment().utc();
1457				var M = moment();
1458				M.set('millisecond', OPT.endutc );
1459
1460				gap = OPT.endutc - Mnow.unix();
1461			}
1462			
1463			// if negative gap
1464			if( gap < 0){
1465				return {
1466					'd': 0,
1467					'h':0,
1468					'm':0,
1469					's':0
1470				}; 
1471			}
1472		
1473			distance = ( gap * 1000);
1474
1475			var days = Math.floor(distance / (1000 * 60 * 60 * 24));
1476			var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
1477			var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
1478			var seconds = Math.floor((distance % (1000 * 60)) / 1000);
1479
1480			minutes = minutes<10? '0'+minutes : minutes;
1481			seconds = seconds<10? '0'+seconds : seconds;
1482
1483			return {
1484				'd': days,
1485				'h':hours,
1486				'm':minutes,
1487				's':seconds
1488			}; 
1489		};
1490		// @u 4.5.2
1491		$.fn.evo_countdown = function(opt){
1492			var defaults = { S1:''};
1493			var OPT = $.extend({}, defaults, opt);
1494			var el = $(this);
1495
1496			const day_text = ( el.data('d') !== undefined && el.data('d') != '' )? el.data('d'):'Day';
1497			const days_text = ( el.data('ds') !== undefined && el.data('ds') != '' )? el.data('ds'):'Days';
1498
1499			// intial run
1500			//var gap = parseInt(el.data('gap'));
1501			var duration = el.data('dur');
1502			var endutc = parseInt(el.data('endutc'));
1503			var text = el.data('t');
1504			
1505			if(text === undefined) text = '';
1506
1507			if( el.hasClass('evo_cd_on')) return;
1508
1509			// get gap using end time utc
1510				var Mnow = moment().utc();
1511				var M = moment();
1512				M.set('millisecond', OPT.endutc );
1513
1514				//console.log(Mnow.unix());
1515				//console.log(endutc);
1516
1517				gap = endutc - Mnow.unix();
1518
1519
1520			// on initial run - event hasnt happened yet
1521			if( gap > 0 ){
1522
1523				// initial
1524				dd = el.evo_countdown_get({ 'gap': gap });
1525				
1526				el.html( ( dd.d>0 ? dd.d + ' ' + ( dd.d >1 ? days_text: day_text ) + " "  :'') + dd.h + ":" + dd.m +':'+ dd.s +'  '+text );
1527				
1528				el.data('gap', ( gap - 1)  );	// save new gap value
1529				el.addClass('evo_cd_on');
1530
1531				//return;
1532				
1533				// set intervals
1534				var CD = setInterval(function(){
1535					
1536					gap = el.data('gap'); // get gap for this cycle
1537					duration = el.data('dur');	
1538
1539					const bar_elm = el.closest('.evo_event_progress').find('.evo_ep_bar');	
1540
1541					// when timer is ticking
1542					if( gap > 0 ){
1543
1544						// increase bar width if exists
1545						if( duration !== undefined && bar_elm.length){
1546							perc = ( (duration - gap)/ duration ) * 100;
1547							bar_elm.find('b').css('width',perc+'%');							
1548						}
1549						
1550						dd = el.evo_countdown_get({ 'gap': gap });	
1551
1552						el.html( ( dd.d>0 ? dd.d + ' '  + ( dd.d >1 ? days_text: day_text ) + " ":'') + dd.h + ":" + dd.m +':'+ dd.s +' '+text );
1553						el.data('gap', ( gap - 1)  );
1554
1555					// when timer expired
1556					}else{
1557
1558						const expire_timer_action = el.data('exp_act');
1559
1560						// perform ajax task after expiration
1561						if(expire_timer_action !== undefined){
1562							$('body').trigger('runajax_refresh_now_cal',[ 
1563								el , 
1564								el.data('n'),
1565							]);
1566						}
1567
1568						const _complete_text = el.evo_get_txt({V:'event_completed'});
1569
1570						// live now text
1571						if(bar_elm.length){
1572							bar_elm.addClass('evo_completed');
1573							//el.siblings('.evo_ep_pre').html( _complete_text );
1574						}
1575
1576
1577						// event tag & live elements
1578						if( el.closest('.evcal_desc').length){
1579							el.closest('.evcal_desc').find('.eventover').html( _complete_text);
1580							el.closest('.evcal_desc').find('.evo_live_now').remove();
1581						}
1582
1583						// event card
1584						if( el.closest('.eventon_list_event').length){
1585							el.closest('.eventon_list_event').find('span.evo_live_now').hide();
1586						}
1587
1588						el.html('');
1589						clearInterval(CD);
1590					}
1591
1592				},1000);
1593			// event has already passed
1594			}else{
1595				// if gap is less
1596				el.closest('.evo_event_progress').find('.evo_ep_bar').hide();
1597				clearInterval(CD);
1598			}
1599		};	
1600
1601	// Handlebar process template data into html
1602		$.fn.evo_HB_process_template = function(opt){
1603			var defaults = { TD:'', part:''}
1604			var OPT = $.extend({}, defaults, opt);
1605
1606			BUS = $('#evo_global_data').data('d');
1607						
1608			template = Handlebars.compile( BUS.temp[ OPT.part ] );
1609			return template( OPT.TD );
1610		}
1611
1612	// Date range and events @4.6.7
1613		// Date range and events - from webpage
1614		$.fn.evo_cal_events_in_range = function(opt){
1615			var defaults = { S:'', E:'', 
1616				hide: true, 
1617				closeEC:true,
1618				showEV: false, // show events
1619				showEVL: false, // show events list
1620				showAllEvs: false // show all events regardless of the range
1621			};
1622			var OPT = $.extend({}, defaults, opt);
1623			var CAL = $(this);
1624
1625			var eJSON = CAL.find('.evo_cal_events').data('events');
1626			var SC = CAL.evo_shortcode_data();
1627
1628			R = {};
1629			html = '';
1630			json = {};
1631
1632			show = 0;
1633
1634			// using events JSON data
1635			if( eJSON && eJSON.length > 0){
1636				$.each(eJSON, function(ind, ED){
1637					eO = CAL.find('#event_'+ ED._ID);
1638					if(eO === undefined || eO.length==0) return;
1639
1640					if(OPT.hide)	eO.hide(); // pre hide
1641					this_show = false;
1642
1643					// month long or year long events
1644					if( ED.month_long || ED.year_long ){
1645						this_show = true;
1646
1647					}else{
1648						if(CAL.evo_is_in_range({
1649							'S': OPT.S,	'E': OPT.E,	'start': ED.unix_start ,	'end':ED.unix_end 
1650						})){						
1651							this_show = true;
1652						} 
1653					}
1654
1655					if( OPT.showAllEvs) this_show = true;
1656					
1657					if( this_show){	
1658						// show event
1659						if( OPT.showEV) eO.show();
1660
1661						// close open event cards
1662						if(OPT.closeEC && SC.evc_open == 'no') eO.find('.event_description').hide().removeClass('open');
1663
1664						html += eO[0].outerHTML;
1665						json[ ED._ID] = ED;
1666						show++;	
1667					} 
1668				});
1669			}else{	
1670				// get all the events in the events list
1671				var cal_events = CAL.find('.eventon_list_event');
1672
1673				cal_events.each(function(index, elm){
1674					var ED = $(elm).evo_cal_get_basic_eventdata();
1675					if( !ED) return;
1676
1677					if(OPT.hide)	$(elm).hide(); // pre hide
1678					this_show = false;
1679
1680					// month long or year long events
1681					if( $(elm).hasClass('month_long') || $(elm).hasClass('year_long') ){
1682						this_show = true;
1683
1684					}else{
1685						if(CAL.evo_is_in_range({
1686							'S': OPT.S,	'E': OPT.E,	'start': ED.unix_start ,	'end':ED.unix_end 
1687						})){						
1688							this_show = true;
1689						} 
1690					}
1691
1692					if( OPT.showAllEvs) this_show = true;
1693					
1694					if( this_show){	
1695						// show event
1696						if( OPT.showEV) $(elm).show();
1697
1698						// close open event cards
1699						if(OPT.closeEC && SC.evc_open == 'no') 
1700							$(elm).find('.event_description').hide().removeClass('open');
1701
1702						html += $(elm)[0].outerHTML;
1703						json[ ED.uID ] = ED;
1704						show++;	
1705					} 
1706				});
1707			}
1708
1709
1710			// No events
1711			if( OPT.showEV){
1712
1713				no_event_content = CAL.evo_get_global({S1: 'html', S2:'no_events'});
1714
1715				tx_noevents = CAL.evo_get_txt({V:'no_events'});
1716				EL = CAL.find('.eventon_events_list');
1717				EL.find('.eventon_list_event.no_events').remove();
1718				if( show == 0 )
1719					EL.append('<div class="eventon_list_event no_events">'+ no_event_content +'</div>');
1720			}
1721
1722			// if show events list
1723			if( OPT.showEVL){
1724				CAL.find('.eventon_events_list').show().removeClass('evo_hide');
1725			}
1726
1727			R['count'] = show;
1728			R['html'] = html;
1729			R['json'] = json;
1730
1731			return R;
1732		}
1733
1734		// check if an event is in the given date range
1735			$.fn.evo_is_in_range = function(opt){
1736				var defaults = { S:'', E:'', start:'',end:''}
1737				var OPT = $.extend({}, defaults, opt);
1738
1739				S = parseInt(OPT.S);
1740				E = parseInt(OPT.E);
1741				start = parseInt(OPT.start);
1742				end = parseInt(OPT.end);
1743
1744				return (
1745					( start <= S && end >= E ) ||
1746					( start <= S && end >= S && end <= E) ||
1747					( start <= E && end >= E ) ||
1748					( start >= S && end <= E )
1749				) ? true: false;
1750			}
1751			$.fn.evo_cal_hide_events = function(){
1752				CAL = $(this);
1753				CAL.find('.eventon_list_event').hide();
1754			}
1755
1756	// get event data basics from html event on page 
1757	// ~@version 4.0.3 @updated 4.9.8
1758		$.fn.evo_cal_get_basic_eventdata = function(){
1759			var ELM = $(this);
1760
1761			var _time = ELM.data('time');
1762			if( _time === undefined ) return false;
1763
1764			const time = _time.split('-');
1765			const ri = ELM.data('ri').replace('r','');
1766			const eID = ELM.data('event_id');
1767
1768			var _event_title = ELM.find('.evcal_event_title').text();
1769			_event_title = _event_title.replace(/'/g, '&apos;');
1770
1771			// extract text time
1772			let timeRange = '';
1773			const timeElement = ELM.find('.evo_tz_time');
1774			if( timeElement.length > 0){
1775				const timeClone = timeElement.clone();
1776		        // Remove the span.evo_tz and its contents
1777		        timeClone.find('.evo_tz').remove();
1778		        // Get the text, trim it, and remove any remaining icon-related characters
1779		        let timeText = timeClone.text().trim();
1780		        // Remove any lingering non-time characters (e.g., leftover from <i> tags)
1781		        timeText = timeText.replace(/[^\d:\s-]/g, '');
1782		        // Trim again to remove any extra spaces
1783		        timeRange = timeText.trim() || 'N/A';
1784			}
1785			
1786			var RR = {
1787				'uID': eID + '_' + ri,
1788				'ID': eID ,
1789				'event_id': eID ,
1790				'ri': ri,
1791				'event_start_unix': parseInt(time[0]),
1792				'event_end_unix': parseInt(time[1]),
1793				'time_text': timeRange, // @since 4.9.8
1794				'ux_val': ELM.find('.evcal_list_a').data('ux_val'),
1795				'event_title': _event_title,
1796				'hex_color': ELM.data('colr'),
1797				'hide_et': ELM.hasClass('no_et') ? 'y':'n', // hide endtime
1798				'evcal_event_color': ELM.data('colr'),
1799				'unix_start': parseInt(time[0]),// @4.5.7
1800				'unix_end': parseInt(time[1]),// @4.5.7
1801			};
1802
1803			// event type
1804			RR['ett1'] = {};
1805			ELM.find('.evoet_eventtypes.ett1 .evoetet_val').each(function(){
1806				RR['ett1'][ $(this).data('id')] = $(this).data('v');
1807			});
1808
1809			// since 4.3.5
1810			const eventtop_data = ELM.find('.evoet_data').data('d');
1811
1812			// location
1813			if(eventtop_data && 'loc.n' in eventtop_data && eventtop_data['loc.n'] != ''){
1814				RR['location'] = eventtop_data['loc.n'];
1815			}
1816
1817			// organizer
1818			if(eventtop_data && 'orgs' in eventtop_data && eventtop_data.orgs !== undefined ){
1819				var org_names = '';
1820				$.each(eventtop_data.orgs, function(index, value){
1821					org_names += value +' ';
1822				});
1823				RR['organizer'] = org_names;
1824			}
1825
1826			// event image
1827			if( ELM.find('.evo_event_schema').length > 0){
1828				imgObj = ELM.find('.evo_event_schema').find('meta[itemprop=image]').attr('content');
1829				RR['image_url'] = imgObj;
1830			}
1831
1832			// event tags @s 4.5.2
1833			if( eventtop_data && 'tags' in eventtop_data && eventtop_data.tags !== undefined ){
1834				//console.log(eventtop_data.tags);
1835				RR['event_tags'] = eventtop_data.tags;
1836			}
1837
1838
1839			return RR;
1840
1841		}
1842
1843
1844	// Calendar Helper functions @+2.8 @updated 4.9	
1845		$.fn.evo_cal_oneevent_onload = function(type){// @since 4.9
1846			if( type != 'complete') return;
1847
1848			const bodyClasses = $('body').attr('class') || '';
1849			const match = bodyClasses.match(/one_event_\d+_\d+/);
1850			if (match) {
1851        		const className = match[0];
1852        		const [, x, y] = className.match(/one_event_(\d+)_(\d+)/);
1853
1854				const event_obj = $('body').find('#event_'+ x +'_'+ y);
1855				const $cal = event_obj.closest('.ajde_evcal_calendar');
1856				const SC = $cal.evo_shortcode_data();
1857
1858
1859				if( event_obj.length > 1 ) return;
1860
1861				const new_SC_data = {
1862		            ...SC,
1863		            repeat_interval: y,
1864		            event_id: x,
1865		            ux_val: '3a',
1866		            evortl: event_obj.find('.eventon_events_list').hasClass('evortl') ? 'yes' : 'no',			            
1867		            ajax_eventtop_show_content: true,
1868		            additional_class: CAL.attr('class').match(/etttc_\w+/)?.[0] || '',
1869		        };
1870
1871		        console.log( new_SC_data);
1872		        $cal.evo_cal_lightbox_trigger(new_SC_data, event_obj, $cal);
1873				
1874			}
1875		}
1876		$.fn.evo_cal_event_get_uxval = function(SC, obj){
1877			const CAL = this;
1878			var ux_val = obj.data('ux_val');
1879
1880			if(SC && 'ux_val' in SC && SC.ux_val!='' && SC.ux_val!== undefined && SC.ux_val!='0'){
1881				ux_val = SC.ux_val;
1882			}
1883
1884			// special mobile only user interaction 
1885			if( SC && SC.ux_val_mob !== undefined && SC.ux_val_mob != '' && 
1886				SC.ux_val_mob != '-' && SC.ux_val_mob != ux_val){
1887				if( CAL.evo_is_mobile() ) ux_val = SC.ux_val_mob;
1888			}
1889			return ux_val;
1890		}
1891
1892		// to run before cal ajax is performed @4.6
1893		$.fn.evo_pre_cal = function(options){
1894			var el = this;
1895			var cal = {};
1896			var OO = $.extend({}, options);
1897
1898			var run = function(){
1899				cal_width_assoc();
1900				cal_load_nav_html();
1901			}
1902			var cal_width_assoc = function(){
1903				cal_w = el.width();
1904				if( cal_w <300) el.addClass('szS');
1905				if( cal_w >300 && cal_w <600) el.addClass('szM');
1906				if( cal_w >600 && cal_w <900) el.addClass('szL');
1907				if( cal_w >900) el.addClass('szX');
1908			}
1909
1910			// load nav html into cal
1911			var cal_load_nav_html = function(){
1912				nav_data = el.evo_cal_get_footer_data('nav_data');				
1913				if( nav_data && 'month_title' in nav_data){
1914					__html = nav_data.month_title;
1915					if( 'arrows' in nav_data ) __html += nav_data.arrows;
1916					el.find('.evo_header_mo').html( __html );
1917					el.find('.evo_footer_nav').html( __html );
1918				}
1919			}
1920			run();
1921		}
1922
1923		// localize time @4.6.7 @u 4.9
1924		$.fn.evo_cal_localize_time = function(){			
1925			this.find('.evo_loct_inprocess').each(function(e){	$(this).evo_localize_time();	});
1926		}
1927		$.fn.evo_localize_time = function( ){
1928			
1929			const eventcard = this.closest('.eventon_list_event');
1930		    const hideEnd = eventcard.hasClass('no_et');
1931		    const textLocal = evo_general_params.text.local_time;
1932
1933		    eventcard.find('.evo_mytime').each(function() {
1934		    	const $el = $(this);
1935		        const isEventCard = $el.hasClass('evocard');
1936		        const { times, __f: fullFormat, __tf: timeOnlyFormat, tzo: utcOffset = 0 } = $el.data();
1937		        const [start, end] = times.split('-').map(Number);
1938
1939		        const startMoment = moment.unix(start).utc().local();
1940		        const endMoment = moment.unix(end).utc().local();
1941		        const sameMonth = startMoment.format('YYYY/M') === endMoment.format('YYYY/M');
1942		        const sameDay = sameMonth && startMoment.format('DD') === endMoment.format('DD');
1943
1944		        const startText = startMoment.format(fullFormat);
1945		        const endText = endMoment.format(sameDay ? timeOnlyFormat : fullFormat);
1946		        let html = `${startText}${hideEnd ? '' : ' - ' + endText}` ;
1947
1948		        // for event card
1949		        if( isEventCard ){
1950		        	html = `<span class='evomarr5'>${textLocal}:</span>` + html;
1951		        }else{
1952		        	html = "<span class=''>" + html + `</span>`;
1953		        }
1954
1955		        $el.replaceWith(`<span class='evo_newmytime'>${html}</span>`);
1956		    });
1957		}	
1958		$.fn.evo_day_in_month = function(opt){
1959			var defaults = { M:'', Y:''}
1960			var OPT = $.extend({}, defaults, opt);
1961
1962			return new Date(OPT.Y, OPT.M, 0).getDate();
1963		}
1964		$.fn.evo_get_day_name_index = function(opt){
1965			var defaults = { M:'', Y:'', D:''}
1966			var OPT = $.extend({}, defaults, opt);
1967
1968			//return moment(OPT.Y+'-'+OPT.M+'-'+OPT.D).utc().day();
1969
1970			return new Date(  Date.UTC(OPT.Y, OPT.M-1, OPT.D) ).getUTCDay();
1971		}
1972
1973		// scrollbar
1974		// Function to initialize custom scrollbar
1975		$.fn.evo_init_scrollbars = function(options){
1976
1977			const defaults = { scrollSpeed: 50 };
1978		    const settings = $.extend({}, defaults, options);
1979
1980
1981		    return this.each(function() {
1982		        const $scope = $(this);
1983		        $scope.find('.evo-scrollbar').each(function() {
1984		            const $container = $(this);
1985		            if ($container.hasClass('evo-scroll-container')) return;
1986
1987		            $container.addClass('evo-scroll-container');
1988		            const $parent = $container.parent();
1989		            if (!$parent.css('height') || $parent.css('height') === 'auto') {
1990		                $parent.css('height', '300px');
1991		            }
1992
1993		            const $content = $container.children().wrapAll('<div class="evo-scroll-content"></div>').parent();
1994		            $container.append('<div class="evo-scroll-tab-container"><div class="evo-scroll-tab"></div></div>');
1995
1996		            const $tabContainer = $container.find('.evo-scroll-tab-container');
1997		            const $tab = $tabContainer.find('.evo-scroll-tab');
1998		            const $scrollContent = $container.find('.evo-scroll-content');
1999
2000		            // Dynamic tab height and visibility
2001		            const updateTabHeight = () => {
2002		                const height = $container.height();
2003		                const contentHeight = $scrollContent[0].scrollHeight;
2004		                const maxScroll = contentHeight - height;
2005		                const tabHeight = Math.max(height * (height / contentHeight), 20);
2006		                $tab.css('height', `${tabHeight}px`);
2007		                $tab.toggleClass('scroll-needed', maxScroll > 0); // Show tab only if scrollable
2008		                console.log(height+' '+contentHeight+' '+maxScroll+' '+tabHeight);
2009            		};
2010		            $container.on('mouseenter', updateTabHeight);
2011
2012		            // Click to scroll
2013		            $tab.on('click', (e) => {
2014		                const height = $container.height();
2015		                const maxScroll = $scrollContent[0].scrollHeight - height;
2016		                const current = $container.scrollTop();
2017		                $container.scrollTop(current < maxScroll ? current + settings.scrollSpeed : current - settings.scrollSpeed);
2018		            });
2019
2020		            // Drag events
2021		            let isDragging = false;
2022		            let startY, startScrollTop;
2023
2024		            // Drag events
2025		            $tab.on('mousedown', (e) => {
2026		                isDragging = true;
2027		                $tab.addClass('dragging');
2028		                startY = e.pageY;
2029		                startScrollTop = $container.scrollTop();
2030		                e.preventDefault();
2031		            });
2032
2033		            $(document).on('mouseup', () => {
2034		                isDragging = false;
2035		                $tab.removeClass('dragging');
2036		            });
2037
2038		            $(document).on('mousemove', (e) => {
2039		                if (!isDragging) return;
2040
2041		                const height = $container.height();
2042		                const maxScroll = $scrollContent[0].scrollHeight - height;
2043		                const tabHeight = $tab.height();
2044		                const tabMaxTravel = height - tabHeight;
2045		                const deltaY = e.pageY - startY;
2046		                const scrollPercent = deltaY / tabMaxTravel;
2047		                $container.scrollTop(Math.max(0, Math.min(startScrollTop + (scrollPercent * maxScroll), maxScroll)));
2048		            });
2049
2050		            // Scroll event with requestAnimationFrame
2051		            $container.on('scroll', () => {
2052		                const height = $container.height();
2053		                const contentHeight = $scrollContent[0].scrollHeight;
2054		                const maxScroll = contentHeight - height;
2055		                const tabHeight = $tab.height();
2056		                const tabMaxTravel = height - tabHeight;
2057		                const scrollPosition = $container.scrollTop();
2058		                const scrollPercent = maxScroll > 0 ? scrollPosition / maxScroll : 0;
2059
2060		                requestAnimationFrame(() => {
2061		                    $tabContainer.css('top', `${scrollPosition}px`);
2062		                    $tab.css('top', `${scrollPercent * tabMaxTravel}px`);
2063		                });
2064		            });
2065		        });
2066		    });
2067		}
2068
2069
2070		/*
2071	    // Run on page load for all elements with .evo-scrollbar
2072	    initCustomScrollbar($('body').find('.evo-scrollbar'));
2073
2074	    // Expose function globally for on-demand use
2075	    window.initCustomScrollbar = function(selector) {
2076	        const $elements = selector ? $(selector) : $('body').find('.evo-scrollbar');
2077	        initCustomScrollbar($elements);
2078	    };
2079	    */
2080
2081
2082
2083	// LIGHTBOX
2084	// page Lightbox functions @+2.8
2085	// append to the lightbox main class name .evo_lightbox		
2086		// Legacy
2087			$.fn.evo_prepare_lb = function(){
2088				$(this).find('.evo_lightbox_body').html('');
2089			}
2090			$.fn.evo_show_lb = function(opt){
2091				var defaults = { RTL:'', calid:''}
2092				var OPT = $.extend({}, defaults, opt);
2093
2094				$(this).addClass('show '+ OPT.RTL).attr('data-cal_id', OPT.calid);
2095				$('body').trigger('evolightbox_show');
2096			}
2097			$.fn.evo_append_lb = function(opt){
2098				var defaults = { C:'', CAL:''}
2099				var OPT = $.extend({}, defaults, opt);
2100				$(this).find('.evo_lightbox_body').html( OPT.C);
2101
2102				if(  OPT.CAL!= '' && OPT.CAL !== undefined && OPT.CAL.hasClass('color')){
2103					const LIST = $(this).find('.eventon_events_list');
2104					if( LIST.length>0){
2105						LIST.find('.eventon_list_event').addClass('color');
2106					}				
2107				}
2108			}
2109
2110	// event image gallery @4.6
2111		$.fn.eventon_process_main_ft_img = function(OO){
2112			const IMG = this;
2113			var img_sty = 'def';
2114			if( IMG.hasClass('fit') ) img_sty = 'fit';
2115			if( IMG.hasClass('full') ) img_sty = 'full';
2116			
2117			// Initialize box dimensions
2118		    let box_width =  IMG.width();
2119		    let box_height =  IMG.height();
2120			
2121			// Ensure valid box dimensions
2122		    box_width = box_width > 0 ? box_width : 100; // Fallback to prevent errors
2123		    box_height = box_height > 0 ? box_height : 100;
2124			
2125
2126			 // Get image dimensions from data attributes
2127		    const img_width = parseInt(IMG.data('w')) || 100; // Fallback to prevent division by zero
2128		    const img_height = parseInt(IMG.data('h')) || 100;
2129		    const img_ratio = img_height / img_width; // Image aspect ratio
2130					
2131			let new_width, new_height;
2132			
2133			// Handle 'fit' style 
2134			if( IMG.hasClass('fit')){
2135				// Scale to fit within box while maintaining aspect ratio
2136		        new_width = box_height / img_ratio;
2137				new_height = box_height;
2138				if( new_width > box_width ){// width is wider than box
2139
2140					if( img_ratio <1 ){
2141						new_width = box_width; new_height = img_ratio * new_width;
2142					}else{
2143						new_height = box_height; new_width = new_height / img_ratio;
2144					}
2145				} 	
2146					
2147				IMG.find('span').css({'width':new_width, 'height': new_height} );
2148			}
2149
2150			// full style
2151			if( IMG.hasClass('full')){
2152				new_height = img_ratio * box_width;
2153				new_width = box_width;
2154				IMG.find('span').css({'width':new_width, 'height': new_height} );
2155				IMG.css({'height': new_height} );
2156			}
2157
2158			//console.log(box_width +' '+img_width+' '+new_width);
2159		}
2160
2161
2162	/**
2163	 * Form functions
2164	 * @version 4.8.2
2165	 * @updated 4.9.6
2166	 */
2167		$.fn.evo_RealTime_form_validation = function() {
2168	        return this.each(function() {
2169	            var form = $(this);
2170	            var req_fields = form.find('.input.req');
2171	            var email_fields = form.find('.input.email');
2172	            var humanvalid_fields = form.find('.input.evoelm_hval_val');
2173
2174            		        
2175	            req_fields.on('input blur', function() { $(this).evo_form_validate_field( 'text'); });
2176            	email_fields.on('input blur', function() { $(this).evo_form_validate_field( 'email'); });
2177            	humanvalid_fields.on('input blur', function() { $(this).evo_form_validate_field( 'humanvalid'); });
2178            	
2179	        });
2180	    }
2181
2182	    $.fn.evo_form_validation_check = function(){
2183
2184	    	var form = this;
2185	    	var req_fields = form.find('.input.req'); // Define here for use in validateForm
2186		    var email_fields = form.find('.input.email');
2187		    var humanvalid_fields = form.find('.input.evoelm_hval_val');
2188
2189	    	
2190            function validateForm() {
2191	            var hasErrors = false;
2192	            req_fields.each(function() {
2193	                if ( $(this).evo_form_validate_field( 'text')) hasErrors = true;
2194	            });
2195	            email_fields.each(function() {
2196	                if ($(this).evo_form_validate_field( 'email')) hasErrors = true;
2197	            });
2198	            humanvalid_fields.each(function() {
2199	                if ($(this).evo_form_validate_field( 'humanvalid')) hasErrors = true;
2200	            });
2201
2202	            return !hasErrors;
2203	        }
2204
2205	        return validateForm();
2206	    }
2207	    $.fn.evo_form_validate_field = function(type){
2208	    	var field = this;
2209	    	var errorElement = field.siblings('em');
2210            var hasError = false;
2211            var fieldValue = field.val().trim();
2212
2213            if (type === 'email') {		   
2214            	if (field.hasClass('req')) {
2215                    // Required email: Check if filled AND valid
2216                    hasError = fieldValue === '' || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(fieldValue);
2217                } else {
2218                    // Optional email: Only check if it’s not empty
2219                    hasError = fieldValue !== '' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(fieldValue);
2220                }
2221                 	
2222            } else if (type === 'humanvalid') {
2223                var correctAnswer =  field.data('val'); // Expected answer from data attribute
2224                hasError = ( '89r329' +field.val().trim()+ '8932ufe' ) !== correctAnswer;
2225            } else {
2226                hasError = field.val().trim() === '';
2227            }                
2228
2229            if (hasError) {
2230                if (errorElement.length === 0) {
2231                    errorElement = $('<em class="evoelm_field_errmsg evopadt5"></em>');
2232                    field.after(errorElement);
2233                }
2234                errorElement.html(getErrorMessage(type === 'email' ? 'err2' : type === 'humanvalid' ? 'err3' : 'err1'))
2235                    .removeClass('evodn')
2236                    .addClass('evodib');
2237                field.addClass('err');
2238            } else {
2239                errorElement.remove();
2240                field.removeClass('err');
2241            }	   
2242
2243            function getErrorMessage(type) {
2244	            const messages = {
2245	                err1: evo_general_params.text.err1, // Required field error
2246	                err2: evo_general_params.text.err2, // Email format error
2247	                err3: evo_general_params.text.err3  // Human validation error (e.g., "Incorrect answer")
2248	            };
2249	            return messages[type] || "";
2250	        }             
2251
2252            return hasError;
2253	    }	
2254
2255	    $('body').on('evo_elm_form_presubmit_validation', function(event, form, callback){
2256    		event.preventDefault();
2257    		var $form = $(form);
2258
2259    		var isValid = $form.evo_form_validation_check();
2260
2261            if (typeof callback === "function") {
2262                callback(isValid); // Return true/false to the callback
2263            }
2264    	});
2265
2266	// Calendar Data & Shortcodes
2267		// get shortcodes from evo bottom
2268		$.fn.evo_shortcode_data = function(){		
2269			var ev_cal = $(this);
2270			return ev_cal.find('.evo_cal_data').data('sc');			
2271		}
2272
2273		// get filter data @4.6
2274			$.fn.evo_get_filter_data = function(){			
2275				return $(this).find('.evo_cal_data').data('filter_data');			
2276			}
2277			$.fn.evo_cal_get_filter_sub_data = function( tax , key){
2278				newdata = $(this).evo_get_filter_data();
2279
2280				if( !( tax in newdata ) ) return;
2281				if( !( key in newdata[tax] ) ) return;
2282				return newdata[ tax ][ key ];
2283			}
2284			$.fn.evo_cal_update_filter_data = function(tax, new_val, key){
2285
2286				newdata = $(this).evo_get_filter_data();
2287				if( key === undefined) key = 'nterms';
2288				newdata[ tax ][ key ] = new_val;
2289				$(this).find('.evo_cal_data').data('filter_data', newdata );
2290			}
2291			$.fn.evo_cal_get_footer_data = function( key ){
2292				data = $(this).find('.evo_cal_data').data();
2293
2294				//console.log(data);
2295
2296				if( data === undefined ) return false; // 4.6.2
2297				if( key in data ) return data[ key ];
2298				return false;		
2299			}
2300
2301		// hide cal data from view
2302		$.fn.evo_cal_hide_data = function(){			
2303			$(this).find('.evo_cal_data').attr({
2304				'data-sc':'',
2305				'data-filter_data':'',
2306				'data-nav_data':'',
2307			});			
2308		}
2309
2310		// update shortcode values from filter changes @u4.6
2311		$.fn.evo_update_sc_from_filters = function(){
2312			var el = $(this); 	
2313			SC = el.evo_shortcode_data();
2314
2315
2316			$.each( el.evo_get_filter_data() , function(index, value){
2317				var default_val 	= value.terms;
2318				var filter_val 		= value.nterms;
2319				const NOT_values 	= value.__notvals;
2320
2321				filter_val = filter_val == ''? 'NOT-all': filter_val;	
2322				
2323				var not_string = '';
2324
2325				// if NOT filter in place > include that in tax value for query
2326				if( NOT_values!== undefined && NOT_values.length >0 && filter_val != default_val ){	
2327					
2328					$.each(NOT_values, function(index, value){
2329						not_string += 'NOT-'+ value +',';
2330					});
2331				}		
2332
2333				SC[ index ] = not_string + filter_val;
2334			});
2335			
2336
2337			el.find('.evo_cal_data').data( 'sc', SC );
2338		}
2339		
2340		
2341
2342		// get shortcode single value
2343		$.fn.evo_get_sc_val = function(opt){
2344			var defaults = {	F:''}
2345			var OPT = $.extend({}, defaults, opt);
2346			var ev_cal = $(this); 
2347
2348			if(OPT.F=='') return false;
2349			SC = ev_cal.find('.evo_cal_data').data('sc')|| {};
2350
2351			if(!(SC[ OPT.F])) return false;
2352			return SC[ OPT.F];
2353		}
2354		// UPDATE Single value
2355		$.fn.evo_update_cal_sc = function(opt){
2356			var defaults = {
2357				F:'', V:''
2358			}
2359			var OPT = $.extend({}, defaults, opt);
2360			var ev_cal = $(this); 
2361			SC = ev_cal.find('.evo_cal_data').data('sc') || {};
2362			
2363
2364			SC[ OPT.F ] = OPT.V;
2365
2366			ev_cal.find('.evo_cal_data').data( 'sc', SC );
2367		}
2368		// UPDATE all shortcode values
2369		$.fn.evo_update_all_cal_sc = function(opt){
2370			var defaults = {SC:''}
2371			var OPT = $.extend({}, defaults, opt);
2372			var CAL = $(this);
2373			CAL.find('.evo_cal_data').data( 'sc', OPT.SC );
2374		}
2375
2376		
2377
2378	// OTHERS
2379		// hex colors // @+2.8 @updated 4.7.2
2380			$.fn.evo_is_hex_dark = function(opt){
2381				var defaults = { hex:'808080'}
2382				var OPT = $.extend({}, defaults, opt);
2383
2384				hex = OPT.hex;
2385
2386				var c = hex.replace('#','');
2387				var is_hex = typeof c === 'string' && c.length === 6 && !isNaN(Number('0x' + c));
2388
2389				if(is_hex){	
2390					var values = c.split('');
2391					r = parseInt(values[0].toString() + values[1].toString(), 16);
2392				    g = parseInt(values[2].toString() + values[3].toString(), 16);
2393				    b = parseInt(values[4].toString() + values[5].toString(), 16);
2394				}else{
2395					var vals = c.substring(c.indexOf('(') +1, c.length -1).split(', ');
2396					var r = vals[0]  // extract red
2397					var g = vals[1];  // extract green
2398					var b = vals[2];
2399				}
2400
2401				var luma = ((r * 299) + (g * 587) + (b * 114)) / 1000; // per ITU-R BT.709
2402
2403				return luma> 128? true:false;
2404			}
2405
2406		// get rgb from hex code @4.5
2407			$.fn.evo_rgb_process = function(opt){
2408				var defaults = { data:'808080',type:'rgb', method:'rgb_to_val'}
2409				var opt = $.extend({}, defaults, opt);
2410
2411				const color = opt.data;
2412
2413				// RGB => hex
2414				if( opt.method == 'rgb_to_hex'){
2415					if(color == '1'){
2416						return;
2417					}else{
2418						if(color !=='' && color){
2419							rgb = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
2420							
2421							return "#" +
2422							("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
2423							("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
2424							("0" + parseInt(rgb[3],10).toString(16)).slice(-2);
2425						}
2426					}
2427				}
2428
2429				// RGB => rgb val
2430				if( opt.method == 'rgb_to_val'){
2431					if( opt.type == 'hex'){
2432						var rgba = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);	
2433						var rgb = new Array();
2434						rgb['r']= parseInt(rgba[1], 16);			
2435						rgb['g']= parseInt(rgba[2], 16);			
2436						rgb['b']= parseInt(rgba[3], 16);
2437						
2438					}else{
2439						rgb = color;
2440					}
2441					
2442					return parseInt((rgb['r'] + rgb['g'] + rgb['b'])/3);
2443				}				
2444			}
2445
2446		// Other data
2447			$.fn.evo_get_OD = function(){			
2448				var ev_cal = $(this);
2449				return ev_cal.find('.evo_cal_data').data('od');			
2450			}
2451
2452	
2453
2454		// get evo data for a given calendar
2455		$.fn.evo_getevodata = function(){
2456
2457			var ev_cal = $(this);
2458			var evoData = {};
2459			
2460			ev_cal.find('.evo-data').each(function(){
2461				$.each(this.attributes, function(i, attrib){
2462					var name = attrib.name;
2463					if(attrib.name!='class' && attrib.name!='style' ){
2464						name__ = attrib.name.split('-');
2465						evoData[name__[1]] = attrib.value;	
2466					}
2467				});
2468			});	
2469
2470			return evoData;
2471		}
2472
2473		// check if mobile device v4.6
2474		$.fn.evo_is_mobile = function(){
2475			return ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) )? true: false;		
2476		}
2477
2478	// eventon loading functions
2479	// v 2.4.5 -- deprecating
2480		$.fn.evo_loader_animation = function(opt){
2481			var defaults = {
2482				direction:'start'
2483			}
2484			var OPT = $.extend({}, defaults, opt);
2485
2486			if(OPT.direction == 'start'){
2487				$(this).find('#eventon_loadbar').slideDown();
2488			}else{
2489				$(this).find('#eventon_loadbar').slideUp();
2490			}
2491		}
2492
2493	// DEPRECATED functions
2494		$.fn.evo_item_shortcodes = function(){			
2495			var OBJ = $(this);
2496			var shortcode_array ={};			
2497			OBJ.each(function(){	
2498				$.each(this.attributes, function(i, attrib){
2499					var name = attrib.name;
2500					if(attrib.name!='class' && attrib.name!='style' && attrib.value !=''){
2501						name__ = attrib.name.split('-');
2502						shortcode_array[name__[1]] = attrib.value;	
2503					}
2504				});
2505			});
2506			return shortcode_array;
2507		}
2508		$.fn.evo_shortcodes = function(){			
2509			var ev_cal = $(this);
2510			var shortcode_array ={};
2511					
2512			ev_cal.find('.cal_arguments').each(function(){
2513				$.each(this.attributes, function(i, attrib){
2514					var name = attrib.name;
2515					if(attrib.name!='class' && attrib.name!='style' && attrib.value !=''){
2516						name__ = attrib.name.split('-');
2517						shortcode_array[name__[1]] = attrib.value;	
2518					}
2519				});
2520			});	
2521			return shortcode_array;
2522		}
2523		
2524
2525});

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.