PageSourceSearch

https://www.artechouse.com/wp-content/plugins/eventon-lite/assets/js/eventon_functions.js?ver=2.5.9

js artechouse.com collected 2026-09-24 09:21:11 UTC 48,798 bytes, 1,581 lines download raw bytes

1/**
2 * Javascript: EventON functions for all calendars
3 * @version: 2.4
4 */
5(function($){
6
7 	// Basic
8		// Calendar function s
9			$.fn.evo_cal_functions = function(O){
10				el = this;
11				switch(O.return){
12					// load shortcodes inside calendar data
13					case 'load_shortcodes':
14						return el.find('.evo_cal_data').data('sc');		
15					break;
16					case 'update_shortcodes':
17						el.find('.evo_cal_data').data( 'sc', O.SC );
18					break;
19				}
20			};
21
22		// access page GLOBALS
23			$.fn.evo_get_global = function(opt){
24				var defaults = { S1:'', S2:''};
25				var OPT = $.extend({}, defaults, opt);
26
27				var BUS = $('#evo_global_data').data('d');
28
29				if(!(OPT.S1 in BUS)) return false;
30				if(!(OPT.S2 in BUS[OPT.S1])) return false;
31				return BUS[OPT.S1][OPT.S2];
32			}
33			$.fn.evo_get_txt = function(opt){
34				var defaults = { V:''}
35				var OPT = $.extend({}, defaults, opt);
36
37				var BUS = $('#evo_global_data').data('d');
38				if(!('txt' in BUS)) return false;
39				if(!(OPT.V in BUS.txt)) return false;
40				return BUS.txt[OPT.V];
41			}
42			$.fn.evo_get_cal_def = function(opt){
43				var defaults = { V:''}
44				var OPT = $.extend({}, defaults, opt);
45
46				var BUS = $('#evo_global_data').data('d');
47				if(!('cal_def' in BUS)) return false;
48				if(!(OPT.V in BUS.cal_def)) return false;
49				return BUS.cal_def[OPT.V];
50			}
51
52			// return dms translates values from global data
53			// added 4.0
54			$.fn.evo_get_dms_vals = function(opt){
55				// type = d, d1,d3, m, m3
56				// V = 0-x
57				var defaults = { type:'d', V:''}
58				var OPT = $.extend({}, defaults, opt);
59
60				var BUS = $('#evo_global_data').data('d');			
61				if(!('dms' in BUS)) return false;
62				if(!(OPT.type in BUS.dms)) return false;
63
64				return BUS.dms[ OPT.type ][ OPT.V ];
65				
66			}
67
68	// GENERAL AJAX ACCESS @4.9.2
69		$.fn.evo_admin_get_ajax = function(opt){
70
71			var el = this,
72		        OO = this.evo_process_ajax_params(opt),
73		        LB = OO.lbdata.class ? $('body').find('.evo_lightbox.' + OO.lbdata.class) : false;
74
75		    var _lbdata = OO.lbdata;
76			var _adata = OO.adata;	
77			var _populate_id = OO._populate_id;	
78
79		    // Allow custom success callback to be passed in opt -- 4.9.2    		
80    		var customBefore = typeof opt.onBefore === 'function' ? opt.onBefore : null;   // New onBefore callback
81		    var customSuccess = typeof opt.onSuccess === 'function' ? opt.onSuccess : (typeof opt.success === 'function' ? opt.success : null); 
82		    	// Rename to onSuccess, keep backward compatibility with 'success'
83		    var customSuccess_Extra = typeof opt.successExtra === 'function' ? opt.successExtra : null; // this will run with default ajax
84		    var customComplete = typeof opt.onComplete === 'function' ? opt.onComplete : null; // New onComplete callback
85
86			var ajax_url = el.evo_get_ajax_url({a: _adata.a, e: _adata.end, type: _adata.ajax_type});
87
88	  		// Run AJAX
89	  		let ajaxResponse = '';
90  			$.ajax({
91				beforeSend: function(){
92					if (customBefore) {   customBefore.call(el, OO, LB); } // Call with onBefore:function(OO, LB){}
93					el.evo_perform_ajax_run_loader( OO, LB, 'start'  );
94				},
95				type: 'POST', url: ajax_url, data: OO.adata.data,	dataType:'json',
96				success:function(data){	
97					ajaxResponse = data;
98					if (customSuccess) {
99		                customSuccess.call(el, OO, data, LB); 
100		                // call data with data.data
101		                // Trigger a custom event for onSuccess - 4.9.11
102		                $('body').trigger('evo_ajax_success_' + OO.uid,[ OO, data , el]);	
103		            } else {
104		                el.evo_perform_ajax_success(OO, data, LB);
105		                if (opt.successExtra) opt.successExtra.call(el, OO, data, LB);
106		            }					
107
108				},complete:function(){
109					if (customComplete) {     customComplete.call(el, OO, ajaxResponse, LB);  } // Call with onSuccess:function( OO, data, LB){} 
110					el.evo_perform_ajax_run_loader( OO, LB, 'end'  );
111					
112				}
113			});				
114		}
115
116		// submit forms via ligtbox
117		// @since 4.2.2		@updated 4.9.2
118		$.fn.evo_ajax_lightbox_form_submit = function(opt , formObj ){
119			
120  			const el = this;
121
122  			var OO = this.evo_process_ajax_params( opt );
123
124  			//console.log(OO);
125
126  			var _lbdata = OO.lbdata;
127			var _adata = OO.adata;	
128			var _populate_id = OO._populate_id;	
129  			
130  			var form = this.closest('form');
131  			if( formObj !== undefined ) form = formObj;
132
133  			// form required fields validation - @4.9
134			if( el.hasClass('validate')){
135
136				var hasError = false;
137
138				$('body').trigger('evo_elm_form_presubmit_validation', [form, function(isValid) {
139				    hasError =  isValid ? false: true;
140				}]);
141
142			    if( hasError){
143			    	LB = el.closest('.evo_lightbox');
144			    	LB.evo_lightbox_show_msg({message:'Required fields missing'});
145			    	return;
146			    }	
147			}
148
149  			// for lightbox
150				var LB = false;
151	  			if( _lbdata.class != '') LB = $('body').find('.evo_lightbox.'+ _lbdata.class );
152
153  			// reset LB message
154  			if( LB) LB.evo_lightbox_hide_msg();
155
156  			var ajax_url = el.evo_get_ajax_url({a: _adata.a, e: _adata.end, type: _adata.ajax_type});
157
158  			// Add passed on data from ajax object @4.8.2
159			var extra_ajax_data = ('data' in _adata ) ? _adata.data : null;
160	  			
161  			// Submit form
162				form.ajaxSubmit({
163					beforeSubmit: function(opt, xhr){
164						el.evo_perform_ajax_run_loader( OO, LB, 'start'  );
165					},
166					dataType: 	'json',	
167					url: ajax_url,	type: 	'POST',
168					data: extra_ajax_data,
169					success:function(data){
170						el.evo_perform_ajax_success( OO, data, LB );
171					},
172					complete:function(){	
173						el.evo_perform_ajax_run_loader( OO, LB, 'end'  );
174					}
175				});
176		}
177
178	// perform ajax functions / type = start/end
179		$.fn.evo_perform_ajax_run_loader = function( OO , LB, type ){
180			var el = this;
181			var _lbdata = OO.lbdata;
182			var _adata = OO.adata;	
183
184			//console.log(OO);
185
186			var customer_loader_elm = false;
187			var loader_btn_el = false;
188
189  			if( _adata.loader_el !='')	customer_loader_elm = _adata.loader_el;
190  			if( 'loader_class' in _adata && _adata.loader_class != '') 
191  				customer_loader_elm = $('.' + _adata.loader_class);
192  			if( _adata.loader_btn_el != '' && _adata.loader_btn_el !== undefined ) loader_btn_el = el;
193  			
194  			var LB_loader = false;
195  			if( LB && 'loader' in _lbdata && _lbdata.loader ) LB_loader = true;
196
197  			if( type == 'start'){
198
199  				var trigger_id = ( 'uid' in OO && OO.uid != '' ) ? OO.uid : OO.ajax_action; // @4.8
200  				$('body').trigger('evo_ajax_beforesend_' + trigger_id ,[ OO, el ]);
201
202				if( LB_loader ){
203					LB.find('.ajde_popup_text').addClass( 'evoloading loading'); // legacy
204					LB.evo_lightbox_start_inloading();
205				}
206				if( customer_loader_elm ) $( customer_loader_elm ).addClass('evoloading loading');
207				if( loader_btn_el ) el.addClass('evobtn_loader'); // loader on button
208  			}else{
209
210  				var trigger_id = ( 'uid' in OO && OO.uid != '' ) ? OO.uid : OO.ajax_action; // @4.8
211
212  				$('body').trigger('evo_ajax_complete_' + trigger_id ,[ OO , el ]);
213			
214				if( LB_loader ){
215					LB.find('.ajde_popup_text').removeClass( 'evoloading loading');
216					LB.evo_lightbox_stop_inloading();	
217				}
218				if( customer_loader_elm ) $( customer_loader_elm ).removeClass('evoloading loading');
219				if( loader_btn_el ) el.removeClass('evobtn_loader'); // loader on button
220
221				
222  			}
223
224			return {
225				'l1': customer_loader_elm,
226				'l2':LB_loader
227			};
228		}
229
230		$.fn.evo_perform_ajax_success = function ( OO, data, LB ){
231			var el = this;
232			var _lbdata = OO.lbdata;
233			var _adata = OO.adata;	
234			var _populate_id = OO._populate_id;		
235
236			if( !data || data === undefined ) return;	
237
238			// if json is passing data object @4.9
239			var _success = ('success' in data) ? data.success : (data.status === 'good');
240
241			var extractedContent = 'content' in data ? data.content: '';
242			if( 'data' in data && 'content' in data.data) extractedContent = data.data.content;
243			var extractedData = ('data' in data) ? data.data : data;
244			extractedData['content'] = extractedContent;
245
246			// Ensure extractedData is an object for property checks; if it’s a string, wrap it
247		    if (typeof extractedData !== 'object' || extractedData === null) {
248		        extractedData = { msg: extractedData }; // Convert string to object
249		    }
250
251		    // Assign success and status to the extracted data
252		    extractedData.success = _success;
253		    extractedData.status = ('status' in extractedData) ? extractedData.status : (_success ? 'good' : 'bad');
254
255		    // Replace original data with processed data
256		    data = extractedData;
257
258			// if inside lightbox
259			if( LB.length > 0 ){
260				// show message
261					if (data && typeof data === 'object' && !Array.isArray(data) && 'msg' in data && data.msg !== '') {
262						LB.evo_lightbox_show_msg({
263							'type': ( _success ? 'good':'bad'), 
264							'message':data.msg, 
265							hide_lightbox: (  _success ? _lbdata.hide : false ),	
266							hide_message: _lbdata.hide_msg
267						});
268					}	
269
270				// populate lightbox
271				if( data && _lbdata.new_content && 'content' in data && data.content != '' ){
272
273					// populate a specific dom element with content
274					if( _populate_id ){
275						$('body').find('#'+_populate_id ).replaceWith( data.content );					
276					}else{
277						LB.evo_lightbox_populate_content({content: data.content});
278					}
279				}	
280								
281			}else{
282				// populate content
283				if( data && _populate_id && 'content' in data && data.content != ''){
284					$('body').find('#'+_populate_id ).html( data.content );
285				}						
286			}
287
288			// Show snackbar message
289				if( 'show_snackbar' in  _adata && ('msg' in data)  && data.msg != '' ) 
290					el.evo_snackbar({message: data.msg});
291
292			// populate content with matching DOM class names, will set new html @4.7.2
293				if( 'populate_dom_classes' in data){
294					$.each( data.populate_dom_classes, function( domclass, content){
295						$('body').find('.'+ domclass).html( content );
296					} );
297				}
298
299			// if ajax data pass dom content to be replaced with run through each and replace - @4.2.3
300				if( 'refresh_dom_content' in data ){
301					$.each(data.refresh_dom_content, function(domid, content){
302						$('body').find('#'+ domid).replaceWith( content);
303					});
304				}
305
306			// for SP content @since 4.5.2
307				if(data &&  'sp_content' in data){
308					$("body").find('#evops_content').html( data.sp_content);
309				}
310			// SP footer content @since 4.5.2
311				if( data && 'sp_content_foot' in data){
312					$("body").find('.evosp_foot').html( data.sp_content_foot);
313				}
314			// process trumbowyg editors
315				$('body').trigger('evo_elm_load_interactivity');
316
317
318			// assign dynamic vals to DOM element
319				setTimeout(function(){
320					if( 'evoelms' in data ){
321						$.each( data.evoelms , function( uniqueid, elm_data ){
322
323							$('body').find('.has_dynamic_vals').each(function(){
324
325								if( $(this).attr('id') != uniqueid ) return;
326								var dynamic_elm = $(this);
327
328								$.each( elm_data , function( elm_key, elmv){
329									dynamic_elm.data( elm_key, elmv );
330								});
331							});
332						});
333					}
334				},200);
335
336			//console.log(OO);
337			$('body').trigger('evo_ajax_success_' + OO.uid,[ OO, data , el]);	
338		}
339
340	// Process ajax and lightbox values @4.7.2
341		$.fn.evo_process_ajax_params = function ( opt ){
342			// defaults
343			var defz = { 
344				'uid':'',
345
346				// @since 4.7.2
347				'adata':{}, // @4.7.2 include all ajax data in here, type (ajax,rest,endpoint),action/a, other data
348				'lbdata':{},// @4.7.2 lightbox data all in one place, class, title, size, padding
349				'_populate_id':'', // loading new content into matching elements outside of lightbox
350				
351				// legacy values
352				'content':'',// passed on dynamic content
353				'content_id' :'',// id to get dynamic content from page		
354								
355				't':'', //title
356				'lbc':'',// * lightbox class - REQUIRED
357				'lbac':'',// ligthbox additional class 4.6
358				'lbsz':'',// lightbox size = mid small, s400, s500, s700, s800
359				'lightbox_loader': true,
360				'preload_temp_key': 'init', // 4.6
361				'load_new_content': true, // @since 4.3.5
362				'lb_padding': '', // @4.3.5
363				'load_new_content_id':'',
364
365				'ajax':'no',// use ajax to load content yes no
366				'ajax_url':'',// load content from ajax file
367				'end':'admin',// admin or client end
368				'ajax_action':'', // @4.4 pass on ajax endpoint action key
369				'a':'',
370				'ajax_type':'ajax', // @4.4 ajax type, ajax, rest or endpoint
371				'd':'', // data object for ajax
372				'other_data':'',
373				'ajaxdata':'',				
374			};
375
376
377			// extend passed with defaults
378			var OO = $.extend({}, defz, opt);
379
380			// Build processed object
381				var processed = {};
382				processed['uid'] = OO.uid;
383
384
385			// Ajax	
386				var _adata = ( OO.adata == '') ? {}: OO.adata;
387
388				// type passed value fix
389				var passed_type_val = false;
390				if( 'type' in _adata && _adata.type != '' &&
391					!['ajax', 'rest', 'endpoint'].includes(_adata.type)
392				){
393					passed_type_val = _adata.type;
394					_adata.type = '';
395				}
396
397				// set default needed values
398				var def_avals = { 
399					'a':'',
400					'type':'ajax',
401					'end':'admin',
402					'data': '',
403					'loader_el':'',
404					'loader_btn_el':'',//4.8
405					'loader_class':'',
406					'url':'',
407				}
408				
409				// set default values
410				$.each( def_avals, function(key, value) {					
411					if( key == 'data' && !( 'a' in _adata ) && ('data' in _adata ) && 'a' in _adata.data ) return;
412					if( !(key in _adata ) && value != '' ) _adata[ key ] = value;
413				});	
414
415				//console.log( _adata );
416
417				// map old to new
418				var def_adata_mapping = { 
419					'a' : 'a',
420					'ajax_action' : 'a',
421					'ajax_type':'type',
422					'end': 'end',
423					'ajax_url': 'url',
424					'ajaxdata':'data',
425					'd':'data',
426				}
427				$.each( def_adata_mapping, function(oldV, newV) {					
428					if( newV in _adata && _adata[ newV ] != '' ) return;
429
430					if(  oldV in OO && OO[oldV] !== '' ) {
431						_adata[newV] = OO[oldV];
432					}  
433				});	
434
435				if( _adata.data === undefined ) _adata.data = {};
436
437				//console.log( _adata );			
438
439				// Move additional values in _adata to _adata.data
440					$.each(_adata, function(key, value) {
441						if ( !(key in def_avals)) {
442							//_adata.data[key] = value; // Move any extra values to _adata.data
443							//delete _adata[key]; // Remove them from the main _adata object
444						}
445					});
446
447				if( 'data' in _adata ){
448					//_adata['data']['nn'] = ( _adata.end == 'client' ) ? evo_general_params.n : evo_admin_ajax_handle.postnonce; 
449										
450					_adata['data']['nn'] = (typeof evo_admin_ajax_handle !== 'undefined' && evo_admin_ajax_handle !== null) 
451					    ? evo_admin_ajax_handle.postnonce 
452					    : evo_general_params.n;
453
454
455					_adata['data']['uid'] = processed['uid'];
456					if( passed_type_val ) _adata['data']['type'] = passed_type_val;
457					if( 'action' in _adata.data ) _adata['a'] =  _adata.data.action;
458					if( 'a' in _adata.data ) _adata['a'] =  _adata.data.a;
459					if( 'ajaxdata' in OO ) processed['ajaxdata'] = _adata.data;
460				}		
461
462				processed['adata'] = _adata;
463				
464
465			// lightbox
466				var _lbdata = ( OO.lbdata == '') ? {}: OO.lbdata;
467
468				// if legacy values exists > convert them to new
469				var def_lbdata_mapping = {
470					'lbc':'class',
471				    'lbsz':'size',
472				    'lbac' :'additional_class',
473				    't':'title',
474				    'lb_padding': 'padding',
475				    'load_new_content':'new_content',
476				    'lightbox_loader': 'loader',
477				    'content_id':'content_id',
478				    'content':'content',
479				    'hide_lightbox':'hide',
480				    'hide_message':'hide_msg',
481				    'lightbox_key': 'class',
482				}
483				$.each( def_lbdata_mapping, function(oldV, newV) {
484					// if _lbdata has new value > skip
485					if (newV in _lbdata && _lbdata[newV] !== '' && _lbdata[newV] !== null && _lbdata[newV] !== undefined) {
486				        return; 
487				    }
488					if(  oldV in OO && OO[oldV] !== '' ) {
489						_lbdata[newV] = OO[oldV];
490					} 
491				});	
492
493				// set default needed values
494				var def_lbvals = {
495					'padding':'evopad30',
496					'loader': false,
497					'preload_temp_key':'init',
498					'new_content': true,
499					'additional_class':'',
500					'title':'',
501					'hide':false,
502					'hide_msg':2000,
503					'content':'', // content for lightbox
504					'content_id':'', // content id in DOM to grab content for lightbox
505				}
506				// set default values
507				$.each( def_lbvals, function(key, value) {
508					if(  key in _lbdata )  return;
509					if( value == '') return;
510					_lbdata[ key ] = value;
511				});
512
513
514				//console.log( _lbdata.new_content ) ;
515
516				// load lightbox content legacy
517				if( OO.ajaxdata.load_lbcontent ) _lbdata['new_content'] = true;
518				if( OO.ajaxdata.load_new_content ) _lbdata['new_content'] = true;
519
520				// populate new content @4.7.3
521					processed['_populate_id'] =  false;
522					if( OO.load_new_content_id != '')  processed['_populate_id'] = OO.load_new_content_id;
523					if( 'new_content_id' in _lbdata && _lbdata.new_content_id != '')  processed['_populate_id'] = _lbdata.new_content_id;
524					if( 'content_id' in _lbdata && _lbdata.content_id != '') processed['_populate_id'] = _lbdata.content_id;
525
526				processed['lbdata'] = _lbdata;
527
528			// make sure uid is moved to main level
529				if( processed.uid == '' && 'uid' in processed['lbdata'] ) processed['uid'] = processed['lbdata']['uid'];
530
531			// add legacy variables for backward compatibility
532				$.each(opt, function(oldkey, oldval){
533					if( oldkey in processed ) return;
534					processed[ oldkey ] = oldval;
535				});
536
537			//console.log( processed );
538
539			return processed;
540		}
541
542	// LIGHTBOX version 4.2
543		// @version 4.2
544		$('body').on('click','.evolb_trigger', function(event){
545			if( event !== undefined ){
546				event.preventDefault();
547				event.stopPropagation();
548			}
549			
550			$(this).evo_lightbox_open($(this).data('lbvals'));
551		});
552		$('body').on('click','.evolb_close_btn', function (){
553			const LB = $(this).closest('.evo_lightbox');
554			LB.evo_lightbox_close();
555		});
556
557		// @since 4.2.2
558		$('body').on('click','.evolb_trigger_save, .evo_submit_form', function(event){
559			if( event !== undefined ){
560				event.preventDefault();
561				event.stopPropagation();
562			}
563			$(this).evo_ajax_lightbox_form_submit( $(this).data('d') );
564		});
565
566		$('body').on('click','.evo_trigger_ajax_run', function(event){
567			if( event !== undefined ){
568				event.preventDefault();
569				event.stopPropagation();
570			}
571			$(this).evo_admin_get_ajax( $(this).data('d') );
572		});
573		// @since 4.3.3
574		$('body').on('evo_lightbox_trigger', function(event, data){
575			$('body').evo_lightbox_open(data);
576		});
577		
578
579	// Lightbox opening
580		$.fn.evo_alert = function(opt){ // @since 4.9.2
581			var defz = { 
582		        'title': 'Confirmation Action',
583		        'message': '',
584		        'yes_text': 'Proceed',
585		        'no_text': 'No',
586		        'on_yes': function() {}, // Callback for Yes
587		        'on_no': function() {}   // Callback for No
588		    };	
589
590		    // Extend passed options with defaults
591		    var options = $.extend({}, defz, opt);
592
593		    // Create alert HTML content
594		    var alertHtml = '<div class="evo_alert_box">' +
595		        '<p class="evotal evopad10i">' + options.message + '</p>' +
596		        '<div class="evo_alert_buttons evotar">' +		            
597		            '<button class="evo_alert_no evoboxsn evobrn evooln evocurp evohoop7 evopad10-20 evobr20 evobgclt">' + options.no_text + '</button>' +
598		            '<button class="evo_alert_yes evoboxsn evobrn evooln evocurp evoHbgc1 evopad10-20 evobr20 evomarr10 evobgclp evoclw">' + options.yes_text + '</button>' +
599		        '</div></div>';
600
601		    // Define lightbox options with the alert content
602		    var lightboxOptions = {
603		        lbdata: {
604		            class: 'evo_alert_lightbox',
605		            title: options.title || 'Alert',
606		            content: alertHtml, // Set the alert HTML as the lightbox content
607		            padding: 'pad20', // Optional: Add padding class if needed
608		            size:'small',
609		        },
610		    };
611
612		    // Open the lightbox with the alert content
613		    $(this).evo_lightbox_open(lightboxOptions);
614
615		    // After the lightbox is opened, attach event handlers
616		    setTimeout(function() {
617		        var LIGHTBOX = $('.evo_lightbox.evo_alert_lightbox');
618		        
619		        LIGHTBOX.find('.evo_alert_yes').on('click', function() {
620		            options.on_yes(LIGHTBOX); // Execute Yes callback
621		            LIGHTBOX.evo_lightbox_close(); // Close the lightbox
622		            removeKeyListeners(); // Remove key listeners
623		        });
624
625		        LIGHTBOX.find('.evo_alert_no').on('click', function() {
626		            options.on_no(LIGHTBOX); // Execute No callback
627		            LIGHTBOX.evo_lightbox_close(); // Close the lightbox
628		            removeKeyListeners(); // Remove key listeners
629		        });
630
631		        // Keypress handler function
632		        function handleKeyPress(event) {
633		            if (event.key === 'Escape') { // Esc key
634		                options.on_no(LIGHTBOX); // Execute No callback
635		                LIGHTBOX.remove(); // Close the lightbox
636		                removeKeyListeners(); // Remove key listeners
637		            } else if (event.key === 'Enter') { // Enter key
638		                options.on_yes(LIGHTBOX); // Execute Yes callback
639		                LIGHTBOX.remove(); // Close the lightbox
640		                removeKeyListeners(); // Remove key listeners
641		            }
642		        }
643
644		        // Add keypress listener
645		        $(document).on('keydown', handleKeyPress);
646
647		        // Function to remove key listeners
648		        function removeKeyListeners() {
649		            $(document).off('keydown', handleKeyPress);
650		        }
651
652		        // Ensure key listeners are removed when lightbox is closed manually (e.g., via close button)
653		        LIGHTBOX.find('.evolb_close_btn').on('click', function() {
654		            removeKeyListeners();
655		        });
656		    }, 350); // Delay to ensure lightbox is fully rendered
657		}
658		$.fn.evo_lightbox_open = function (opt ){
659
660			var OO = this.evo_process_ajax_params( opt );
661			
662			var _lbdata = OO.lbdata;
663			var _adata = OO.adata;
664			var _populate_id = OO._populate_id;
665
666			///console.log(OO);
667
668			// check if required values missing for lightbox
669			if( !('class' in _lbdata) || _lbdata.class == '' ) return;
670
671
672			const fl_footer = _adata.end == 'client' ? '<div class="evolb_footer"></div>' :'';
673
674			// create lightbox HTML
675				var __lb_size = _lbdata.size === undefined ? '' : _lbdata.size;
676
677				var html = '<div class="evo_lightbox '+_lbdata.class+' '+_adata.end+' '+ ( _lbdata.additional_class !== undefined ? _lbdata.additional_class :'') +'" data-lbc="'+_lbdata.class+'"><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>';
678				if( _lbdata.title !== undefined ) html += '<p class="evolb_title">' + _lbdata.title + '</p>';
679				html += '<span class="evolb_close_btn evolbclose "><i class="fa fa-xmark"><i></span></div><div class="evolb_content '+ _lbdata.padding +'"></div><p class="message"></p>'+fl_footer+'</div></div></div></div>';
680
681			$('#evo_lightboxes').append( html );	
682			var LIGHTBOX = $('.evo_lightbox.'+ _lbdata.class );		
683
684			
685			// Open lightbox on page
686				setTimeout( function(){ 
687					$('#evo_lightboxes').show();
688					LIGHTBOX.addClass('show');	
689					$('body').addClass('evo_overflow');
690					$('html').addClass('evo_overflow');
691				},300);
692
693				// show loading animation
694				LIGHTBOX.evo_lightbox_show_open_animation(OO);
695
696
697			// Load content locally from DOM
698			    if (_lbdata.content_id != '') {
699			        var content = $('#' + _lbdata.content_id).html();
700			        LIGHTBOX.find('.evolb_content').html(content);
701			    }
702			    if (_lbdata.content != '') {
703			        LIGHTBOX.find('.evolb_content').html(_lbdata.content);
704			    }
705
706			// run ajax to load content for the lightbox inside
707				if( 'a' in _adata  && _adata.a != ''){ // @4.7.2
708					LB.evo_admin_get_ajax( OO );
709				}
710				
711			// load content from a AJAX file			
712				if( 'url' in _adata && _adata.url != '' ){
713					$.ajax({
714						beforeSend: function(){},
715						url:	OO.ajax_url,
716						success:function(data){
717							LIGHTBOX.find('.evolb_content').html( data);							
718						},complete:function(){}
719					});
720				}
721			
722			$('body').trigger('evo_lightbox_processed', [ OO, LIGHTBOX]);
723		}
724
725		$.fn.evo_lightbox_close = function(opt) {
726		    if (!this.hasClass('show')) return;
727
728		    const defaults = { delay: 500, remove_from_dom: true };
729		    const OO = $.extend({}, defaults, opt);
730		    const hideDelay = parseInt(OO.delay);
731		    const completeClose = this.parent().find('.evo_lightbox.show').length === 1;
732
733		    // Remove 'show' class with delay if needed
734		    hideDelay > 500 ? setTimeout(() => this.removeClass('show'), hideDelay - 500) : this.removeClass('show');
735
736		    // Final cleanup after delay
737		    setTimeout(() => {
738		        if (completeClose) {
739		            $('body, html').removeClass('evo_overflow');
740		        }
741		        if (OO.remove_from_dom) this.remove();
742		    }, hideDelay);
743		};
744
745
746		// Other LB functions
747			$.fn.evo_lightbox_populate_content = function(opt){
748				LB = this;
749				var defaults = { 
750					'content':'',
751				}; var OO = $.extend({}, defaults, opt);
752				LB.find('.evolb_content').html( OO.content );
753			}
754			
755			$.fn.evo_lightbox_show_msg = function(opt){
756				LB = this;
757				var defaults = { 
758					'type':'good',
759					'message':'',
760					'hide_message': false,// hide message after some time pass time or false
761					'hide_lightbox': false, // hide lightbox after some time of false
762				}; var OO = $.extend({}, defaults, opt);
763				LB.find('.message').removeClass('bad good').addClass( OO.type ).html( OO.message ).fadeIn();
764
765				if( OO.hide_message ) setTimeout(function(){  LB.evo_lightbox_hide_msg() }, OO.hide_message );
766
767				if( OO.hide_lightbox ) LB.evo_lightbox_close({ delay: OO.hide_lightbox });
768			}
769			$.fn.evo_lightbox_hide_msg = function(opt){
770				LB = this;
771				LB.find('p.message').hide();
772			}
773
774
775			// add preload animations to lightbox u4.6
776			$.fn.evo_lightbox_show_open_animation = function(opt){
777				LB = this;
778				var defaults = { 
779					'animation_type':'initial', // animation type initial or saving
780					'preload_temp_key': 'init', // 4.6 passed on preload template key
781					'end':'admin',
782				};
783				var OO = $.extend({}, defaults, opt);
784
785				if( OO.animation_type == 'initial'){
786
787					passed_data = (  typeof evo_admin_ajax_handle !== 'undefined') ? evo_admin_ajax_handle: evo_general_params;
788
789					//console.log( passed_data);
790
791					html = passed_data.html.preload_general;
792					if( OO.preload_temp_key != 'init') html = passed_data.html[ OO.preload_temp_key ];
793					LB.find('.evolb_content').html( html );
794				}
795
796				if( OO.animation_type == 'saving')
797					LB.find('.evolb_content').addClass('loading');
798			}
799
800	// Get Ajax url @since 4.4 @u 4.5.5
801		$.fn.evo_get_ajax_url = function(opt){
802			var defaults = { 
803				a:'', // action key
804				e:'client', // end
805				type: 'ajax'};
806			var OO = $.extend({}, defaults, opt);
807
808			// end point url
809			if( OO.type == 'endpoint'){
810				var evo_ajax_url = ( OO.e == 'client' || typeof evo_general_params !== 'undefined' )? 
811					evo_general_params.evo_ajax_url : evo_admin_ajax_handle.evo_ajax_url;
812				return  evo_ajax_url.toString().replace( '%%endpoint%%', OO.a );
813			// rest api url
814			}else if( OO.type == 'rest' ){
815				var evo_ajax_url = ( OO.e == 'client' || typeof evo_general_params !== 'undefined')? 
816					evo_general_params.rest_url : evo_admin_ajax_handle.rest_url;
817					//console.log(evo_ajax_url);
818					//console.log(OO);
819				return  evo_ajax_url.toString().replace( '%%endpoint%%', OO.a );
820			}else{
821				action_add = OO.a != '' ? '?action='+ OO.a: '';
822				return ( OO.e == 'client' || typeof evo_general_params !== 'undefined') ? 
823					evo_general_params.ajaxurl + action_add : evo_admin_ajax_handle.ajaxurl + action_add;
824			}	
825		}
826
827	// loading animations @2.3
828		$.fn.evo_start_loading = function( opt ){
829			var defaults = { type:'1'};
830			var OPT = $.extend({}, defaults, opt);
831			var el = this;
832
833			if( OPT.type == '1') el.addClass('evoloading loading');
834			if( OPT.type == '2') el.addClass('evoloading_2');
835		}
836		$.fn.evo_stop_loading = function( opt ){
837			var el = this;
838			var defaults = { type:'1'};
839			var OPT = $.extend({}, defaults, opt);
840
841			if( OPT.type == '1') el.removeClass('evoloading loading');
842			if( OPT.type == '2') el.removeClass('evoloading_2');
843		}
844		$.fn.evo_lightbox_start_inloading = function(opt){
845			LB = this;
846			LB.find('.evolb_content').addClass('loading');
847		}
848		$.fn.evo_lightbox_stop_inloading = function(opt){
849			LB = this;
850			LB.find('.evolb_content').removeClass('loading');
851		}
852		
853	// Count down	// @+ 4.5
854		$.fn.evo_countdown_get = function(opt){
855			var defaults = { gap:'', endutc: ''};
856			var OPT = $.extend({}, defaults, opt);
857			var gap = OPT.gap;
858
859			// if gap not provided use endutc
860			if( gap == '' ){				
861				var Mnow = moment().utc();
862				var M = moment();
863				M.set('millisecond', OPT.endutc );
864
865				gap = OPT.endutc - Mnow.unix();
866			}
867			
868			// if negative gap
869			if( gap < 0){
870				return {
871					'd': 0,
872					'h':0,
873					'm':0,
874					's':0
875				}; 
876			}
877		
878			distance = ( gap * 1000);
879
880			var days = Math.floor(distance / (1000 * 60 * 60 * 24));
881			var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
882			var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
883			var seconds = Math.floor((distance % (1000 * 60)) / 1000);
884
885			minutes = minutes<10? '0'+minutes : minutes;
886			seconds = seconds<10? '0'+seconds : seconds;
887
888			return {
889				'd': days,
890				'h':hours,
891				'm':minutes,
892				's':seconds
893			}; 
894		};
895		$.fn.evo_countdown = function(opt){
896			var defaults = { S1:''};
897			var OPT = $.extend({}, defaults, opt);
898			var el = $(this);
899
900			const day_text = ( el.data('d') !== undefined && el.data('d') != '' )? el.data('d'):'Day';
901			const days_text = ( el.data('ds') !== undefined && el.data('ds') != '' )? el.data('ds'):'Days';
902
903			// intial run
904			//var gap = parseInt(el.data('gap'));
905			var duration = el.data('dur');
906			var endutc = parseInt(el.data('endutc'));
907			var text = el.data('t');
908			
909			if(text === undefined) text = '';
910
911			if( el.hasClass('evo_cd_on')) return;
912
913			// get gap using end time utc
914				var Mnow = moment().utc();
915				var M = moment();
916				M.set('millisecond', OPT.endutc );
917
918				gap = endutc - Mnow.unix();
919
920
921			if( gap > 0 ){
922
923				// initial
924				dd = el.evo_countdown_get({ 'gap': gap });
925				
926				el.html( ( dd.d>0 ? dd.d + ' ' + ( dd.d >1 ? days_text: day_text ) + " "  :'') + dd.h + ":" + dd.m +':'+ dd.s +'  '+text );
927				
928				el.data('gap', ( gap - 1)  );	// save new gap value
929				el.addClass('evo_cd_on');
930				
931				// set intervals
932				var CD = setInterval(function(){
933					
934					gap = el.data('gap'); // get gap for this cycle
935					duration = el.data('dur');	
936
937					const bar_elm = el.closest('.evo_event_progress').find('.evo_ep_bar');						
938					if( gap > 0 ){
939
940						// increase bar width if exists
941						if( duration !== undefined && bar_elm.length){
942							perc = ( (duration - gap)/ duration ) * 100;
943							bar_elm.find('b').css('width',perc+'%');							
944						}
945						
946						dd = el.evo_countdown_get({ 'gap': gap });	
947
948						el.html( ( dd.d>0 ? dd.d + ' '  + ( dd.d >1 ? days_text: day_text ) + " ":'') + dd.h + ":" + dd.m +':'+ dd.s +' '+text );
949						el.data('gap', ( gap - 1)  );						
950
951					}else{
952
953						const expire_timer_action = el.data('exp_act');
954
955						// perform ajax task after expiration
956						if(expire_timer_action !== undefined){
957							$('body').trigger('runajax_refresh_now_cal',[ 
958								el , 
959								el.data('n'),
960							]);
961						}
962
963						const _complete_text = el.evo_get_txt({V:'event_completed'});
964
965						// live now text
966						if(bar_elm.length){
967							bar_elm.addClass('evo_completed');
968							//el.siblings('.evo_ep_pre').html( _complete_text );
969						}
970
971
972						// event tag & live elements
973						if( el.closest('.evcal_desc').length){
974							el.closest('.evcal_desc').find('.eventover').html( _complete_text);
975							el.closest('.evcal_desc').find('.evo_live_now').remove();
976						}
977
978						// event card
979						if( el.closest('.eventon_list_event').length){
980							el.closest('.eventon_list_event').find('span.evo_live_now').hide();
981						}
982
983						el.html('');
984						clearInterval(CD);
985					}
986
987				},1000);
988			}else{
989				clearInterval(CD);
990			}
991		};	
992	
993	// Handlebar process template data into html
994		$.fn.evo_HB_process_template = function(opt){
995			var defaults = { TD:'', part:''}
996			var OPT = $.extend({}, defaults, opt);
997
998			BUS = $('#evo_global_data').data('d');
999						
1000			template = Handlebars.compile( BUS.temp[ OPT.part ] );
1001			return template( OPT.TD );
1002		}
1003
1004	// Date range and events
1005		// Date range and events - from webpage
1006		$.fn.evo_cal_events_in_range = function(opt){
1007			var defaults = { S:'', E:'', 
1008				hide: true, 
1009				closeEC:true,
1010				showEV: false, // show events
1011				showEVL: false, // show events list
1012				showAllEvs: false // show all events regardless of the range
1013			};
1014			var OPT = $.extend({}, defaults, opt);
1015			var CAL = $(this);
1016
1017			eJSON = CAL.find('.evo_cal_events').data('events');
1018
1019			R = {};
1020			html = '';
1021			json = {};
1022
1023			show = 0;
1024
1025			// using events JSON data
1026			if( eJSON && eJSON.length > 0){
1027				$.each(eJSON, function(ind, ED){
1028					eO = CAL.find('#event_'+ ED._ID);
1029					if(eO === undefined || eO.length==0) return;
1030
1031					if(OPT.hide)	eO.hide(); // pre hide
1032					this_show = false;
1033
1034					// month long or year long events
1035					if( ED.month_long || ED.year_long ){
1036						this_show = true;
1037
1038					}else{
1039						if(CAL.evo_is_in_range({
1040							'S': OPT.S,	'E': OPT.E,	'start': ED.event_start_unix ,	'end':ED.event_end_unix 
1041						})){						
1042							this_show = true;
1043						} 
1044					}
1045
1046					if( OPT.showAllEvs) this_show = true;
1047					
1048					if( this_show){	
1049						// show event
1050						if( OPT.showEV) eO.show();
1051
1052						// close open event cards
1053						if(OPT.closeEC && SC.evc_open == 'no') eO.find('.event_description').hide().removeClass('open');
1054
1055						html += eO[0].outerHTML;
1056						json[ ED._ID] = ED;
1057						show++;	
1058					} 
1059				});
1060			}else{	
1061				// get all the events in the events list
1062				var cal_events = CAL.find('.eventon_list_event');
1063
1064				cal_events.each(function(index, elm){
1065					var ED = $(elm).evo_cal_get_basic_eventdata();
1066					if( !ED) return;
1067
1068					if(OPT.hide)	$(elm).hide(); // pre hide
1069					this_show = false;
1070
1071					// month long or year long events
1072					if( $(elm).hasClass('month_long') || $(elm).hasClass('year_long') ){
1073						this_show = true;
1074
1075					}else{
1076						if(CAL.evo_is_in_range({
1077							'S': OPT.S,	'E': OPT.E,	'start': ED.event_start_unix ,	'end':ED.event_end_unix 
1078						})){						
1079							this_show = true;
1080						} 
1081					}
1082
1083					if( OPT.showAllEvs) this_show = true;
1084					
1085					if( this_show){	
1086						// show event
1087						if( OPT.showEV) $(elm).show();
1088
1089						// close open event cards
1090						if(OPT.closeEC && SC.evc_open == 'no') 
1091							$(elm).find('.event_description').hide().removeClass('open');
1092
1093						html += $(elm)[0].outerHTML;
1094						json[ ED.uID ] = ED;
1095						show++;	
1096					} 
1097				});
1098			}
1099
1100
1101			// No events
1102			if( OPT.showEV){
1103
1104				no_event_content = CAL.evo_get_global({S1: 'html', S2:'no_events'});
1105
1106				tx_noevents = CAL.evo_get_txt({V:'no_events'});
1107				EL = CAL.find('.eventon_events_list');
1108				EL.find('.eventon_list_event.no_events').remove();
1109				if( show == 0 )
1110					EL.append('<div class="eventon_list_event no_events">'+ no_event_content +'</div>');
1111			}
1112
1113			// if show events list
1114			if( OPT.showEVL){
1115				CAL.find('.eventon_events_list').show().removeClass('evo_hide');
1116			}
1117
1118			R['count'] = show;
1119			R['html'] = html;
1120			R['json'] = json;
1121
1122			return R;
1123		}
1124
1125	// check if an event is in the given date range
1126		$.fn.evo_is_in_range = function(opt){
1127			var defaults = { S:'', E:'', start:'',end:''}
1128			var OPT = $.extend({}, defaults, opt);
1129
1130			S = parseInt(OPT.S);
1131			E = parseInt(OPT.E);
1132			start = parseInt(OPT.start);
1133			end = parseInt(OPT.end);
1134
1135			return (
1136				( start <= S && end >= E ) ||
1137				( start <= S && end >= S && end <= E) ||
1138				( start <= E && end >= E ) ||
1139				( start >= S && end <= E )
1140			) ? true: false;
1141		}
1142		$.fn.evo_cal_hide_events = function(){
1143			CAL = $(this);
1144			CAL.find('.eventon_list_event').hide();
1145		}
1146
1147	// get event data basics from html event on page 
1148	// ~@version 4.0.3
1149		$.fn.evo_cal_get_basic_eventdata = function(){
1150			var ELM = $(this);
1151
1152			var _time = ELM.data('time');
1153			if( _time === undefined ) return false;
1154
1155			const time = _time.split('-');
1156			const ri = ELM.data('ri').replace('r','');
1157			const eID = ELM.data('event_id');
1158
1159			var _event_title = ELM.find('.evcal_event_title').text();
1160			_event_title = _event_title.replace(/'/g, '&apos;');
1161
1162
1163			var RR = {
1164				'uID': eID + '_' + ri,
1165				'ID': eID ,
1166				'event_id': eID ,
1167				'ri': ri,
1168				'event_start_unix': parseInt(time[0]),
1169				'event_end_unix': parseInt(time[1]),
1170				'ux_val': ELM.find('.evcal_list_a').data('ux_val'),
1171				'event_title': _event_title,
1172				'hex_color': ELM.data('colr'),
1173				'hide_et': ELM.hasClass('no_et') ? 'y':'n', // hide endtime
1174				'evcal_event_color': ELM.data('colr'),
1175				'unix_start': parseInt(time[0]),// @4.5.7
1176				'unix_end': parseInt(time[1]),// @4.5.7
1177			};
1178
1179			// event type
1180			RR['ett1'] = {};
1181			ELM.find('.evoet_eventtypes.ett1 .evoetet_val').each(function(){
1182				RR['ett1'][ $(this).data('id')] = $(this).data('v');
1183			});
1184
1185			// since 4.3.5
1186			const eventtop_data = ELM.find('.evoet_data').data('d');
1187
1188			// location
1189			if(eventtop_data && 'loc.n' in eventtop_data && eventtop_data['loc.n'] != ''){
1190				RR['location'] = eventtop_data['loc.n'];
1191			}
1192
1193			// organizer
1194			if(eventtop_data && 'orgs' in eventtop_data && eventtop_data.orgs !== undefined ){
1195				var org_names = '';
1196				$.each(eventtop_data.orgs, function(index, value){
1197					org_names += value +' ';
1198				});
1199				RR['organizer'] = org_names;
1200			}
1201
1202			// event image
1203			if( ELM.find('.evo_event_schema').length > 0){
1204				imgObj = ELM.find('.evo_event_schema').find('meta[itemprop=image]').attr('content');
1205				RR['image_url'] = imgObj;
1206			}
1207
1208			// event tags @s 4.5.2
1209			if( eventtop_data && 'tags' in eventtop_data && eventtop_data.tags !== undefined ){
1210				//console.log(eventtop_data.tags);
1211				RR['event_tags'] = eventtop_data.tags;
1212			}
1213
1214
1215			return RR;
1216
1217		}
1218
1219	// localize time @2.5
1220		$.fn.evo_cal_localize_time = function(){			
1221			this.find('.evo_loct_inprocess').each(function(e){	$(this).evo_localize_time();	});
1222		}
1223		$.fn.evo_localize_time = function( ){
1224			
1225			const eventcard = this.closest('.eventon_list_event');
1226		    const hideEnd = eventcard.hasClass('no_et');
1227		    const textLocal = evo_general_params.text.local_time;
1228
1229		    eventcard.find('.evo_mytime').each(function() {
1230		    	const $el = $(this);
1231		        const isEventCard = $el.hasClass('evocard');
1232		        const { times, __f: fullFormat, __tf: timeOnlyFormat, tzo: utcOffset = 0 } = $el.data();
1233		        const [start, end] = times.split('-').map(Number);
1234
1235		        const startMoment = moment.unix(start).utc().local();
1236		        const endMoment = moment.unix(end).utc().local();
1237		        const sameMonth = startMoment.format('YYYY/M') === endMoment.format('YYYY/M');
1238		        const sameDay = sameMonth && startMoment.format('DD') === endMoment.format('DD');
1239
1240		        const startText = startMoment.format(fullFormat);
1241		        const endText = endMoment.format(sameDay ? timeOnlyFormat : fullFormat);
1242		        const html = `${startText}${hideEnd ? '' : ' - ' + endText}` + 
1243		                     (isEventCard ? `<span class='evomarl5'>(${textLocal})</span>` : '');
1244
1245		        $el.replaceWith(`<span class='evo_newmytime'>${html}</span>`);
1246		    });
1247		}	
1248
1249	// DATE time functions @+2.8		
1250		$.fn.evo_day_in_month = function(opt){
1251			var defaults = { M:'', Y:''}
1252			var OPT = $.extend({}, defaults, opt);
1253
1254			return new Date(OPT.Y, OPT.M, 0).getDate();
1255		}
1256		$.fn.evo_get_day_name_index = function(opt){
1257			var defaults = { M:'', Y:'', D:''}
1258			var OPT = $.extend({}, defaults, opt);
1259
1260			//return moment(OPT.Y+'-'+OPT.M+'-'+OPT.D).utc().day();
1261
1262			return new Date(  Date.UTC(OPT.Y, OPT.M-1, OPT.D) ).getUTCDay();
1263		}
1264
1265	// LIGHTBOX
1266	// page Lightbox functions @+2.8
1267	// append to the lightbox main class name .evo_lightbox
1268		
1269		// Legacy
1270			$.fn.evo_prepare_lb = function(){
1271				$(this).find('.evo_lightbox_body').html('');
1272			}
1273			$.fn.evo_show_lb = function(opt){
1274				var defaults = { RTL:'', calid:''}
1275				var OPT = $.extend({}, defaults, opt);
1276
1277				$(this).addClass('show '+ OPT.RTL).attr('data-cal_id', OPT.calid);
1278				$('body').trigger('evolightbox_show');
1279			}
1280			$.fn.evo_append_lb = function(opt){
1281				var defaults = { C:'', CAL:''}
1282				var OPT = $.extend({}, defaults, opt);
1283				$(this).find('.evo_lightbox_body').html( OPT.C);
1284
1285				if(  OPT.CAL!= '' && OPT.CAL !== undefined && OPT.CAL.hasClass('color')){
1286					const LIST = $(this).find('.eventon_events_list');
1287					if( LIST.length>0){
1288						LIST.find('.eventon_list_event').addClass('color');
1289					}				
1290				}
1291			}
1292
1293	// event image gallery LITE version 2.5
1294		$.fn.eventon_process_main_ft_img = function(OO){
1295			const IMG = this;
1296			var img_sty = 'def';
1297			if( IMG.hasClass('fit') ) img_sty = 'fit';
1298			if( IMG.hasClass('full') ) img_sty = 'full';
1299			
1300			// Initialize box dimensions
1301		    let box_width =  IMG.width();
1302		    let box_height =  IMG.height();
1303			
1304			// Ensure valid box dimensions
1305		    box_width = box_width > 0 ? box_width : 100; // Fallback to prevent errors
1306		    box_height = box_height > 0 ? box_height : 100;
1307			
1308
1309			 // Get image dimensions from data attributes
1310		    const img_width = parseInt(IMG.data('w')) || 100; // Fallback to prevent division by zero
1311		    const img_height = parseInt(IMG.data('h')) || 100;
1312		    const img_ratio = img_height / img_width; // Image aspect ratio
1313					
1314			let new_width, new_height;
1315			
1316			// Handle 'fit' style 
1317			if( IMG.hasClass('fit')){
1318				// Scale to fit within box while maintaining aspect ratio
1319		        new_width = box_height / img_ratio;
1320				new_height = box_height;
1321				if( new_width > box_width ){// width is wider than box
1322
1323					if( img_ratio <1 ){
1324						new_width = box_width; new_height = img_ratio * new_width;
1325					}else{
1326						new_height = box_height; new_width = new_height / img_ratio;
1327					}
1328				} 	
1329					
1330				IMG.find('span').css({'width':new_width, 'height': new_height} );
1331			}
1332
1333			// full style
1334			if( IMG.hasClass('full')){
1335				new_height = img_ratio * box_width;
1336				new_width = box_width;
1337				IMG.find('span').css({'width':new_width, 'height': new_height} );
1338				IMG.css({'height': new_height} );
1339			}
1340
1341			//console.log(box_width +' '+img_width+' '+new_width);
1342		}
1343
1344		
1345
1346	// Shortcodes
1347		// update shortcode values from filter changes
1348		$.fn.evo_update_sc_from_filters = function(){
1349			var ev_cal = $(this); 	
1350			SC = ev_cal.find('.evo_cal_data').data('sc');		
1351
1352			var filter_section = ev_cal.find('.eventon_filter_line').first();
1353			
1354			filter_section.find('.eventon_filter').each(function(index){
1355				O = $(this);
1356				var filter_val = O.data('filter_val');	
1357				filter_val = filter_val == ''? 'NOT-all': filter_val;				
1358
1359				ADD = (O.data('fl_o') && O.data('fl_o') != 'IN')? O.data('fl_o')+'-': '';
1360				SC[ O.data('filter_field') ] = ADD + filter_val;
1361			});	
1362
1363			ev_cal.find('.evo_cal_data').data( 'sc', SC );
1364		}
1365		
1366		// get shortcodes from evo bottom
1367		$.fn.evo_shortcode_data = function(){			
1368			var ev_cal = $(this);
1369			return ev_cal.find('.evo_cal_data').data('sc');			
1370		}
1371
1372		// get shortcode single value
1373		$.fn.evo_get_sc_val = function(opt){
1374			var defaults = {	F:''}
1375			var OPT = $.extend({}, defaults, opt);
1376			var ev_cal = $(this); 
1377
1378			if(OPT.F=='') return false;
1379			SC = ev_cal.find('.evo_cal_data').data('sc');
1380
1381			if(!(SC[ OPT.F])) return false;
1382			return SC[ OPT.F];
1383		}
1384		// UPDATE Single value
1385		$.fn.evo_update_cal_sc = function(opt){
1386			var defaults = {
1387				F:'', V:''
1388			}
1389			var OPT = $.extend({}, defaults, opt);
1390			var ev_cal = $(this); 
1391			SC = ev_cal.find('.evo_cal_data').data('sc');
1392
1393			SC[ OPT.F ] = OPT.V;
1394
1395			ev_cal.find('.evo_cal_data').data( 'sc', SC );
1396		}
1397		// UPDATE all shortcode values
1398		$.fn.evo_update_all_cal_sc = function(opt){
1399			var defaults = {SC:''}
1400			var OPT = $.extend({}, defaults, opt);
1401			var CAL = $(this);
1402			CAL.find('.evo_cal_data').data( 'sc', OPT.SC );
1403		}
1404
1405	// OTHERS
1406		// hex colors // @+2.8
1407		$.fn.evo_is_hex_dark = function(opt){
1408			var defaults = { hex:'808080'}
1409			var OPT = $.extend({}, defaults, opt);
1410
1411			hex = OPT.hex;
1412
1413			var c = hex.replace('#','');
1414			var is_hex = typeof c === 'string' && c.length === 6 && !isNaN(Number('0x' + c));
1415
1416			if(is_hex){	
1417				var values = c.split('');
1418				r = parseInt(values[0].toString() + values[1].toString(), 16);
1419			    g = parseInt(values[2].toString() + values[3].toString(), 16);
1420			    b = parseInt(values[4].toString() + values[5].toString(), 16);
1421			}else{
1422				var vals = c.substring(c.indexOf('(') +1, c.length -1).split(', ');
1423				var r = vals[0]  // extract red
1424				var g = vals[1];  // extract green
1425				var b = vals[2];
1426			}
1427
1428			var luma = ((r * 299) + (g * 587) + (b * 114)) / 1000; // per ITU-R BT.709
1429
1430			return luma>155? true:false;
1431		}
1432
1433		// get rgb from hex code @4.5
1434			$.fn.evo_rgb_process = function(opt){
1435				var defaults = { data:'808080',type:'rgb', method:'rgb_to_val'}
1436				var opt = $.extend({}, defaults, opt);
1437
1438				const color = opt.data;
1439
1440				// RGB => hex
1441				if( opt.method == 'rgb_to_hex'){
1442					if(color == '1'){
1443						return;
1444					}else{
1445						if(color !=='' && color){
1446							rgb = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
1447							
1448							return "#" +
1449							("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
1450							("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
1451							("0" + parseInt(rgb[3],10).toString(16)).slice(-2);
1452						}
1453					}
1454				}
1455
1456				// RGB => rgb val
1457				if( opt.method == 'rgb_to_val'){
1458					if( opt.type == 'hex'){
1459						var rgba = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);	
1460						var rgb = new Array();
1461						rgb['r']= parseInt(rgba[1], 16);			
1462						rgb['g']= parseInt(rgba[2], 16);			
1463						rgb['b']= parseInt(rgba[3], 16);
1464						
1465					}else{
1466						rgb = color;
1467					}
1468					
1469					return parseInt((rgb['r'] + rgb['g'] + rgb['b'])/3);
1470				}				
1471			}
1472			
1473		// Other data
1474			$.fn.evo_get_OD = function(){			
1475				var ev_cal = $(this);
1476				return ev_cal.find('.evo_cal_data').data('od');			
1477			}
1478
1479	// return all filter values for given calendar -- DEP 2.8
1480		$.fn.evoGetFilters = function(){
1481
1482			var ev_cal = $(this); 
1483			var evodata = ev_cal.find('.evo-data');
1484			
1485			var filters_on = ( evodata.attr('data-filters_on')=='true')?'true':'false';
1486			
1487			// creat the filtering data array if exist
1488			if(filters_on =='true'){
1489				var filter_section = ev_cal.find('.eventon_filter_line');
1490				var filter_array = [];
1491				
1492
1493				filter_section.find('.eventon_filter').each(function(index){
1494					var filter_val = $(this).attr('data-filter_val');
1495					
1496					if(filter_val !='all'){
1497						var filter_ar = {};
1498						filter_ar['filter_type'] = $(this).attr('data-filter_type');
1499						filter_ar['filter_name'] = $(this).attr('data-filter_field');
1500
1501						if($(this).attr('data-fl_o')=='NOT'){
1502							filter_ar['filter_op']='NOT IN';
1503						}
1504						filter_ar['filter_val'] = filter_val;
1505						filter_array.push(filter_ar);
1506					}
1507				});		
1508			}else{
1509				var filter_array ='';
1510			}			
1511			return filter_array;
1512		}
1513		
1514
1515		// get evo data for a given calendar
1516		$.fn.evo_getevodata = function(){
1517
1518			var ev_cal = $(this);
1519			var evoData = {};
1520			
1521			ev_cal.find('.evo-data').each(function(){
1522				$.each(this.attributes, function(i, attrib){
1523					var name = attrib.name;
1524					if(attrib.name!='class' && attrib.name!='style' ){
1525						name__ = attrib.name.split('-');
1526						evoData[name__[1]] = attrib.value;	
1527					}
1528				});
1529			});	
1530
1531			return evoData;
1532		}
1533
1534	// eventon loading functions
1535	// v 2.4.5
1536		$.fn.evo_loader_animation = function(opt){
1537			var defaults = {
1538				direction:'start'
1539			}
1540			var OPT = $.extend({}, defaults, opt);
1541
1542			if(OPT.direction == 'start'){
1543				$(this).find('#eventon_loadbar').slideDown();
1544			}else{
1545				$(this).find('#eventon_loadbar').slideUp();
1546			}
1547		}
1548
1549	// DEPRECATED functions
1550		$.fn.evo_item_shortcodes = function(){			
1551			var OBJ = $(this);
1552			var shortcode_array ={};			
1553			OBJ.each(function(){	
1554				$.each(this.attributes, function(i, attrib){
1555					var name = attrib.name;
1556					if(attrib.name!='class' && attrib.name!='style' && attrib.value !=''){
1557						name__ = attrib.name.split('-');
1558						shortcode_array[name__[1]] = attrib.value;	
1559					}
1560				});
1561			});
1562			return shortcode_array;
1563		}
1564		$.fn.evo_shortcodes = function(){			
1565			var ev_cal = $(this);
1566			var shortcode_array ={};
1567					
1568			ev_cal.find('.cal_arguments').each(function(){
1569				$.each(this.attributes, function(i, attrib){
1570					var name = attrib.name;
1571					if(attrib.name!='class' && attrib.name!='style' && attrib.value !=''){
1572						name__ = attrib.name.split('-');
1573						shortcode_array[name__[1]] = attrib.value;	
1574					}
1575				});
1576			});	
1577			return shortcode_array;
1578		}
1579		
1580
1581}(jQuery));

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.