PageSourceSearch

https://cbsrwanda.org/js/theme.js

js cbsrwanda.org collected 2026-10-08 20:34:06 UTC 255,581 bytes, 9,515 lines download raw bytes

1// Theme
2window.theme = {};
3
4// Theme Common Functions
5window.theme.fn = {
6
7    getOptions(opts) {
8
9        if (typeof(opts) == 'object') {
10
11            return opts;
12
13        } else if (typeof(opts) == 'string') {
14
15            try {
16                return JSON.parse(opts.replace(/'/g, '"').replace(';', ''));
17            } catch (e) {
18                return {};
19            }
20
21        } else {
22
23            return {};
24
25        }
26
27    },
28
29    execPluginFunction(functionName, context) {
30        const args = Array.prototype.slice.call(arguments, 2);
31        const namespaces = functionName.split(".");
32        const func = namespaces.pop();
33
34        for (let i = 0; i < namespaces.length; i++) {
35            context = context[namespaces[i]];
36        }
37
38        return context[func](...args);
39    },
40
41    intObs(selector, functionName, intObsOptions, alwaysObserve) {
42        const $el = document.querySelectorAll(selector);
43        let intersectionObserverOptions = {
44            rootMargin: '0px 0px 200px 0px'
45        };
46
47        if (Object.keys(intObsOptions).length) {
48            intersectionObserverOptions = $.extend(intersectionObserverOptions, intObsOptions);
49        }
50
51        const observer = new IntersectionObserver(entries => {
52            for (const entry of entries) {
53                if (entry.intersectionRatio > 0) {
54                    if (typeof functionName === 'string') {
55                        const func = Function('return ' + functionName)();
56                    } else {
57                        const callback = functionName;
58
59                        callback.call($(entry.target));
60                    }
61
62                    // Unobserve
63                    if (!alwaysObserve) {
64                        observer.unobserve(entry.target);
65                    }
66
67                }
68            }
69        }, intersectionObserverOptions);
70
71        $($el).each(function() {
72            observer.observe($(this)[0]);
73        });
74    },
75
76    intObsInit(selector, functionName) {
77        const $el = document.querySelectorAll(selector);
78        const intersectionObserverOptions = {
79            rootMargin: '200px'
80        };
81
82        const observer = new IntersectionObserver(entries => {
83            for (const entry of entries) {
84                if (entry.intersectionRatio > 0) {
85                    const $this = $(entry.target);
86                    let opts;
87
88                    const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
89                    if (pluginOptions)
90                        opts = pluginOptions;
91
92                    theme.fn.execPluginFunction(functionName, $this, opts);
93
94                    // Unobserve
95                    observer.unobserve(entry.target);
96                }
97            }
98        }, intersectionObserverOptions);
99
100        $($el).each(function() {
101            observer.observe($(this)[0]);
102        });
103    },
104
105    dynIntObsInit(selector, functionName, pluginDefaults) {
106        const $el = document.querySelectorAll(selector);
107
108        $($el).each(function() {
109            const $this = $(this);
110            let opts;
111
112            const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
113            if (pluginOptions)
114                opts = pluginOptions;
115
116            const mergedPluginDefaults = theme.fn.mergeOptions(pluginDefaults, opts);
117
118            const intersectionObserverOptions = {
119                rootMargin: theme.fn.getRootMargin(functionName, mergedPluginDefaults),
120                threshold: 0
121            };
122
123            if (!mergedPluginDefaults.forceInit) {
124
125                const observer = new IntersectionObserver(entries => {
126                    for (const entry of entries) {
127                        if (entry.intersectionRatio > 0) {
128                            theme.fn.execPluginFunction(functionName, $this, mergedPluginDefaults);
129
130                            // Unobserve
131                            observer.unobserve(entry.target);
132                        }
133                    }
134                }, intersectionObserverOptions);
135
136                observer.observe($this[0]);
137
138            } else {
139                theme.fn.execPluginFunction(functionName, $this, mergedPluginDefaults);
140            }
141        });
142    },
143
144    getRootMargin(plugin, { accY }) {
145        switch (plugin) {
146            case 'themePluginCounter':
147                return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
148                break;
149
150            case 'themePluginAnimate':
151                return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
152                break;
153
154            case 'themePluginIcon':
155                return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
156                break;
157
158            case 'themePluginRandomImages':
159                return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
160                break;
161
162            default:
163                return '0px 0px 200px 0px';
164                break;
165        }
166    },
167
168    mergeOptions(obj1, obj2) {
169        const obj3 = {};
170
171        for (var attrname in obj1) {
172            obj3[attrname] = obj1[attrname];
173        }
174        for (var attrname in obj2) {
175            obj3[attrname] = obj2[attrname];
176        }
177
178        return obj3;
179    },
180
181    execOnceTroughEvent($el, event, callback) {
182        const self = this,
183            dataName = self.formatDataName(event);
184
185        $($el).on(event, function() {
186            if (!$(this).data(dataName)) {
187
188                // Exec Callback Function
189                callback.call($(this));
190
191                // Add data name 
192                $(this).data(dataName, true);
193
194                // Unbind event
195                $(this).off(event);
196            }
197        });
198
199        return this;
200    },
201
202    execOnceTroughWindowEvent($el, event, callback) {
203        const self = this,
204            dataName = self.formatDataName(event);
205
206        $($el).on(event, function() {
207            if (!$(this).data(dataName)) {
208
209                // Exec Callback Function
210                callback();
211
212                // Add data name 
213                $(this).data(dataName, true);
214
215                // Unbind event
216                $(this).off(event);
217            }
218        });
219
220        return this;
221    },
222
223    formatDataName(name) {
224        name = name.replace('.', '');
225        return name;
226    },
227
228    isElementInView($el) {
229        const rect = $el[0].getBoundingClientRect();
230
231        return (
232            rect.top <= (window.innerHeight / 3)
233        );
234    },
235
236    getScripts(arr, path) {
237        const _arr = $.map(arr, scr => $.getScript((path || "") + scr));
238
239        _arr.push($.Deferred(({ resolve }) => {
240            $(resolve);
241        }));
242
243        return $.when(..._arr);
244    },
245
246    showErrorMessage(title, content) {
247
248        if ($('html').hasClass('disable-local-warning')) {
249            return;
250        }
251
252        $('.modalThemeErrorMessage').remove();
253        $('body').append('<div class="modal fade" id="modalThemeErrorMessage"><div class="modal-dialog modal-dialog-centered"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">' + title + '</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body">' + content + '</div><div class="modal-footer"><button type="button" class="btn btn-primary" data-bs-dismiss="modal">Close</button></div></div></div></div>');
254
255        var modalThemeErrorMessage = document.getElementById('modalThemeErrorMessage');
256        var modalThemeErrorMessage = bootstrap.Modal.getOrCreateInstance(modalThemeErrorMessage);
257        modalThemeErrorMessage.show();
258
259    }
260
261};
262
263(((theme = {}, $) => {
264            /*
265            Local Environment Warning
266            */
267            try {
268                if ("file://" === location.origin) {
269                    if ($('[data-icon]').length || $('iframe').length) {
270
271                        theme.fn.showErrorMessage('Local Environment Warning', 'SVG Objects, Icons, YouTube and Vimeo Videos might not show correctly on local environment. For better result, please preview on a server.<br><br><a target="_blank" href="https://www.okler.net/forums/topic/how-to-disable-local-environment-warning/" class="fw-semibold"><i class="fa-solid fa-link"></i> How to Disable Local Environment Warning</a>');
272
273                    }
274                }
275            } catch (e) {}
276
277            /*
278            Browser Selector
279            */
280            $.extend({
281
282                        browserSelector() {
283
284                            // jQuery.browser.mobile (http://detectmobilebrowser.com/)
285                            (a => {
286                                (jQuery.browser = jQuery.browser || {}).mobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))
287                            })(navigator.userAgent || navigator.vendor || window.opera);
288
289                            // Touch
290                            const hasTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
291
292                            const u = navigator.userAgent,
293                                ua = u.toLowerCase(),
294                                is = t => ua.includes(t),
295                                g = 'gecko',
296                                w = 'webkit',
297                                s = 'safari',
298                                o = 'opera',
299                                h = document.documentElement,
300                                b = [(!(/opera|webtv/i.test(ua)) && /msie\s(\d)/.test(ua)) ? (`ie ie${parseFloat(navigator.appVersion.split("MSIE")[1])}`) : is('firefox/2') ? `${g} ff2` : is('firefox/3.5') ? `${g} ff3 ff3_5` : is('firefox/3') ? `${g} ff3` : is('gecko/') ? g : is('opera') ? o + (/version\/(\d+)/.test(ua) ? ` ${o}${RegExp.jQuery1}` : (/opera(\s|\/)(\d+)/.test(ua) ? ` ${o}${RegExp.jQuery2}` : '')) : is('konqueror') ? 'konqueror' : is('chrome') ? `${w} chrome` : is('iron') ? `${w} iron` : is('applewebkit/') ? `${w} ${s}${/version\/(\d+)/.test(ua) ? ` ${s}${RegExp.jQuery1}` : ''}` : is('mozilla/') ? g : '', is('j2me') ? 'mobile' : is('iphone') ? 'iphone' : is('ipod') ? 'ipod' : is('mac') ? 'mac' : is('darwin') ? 'mac' : is('webtv') ? 'webtv' : is('win') ? 'win' : is('freebsd') ? 'freebsd' : (is('x11') || is('linux')) ? 'linux' : '', 'js'];
301
302			c = b.join(' ');
303
304			if ($.browser.mobile) {
305				c += ' mobile';
306			}
307
308			if (hasTouch) {
309				c += ' touch';
310			}
311
312			h.className += ` ${c}`;
313
314			// Edge Detect
315			const isEdge = /Edge/.test(navigator.userAgent);
316
317			if(isEdge) {
318				$('html').removeClass('chrome').addClass('edge');
319			}
320
321			// Dark and Boxed Compatibility
322			if($('body').hasClass('dark')) {
323				$('html').addClass('dark');
324			}
325
326			if($('body').hasClass('boxed')) {
327				$('html').addClass('boxed');
328			}
329
330		}
331
332	});
333
334	$.browserSelector();
335
336	/*
337	Browser Workarounds
338	*/
339	if (/iPad|iPhone|iPod/.test(navigator.platform)) {
340
341		// iPad/Iphone/iPod Hover Workaround
342		$(document).ready($ => {
343			$('.thumb-info').attr('onclick', 'return true');
344		});
345	}
346
347	/*
348	Lazy Load Bacground Images
349	*/
350
351	// Check for IntersectionObserver support
352	if ('IntersectionObserver' in window) {
353		document.addEventListener("DOMContentLoaded", function() {
354
355			function handleIntersection(entries) {
356				entries.map((entry) => {
357					if (entry.isIntersecting) {
358						// Item has crossed our observation
359						// threshold - load src from data-src
360						entry.target.style.backgroundImage = "url('" + entry.target.dataset.bgSrc + "')";
361						// Job done for this item - no need to watch it!
362						observer.unobserve(entry.target);
363					}
364				});
365			}
366
367			const lazyLoadElements = document.querySelectorAll('.lazyload');
368			const observer = new IntersectionObserver(
369				handleIntersection, {
370					rootMargin: "100px"
371				}
372			);
373			lazyLoadElements.forEach(lazyLoadEl => observer.observe(lazyLoadEl));
374		});
375	} else {
376		// No interaction support? Load all background images automatically
377		const lazyLoadElements = document.querySelectorAll('.lazyload');
378		lazyLoadElements.forEach(lazyLoadEl => {
379			lazyLoadEl.style.backgroundImage = "url('" + lazyLoadEl.dataset.bgSrc + "')";
380		});
381	}
382
383	/*
384	Tabs
385	*/
386	if( $('a[data-bs-toggle="tab"]').length ) {
387		$('a[data-bs-toggle="tab"]').on('shown.bs.tab', function({target}) {
388			const $tabPane = $($(target).attr('href'));
389
390			// Carousel Refresh
391			if($tabPane.length) {
392				$tabPane.find('.owl-carousel').trigger('refresh.owl.carousel');
393			}
394
395			// Change Active Class
396			$(this).parents('.nav-tabs').find('.active').removeClass('active');
397			$(this).addClass('active').parent().addClass('active');
398		});	
399
400		if( window.location.hash ) {
401			$(window).on('load', () => {
402				if( window.location.hash !== '*' && $( window.location.hash ).get(0) ) {
403					new bootstrap.Tab( $('a.nav-link[href="'+ window.location.hash +'"]:not([data-hash])')[0] ).show();
404				}
405			});
406		}
407	}
408
409	/*
410	On Load Scroll
411	*/
412	if( !$('html').hasClass('disable-onload-scroll') && window.location.hash && !['#*'].includes( window.location.hash ) ) {
413
414		window.scrollTo(0, 0);
415
416		$(window).on('load', () => {
417			setTimeout(() => {
418				const target = window.location.hash;
419				let offset = ( $(window).width() < 768 ) ? 180 : 90;
420
421				if (!$(target).length) {
422					return;
423				}
424
425				if ( $("a[href$='" + window.location.hash + "']").is('[data-hash-offset]') ) {
426					offset = parseInt( $("a[href$='" + window.location.hash + "']").first().attr('data-hash-offset') );
427				} else if ( $("html").is('[data-hash-offset]') ) {
428					offset = parseInt( $("html").attr('data-hash-offset') );
429				}
430
431				if (isNaN(offset)) {
432					offset = 0;
433				}
434
435				$('body').addClass('scrolling');
436
437				$('html, body').animate({
438					scrollTop: $(target).offset().top - offset
439				}, 600, 'easeOutQuad', () => {
440					$('body').removeClass('scrolling');
441				});
442			}, 1);
443		});
444	}
445
446	/*
447	* Text Rotator
448	*/
449	$.fn.extend({
450		textRotator(options) {
451
452			const defaults = {
453				fadeSpeed: 500,
454				pauseSpeed: 100,
455				child: null
456			};
457
458			var options = $.extend(defaults, options);
459
460			return this.each(function() {
461				const o = options;
462				const obj = $(this);
463				const items = $(obj.children(), obj);
464				items.each(function() {
465					$(this).hide();
466				})
467				if (!o.child) {
468					var next = $(obj).children(':first');
469				} else {
470					var next = o.child;
471				}
472				$(next).fadeIn(o.fadeSpeed, () => {
473					$(next).delay(o.pauseSpeed).fadeOut(o.fadeSpeed, function() {
474						let next = $(this).next();
475						if (next.length == 0) {
476							next = $(obj).children(':first');
477						}
478						$(obj).textRotator({
479							child: next,
480							fadeSpeed: o.fadeSpeed,
481							pauseSpeed: o.pauseSpeed
482						});
483					})
484				});
485			});
486		}
487	});
488
489	/*
490	* Notice Top bar
491	*/
492	const $noticeTopBar = {
493		$wrapper: $('.notice-top-bar'),
494		$closeBtn: $('.notice-top-bar-close'),
495		$header: $('#header'),
496		$body: $('.body'),
497		init() {
498			const self = this;
499
500			if( !$.cookie('portoNoticeTopBarClose') ) {
501				self
502					.build()
503					.events();
504			} else {
505				self.$wrapper.parent().prepend( '<!-- Notice Top Bar removed by cookie -->' );
506				self.$wrapper.remove();
507			}
508
509			return this;
510		},
511		build() {
512			const self = this;
513
514			$(window).on('load', () => {
515				setTimeout(() => {
516					self.$body.css({
517						'margin-top': self.$wrapper.outerHeight(),
518						'transition': 'ease margin 300ms'
519					});
520
521					$('#noticeTopBarContent').textRotator({
522						fadeSpeed: 500,
523						pauseSpeed: 5000
524					});
525
526					if( ['absolute', 'fixed'].includes( self.$header.css('position') ) ) {
527						self.$header.css({
528							'top': self.$wrapper.outerHeight(),
529							'transition': 'ease top 300ms'
530						});
531					}
532
533					$(window).trigger('notice.top.bar.opened');
534
535				}, 1000);
536			});
537
538			return this;
539		},
540		events() {
541			const self = this;
542
543			self.$closeBtn.on('click', e => {
544				e.preventDefault();
545
546				self.$body.animate({
547					'margin-top': 0,
548				}, 300, () => {
549					self.$wrapper.remove();
550					self.saveCookie();
551				});
552
553				if( ['absolute', 'fixed'].includes( self.$header.css('position') ) ) {
554					self.$header.animate({
555						top: 0
556					}, 300);
557				}
558
559				// When header has shrink effect
560				if( self.$header.hasClass('header-effect-shrink') ) {
561					self.$header.find('.header-body').animate({
562						top: 0
563					}, 300);
564				}
565
566				$(window).trigger('notice.top.bar.closed');
567			});
568
569			return this;
570		},
571		checkCookie() {
572			const self = this;
573
574			if( $.cookie('portoNoticeTopBarClose') ) {
575				return true;
576			} else {
577				return false;
578			}
579
580			return this;
581		},
582		saveCookie() {
583			const self = this;
584
585			$.cookie('portoNoticeTopBarClose', true);
586
587			return this;
588		}
589	};
590
591	if( $('.notice-top-bar').length ) {
592		$noticeTopBar.init();
593	}
594
595	/*
596	* Image Hotspots
597	*/
598	if( $('.image-hotspot').length ) {
599		$('.image-hotspot')
600			.append('<span class="ring"></span>')
601			.append('<span class="circle"></span>');
602	}
603
604	/*
605	* Reading Progress
606	*/
607	if( $('.progress-reading').length ) {
608
609		function updateScrollProgress() {
610			const pixels = $(document).scrollTop();
611				pageHeight = $(document).height() - $(window).height()
612				progress = 100 * pixels / pageHeight;
613
614			$('.progress-reading .progress-bar').width(parseInt(progress) + "%");
615		}
616
617		$(document).on('scroll ready', () => {
618			updateScrollProgress();
619		});
620
621		$(document).ready(() => {
622			$(window).afterResize(() => {
623				updateScrollProgress();
624			});
625		});
626
627	}
628
629	/*
630	* Page Transition
631	*/
632	if( $('body[data-plugin-page-transition]').length ) {
633		
634		let link_click = false;
635
636		$(document).on('click', 'a', function(e){
637			link_click = $(this);
638		});
639
640		$(window).on("beforeunload", e => {
641			if( typeof link_click === 'object' ) {
642				const href = link_click.attr('href');
643
644				if( href.indexOf('mailto:') != 0 && href.indexOf('tel:') != 0 && !link_click.data('rm-from-transition') ) {
645					$('body').addClass('page-transition-active');
646				}
647			}
648		});
649
650		$(window).on("pageshow", ({persisted, originalEvent}) => {
651			if( persisted || originalEvent.persisted) {
652				if( $('html').hasClass('safari') ) {
653					window.location.reload();
654				}
655				
656				$('body').removeClass('page-transition-active');
657			}
658		});
659	}
660
661	/*
662	* Clone Element
663	*/
664	if( $('[data-clone-element]').length ) {
665
666		$('[data-clone-element]').each(function() {
667
668			const $el = $(this), content = $el.html(), qty = $el.attr('data-clone-element');
669
670			for (let i = 0; i < qty; i++) {
671				$el.html($el.html() + content);
672			}
673
674		});
675
676	}
677
678	if( $('[data-clone-element-to]').length ) {
679
680		$('[data-clone-element-to]').each(function() {
681
682			const $el = $(this);
683			const content = $el.html();
684			const $to = $($el.attr('data-clone-element-to'));
685
686			$to.html($to.html() + content);
687
688		});
689
690	}
691
692	/*
693	* Thumb Info Floating Caption
694	*/
695	$('.thumb-info-floating-caption').each(function() {
696
697		$(this)
698			.addClass('thumb-info-floating-element-wrapper')
699			.append( '<span class="thumb-info-floating-element thumb-info-floating-caption-title d-none">'+ $(this).data('title') +'</span>' );
700
701		if( $(this).data('type') ) {
702			$('.thumb-info-floating-caption-title', $(this))
703				.append( '<div class="thumb-info-floating-caption-type">'+ $(this).data('type') +'</div>' )
704				.css({
705					'padding-bottom' : 22
706				});
707		}
708
709		if( $(this).hasClass('thumb-info-floating-caption-clean') ) {
710			$('.thumb-info-floating-element', $(this)).addClass('bg-transparent');
711		}
712
713	});
714
715	/*
716	* Thumb Info Floating Element
717	*/
718	if( $('.thumb-info-floating-element-wrapper').length ) {
719
720		if (typeof gsap !== 'undefined') {
721
722			$('.thumb-info-floating-element-wrapper').on('mouseenter', function({clientX, clientY}) {
723				
724				if(!$(this).data('offset')) {
725					$(this).data('offset', 0);
726				}
727
728				const offset = parseInt($(this).data('offset'));
729
730				$('.thumb-info-floating-element-clone').remove();
731
732				$('.thumb-info-floating-element', $(this)).clone().addClass('thumb-info-floating-element-clone p-fixed p-events-none').attr('style', 'transform: scale(0.1);').removeClass('d-none').appendTo('body');
733
734				$('.thumb-info-floating-element-clone').css({
735					left: clientX + (offset),
736					top: clientY + (offset)
737				}).fadeIn(300);
738
739				gsap.to('.thumb-info-floating-element-clone', 0.5, {
740					css: {
741						scaleX: 1,
742						scaleY: 1
743					}
744				});
745
746				$(document).off('mousemove').on('mousemove', ({clientX, clientY}) => {
747
748					gsap.to('.thumb-info-floating-element-clone', 0.5, {
749						css: {
750							left: clientX + (offset),
751							top: clientY + (offset)
752						}
753					});
754
755				});
756
757			}).on('mouseout', () => {
758
759				gsap.to('.thumb-info-floating-element-clone', 0.5, {
760					css: {
761						scaleX: 0.5,
762						scaleY: 0.5,
763						opacity: 0
764					}
765				});
766
767			});
768
769		} else {
770			theme.fn.showErrorMessage('Failed to Load File', 'Failed to load: GSAP - Include the following file(s): (vendor/gsap/gsap.min.js)');
771		}
772
773	}
774
775	/*
776	* Thumb Info Direction Aware
777	*/
778	$(window).on('load', () => {
779		$('.thumb-info-wrapper-direction-aware').each( function() {
780			$(this).hoverdir({
781				speed : 300,
782				easing : 'ease',
783				hoverDelay : 0,
784				inverse : false,
785				hoverElem: '.thumb-info-wrapper-overlay'
786			});
787		});
788	});
789
790	/*
791	* Thumb Info Container Full
792	*/
793	$('.thumb-info-container-full-img').each(function() {
794
795		const $container = $(this);
796
797		$('[data-full-width-img-src]', $container).each(function() {
798			const uniqueId = 'img' + Math.floor(Math.random() * 10000);
799			$(this).attr('data-rel', uniqueId);
800
801			$container.append('<div style="background-image: url(' + $(this).attr('data-full-width-img-src') + ');" id="' + uniqueId + '" class="thumb-info-container-full-img-large opacity-0"></div>');
802		});
803
804		$('.thumb-info', $container).on('mouseenter', function(e){
805			$('.thumb-info-container-full-img-large').removeClass('active');
806			$('#' + $(this).attr('data-rel')).addClass('active');
807		});
808
809	});
810
811	/*
812	* Toggle Text Click
813	*/
814	$('[data-toggle-text-click]').on('click', function () {
815		$(this).text(function(i, text){
816			return text === $(this).attr('data-toggle-text-click') ? $(this).attr('data-toggle-text-click-alt') : $(this).attr('data-toggle-text-click');
817		});
818	});
819
820	/*
821	* Toggle Class
822	*/
823	$('[data-toggle-class]').on('click', function (e) {
824		e.preventDefault();
825
826		$(this).toggleClass( $(this).data('toggle-class') );
827	});
828
829	/*
830	* Shape Divider Aspect Ratio
831	*/
832	if( $('.shape-divider').length ) {
833		aspectRatioSVG();
834		$(window).on('resize', () => {
835			aspectRatioSVG();
836		});
837	}
838
839	/*
840	* Shape Divider Animated
841	*/
842	if( $('.shape-divider-horizontal-animation').length ) {
843		theme.fn.intObs('.shape-divider-horizontal-animation', function(){
844			for( let i = 0; i <= 1; i++ ) {
845				const svgClone = $(this).find('svg:nth-child(1)').clone();
846
847				$(this).append( svgClone )
848			}
849
850			$(this).addClass('start');
851		}, {});
852	}
853
854	/*
855	* Shape Divider - SVG Aspect Ratio
856	*/
857	function aspectRatioSVG() {
858		if( $(window).width() < 1950 ) {
859			$('.shape-divider svg[preserveAspectRatio]').each(function(){
860				if( !$(this).parent().hasClass('shape-divider-horizontal-animation') ) {
861					$(this).attr('preserveAspectRatio', 'xMinYMin');
862				} else {
863					$(this).attr('preserveAspectRatio', 'none');
864				}
865			});
866		} else {
867			$('.shape-divider svg[preserveAspectRatio]').each(function(){
868				$(this).attr('preserveAspectRatio', 'none');
869			});
870		}
871	}
872
873	/*
874	* Content Switcher
875	*/
876	$('[data-content-switcher]').on('change', function(e, v) {
877		const switcherRel = ($(this).is(':checked') ? '1' : '2' ), switcherId = $(this).attr('data-content-switcher-content-id');
878
879		$('[data-content-switcher-id=' + switcherId + ']').addClass('initialized').removeClass('active');
880
881		const $activeEl = $('[data-content-switcher-id=' + switcherId + '][data-content-switcher-rel=' + switcherRel + ']');
882
883		$activeEl.addClass('active');
884
885		$activeEl.parent().css('height', $activeEl.height());
886	});
887
888	$('[data-content-switcher]').trigger('change');
889
890	/*
891	* Dynamic Height
892	*/
893	var $window = $(window);
894	$window.on('resize dynamic.height.resize', () => {
895		$('[data-dynamic-height]').each(function(){
896			const $this = $(this), values = JSON.parse($this.data('dynamic-height').replace(/'/g,'"').replace(';',''));
897
898			// XS
899			if( $window.width() < 576 ) {
900				$this.height( values[4] );
901			}
902
903			// SM
904			if( $window.width() > 575 && $window.width() < 768 ) {
905				$this.height( values[3] );
906			}
907
908			// MD
909			if( $window.width() > 767 && $window.width() < 992 ) {
910				$this.height( values[2] );
911			}
912
913			// LG
914			if( $window.width() > 991 && $window.width() < 1200 ) {
915				$this.height( values[1] );
916			}
917
918			// XS
919			if( $window.width() > 1199 ) {
920				$this.height( values[0] );
921			}
922		});
923	});
924
925	// Mobile First Load
926	if( $window.width() < 992 ) {
927		$window.trigger('dynamic.height.resize');
928	}
929
930	/*
931	* Video - Trigger Play
932	*/
933	if( $('[data-trigger-play-video]').length ) {
934		theme.fn.execOnceTroughEvent( '[data-trigger-play-video]', 'mouseover.trigger.play.video', function(){
935			const $video = $( $(this).data('trigger-play-video') );
936
937			$(this).on('click', function(e){
938				e.preventDefault();
939
940				if( $(this).data('trigger-play-video-remove') == 'yes' ) {
941					$(this).animate({
942						opacity: 0
943					}, 300, function(){
944						$video[0].play();
945
946						$(this).remove();
947					});
948				} else {
949					setTimeout(() => {
950						$video[0].play();
951					},300);
952				}
953			});
954		});
955	}
956
957	/*
958	* Video - Auto Play
959	*/
960	if( $('video[data-auto-play]').length ) {
961		$(window).on('load', () => {
962			$('video[data-auto-play]').each(function(){
963				const $video = $(this);
964
965				setTimeout(() => {
966					if( $( '#' + $video.attr('id') ).length ) {
967						if( $( '[data-trigger-play-video="#' + $video.attr('id') + '"]' ).data('trigger-play-video-remove') == 'yes' ) {
968							$( '[data-trigger-play-video="#' + $video.attr('id') + '"]' ).animate({
969								opacity: 0
970							}, 300, () => {
971								$video[0].play();
972
973								$( '[data-trigger-play-video="#' + $video.attr('id') + '"]' ).remove();
974							});
975						} else {
976							setTimeout(() => {
977								$video[0].play();
978							},300);
979						}
980					}
981				}, 100);
982
983			});
984		});
985	}
986
987	/*
988	* Remove min height after the load of page
989	*/
990	if( $('[data-remove-min-height]').length ) {
991		$(window).on('load', () => {
992			$('[data-remove-min-height]').each(function(){
993				$(this).css({
994					'min-height': 0
995				});
996			});
997		});
998	}
999
1000	/*
1001	* Title Border
1002	*/
1003	if($('[data-title-border]').length) {
1004
1005		const $pageHeaderTitleBorder = $('<span class="page-header-title-border"></span>'), $pageHeaderTitle = $('[data-title-border]'), $window = $(window);
1006
1007		$pageHeaderTitle.before($pageHeaderTitleBorder);
1008
1009		const setPageHeaderTitleBorderWidth = () => {
1010			$pageHeaderTitleBorder.width($pageHeaderTitle.width());
1011		};
1012
1013		$window.afterResize(() => {
1014			setPageHeaderTitleBorderWidth();
1015		});
1016
1017		setPageHeaderTitleBorderWidth();
1018
1019		$pageHeaderTitleBorder.addClass('visible');
1020	}
1021
1022	/*
1023	* Footer Reveal
1024	*/
1025	($ => {
1026		const $footerReveal = {
1027			$wrapper: $('.footer-reveal'),
1028			init() {
1029				const self = this;
1030
1031				self.build();
1032				self.events();
1033			},
1034			build() {
1035				const self = this, footer_height = self.$wrapper.outerHeight(true), window_height = ( $(window).height() - $('.header-body').height() );
1036
1037				if( footer_height > window_height ) {
1038					$('#footer').removeClass('footer-reveal');
1039					$('body').css('margin-bottom', 0);
1040				} else {
1041					$('#footer').addClass('footer-reveal');
1042					$('body').css('margin-bottom', footer_height);
1043				}
1044
1045			},
1046			events() {
1047				const self = this, $window = $(window);
1048
1049				$window.on('load', () => {
1050					$window.afterResize(() => {
1051						self.build();
1052					});
1053				});
1054			}
1055		};
1056
1057		if( $('.footer-reveal').length ) {
1058			$footerReveal.init();
1059		}
1060	})(jQuery);
1061
1062	/*
1063	* Re-Init Plugin
1064	*/
1065	if( $('[data-reinit-plugin]').length ) {
1066		$('[data-reinit-plugin]').on('click', function(e) {
1067			e.preventDefault();
1068
1069			const pluginInstance = $(this).data('reinit-plugin'), pluginFunction = $(this).data('reinit-plugin-function'), pluginElement  = $(this).data('reinit-plugin-element'), pluginOptions  = theme.fn.getOptions($(this).data('reinit-plugin-options'));
1070
1071			$( pluginElement ).data( pluginInstance ).destroy();
1072
1073			setTimeout(() => {
1074				theme.fn.execPluginFunction(pluginFunction, $( pluginElement ), pluginOptions);	
1075			}, 1000);
1076
1077		});
1078	}
1079
1080	/*
1081	* Simple Copy To Clipboard
1082	*/
1083	if( $('[data-copy-to-clipboard]').length ) {
1084		theme.fn.intObs( '[data-copy-to-clipboard]', function(){
1085			const $this = $(this);
1086
1087			$this.wrap( '<div class="copy-to-clipboard-wrapper position-relative"></div>' );
1088
1089			const $copyButton = $('<a href="#" class="btn btn-primary btn-px-2 py-1 text-0 position-absolute top-8 right-8">COPY</a>');
1090			$this.parent().prepend( $copyButton );
1091
1092			$copyButton.on('click', function(e){
1093				e.preventDefault();
1094
1095				const $btn       = $(this), $temp = $('<textarea class="d-block opacity-0" style="height: 0;">');
1096
1097				$btn.parent().append( $temp );
1098
1099				$temp.val( $this.text() );
1100					
1101				$temp[0].select();
1102				$temp[0].setSelectionRange(0, 99999);
1103
1104				document.execCommand("copy");
1105
1106				$btn.addClass('copied');
1107				setTimeout(() => {
1108					$btn.removeClass('copied');
1109				}, 1000);
1110
1111				$temp.remove();
1112			});
1113		}, {
1114			rootMargin: '0px 0px 0px 0px'
1115		} );
1116	}
1117
1118	/*
1119	* Marquee
1120	*/
1121	if( $('.marquee').length && $.isFunction($.fn.marquee) ) {
1122		$('.marquee').marquee({
1123			duration: 5000,
1124			gap: 0,
1125			delayBeforeStart: 0,
1126			direction: 'left',
1127			duplicated: true
1128		});
1129	}
1130
1131	/*
1132	* Style Switcher Open Loader Button
1133	*/
1134	if( $('.style-switcher-open-loader').length ) {
1135
1136		const urlParams = new URLSearchParams(window.location.search);
1137
1138		let hideStyleSwitcherAfterShow = false;
1139
1140		$('.style-switcher-open-loader').on('click', function(e){
1141			e.preventDefault();
1142
1143			const $this = $(this);
1144
1145			// Add Spinner to icon
1146			$this.addClass('style-switcher-open-loader-loading');
1147
1148			const basePath = $(this).data('base-path'), skinSrc = $(this).data('skin-src');
1149
1150			const script1 = document.createElement("script");
1151			script1.src = basePath + "master/style-switcher/style.switcher.localstorage.js";
1152
1153			const script2 = document.createElement("script");
1154			script2.src = basePath + "master/style-switcher/style.switcher.js";
1155			script2.id = "styleSwitcherScript";
1156			script2.setAttribute('data-base-path', basePath);
1157			script2.setAttribute('data-skin-src', skinSrc);
1158
1159			script2.onload = () => {
1160				setTimeout(() => {
1161					// Trigger a click to open the style switcher sidebar
1162					function checkIfReady() {
1163						if( !$('.style-switcher-open').length ) {
1164							window.setTimeout(checkIfReady, 100);
1165						} else {
1166							$('.style-switcher-open').trigger('click');
1167
1168							if (hideStyleSwitcherAfterShow) {
1169								setTimeout(() => {
1170									$('.style-switcher-open').trigger('click');
1171								}, 2000);
1172							}
1173						}
1174					}
1175					checkIfReady();
1176
1177				}, 500);
1178			}
1179
1180			document.body.appendChild(script1);
1181			document.body.appendChild(script2);	
1182
1183		});
1184
1185		let htmlDataOptions = $('html').data('style-switcher-options');
1186		let showSwitcher = false;
1187
1188		if(htmlDataOptions) {
1189			htmlDataOptions = htmlDataOptions.replace(/'/g, '"');
1190
1191			if (JSON.parse(htmlDataOptions).showSwitcher) {
1192				showSwitcher = true;
1193			}
1194
1195			if (JSON.parse(htmlDataOptions).hideStyleSwitcherAfterShow) {
1196				hideStyleSwitcherAfterShow = true;
1197			}
1198		}
1199
1200		if (urlParams.has("showStyleSwitcher")) {
1201			showSwitcher = true;
1202		}
1203
1204		if (urlParams.has("hideStyleSwitcherAfterShow")) {
1205			hideStyleSwitcherAfterShow = true;
1206		}
1207
1208		if (showSwitcher) {
1209			$('.style-switcher-open-loader').trigger('click');
1210		}
1211
1212	}
1213
1214})).apply(this, [ window.theme, jQuery ]);
1215
1216// Animate
1217(((theme = {}, $) => {
1218    const instanceName = '__animate';
1219
1220    class PluginAnimate {
1221        constructor($el, opts) {
1222            return this.initialize($el, opts);
1223        }
1224
1225        initialize($el, opts) {
1226			if ($el.data(instanceName)) {
1227				return this;
1228			}
1229
1230			this.$el = $el;
1231
1232			this
1233				.setData()
1234				.setOptions(opts)
1235				.build();
1236
1237			return this;
1238		}
1239
1240        setData() {
1241			this.$el.data(instanceName, this);
1242
1243			return this;
1244		}
1245
1246        setOptions(opts) {
1247			this.options = $.extend(true, {}, PluginAnimate.defaults, opts, {
1248				wrapper: this.$el
1249			});
1250
1251			return this;
1252		}
1253
1254        build() {
1255			const self = this;
1256
1257			// Flag Class Only
1258			// - Useful for simple animations like hightlight
1259			// - Less ourwork and memory
1260			if( self.options.flagClassOnly ) {
1261				const delay = self.options.wrapper.attr('data-appear-animation-delay') ? self.options.wrapper.attr('data-appear-animation-delay') : self.options.delay;
1262				
1263				self.options.wrapper.css({
1264					'animation-delay': delay + 'ms',
1265					'transition-delay': delay + 'ms'
1266				});
1267				self.options.wrapper.addClass( self.options.wrapper.attr('data-appear-animation') );
1268
1269				return this;
1270			}
1271
1272			if($('body').hasClass('loading-overlay-showing')) {
1273				$(window).on('loading.overlay.ready', () => {
1274					self.animate();
1275				});
1276			} else {
1277				self.animate();
1278			}
1279
1280			return this;
1281		}
1282
1283        animate() {
1284            const self = this;
1285            const $el = this.options.wrapper;
1286            let delay = 0;
1287            let duration = this.options.duration;
1288            const elTopDistance = $el.offset().top;
1289            const windowTopDistance = $(window).scrollTop();
1290
1291            // If has appear animation elements inside a SVG. 
1292            // Intersection Observer API do not check elements inside SVG's, so we need initialize trough top parent SVG
1293            if( $el.data('appear-animation-svg') ) {
1294				$el.find('[data-appear-animation]').each(function(){
1295                    const $this = $(this);
1296                    let opts;
1297
1298                    const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
1299                    if (pluginOptions)
1300						opts = pluginOptions;
1301
1302                    $this.themePluginAnimate(opts);
1303                });
1304
1305				return this;
1306			}
1307
1308            // No animation at the first load of page. This is good for performance
1309            if( self.options.firstLoadNoAnim ) {
1310				$el.removeClass('appear-animation');
1311
1312				// Inside Carousel
1313				if( $el.closest('.owl-carousel').get(0) ) {
1314					setTimeout(() => {
1315						$el.closest('.owl-carousel').on('change.owl.carousel', () => {
1316							self.options.firstLoadNoAnim = false;
1317							$el.removeData('__animate');
1318							$el.themePluginAnimate( self.options );
1319						});
1320					}, 500);
1321				}
1322
1323				return this;
1324			}
1325
1326            $el.addClass('appear-animation animated');
1327
1328            if (!$('html').hasClass('no-csstransitions') && $(window).width() > self.options.minWindowWidth && elTopDistance >= windowTopDistance || self.options.forceAnimation == true) {
1329				delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
1330				duration = ($el.attr('data-appear-animation-duration') ? $el.attr('data-appear-animation-duration') : self.options.duration);
1331
1332				if (duration != '750ms') {
1333					$el.css('animation-duration', duration);
1334				}
1335
1336				$el.css('animation-delay', delay + 'ms');
1337				$el.addClass($el.attr('data-appear-animation') + ' appear-animation-visible');
1338				
1339				$el.trigger('animation:show');
1340
1341			} else {
1342				$el.addClass('appear-animation-visible');
1343			}
1344
1345            return this;
1346        }
1347    }
1348
1349    PluginAnimate.defaults = {
1350		accX: 0,
1351		accY: -80,
1352		delay: 100,
1353		duration: '750ms',
1354		minWindowWidth: 0,
1355		forceAnimation: false,
1356		flagClassOnly: false
1357	};
1358
1359    // expose to scope
1360    $.extend(theme, {
1361		PluginAnimate
1362	});
1363
1364    // jquery plugin
1365    $.fn.themePluginAnimate = function(opts) {
1366		return this.map(function() {
1367			const $this = $(this);
1368
1369			if ($this.data(instanceName)) {
1370				return $this.data(instanceName);
1371			} else {
1372				return new PluginAnimate($this, opts);
1373			}
1374
1375		});
1376	};
1377})).apply(this, [window.theme, jQuery]);
1378
1379// Animated Content
1380(((theme = {}, $) => {
1381    const instanceName = '__animatedContent';
1382
1383    class PluginAnimatedContent {
1384        constructor($el, opts) {
1385            return this.initialize($el, opts);
1386        }
1387
1388        initialize($el, opts) {
1389			if ($el.data(instanceName)) {
1390				return this;
1391			}
1392
1393			const self = this;
1394
1395			this.$el = $el;
1396			this.initialText = $el.text();
1397
1398			this
1399				.setData()
1400				.setOptions(opts)
1401				.build()
1402				.events();
1403
1404			return this;
1405		}
1406
1407        setData() {
1408			this.$el.data(instanceName, this);
1409
1410			return this;
1411		}
1412
1413        setOptions(opts) {
1414			this.options = $.extend(true, {}, PluginAnimatedContent.defaults, opts, {
1415				wrapper: this.$el
1416			});
1417
1418			return this;
1419		}
1420
1421        build() {
1422			const self    = this;
1423
1424			if( $(window).width() < self.options.minWindowWidth ) {
1425				return this;
1426			}
1427
1428			if( self.options.firstLoadNoAnim ) {
1429				self.$el.css({
1430					visibility: 'visible'
1431				});
1432
1433				// Inside Carousel
1434				if( self.$el.closest('.owl-carousel').get(0) ) {
1435					setTimeout(() => {
1436						self.$el.closest('.owl-carousel').on('change.owl.carousel', () => {
1437							self.options.firstLoadNoAnim = false;
1438							self.build();
1439						});
1440					}, 500);
1441				}
1442
1443				return this;
1444			}
1445
1446			// Set Min Height to avoid flicking issues
1447			self.setMinHeight();
1448
1449			// Letter
1450			if( self.options.contentType == 'letter' ) {
1451
1452				self.$el.addClass('initialized');
1453
1454				const letters = self.$el.text().split('');
1455
1456				self.$el.text('');
1457
1458				// Type Writer
1459				if( self.options.animationName == 'typeWriter' ) {
1460					self.$el.append( '<span class="letters-wrapper"></span><span class="typeWriter"></pre>' );
1461
1462					let index = 0;
1463
1464					setTimeout(() => {
1465
1466						const timeout = () => {
1467							const st = setTimeout(() => {
1468								const letter = letters[index];
1469								
1470								self.$el.find('.letters-wrapper').append( '<span class="letter '+ ( self.options.letterClass ? self.options.letterClass + ' ' : '' ) +'">' + letter + '</span>' );
1471
1472								index++;
1473								timeout();
1474							}, self.options.animationSpeed);
1475
1476							if( index >= letters.length ) {
1477								clearTimeout(st);
1478							}
1479						};
1480						timeout();
1481
1482					}, self.options.startDelay);
1483
1484				// Class Animation
1485				} else {
1486					setTimeout(() => {
1487						for( let i = 0; i < letters.length; i++ ) {
1488							const letter = letters[i];
1489							
1490							self.$el.append( '<span class="animated-letters-wrapper ' + self.options.wrapperClass + '"><span class="animated-letters-item letter '+ ( self.options.letterClass ? self.options.letterClass + ' ' : '' ) + self.options.animationName +' animated" style="animation-delay: '+ ( i * self.options.animationSpeed ) +'ms;">' + ( letter == ' ' ? '&nbsp;' : letter ) + '</span></span>' );
1491		
1492						}
1493					}, self.options.startDelay);
1494				}
1495
1496			// Words
1497			} else if( self.options.contentType == 'word' ) {
1498                const words = self.$el.text().split(" ");
1499                let delay = self.options.startDelay;
1500
1501                self.$el.empty();
1502
1503                $.each(words, (i, v) => {
1504					self.$el.append( $('<span class="animated-words-wrapper ' + self.options.wrapperClass + '">').html('<span class="animated-words-item ' + self.options.wordClass + ' appear-animation" data-appear-animation="' + self.options.animationName + '" data-appear-animation-delay="' + delay + '">' + v + '&nbsp;</span>') );
1505					delay = delay + self.options.animationSpeed;
1506				});
1507
1508                if ($.isFunction($.fn['themePluginAnimate']) && $('.animated-words-item[data-appear-animation]').length) {
1509					theme.fn.dynIntObsInit( '.animated-words-item[data-appear-animation]', 'themePluginAnimate', theme.PluginAnimate.defaults );
1510				}
1511
1512                self.$el.addClass('initialized');
1513            }
1514
1515			return this;
1516		}
1517
1518        setMinHeight() {
1519			const self = this;
1520
1521			// if it's inside carousel
1522			if( self.$el.closest('.owl-carousel').get(0) ) {
1523				self.$el.closest('.owl-carousel').addClass('d-block');
1524				self.$el.css( 'min-height', self.$el.height() );
1525				self.$el.closest('.owl-carousel').removeClass('d-block');
1526			} else {
1527				self.$el.css( 'min-height', self.$el.height() );
1528			}
1529
1530			return this;
1531		}
1532
1533        destroy() {
1534			const self = this;
1535
1536			self.$el
1537				.html( self.initialText )
1538				.css( 'min-height', '' );
1539
1540			return this;
1541		}
1542
1543        events() {
1544			const self = this;
1545
1546			// Destroy
1547			self.$el.on('animated.letters.destroy', () => {
1548				self.destroy();
1549			});
1550
1551			// Initialize
1552			self.$el.on('animated.letters.initialize', () => {
1553				self.build();
1554			});
1555
1556			return this;
1557		}
1558    }
1559
1560    PluginAnimatedContent.defaults = {
1561		contentType: 'letter',
1562		animationName: 'fadeIn',
1563		animationSpeed: 50,
1564		startDelay: 500,
1565		minWindowWidth: 768,
1566		letterClass: '',
1567		wordClass: '',
1568		wrapperClass: ''
1569	};
1570
1571    // expose to scope
1572    $.extend(theme, {
1573		PluginAnimatedContent
1574	});
1575
1576    // jquery plugin
1577    $.fn.themePluginAnimatedContent = function(opts) {
1578		return this.map(function() {
1579			const $this = $(this);
1580
1581			if ($this.data(instanceName)) {
1582				return $this.data(instanceName);
1583			} else {
1584				return new PluginAnimatedContent($this, opts);
1585			}
1586
1587		});
1588	}
1589})).apply(this, [window.theme, jQuery]);
1590
1591// Before / After
1592(((theme = {}, $) => {
1593    const instanceName = '__beforeafter';
1594
1595    class PluginBeforeAfter {
1596        constructor($el, opts) {
1597            return this.initialize($el, opts);
1598        }
1599
1600        initialize($el, opts) {
1601			this.$el = $el;
1602
1603			this
1604				.setData()
1605				.setOptions(opts)
1606				.build();
1607
1608			return this;
1609		}
1610
1611        setData() {
1612			this.$el.data(instanceName, this);
1613
1614			return this;
1615		}
1616
1617        setOptions(opts) {
1618			this.options = $.extend(true, {}, PluginBeforeAfter.defaults, opts, {
1619				wrapper: this.$el
1620			});
1621
1622			return this;
1623		}
1624
1625        build() {
1626
1627			if ($.isFunction($.fn.twentytwenty)) {
1628
1629				const self = this;
1630
1631				self.options.wrapper.waitForImages(() => {
1632					self.options.wrapper.twentytwenty(self.options);
1633				});
1634
1635			} else {
1636
1637				theme.fn.showErrorMessage('Failed to Load File', 'Failed to load: twentytwenty - Include the following file(s): (vendor/twentytwenty/css/twentytwenty.css, vendor/twentytwenty/js/jquery.event.move.js, vendor/twentytwenty/js/jquery.twentytwenty.js)');
1638
1639			}
1640
1641			return this;
1642
1643		}
1644    }
1645
1646    PluginBeforeAfter.defaults = {
1647		forceInit: true,
1648		default_offset_pct: 0.5,
1649		orientation: 'horizontal',
1650		before_label: 'Before',
1651		after_label: 'After',
1652		no_overlay: false,
1653		move_slider_on_hover: false,
1654		move_with_handle_only: true,
1655		click_to_move: false
1656	};
1657
1658    // expose to scope
1659    $.extend(theme, {
1660		PluginBeforeAfter
1661	});
1662
1663    // jquery plugin
1664    $.fn.themePluginBeforeAfter = function(opts) {
1665		return this.map(function() {
1666			const $this = $(this);
1667
1668			if ($this.data(instanceName)) {
1669				return $this.data(instanceName);
1670			} else {
1671				return new PluginBeforeAfter($this, opts);
1672			}
1673
1674		});
1675	}
1676})).apply(this, [window.theme, jQuery]);
1677
1678// Carousel Light
1679(((theme = {}, $) => {
1680    const instanceName = '__carouselLight';
1681
1682    class PluginCarouselLight {
1683        constructor($el, opts) {
1684            return this.initialize($el, opts);
1685        }
1686
1687        initialize($el, opts) {
1688			if ($el.data(instanceName)) {
1689				return this;
1690			}
1691
1692			this.$el = $el;
1693			this.clickFlag = true;
1694
1695			this
1696				.setData()
1697				.setOptions(opts)
1698				.build()
1699				.owlNav()
1700				.owlDots()
1701				.autoPlay()
1702				.events();
1703
1704			return this;
1705		}
1706
1707        setData() {
1708			this.$el.data(instanceName, this);
1709
1710			return this;
1711		}
1712
1713        setOptions(opts) {
1714			this.options = $.extend(true, {}, PluginCarouselLight.defaults, opts, {
1715				wrapper: this.$el
1716			});
1717
1718			return this;
1719		}
1720
1721        build() {
1722			const self = this;
1723
1724			self.$el
1725				.css('opacity', 1)
1726				.find('.owl-item:first-child')
1727				.addClass('active');
1728
1729			self.$el.trigger('initialized.owl.carousel');
1730
1731			// Carousel Navigate By ID and item index
1732			self.carouselNavigate();
1733
1734			return this;
1735		}
1736
1737        changeSlide($nextSlide) {
1738			const self = this, $prevSlide = self.$el.find('.owl-item.active');
1739
1740			self.$el.find('.owl-item.active').addClass('removing');
1741
1742			$prevSlide
1743				.removeClass('fadeIn')
1744				.addClass( 'fadeOut animated' );
1745
1746			setTimeout(() => {
1747				setTimeout(() => {
1748					$prevSlide.removeClass('active');
1749				}, 400);
1750
1751				$nextSlide
1752					.addClass('active')
1753					.removeClass('fadeOut')
1754					.addClass( 'fadeIn animated' );
1755
1756			}, 200);
1757
1758			// Dots
1759			self.$el
1760				.find('.owl-dot')
1761				.removeClass('active')
1762				.eq( $nextSlide.index() )
1763				.addClass('active');
1764
1765			self.$el.trigger({
1766				type: 'change.owl.carousel',
1767				nextSlideIndex: $nextSlide.index(),
1768				prevSlideIndex: $prevSlide.index()
1769			});
1770
1771			setTimeout(() => {
1772				self.$el.trigger({
1773					type: 'changed.owl.carousel',
1774					nextSlideIndex: $nextSlide.index(),
1775					prevSlideIndex: $prevSlide.index()
1776				});
1777			}, 500);
1778		}
1779
1780        owlNav() {
1781			const self = this, $owlNext = self.$el.find('.owl-next'), $owlPrev = self.$el.find('.owl-prev');
1782
1783			$owlPrev.on('click', e => {
1784				e.preventDefault();
1785
1786				if( self.options.disableAutoPlayOnClick ) {
1787					window.clearInterval(self.autoPlayInterval);
1788				}
1789
1790				if( self.avoidMultipleClicks() ) {
1791					return false;
1792				}
1793
1794				self.owlPrev();
1795			});
1796
1797			$owlNext.on('click', e => {
1798				e.preventDefault();
1799
1800				if( self.options.disableAutoPlayOnClick ) {
1801					window.clearInterval(self.autoPlayInterval);
1802				}
1803
1804				if( self.avoidMultipleClicks() ) {
1805					return false;
1806				}
1807
1808				self.owlNext();
1809			});
1810
1811			return this;
1812		}
1813
1814        owlDots() {
1815			const self = this, $owlDot = self.$el.find('.owl-dot');
1816
1817			$owlDot.on('click', function(e){
1818				let $this = $(this);
1819
1820				e.preventDefault();
1821
1822				if( self.options.disableAutoPlayOnClick ) {
1823					window.clearInterval(self.autoPlayInterval);
1824				}
1825
1826				if( self.avoidMultipleClicks() ) {
1827					return false;
1828				}
1829
1830				const dotIndex = $(this).index();
1831
1832				// Do nothing if respective dot slide is active/showing
1833				if( $this.hasClass('active') ) {
1834					return false;
1835				}
1836
1837				self.changeSlide( self.$el.find('.owl-item').eq( dotIndex ) );
1838			});
1839
1840			return this;
1841		}
1842
1843        owlPrev() {
1844			const self = this;
1845
1846			if( self.$el.find('.owl-item.active').prev().get(0) ) {
1847				self.changeSlide( self.$el.find('.owl-item.active').prev() );
1848			} else {
1849				self.changeSlide( self.$el.find('.owl-item:last-child') );
1850			}
1851		}
1852
1853        owlNext() {
1854			const self = this;
1855
1856			if( self.$el.find('.owl-item.active').next().get(0) ) {
1857				self.changeSlide( self.$el.find('.owl-item.active').next() );
1858			} else {
1859				self.changeSlide( self.$el.find('.owl-item').eq(0) );
1860			}
1861		}
1862
1863        avoidMultipleClicks() {
1864			const self = this;
1865
1866			if( !self.clickFlag ) {
1867				return true;
1868			}
1869
1870			if( self.clickFlag ) {
1871				self.clickFlag = false;
1872				setTimeout(() => {
1873					self.clickFlag = true; 
1874				}, 1000);
1875			}
1876
1877			return false;
1878		}
1879
1880        autoPlay() {
1881			const self = this, $el  = this.options.wrapper;
1882
1883			if( self.options.autoplay ) {
1884				self.autoPlayInterval = window.setInterval(() => {
1885					self.owlNext();
1886				}, self.options.autoplayTimeout);
1887			}
1888
1889			return this;
1890		}
1891
1892        carouselNavigate() {
1893			const self      = this, $el       = this.options.wrapper, $carousel = $el;
1894
1895			if( $('[data-carousel-navigate]').get(0) ) {
1896				$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').each(function(){
1897					const $this = $(this), hasCarousel = $( $this.data('carousel-navigate-id') ).get(0), toIndex = $this.data('carousel-navigate-to');
1898
1899					if( hasCarousel ) {
1900
1901						$this.on('click', () => {
1902
1903							if( self.options.disableAutoPlayOnClick ) {
1904								window.clearInterval(self.autoPlayInterval);
1905							}
1906							
1907							self.changeSlide( self.$el.find('.owl-item').eq( parseInt(toIndex) - 1 ) );
1908						});
1909
1910					}
1911				});
1912
1913				$el.on('change.owl.carousel', e => {
1914					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').removeClass('active');
1915				});
1916
1917				$el.on('changed.owl.carousel', ({nextSlideIndex}) => {
1918					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"][data-carousel-navigate-to="'+ ( nextSlideIndex + 1 ) +'"]').addClass('active');
1919				});
1920			}
1921
1922			return this;
1923		}
1924
1925        events() {
1926			const self = this;
1927
1928			self.$el.on('change.owl.carousel', event => {
1929
1930				// Hide elements inside carousel
1931			    self.$el.find('[data-appear-animation]:not(.background-image-wrapper), [data-plugin-animated-letters]').addClass('invisible');
1932
1933			    // Animated Letters
1934			    self.$el.find('[data-plugin-animated-letters]').trigger('animated.letters.destroy');
1935
1936			    // Remove "d-none" class before show the element. This is useful when using background images inside a carousel. Like ken burns effect
1937			    self.$el.find('.owl-item:not(.active) [data-carousel-onchange-show]').removeClass('d-none');
1938
1939			});
1940
1941			self.$el.on('changed.owl.carousel', event => {
1942				setTimeout(() => {
1943
1944				    // Appear Animation
1945				    if( self.$el.find('.owl-item.cloned [data-appear-animation]').get(0) ) {
1946				    	self.$el.find('.owl-item.cloned [data-appear-animation]').each(function() {
1947                            const $this = $(this);
1948                            let opts;
1949
1950                            const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
1951                            if (pluginOptions)
1952								opts = pluginOptions;
1953
1954                            $this.themePluginAnimate(opts);
1955                        });
1956				    }
1957
1958					// Show elements inside carousel
1959				    self.$el.find('.owl-item.active [data-appear-animation]:not(.background-image-wrapper), [data-plugin-animated-letters]').removeClass('invisible');
1960
1961				    // Animated Letters
1962				    self.$el.find('.owl-item.active [data-plugin-animated-letters]').trigger('animated.letters.initialize');
1963
1964				    // Background Video
1965				    self.$el.find('.owl-item.cloned.active [data-plugin-video-background]').trigger('video.background.initialize');
1966
1967				}, 500);
1968			    
1969			});
1970
1971			if( self.options.swipeEvents ) {
1972				self.$el.swipe({
1973					swipe(event, direction, distance, duration, fingerCount, fingerData) {
1974						switch ( direction ) {
1975							case 'right':
1976								self.owlPrev();
1977							break;
1978				
1979							case 'left':
1980								self.owlNext();
1981							break;
1982						}
1983					},
1984					allowPageScroll: "vertical"
1985				});
1986			}
1987		}
1988    }
1989
1990    PluginCarouselLight.defaults = {
1991		autoplay: true,
1992		autoplayTimeout: 7000,
1993		disableAutoPlayOnClick: true,
1994		swipeEvents: true
1995	};
1996
1997    // expose to scope
1998    $.extend(theme, {
1999		PluginCarouselLight
2000	});
2001
2002    // jquery plugin
2003    $.fn.themePluginCarouselLight = function(opts) {
2004		return this.map(function() {
2005			const $this = $(this);
2006
2007			if ($this.data(instanceName)) {
2008				return $this.data(instanceName);
2009			} else {
2010				return new PluginCarouselLight($this, opts);
2011			}
2012
2013		});
2014	};
2015})).apply(this, [window.theme, jQuery]);
2016
2017// Carousel
2018(((theme = {}, $) => {
2019    const instanceName = '__carousel';
2020
2021    class PluginCarousel {
2022        constructor($el, opts) {
2023            return this.initialize($el, opts);
2024        }
2025
2026        initialize($el, opts) {
2027			if ($el.data(instanceName)) {
2028				return this;
2029			}
2030
2031			this.$el = $el;
2032
2033			// If has data-icon inside, initialize only after icons get rendered
2034			// Prevent flicking issues
2035			if( $el.find('[data-icon]').get(0) ) {
2036				const self = this;
2037
2038				$(window).on('icon.rendered', function(){
2039					if ($el.data(instanceName)) {
2040						return this;
2041					}
2042
2043					setTimeout(() => {
2044						self
2045							.setData()
2046							.setOptions(opts)
2047							.build();
2048					}, 1000);
2049				});
2050
2051				return this;
2052			}
2053
2054			this
2055				.setData()
2056				.setOptions(opts)
2057				.build();
2058
2059			return this;
2060		}
2061
2062        setData() {
2063			this.$el.data(instanceName, this);
2064
2065			return this;
2066		}
2067
2068        setOptions(opts) {
2069			this.options = $.extend(true, {}, PluginCarousel.defaults, opts, {
2070				wrapper: this.$el
2071			});
2072
2073			return this;
2074		}
2075
2076        build() {
2077			if (!($.isFunction($.fn.owlCarousel))) {
2078				return this;
2079			}
2080
2081			const self = this, $el = this.options.wrapper;
2082
2083			// Add Theme Class
2084			$el.addClass('owl-theme');
2085
2086			// Add Loading
2087			$el.addClass('owl-loading');
2088
2089			// Force RTL according to HTML dir attribute
2090			if ($('html').attr('dir') == 'rtl') {
2091				this.options = $.extend(true, {}, this.options, {
2092					rtl: true
2093				});
2094			}
2095
2096			if (this.options.items == 1) {
2097				this.options.responsive = {}
2098			}
2099
2100			if (this.options.items > 4) {
2101				this.options = $.extend(true, {}, this.options, {
2102					responsive: {
2103						1199: {
2104							items: this.options.items
2105						}
2106					}
2107				});
2108			}
2109
2110			// Auto Height Fixes
2111			if (this.options.autoHeight) {
2112				const itemsHeight = [];
2113
2114				$el.find('.owl-item').each(function(){
2115					if( $(this).hasClass('active') ) {
2116						itemsHeight.push( $(this).height() );
2117					}
2118				});
2119
2120				$(window).afterResize(() => {
2121					$el.find('.owl-stage-outer').height( Math.max.apply(null, itemsHeight) );
2122				});
2123
2124				$(window).on('load', () => {
2125					$el.find('.owl-stage-outer').height( Math.max.apply(null, itemsHeight) );
2126				});
2127			}
2128
2129			// Initialize OwlCarousel
2130			$el.owlCarousel(this.options).addClass('owl-carousel-init animated fadeIn');
2131
2132			// Remove "animated fadeIn" class to prevent conflicts
2133			setTimeout(() => {
2134				$el.removeClass('animated fadeIn');
2135			}, 1000);
2136
2137			// Owl Carousel Wrapper
2138			if( $el.closest('.owl-carousel-wrapper').get(0) ) {
2139				setTimeout(() => {
2140					$el.closest('.owl-carousel-wrapper').css({
2141						height: ''
2142					});
2143				}, 500);
2144			}
2145
2146			// Owl Carousel Loader
2147			if( $el.prev().hasClass('owl-carousel-loader') ) {
2148				$el.prev().remove();
2149			}
2150
2151			// Nav Offset
2152			self.navigationOffsets();
2153
2154			// Nav Outside
2155			if( $el.hasClass('nav-outside') ) {
2156				$(window).on('owl.carousel.nav.outside', () => {
2157					if( $(window).width() < 992 ) {
2158						self.options.stagePadding = 40;
2159						$el.addClass('stage-margin');
2160					} else {
2161						self.options.stagePadding = 0;
2162						$el.removeClass('stage-margin');
2163					}
2164
2165					$el.owlCarousel('destroy').owlCarousel( self.options );
2166
2167					// Nav Offset
2168					self.navigationOffsets();
2169				});
2170
2171				// Window Resize
2172				$(window).on('load', () => {
2173					$(window).afterResize(() => {
2174						$(window).trigger('owl.carousel.nav.outside');
2175					});
2176				});
2177
2178				// First Load
2179				$(window).trigger('owl.carousel.nav.outside');
2180			}
2181
2182			// Nav style 5 (SVG Arrows)
2183			if( $el.hasClass('nav-svg-arrows-1') ) {
2184				const svg_arrow = '' +
2185					'<svg version="1.1" viewBox="0 0 15.698 8.706" width="17" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
2186						'<polygon stroke="#212121" stroke-width="0.1" fill="#212121" points="11.354,0 10.646,0.706 13.786,3.853 0,3.853 0,4.853 13.786,4.853 10.646,8 11.354,8.706 15.698,4.353 "/>' +
2187					'</svg>';
2188
2189				$el.find('.owl-next, .owl-prev').append( svg_arrow );
2190			}
2191
2192			// Sync
2193			if( $el.attr('data-sync') ) {
2194				$el.on('change.owl.carousel', ({namespace, property, relatedTarget}) => {
2195					if (namespace && property.name === 'position') {
2196					    const target = relatedTarget.relative(property.value, true);
2197					    $( $el.data('sync') ).owlCarousel('to', target, 300, true);				        
2198				  	}
2199				});
2200			}
2201
2202			// Carousel Center Active Item
2203			if( $el.hasClass('carousel-center-active-item') ) {
2204				const itemsActive    = $el.find('.owl-item.active'), indexCenter    = Math.floor( ($el.find('.owl-item.active').length - 1) / 2 ), itemCenter     = itemsActive.eq
2204(indexCenter);
2205
2206				itemCenter.addClass('current');
2207
2208				$el.on('change.owl.carousel', event => {
2209				  	$el.find('.owl-item').removeClass('current');
2210					
2211					setTimeout(() => {
2212					  	const itemsActive    = $el.find('.owl-item.active'), indexCenter    = Math.floor( ($el.find('.owl-item.active').length - 1) / 2 ), itemCenter     = itemsActive.eq(indexCenter);
2213
2214					  	itemCenter.addClass('current');
2215					}, 100);
2216				});
2217
2218				// Refresh
2219				$el.trigger('refresh.owl.carousel');
2220
2221			}
2222
2223			// AnimateIn / AnimateOut Fix
2224			if( self.options.animateIn || self.options.animateOut ) {
2225				$el.on('change.owl.carousel', event => {
2226
2227					// Hide elements inside carousel
2228				    $el.find('[data-appear-animation], [data-plugin-animated-letters]').addClass('d-none');
2229
2230				    // Animated Letters
2231				    $el.find('[data-plugin-animated-letters]').trigger('animated.letters.destroy');
2232
2233				    // Remove "d-none" class before show the element. This is useful when using background images inside a carousel. Like ken burns effect
2234				    $el.find('.owl-item:not(.active) [data-carousel-onchange-show]').removeClass('d-none');
2235
2236				});
2237
2238				$el.on('changed.owl.carousel', event => {
2239					setTimeout(() => {
2240
2241					    // Appear Animation
2242				    	$el.find('[data-appear-animation]').each(function() {
2243                            const $this = $(this);
2244                            let opts;
2245
2246                            const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
2247                            if (pluginOptions)
2248								opts = pluginOptions;
2249
2250                            $this.themePluginAnimate(opts);
2251                        });
2252
2253						// Show elements inside carousel
2254					    $el.find('.owl-item.active [data-appear-animation], [data-plugin-animated-letters]').removeClass('d-none');
2255
2256					    // Animated Letters
2257					    $el.find('.owl-item.active [data-plugin-animated-letters]').trigger('animated.letters.initialize');
2258
2259					    // Background Video
2260					    $el.find('.owl-item.cloned.active [data-plugin-video-background]').trigger('video.background.initialize');
2261
2262					}, 10);
2263				    
2264				});
2265			}
2266
2267			// data-icon inside carousel
2268			if( $el.find('[data-icon]').length ) {
2269				$el.on('change.owl.carousel drag.owl.carousel', () => {
2270					$el.find('.owl-item.cloned [data-icon]').each(function(){
2271                        const $this = $(this);
2272                        let opts;
2273
2274                        const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
2275                        if (pluginOptions)
2276							opts = pluginOptions;
2277
2278                        $this.themePluginIcon(opts);
2279                    });
2280				});
2281			}
2282
2283			// Render Background Videos inside carousel. Just a trigger on window is sufficient to render
2284			if( $el.find('[data-plugin-video-background]').get(0) ) {
2285				$(window).resize();
2286			}
2287
2288			// Remove Loading
2289			$el.removeClass('owl-loading');
2290
2291			// Remove Height
2292			$el.css('height', 'auto');
2293
2294			// Carousel Navigate By ID and item index
2295			self.carouselNavigate();
2296
2297			// Refresh Carousel
2298			if( self.options.refresh ) {
2299				$el.owlCarousel('refresh');
2300			}
2301
2302			return this;
2303		}
2304
2305        navigationOffsets() {
2306			const self 			 = this, $el  			 = this.options.wrapper, navHasTransform  = $el.find('.owl-nav').css('transform') == 'none' ? false : true, dotsHasTransform = $el.find('.owl-dots').css('transform') == 'none' ? false : true;
2307
2308			// ************* NAV *****************
2309			// Nav Offset - Horizontal
2310			if( self.options.navHorizontalOffset && !self.options.navVerticalOffset ) {
2311				if( !navHasTransform ) {
2312					$el.find('.owl-nav').css({
2313						transform: 'translate3d('+ self.options.navHorizontalOffset +', 0, 0)'
2314					});
2315				} else {
2316					$el.find('.owl-nav').css({
2317						left: self.options.navHorizontalOffset
2318					});
2319				}
2320			}
2321
2322			// Nav Offset - Vertical
2323			if( self.options.navVerticalOffset && !self.options.navHorizontalOffset ) {
2324				if( !navHasTransform ) {
2325					$el.find('.owl-nav').css({
2326						transform: 'translate3d(0, '+ self.options.navVerticalOffset +', 0)'
2327					});
2328				} else {
2329					$el.find('.owl-nav').css({
2330						top: 'calc( 50% - '+ self.options.navVerticalOffset +' )'
2331					});
2332				}
2333			}
2334
2335			// Nav Offset - Horizontal & Vertical
2336			if( self.options.navVerticalOffset && self.options.navHorizontalOffset ) {
2337				if( !navHasTransform ) {
2338					$el.find('.owl-nav').css({
2339						transform: 'translate3d('+ self.options.navHorizontalOffset +', '+ self.options.navVerticalOffset +', 0)'
2340					});
2341				} else {
2342					$el.find('.owl-nav').css({
2343						top: 'calc( 50% - '+ self.options.navVerticalOffset +' )',
2344						left: self.options.navHorizontalOffset
2345					});
2346				}
2347			}
2348
2349			// ********** DOTS *********************
2350			// Dots Offset - Horizontal
2351			if( self.options.dotsHorizontalOffset && !self.options.dotsVerticalOffset ) {
2352				$el.find('.owl-dots').css({
2353					transform: 'translate3d('+ self.options.dotsHorizontalOffset +', 0, 0)'
2354				});
2355			}
2356
2357			// Dots Offset - Vertical
2358			if( self.options.dotsVerticalOffset && !self.options.dotsHorizontalOffset ) {
2359				if( !dotsHasTransform ) {
2360					$el.find('.owl-dots').css({
2361						transform: 'translate3d(0, '+ self.options.dotsVerticalOffset +', 0)'
2362					});
2363				} else {
2364					$el.find('.owl-dots').css({
2365						top: 'calc( 50% - '+ self.options.dotsVerticalOffset +' )'
2366					});
2367				}
2368			}
2369
2370			// Dots Offset - Horizontal & Vertical
2371			if( self.options.dotsVerticalOffset && self.options.dotsHorizontalOffset ) {
2372				$el.find('.owl-dots').css({
2373					transform: 'translate3d('+ self.options.dotsHorizontalOffset +', '+ self.options.dotsVerticalOffset +', 0)'
2374				});
2375			}
2376
2377			return this;
2378		}
2379
2380        carouselNavigate() {
2381			const self      = this, $el       = this.options.wrapper, $carousel = $el.data('owl.carousel');
2382
2383			if( $('[data-carousel-navigate]').get(0) ) {
2384				$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').each(function(){
2385					const $this = $(this), hasCarousel = $( $this.data('carousel-navigate-id') ).get(0), toIndex = $this.data('carousel-navigate-to');
2386
2387					if( hasCarousel ) {
2388
2389						$this.on('click', () => {
2390							$carousel.to( parseInt(toIndex) - 1 );
2391						});
2392
2393					}
2394				});
2395
2396				$el.on('change.owl.carousel', () => {
2397					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').removeClass('active');
2398				});
2399
2400				$el.on('changed.owl.carousel', ({item}) => {
2401					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"][data-carousel-navigate-to="'+ ( item.index + 1 ) +'"]').addClass('active');
2402				});
2403			}
2404
2405			return this;
2406		}
2407    }
2408
2409    PluginCarousel.defaults = {
2410		loop: true,
2411		responsive: {
2412			0: {
2413				items: 1
2414			},
2415			479: {
2416				items: 1
2417			},
2418			768: {
2419				items: 2
2420			},
2421			979: {
2422				items: 3
2423			},
2424			1199: {
2425				items: 4
2426			}
2427		},
2428		navText: [],
2429		refresh: false
2430	};
2431
2432    // expose to scope
2433    $.extend(theme, {
2434		PluginCarousel
2435	});
2436
2437    // jquery plugin
2438    $.fn.themePluginCarousel = function(opts) {
2439		return this.map(function() {
2440			const $this = $(this);
2441
2442			if ($this.data(instanceName)) {
2443				return $this.data(instanceName);
2444			} else {
2445				return new PluginCarousel($this, opts);
2446			}
2447
2448		});
2449	}
2450})).apply(this, [window.theme, jQuery]);
2451
2452// Chart Circular
2453(((theme = {}, $) => {
2454    const instanceName = '__chartCircular';
2455
2456    class PluginChartCircular {
2457        constructor($el, opts) {
2458            return this.initialize($el, opts);
2459        }
2460
2461        initialize($el, opts) {
2462			if ($el.data(instanceName)) {
2463				return this;
2464			}
2465
2466			this.$el = $el;
2467
2468			this
2469				.setData()
2470				.setOptions(opts)
2471				.build();
2472
2473			return this;
2474		}
2475
2476        setData() {
2477			this.$el.data(instanceName, this);
2478
2479			return this;
2480		}
2481
2482        setOptions(opts) {
2483			this.options = $.extend(true, {}, PluginChartCircular.defaults, opts, {
2484				wrapper: this.$el
2485			});
2486
2487			return this;
2488		}
2489
2490        build() {
2491			if (!($.isFunction($.fn.easyPieChart))) {
2492				return this;
2493			}
2494
2495			const self = this, $el = this.options.wrapper, value = ($el.attr('data-percent') ? $el.attr('data-percent') : 0), percentEl = $el.find('.percent');
2496
2497			$.extend(true, self.options, {
2498				onStep(from, to, currentValue) {
2499					percentEl.html(parseInt(currentValue));
2500				}
2501			});
2502
2503			$el.attr('data-percent', 0);
2504
2505			$el.easyPieChart(self.options);
2506
2507			setTimeout(() => {
2508
2509				$el.data('easyPieChart').update(value);
2510				$el.attr('data-percent', value);
2511
2512			}, self.options.delay);
2513
2514			return this;
2515		}
2516    }
2517
2518    PluginChartCircular.defaults = {
2519		accX: 0,
2520		accY: -150,
2521		delay: 1,
2522		barColor: '#0088CC',
2523		trackColor: '#f2f2f2',
2524		scaleColor: false,
2525		scaleLength: 5,
2526		lineCap: 'round',
2527		lineWidth: 13,
2528		size: 175,
2529		rotate: 0,
2530		animate: ({
2531			duration: 2500,
2532			enabled: true
2533		})
2534	};
2535
2536    // expose to scope
2537    $.extend(theme, {
2538		PluginChartCircular
2539	});
2540
2541    // jquery plugin
2542    $.fn.themePluginChartCircular = function(opts) {
2543		return this.map(function() {
2544			const $this = $(this);
2545
2546			if ($this.data(instanceName)) {
2547				return $this.data(instanceName);
2548			} else {
2549				return new PluginChartCircular($this, opts);
2550			}
2551
2552		});
2553	}
2554})).apply(this, [window.theme, jQuery]);
2555
2556// Countdown
2557(((theme = {}, $) => {
2558    const instanceName = '__countdown';
2559
2560    class PluginCountdown {
2561        constructor($el, opts) {
2562            return this.initialize($el, opts);
2563        }
2564
2565        initialize($el, opts) {
2566			if ($el.data(instanceName)) {
2567				return this;
2568			}
2569
2570			this.$el = $el;
2571
2572			this
2573				.setData()
2574				.setOptions(opts)
2575				.build();
2576
2577			return this;
2578		}
2579
2580        setData() {
2581			this.$el.data(instanceName, this);
2582
2583			return this;
2584		}
2585
2586        setOptions(opts) {
2587			this.options = $.extend(true, {}, PluginCountdown.defaults, opts, {
2588				wrapper: this.$el
2589			});
2590
2591			return this;
2592		}
2593
2594        build() {
2595			if (!($.isFunction($.fn.countTo))) {
2596				return this;
2597			}
2598
2599			const self = this, $el = this.options.wrapper, numberClass = ( self.options.numberClass ) ? ' ' + self.options.numberClass : '', wrapperClass = ( self.options.wrapperClass ) ? ' ' + self.options.wrapperClass : '';
2600
2601			if( self.options.uppercase ) {
2602				$el.countdown(self.options.date).on('update.countdown', function(event) {
2603					const $this = $(this).html(event.strftime(self.options.insertHTMLbefore
2604						+ '<span class="days'+ wrapperClass +'"><span class="'+ numberClass +'">%D</span> '+ self.options.textDay +'</span> '
2605						+ '<span class="hours'+ wrapperClass +'"><span class="'+ numberClass +'">%H</span> '+ self.options.textHour +'</span> '
2606						+ '<span class="minutes'+ wrapperClass +'"><span class="'+ numberClass +'">%M</span> '+ self.options.textMin +'</span> '
2607						+ '<span class="seconds'+ wrapperClass +'"><span class="'+ numberClass +'">%S</span> '+ self.options.textSec +'</span> '
2608						+ self.options.insertHTMLafter
2609					));
2610				});
2611			} else {
2612				$el.countdown(self.options.date).on('update.countdown', function(event) {
2613					const $this = $(this).html(event.strftime(self.options.insertHTMLbefore
2614						+ '<span class="days'+ wrapperClass +'"><span class="'+ numberClass +'">%D</span> '+ self.options.textDay +'</span> '
2615						+ '<span class="hours'+ wrapperClass +'"><span class="'+ numberClass +'">%H</span> '+ self.options.textHour +'</span> '
2616						+ '<span class="minutes'+ wrapperClass +'"><span class="'+ numberClass +'">%M</span> '+ self.options.textMin +'</span> '
2617						+ '<span class="seconds'+ wrapperClass +'"><span class="'+ numberClass +'">%S</span> '+ self.options.textSec +'</span> '
2618						+ self.options.insertHTMLafter
2619					));
2620				});
2621			}
2622
2623			return this;
2624		}
2625    }
2626
2627    PluginCountdown.defaults = {
2628		date: '2030/06/10 12:00:00',
2629		textDay: 'DAYS',
2630		textHour: 'HRS',
2631		textMin: 'MIN',
2632		textSec: 'SEC',
2633		uppercase: true,
2634		numberClass: '',
2635		wrapperClass: '',
2636		insertHTMLbefore: '',
2637		insertHTMLafter: ''
2638	};
2639
2640    // expose to scope
2641    $.extend(theme, {
2642		PluginCountdown
2643	});
2644
2645    // jquery plugin
2646    $.fn.themePluginCountdown = function(opts) {
2647		return this.map(function() {
2648			const $this = $(this);
2649
2650			if ($this.data(instanceName)) {
2651				return $this.data(instanceName);
2652			} else {
2653				return new PluginCountdown($this, opts);
2654			}
2655
2656		});
2657	}
2658})).apply(this, [window.theme, jQuery]);
2659
2660// Counter
2661(((theme = {}, $) => {
2662    const instanceName = '__counter';
2663
2664    class PluginCounter {
2665        constructor($el, opts) {
2666            return this.initialize($el, opts);
2667        }
2668
2669        initialize($el, opts) {
2670			if ($el.data(instanceName)) {
2671				return this;
2672			}
2673
2674			this.$el = $el;
2675
2676			this
2677				.setData()
2678				.setOptions(opts)
2679				.build();
2680
2681			return this;
2682		}
2683
2684        setData() {
2685			this.$el.data(instanceName, this);
2686
2687			return this;
2688		}
2689
2690        setOptions(opts) {
2691			this.options = $.extend(true, {}, PluginCounter.defaults, opts, {
2692				wrapper: this.$el
2693			});
2694
2695			return this;
2696		}
2697
2698        build() {
2699			if (!($.isFunction($.fn.countTo))) {
2700				return this;
2701			}
2702
2703			const self = this, $el = this.options.wrapper;
2704
2705			if (self.options.comma) {
2706				self.options.formatter = (value, {decimals}) => value.toFixed(decimals).toString().replace('.',',')
2707			}
2708
2709			$.extend(self.options, {
2710				onComplete() {
2711					
2712					if ($el.data('append')) {
2713						if( self.options.appendWrapper ) {
2714							const appendWrapper = $( self.options.appendWrapper );
2715
2716							appendWrapper.append( $el.data('append') );
2717
2718							$el.html( $el.html() + appendWrapper[0].outerHTML );
2719						} else {
2720							$el.html($el.html() + $el.data('append'));
2721						}
2722					}
2723
2724					if ($el.data('prepend')) {
2725						if( self.options.prependWrapper ) {
2726							const prependWrapper = $( self.options.prependWrapper );
2727
2728							prependWrapper.append( $el.data('prepend') );
2729
2730							$el.html( $el.html() + prependWrapper[0].outerHTML );
2731						} else {
2732							$el.html($el.data('prepend') + $el.html());
2733						}
2734					}
2735				}
2736			});
2737
2738			$el.countTo(self.options);
2739
2740			return this;
2741		}
2742    }
2743
2744    PluginCounter.defaults = {
2745		accX: 0,
2746		accY: 0,
2747		appendWrapper: false,
2748		prependWrapper: false,
2749		speed: 3000,
2750		refreshInterval: 100,
2751		decimals: 0,
2752		comma: false,
2753		onUpdate: null,
2754		onComplete: null
2755	}
2756
2757    // expose to scope
2758    $.extend(theme, {
2759		PluginCounter
2760	});
2761
2762    // jquery plugin
2763    $.fn.themePluginCounter = function(opts) {
2764		return this.map(function() {
2765			const $this = $(this);
2766
2767			if ($this.data(instanceName)) {
2768				return $this.data(instanceName);
2769			} else {
2770				return new PluginCounter($this, opts);
2771			}
2772
2773		});
2774	}
2775})).apply(this, [window.theme, jQuery]);
2776
2777// CursorEffect
2778(((theme = {}, $) => {
2779    const instanceName = '__cursorEffect';
2780
2781    class PluginCursorEffect {
2782        constructor($el, opts) {
2783            return this.initialize($el, opts);
2784        }
2785
2786        initialize($el, opts) {
2787			if ($el.data(instanceName)) {
2788				return this;
2789			}
2790
2791			this.$el = $el;
2792
2793			this
2794				.setData()
2795				.setOptions(opts)
2796				.build()
2797				.events();
2798
2799			return this;
2800		}
2801
2802        setData() {
2803			this.$el.data(instanceName, this);
2804
2805			return this;
2806		}
2807
2808        setOptions(opts) {
2809			this.options = $.extend(true, {}, PluginCursorEffect.defaults, opts, {
2810				wrapper: this.$el
2811			});
2812
2813			return this;
2814		}
2815
2816        build() {
2817			const self = this;
2818
2819			// Global Variables for cursor position
2820			self.clientX = -100;
2821			self.clientY = -100;
2822
2823			// Hide Mouse Cursor
2824			if( self.options.hideMouseCursor ) {
2825				self.$el.addClass('hide-mouse-cursor');
2826			}
2827
2828			// Creates the cursor wrapper node
2829			const cursorOuter = document.createElement('DIV');
2830				cursorOuter.className = 'cursor-outer';
2831
2832			// Creates the cursor inner node
2833			const cursorInner = document.createElement('DIV');
2834				cursorInner.className = 'cursor-inner';
2835
2836			// Custom Cursor Outer Color
2837			if( self.options.cursorOuterColor ) {
2838				cursorOuter.style = 'border-color: ' + self.options.cursorOuterColor + ';';
2839			}
2840
2841			// Custom Cursor Inner Color
2842			if( self.options.cursorInnerColor ) {
2843				cursorInner.style = 'background-color: ' + self.options.cursorInnerColor + ';';
2844			}
2845
2846			// Size
2847			if( self.options.size ) {
2848				switch ( self.options.size ) {
2849					case 'small':
2850						self.$el.addClass( 'cursor-effect-size-small' );
2851						break;
2852					
2853					case 'big':
2854						self.$el.addClass( 'cursor-effect-size-big' );
2855						break;
2856				}
2857			}
2858
2859			// Style
2860			if( self.options.style ) {
2861				self.$el.addClass( self.options.style );
2862			}
2863
2864			// Prepend cursor wrapper node to the body
2865			document.body.prepend( cursorOuter );
2866
2867			// Prepend cursor inner node to the body
2868			document.body.prepend( cursorInner );
2869
2870			// Loop for render
2871			const render = () => {
2872				cursorOuter.style.transform = 'translate('+ self.clientX +'px, '+ self.clientY +'px)';
2873				cursorInner.style.transform = 'translate('+ self.clientX +'px, '+ self.clientY +'px)';
2874
2875				self.loopInside = requestAnimationFrame(render);
2876			};
2877			self.loop = requestAnimationFrame(render);
2878
2879			return this;
2880		}
2881
2882        events() {
2883			const self = this, $cursorOuter = $('.cursor-outer'), $cursorInner = $('.cursor-inner');
2884
2885			const initialCursorOuterBox    = $cursorOuter[0].getBoundingClientRect(), initialCursorOuterRadius = $cursorOuter.css('border-radius');
2886
2887			// Update Cursor Position
2888			document.addEventListener('mousemove', ({clientX, clientY}) => {
2889				if( !self.isStuck ) {
2890					self.clientX = clientX - 20;
2891					self.clientY = clientY - 20;
2892				}
2893
2894				$cursorOuter.removeClass('opacity-0');
2895			});
2896
2897			self.isStuck = false;
2898			$('[data-cursor-effect-hover]').on('mouseenter', function(e){
2899
2900				// Identify Event With Hover Class
2901				$cursorOuter.addClass('cursor-outer-hover');
2902				$cursorInner.addClass('cursor-inner-hover');
2903
2904				// Hover Color
2905				const hoverColor = $(this).data('cursor-effect-hover-color');
2906				$cursorOuter.addClass( 'cursor-color-' + hoverColor );
2907				$cursorInner.addClass( 'cursor-color-' + hoverColor );
2908
2909				// Effect Types
2910				switch ( $(this).data('cursor-effect-hover') ) {
2911					case 'fit':
2912						const thisBox = $(this)[0].getBoundingClientRect();
2913
2914						self.clientX = thisBox.x;
2915						self.clientY = thisBox.y;
2916
2917						$cursorOuter.css({
2918							width: thisBox.width,
2919							height: thisBox.height,
2920							'border-radius': $(this).css('border-radius')
2921						}).addClass('cursor-outer-fit');
2922
2923						$cursorInner.addClass('opacity-0');
2924
2925						self.isStuck = true;
2926						break;
2927
2928					case 'plus':
2929						$cursorInner.addClass('cursor-inner-plus');
2930						break;
2931				}
2932			});
2933
2934			$('[data-cursor-effect-hover]').on('mouseleave', function(){
2935				
2936				// Identify Event With Hover Class
2937				$cursorOuter.removeClass('cursor-outer-hover');
2938				$cursorInner.removeClass('cursor-inner-hover');
2939
2940				// Remove Color Class
2941				const hoverColor = $(this).data('cursor-effect-hover-color');
2942				$cursorOuter.removeClass( 'cursor-color-' + hoverColor );
2943				$cursorInner.removeClass( 'cursor-color-' + hoverColor );
2944
2945				// Effect Types
2946				switch ( $(this).data('cursor-effect-hover') ) {
2947					case 'fit':
2948						$cursorOuter.css({
2949							width: initialCursorOuterBox.width,
2950							height: initialCursorOuterBox.height,
2951							'border-radius': initialCursorOuterRadius
2952						}).removeClass('cursor-outer-fit');
2953
2954						$cursorInner.removeClass('opacity-0');
2955
2956						self.isStuck = false;
2957						break;
2958
2959					case 'plus':
2960						$cursorInner.removeClass('cursor-inner-plus');
2961						break;
2962				}
2963			});
2964
2965			$(window).on('scroll', () => {
2966				if( $cursorOuter.hasClass('cursor-outer-fit') ) {
2967					$cursorOuter.addClass('opacity-0').removeClass('cursor-outer-fit');
2968				}
2969			});
2970
2971			return this;
2972		}
2973
2974        destroy() {
2975			const self = this;
2976
2977			self.$el.removeClass('hide-mouse-cursor cursor-effect-size-small cursor-effect-size-big cursor-effect-style-square');		
2978
2979			cancelAnimationFrame( self.loop );
2980			cancelAnimationFrame( self.loopInside );
2981
2982			document.querySelector('.cursor-outer').remove();
2983			document.querySelector('.cursor-inner').remove();
2984
2985			self.$el.removeData( instanceName, self );
2986		}
2987    }
2988
2989    PluginCursorEffect.defaults = {
2990
2991	}
2992
2993    // expose to scope
2994    $.extend(theme, {
2995		PluginCursorEffect
2996	});
2997
2998    // jquery plugin
2999    $.fn.themePluginCursorEffect = function(opts) {
3000		return this.map(function() {
3001			const $this = $(this);
3002
3003			if ($this.data(instanceName)) {
3004				return $this.data(instanceName);
3005			} else {
3006				return new PluginCursorEffect($this, opts);
3007			}
3008
3009		});
3010	}
3011})).apply(this, [window.theme, jQuery]);
3012
3013// Float Element
3014(((theme = {}, $) => {
3015    const instanceName = '__floatElement';
3016
3017    class PluginFloatElement {
3018        constructor($el, opts) {
3019            return this.initialize($el, opts);
3020        }
3021
3022        initialize($el, opts) {
3023			if ($el.data(instanceName)) {
3024				return this;
3025			}
3026
3027			this.$el = $el;
3028
3029			this
3030				.setData()
3031				.setOptions(opts)
3032				.build();
3033
3034			return this;
3035		}
3036
3037        setData() {
3038			this.$el.data(instanceName, this);
3039
3040			return this;
3041		}
3042
3043        setOptions(opts) {
3044			this.options = $.extend(true, {}, PluginFloatElement.defaults, opts, {
3045				wrapper: this.$el
3046			});
3047
3048			return this;
3049		}
3050
3051        build() {
3052            const self = this;
3053            const $el = this.options.wrapper;
3054            const $window = $(window);
3055            let minus;
3056
3057            // If has floating elements inside a SVG. 
3058            // Intersection Observer API do not check elements inside SVG's, so we need initialize trough top parent SVG
3059            if( $el.data('plugin-float-element-svg') ) {
3060				$el.find('[data-plugin-float-element]').each(function(){
3061                    const $this = $(this);
3062                    let opts;
3063
3064                    const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
3065                    if (pluginOptions)
3066						opts = pluginOptions;
3067
3068                    $this.themePluginFloatElement(opts);
3069                });
3070
3071				return this;
3072			}
3073
3074            if( self.options.style ) {
3075				$el.attr('style', self.options.style);
3076			}
3077
3078            if( $window.width() > self.options.minWindowWidth ) {
3079
3080				// Set Start Position
3081				if( self.options.startPos == 'none' ) {
3082					minus = '';
3083				} else if( self.options.startPos == 'top' ) {
3084					$el.css({
3085						top: 0
3086					});
3087					minus = '';
3088				} else {
3089					$el.css({
3090						bottom: 0
3091					});
3092					minus = '-';
3093				}
3094
3095				// Set Transition
3096				if( self.options.transition ) {
3097					$el.css({
3098						transition: 'ease-out transform '+ self.options.transitionDuration +'ms ' + self.options.transitionDelay + 'ms'
3099					});
3100				}
3101
3102				// First Load
3103				self.movement(minus);	
3104
3105				// Scroll
3106				$window.on('scroll', () => {
3107					self.movement(minus);				   
3108				});
3109
3110			}
3111
3112            return this;
3113        }
3114
3115        movement(minus) {
3116			const self = this, $el = this.options.wrapper, $window = $(window), scrollTop = $window.scrollTop(), elementOffset = $el.offset().top, currentElementOffset = (elementOffset - scrollTop), factor = ( self.options.isInsideSVG ) ? 2 : 100;
3117
3118		   	const scrollPercent = factor * currentElementOffset / ($window.height());
3119
3120		   	if( $el.visible( true ) ) {
3121
3122		   		if( !self.options.horizontal ) {
3123
3124		   			$el.css({
3125			   			transform: 'translate3d(0, '+ minus + scrollPercent / self.options.speed +'%, 0)'
3126			   		});
3127
3128		   		} else {
3129
3130		   			$el.css({
3131			   			transform: 'translate3d('+ minus + scrollPercent / self.options.speed +'%, 0, 0)'
3132			   		});
3133
3134		   		}
3135		   		
3136		   	}
3137
3138		}
3139    }
3140
3141    PluginFloatElement.defaults = {
3142		startPos: 'top',
3143		speed: 3,
3144		horizontal: false,
3145		isInsideSVG: false,
3146		transition: false,
3147		transitionDelay: 0,
3148		transitionDuration: 500,
3149		minWindowWidth: 991
3150	};
3151
3152    // expose to scope
3153    $.extend(theme, {
3154		PluginFloatElement
3155	});
3156
3157    // jquery plugin
3158    $.fn.themePluginFloatElement = function(opts) {
3159		return this.map(function() {
3160			const $this = $(this);
3161
3162			if ($this.data(instanceName)) {
3163				return $this.data(instanceName);
3164			} else {
3165				return new PluginFloatElement($this, opts);
3166			}
3167
3168		});
3169	}
3170})).apply(this, [window.theme, jQuery]);
3171
3172// GDPR
3173(((theme = {}, $) => {
3174    const instanceName = '__gdpr';
3175
3176    class PluginGDPR {
3177        constructor($el, opts) {
3178            return this.initialize($el, opts);
3179        }
3180
3181        initialize($el, opts) {
3182			const self = this;
3183
3184			this.$el = $el;
3185
3186			this
3187				.setData()
3188				.setOptions(opts)
3189				.build()
3190				.events();
3191
3192			return this;
3193		}
3194
3195        setData() {
3196			this.$el.data(instanceName, this);
3197
3198			return this;
3199		}
3200
3201        setOptions(opts) {
3202			this.options = $.extend(true, {}, PluginGDPR.defaults, opts, {
3203				wrapper: this.$el
3204			});
3205
3206			return this;
3207		}
3208
3209        build() {
3210			const self = this;
3211
3212			// Show
3213			if( !$.cookie( 'porto-privacy-bar' ) ) {
3214				setTimeout(() => {
3215					self.options.wrapper.addClass('show');
3216				}, self.options.cookieBarShowDelay);
3217			}
3218
3219			// If already has preferences cookie, check inputs according preferences cookie data
3220			if( $.cookie( 'porto-gdpr-preferences' ) ) {
3221				const preferencesArr = $.cookie( 'porto-gdpr-preferences' ).split(',');
3222
3223				for( let i = 0; i < preferencesArr.length; i++ ) {
3224					if( $('input[value="'+ preferencesArr[i] +'"]').get(0) ) {
3225						if( $('input[value="'+ preferencesArr[i] +'"]').is(':checkbox') ) {
3226							$('input[value="'+ preferencesArr[i] +'"]').prop('checked', true);
3227						}
3228					}
3229				}
3230			}
3231
3232			return this;
3233
3234		}
3235
3236        events() {
3237			const self = this;
3238
3239			// Agree Trigger
3240			self.options.wrapper.find('.gdpr-agree-trigger').on('click', e => {
3241				e.preventDefault();
3242
3243				$('.gdpr-preferences-form').find('.gdpr-input').each(function(){
3244					if( $(this).is(':checkbox') || $(this).is(':hidden') ) {
3245						$(this).prop('checked', true);
3246					}
3247				});
3248
3249				$('.gdpr-preferences-form').trigger('submit').removeClass('show');
3250
3251				self.removeCookieBar();
3252			});
3253
3254			// Preferences Trigger
3255			self.options.wrapper.find('.gdpr-preferences-trigger').on('click', e => {
3256				e.preventDefault();
3257
3258				$('.gdpr-preferences-popup').addClass('show');
3259			});
3260
3261			// Close Popup Button
3262			$('.gdpr-close-popup').on('click', e => {
3263				e.preventDefault();
3264
3265				$('.gdpr-preferences-popup').removeClass('show');
3266			});
3267
3268			// Close Popup When Click Outside of popup area
3269			$('.gdpr-preferences-popup').on('click', ({target}) => {
3270				if( !$(target).closest('.gdpr-preferences-popup-content').get(0) ) {
3271					$('.gdpr-preferences-popup').removeClass('show');
3272				}
3273			});
3274
3275			// Preference Form
3276			$('.gdpr-preferences-form').on('submit', function(e){
3277				e.preventDefault();
3278
3279				const $this = $(this);
3280
3281				// Save Preferences Button
3282				$this.find('button[type="submit"]').text( 'SAVING...' );
3283
3284				// Form Data
3285				const formData = [];
3286				$this.find('.gdpr-input').each(function(){
3287					if( $(this).is(':checkbox') && $(this).is(':checked') || $(this).is(':hidden') ) {
3288						formData.push( $(this).val() );
3289					}
3290				});
3291
3292				$.cookie( 'porto-privacy-bar', true, {expires: self.options.expires} );
3293
3294				setTimeout(() => {
3295					$this.find('button[type="submit"]').text( 'SAVED!' ).removeClass('btn-primary').addClass('btn-success');
3296
3297					setTimeout(() => {
3298						$('.gdpr-preferences-popup').removeClass('show');
3299						self.removeCookieBar();
3300
3301						$this.find('button[type="submit"]').text( 'SAVE PREFERENCES' ).removeClass('btn-success').addClass('btn-primary');
3302
3303						if( $.cookie( 'porto-gdpr-preferences' ) ) {
3304
3305							$.cookie( 'porto-gdpr-preferences', formData, {expires: self.options.expires} );
3306							location.reload();
3307
3308						} else {
3309
3310							$.cookie( 'porto-gdpr-preferences', formData, {expires: self.options.expires} );
3311
3312							if ($.isFunction($.fn['themePluginGDPRWrapper']) && $('[data-plugin-gdpr-wrapper]').length) {
3313
3314								$(() => {
3315									$('[data-plugin-gdpr-wrapper]:not(.manual)').each(function() {
3316                                        const $this = $(this);
3317                                        let opts;
3318
3319                                        $this.removeData('__gdprwrapper');
3320
3321                                        const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
3322                                        if (pluginOptions)
3323											opts = pluginOptions;
3324
3325                                        $this.themePluginGDPRWrapper(opts);
3326                                    });
3327								});
3328
3329							}
3330
3331						}
3332
3333					}, 500);
3334				}, 1000);
3335			});
3336
3337			// Remove/Reset Cookies
3338			$('.gdpr-reset-cookies').on('click', e => {
3339				e.preventDefault();
3340
3341				self.clearCookies();
3342
3343				location.reload();
3344			});
3345
3346			// Open Preferences
3347			$('.gdpr-open-preferences').on('click', e => {
3348				e.preventDefault();
3349
3350				$('.gdpr-preferences-popup').toggleClass('show');
3351			});
3352
3353			return this;
3354		}
3355
3356        removeCookieBar() {
3357			const self = this;
3358
3359			self.options.wrapper.addClass('removing').on('transitionend', () => {
3360				setTimeout(() => {
3361					self.options.wrapper.removeClass('show removing');
3362				}, 500);
3363			});
3364
3365			return this;
3366		}
3367
3368        clearCookies() {
3369			const self = this;
3370
3371			$.removeCookie( 'porto-privacy-bar' );
3372			$.removeCookie( 'porto-gdpr-preferences' );
3373
3374			return this;
3375		}
3376    }
3377
3378    PluginGDPR.defaults = {
3379		cookieBarShowDelay: 3000,
3380		expires: 365
3381	};
3382
3383    // expose to scope
3384    $.extend(theme, {
3385		PluginGDPR
3386	});
3387
3388    // jquery plugin
3389    $.fn.themePluginGDPR = function(opts) {
3390		return this.map(function() {
3391			const $this = $(this);
3392
3393			if ($this.data(instanceName)) {
3394				return $this.data(instanceName);
3395			} else {
3396				return new PluginGDPR($this, opts);
3397			}
3398
3399		});
3400	}
3401})).apply(this, [window.theme, jQuery]);
3402
3403// GDPR Wrapper
3404(((theme = {}, $) => {
3405    const instanceName = '__gdprwrapper';
3406
3407    class PluginGDPRWrapper {
3408        constructor($el, opts) {
3409            return this.initialize($el, opts);
3410        }
3411
3412        initialize($el, opts) {
3413			const self = this;
3414
3415			this.$el = $el;
3416
3417			this
3418				.setData()
3419				.setOptions(opts)
3420				.build();
3421				
3422			return this;
3423		}
3424
3425        setData() {
3426			this.$el.data(instanceName, this);
3427
3428			return this;
3429		}
3430
3431        setOptions(opts) {
3432			this.options = $.extend(true, {}, PluginGDPRWrapper.defaults, opts, {
3433				wrapper: this.$el
3434			});
3435
3436			return this;
3437		}
3438
3439        build() {
3440			const self = this;
3441
3442			if( $.cookie( 'porto-gdpr-preferences' ) && $.cookie( 'porto-gdpr-preferences' ).includes(self.options.checkCookie) ) {
3443
3444				$.ajax({
3445					url: self.options.ajaxURL,
3446					cache: false,
3447					complete({responseText}) {
3448					
3449						setTimeout(() => {
3450
3451							self.options.wrapper.html(responseText).addClass('show');
3452
3453						}, 1000);
3454
3455					}
3456				});
3457
3458			} else {
3459				self.options.wrapper.addClass('show');
3460			}
3461
3462			return this;
3463
3464		}
3465    }
3466
3467    PluginGDPRWrapper.defaults = {
3468
3469	};
3470
3471    // expose to scope
3472    $.extend(theme, {
3473		PluginGDPRWrapper
3474	});
3475
3476    // jquery plugin
3477    $.fn.themePluginGDPRWrapper = function(opts) {
3478		return this.map(function() {
3479			const $this = $(this);
3480
3481			if ($this.data(instanceName)) {
3482				return $this.data(instanceName);
3483			} else {
3484				return new PluginGDPRWrapper($this, opts);
3485			}
3486
3487		});
3488	}
3489})).apply(this, [window.theme, jQuery]);
3490
3491// Hover Effect
3492(((theme = {}, $) => {
3493    const instanceName = '__hoverEffect';
3494
3495    class PluginHoverEffect {
3496        constructor($el, opts) {
3497            return this.initialize($el, opts);
3498        }
3499
3500        initialize($el, opts) {
3501			if ($el.data(instanceName)) {
3502				return this;
3503			}
3504
3505			this.$el = $el;
3506
3507			this
3508				.setData()
3509				.setOptions(opts)
3510				.build();
3511
3512			return this;
3513		}
3514
3515        setData() {
3516			this.$el.data(instanceName, this);
3517
3518			return this;
3519		}
3520
3521        setOptions(opts) {
3522			this.options = $.extend(true, {}, PluginHoverEffect.defaults, opts, {
3523				wrapper: this.$el
3524			});
3525
3526			return this;
3527		}
3528
3529        build() {
3530			const self = this;
3531
3532			if(self.$el.hasClass('hover-effect-3d')) {
3533				self.options.effect = '3d';
3534			}
3535
3536			// Magnetic
3537			if(self.options.effect == 'magnetic') {
3538				self.magnetic();
3539			}
3540
3541			// 3d
3542			if(self.options.effect == '3d') {
3543				self.hover3d();
3544			}
3545
3546			return this;
3547		}
3548
3549        magnetic() {
3550			const self = this;
3551
3552			self.$el.mousemove(function({clientX, clientY}) {
3553
3554				const pos = this.getBoundingClientRect();
3555				const mx = clientX - pos.left - pos.width/2; 
3556				const my = clientY - pos.top - pos.height/2;
3557
3558				this.style.transform = 'translate('+ mx * self.options.magneticMx +'px, '+ my * self.options.magneticMx +'px)';
3559
3560			});
3561
3562			self.$el.mouseleave(function(e) {
3563
3564				this.style.transform = 'translate3d(0px, 0px, 0px)';
3565
3566			});
3567
3568			return this;
3569
3570		}
3571
3572        hover3d() {
3573			const self = this;
3574
3575			if ($.isFunction($.fn['hover3d'])) {
3576
3577				self.$el.hover3d({
3578					selector: self.options.selector,
3579					sensitivity: self.options.sensitivity
3580				});
3581
3582			}
3583
3584			return this;
3585
3586		}
3587    }
3588
3589    PluginHoverEffect.defaults = {
3590		effect: 'magnetic',
3591		magneticMx: 0.15,
3592		magneticMy: 0.3,
3593		magneticDeg: 12,
3594		selector: '.thumb-info, .hover-effect-3d-wrapper',
3595		sensitivity: 20
3596	};
3597
3598    // expose to scope
3599    $.extend(theme, {
3600		PluginHoverEffect
3601	});
3602
3603    // jquery plugin
3604    $.fn.themePluginHoverEffect = function(opts) {
3605		return this.map(function() {
3606			const $this = $(this);
3607
3608			if ($this.data(instanceName)) {
3609				return $this.data(instanceName);
3610			} else {
3611				return new PluginHoverEffect($this, opts);
3612			}
3613
3614		});
3615	};
3616})).apply(this, [window.theme, jQuery]);
3617
3618// Icon
3619(((theme = {}, $) => {
3620    const instanceName = '__icon';
3621
3622    class PluginIcon {
3623        constructor($el, opts) {
3624            return this.initialize($el, opts);
3625        }
3626
3627        initialize($el, opts) {
3628			if ($el.data(instanceName)) {
3629				return this;
3630			}
3631
3632			this.$el = $el;
3633
3634			this
3635				.setData()
3636				.setOptions(opts)
3637				.build();
3638
3639			return this;
3640		}
3641
3642        setData() {
3643			this.$el.data(instanceName, this);
3644
3645			return this;
3646		}
3647
3648        setOptions(opts) {
3649			this.options = $.extend(true, {}, PluginIcon.defaults, opts, {
3650				wrapper: this.$el
3651			});
3652
3653			return this;
3654		}
3655
3656        build() {
3657            const self  	 = this;
3658            let $el   	 = this.options.wrapper;
3659            const color 	 = self.options.color;
3660            const elTopDistance = $el.offset().top;
3661            const windowTopDistance = $(window).scrollTop();
3662            let duration = ( self.options.animated && !self.options.strokeBased ) ? 200 : 100;
3663
3664            // Check origin
3665            if( window.location.protocol === 'file:' ) {
3666				$el.css({
3667					opacity: 1,
3668					width: $el.attr('width')
3669				});
3670
3671				if( self.options.extraClass ) {
3672					$el.addClass( self.options.extraClass );
3673				}
3674
3675				if( self.options.extraClass.indexOf('-color-light') > 0 ) {
3676					$el.css({
3677						filter: 'invert(1)'
3678					});
3679				}
3680
3681				$(window).trigger('icon.rendered');
3682				return;
3683			}
3684
3685            // Duration
3686            if( self.options.duration ) {
3687				duration = self.options.duration;
3688			}
3689
3690            // SVG Content
3691			const fileName = $el.attr('src');
3692
3693			if(fileName.split('.').pop() == 'svg') {
3694				const SVGContent = $.get({
3695					url: fileName, 
3696					success(data, status, {responseText}) {
3697						const iconWrapper = self.options.fadeIn ? $('<div class="animated-icon animated fadeIn">'+ responseText +'</div>') : $('<div class="animated-icon animated">'+ responseText +'</div>'), uniqid = 'icon_' + Math.floor(Math.random() * 26) + Date.now();
3698
3699						// Add ID
3700						iconWrapper.find('svg').attr('id', uniqid);
3701
3702						// Identify with filename
3703						iconWrapper.find('svg').attr('data-filename', $el.attr('src').split(/(\\|\/)/g).pop());
3704
3705						if( $el.attr('width') ) {
3706							iconWrapper.find('svg')
3707								.attr('width', $el.attr('width'))
3708								.attr('height', $el.attr('width'));						
3709						}
3710
3711						if( $el.attr('height') ) {
3712							iconWrapper.find('svg')
3713								.attr('height', $el.attr('height'));	
3714						}
3715
3716						if( self.options.svgViewBox ) {
3717							iconWrapper.find('svg')
3718								.attr('viewBox', self.options.svgViewBox);
3719						}
3720
3721						$el.replaceWith(iconWrapper);
3722
3723						if( self.options.extraClass ) {
3724							iconWrapper.addClass( self.options.extraClass );
3725						}
3726
3727						if( self.options.removeClassAfterInit ) {
3728							iconWrapper.removeClass(self.options.removeClassAfterInit);
3729						}
3730
3731						if( self.options.onlySVG ) {
3732							$(window).trigger('icon.rendered');
3733							return this;
3734						}
3735
3736						$el = iconWrapper;
3737
3738						const icon = new Vivus(uniqid, {start: 'manual', type: 'sync', selfDestroy: true, duration, onReady({el}) {
3739							const styleElement = document.createElementNS("http://www.w3.org/2000/svg", "style");
3740							let animateStyle = '';
3741
3742							// SVG Fill Based
3743							if( self.options.animated && !self.options.strokeBased || !self.options.animated && color && !self.options.strokeBased ) {
3744								animateStyle = 'stroke-width: 0.1px; fill-opacity: 0; transition: ease fill-opacity 300ms;';
3745								
3746								// Set Style on SVG inside object
3747								styleElement.textContent = '#' + uniqid + ' path, #' + uniqid + ' line, #' + uniqid + ' rect, #' + uniqid + ' circle, #' + uniqid + ' polyline { fill: '+ color +'; stroke: '+ color +'; '+ animateStyle + (self.options.svgStyle ? self.options.svgStyle : "") + ' } .finished path { fill-opacity: 1; }';
3748								el.appendChild(styleElement);
3749							}
3750
3751							// SVG Stroke Based
3752							if( self.options.animated && self.options.strokeBased || !self.options.animated && color && self.options.strokeBased ) {
3753
3754								// Set Style on SVG inside object
3755								styleElement.textContent = '#' + uniqid + ' path, #' + uniqid + ' line, #' + uniqid + ' rect, #' + uniqid + ' circle, #' + uniqid + ' polyline { stroke: '+ color +'; ' + (self.options.svgStyle ? self.options.svgStyle : "") + '}';
3756								el.appendChild(styleElement);
3757							}
3758
3759							$.event.trigger('theme.plugin.icon.svg.ready');
3760						}});
3761
3762						// Isn't animated
3763						if( !self.options.animated ) {
3764							setTimeout(() => {
3765								icon.finish();
3766							}, 10);
3767							$el.css({ opacity: 1 });
3768						}
3769
3770						// Animated
3771						if( self.options.animated && $(window).width() > 767 ) {
3772							
3773							// First Load
3774							if( $el.visible( true ) ) {
3775								self.startIconAnimation( icon, $el );
3776							} else if( elTopDistance < windowTopDistance ) {
3777								self.startIconAnimation( icon, $el );
3778							}
3779
3780							// On Scroll
3781							$(window).on('scroll', () => {
3782								if( $el.visible( true ) ) {
3783									self.startIconAnimation( icon, $el );
3784								}
3785							});
3786
3787						} else {
3788							
3789							$el.css({ opacity: 1 });
3790							icon.finish();
3791							
3792							$(window).on('theme.plugin.icon.svg.ready', () => {
3793								setTimeout(() => {
3794									icon.el.setAttribute('class', 'finished');
3795									icon.finish();
3796								}, 300);
3797							});
3798							
3799						}
3800
3801						$(window).trigger('icon.rendered');
3802					}
3803				});
3804			} else {
3805				$el.removeAttr('data-icon');
3806			}
3807
3808            return this;
3809        }
3810
3811        startIconAnimation(icon, $el) {
3812			const self = this;
3813
3814			// Animate for better performance
3815			$({to:0}).animate({to:1}, ((self.options.strokeBased) ? self.options.delay : self.options.delay + 300 ), () => {
3816				$el.css({ opacity: 1 });
3817			});
3818
3819			$({to:0}).animate({to:1}, self.options.delay, () => {
3820				icon.play(1);
3821
3822				setTimeout(() => {
3823					icon.el.setAttribute('class', 'finished');
3824				}, icon.duration * 5 );
3825			});
3826		}
3827    }
3828
3829    PluginIcon.defaults = {
3830		color: '#2388ED',
3831		animated: false,
3832		delay: 300,
3833		onlySVG: false,
3834		removeClassAfterInit: false,
3835		fadeIn: true,
3836		accY: 0
3837	};
3838
3839    // expose to scope
3840    $.extend(theme, {
3841		PluginIcon
3842	});
3843
3844    // jquery plugin
3845    $.fn.themePluginIcon = function(opts) {
3846		return this.map(function() {
3847			const $this = $(this);
3848
3849			if ($this.data(instanceName)) {
3850				return $this.data(instanceName);
3851			} else {
3852				return new PluginIcon($this, opts);
3853			}
3854
3855		});
3856	};
3857})).apply(this, [window.theme, jQuery]);
3858
3859// In Viewport Style
3860(((theme = {}, $) => {
3861    const instanceName = '__inviewportstyle';
3862
3863    class PluginInViewportStyle {
3864        constructor($el, opts) {
3865            return this.initialize($el, opts);
3866        }
3867
3868        initialize($el, opts) {
3869			if ($el.data(instanceName)) {
3870				return this;
3871			}
3872
3873			this.$el = $el;
3874
3875			this
3876				.setData()
3877				.setOptions(opts)
3878				.build();
3879
3880			return this;
3881		}
3882
3883        setData() {
3884			this.$el.data(instanceName, this);
3885
3886			return this;
3887		}
3888
3889        setOptions(opts) {
3890			this.options = $.extend(true, {}, PluginInViewportStyle.defaults, opts, {});
3891
3892			return this;
3893		}
3894
3895        build() {
3896			const self = this, el = self.$el.get(0);
3897
3898			self.$el.css(self.options.style);
3899
3900		    if (typeof window.IntersectionObserver === 'function') {
3901			    const un = observeElementInViewport.observeElementInViewport(
3902			        el, () => {
3903			        	self.$el.css(self.options.styleIn);
3904			        	self.$el
3905			        		.addClass(self.options.classIn)
3906			        		.removeClass(self.options.classOut);
3907			        }, () => {
3908			        	self.$el.css(self.options.styleOut);
3909			        	self.$el
3910			        		.addClass(self.options.classOut)
3911			        		.removeClass(self.options.classIn);
3912			        }, {
3913			        	viewport: self.options.viewport, 
3914			            threshold: self.options.threshold,
3915						modTop: self.options.modTop,
3916						modBottom: self.options.modBottom
3917			        }
3918			    )
3919		    };
3920
3921			return this;
3922		}
3923    }
3924
3925    PluginInViewportStyle.defaults = {
3926		viewport: window, 
3927		threshold: [0],
3928		modTop: '-200px',
3929		modBottom: '-200px',
3930		style: {'transition': 'all 1s ease-in-out'},
3931		styleIn: '',
3932		styleOut: '',
3933		classIn: '',
3934		classOut: ''
3935	};
3936
3937    // expose to scope
3938    $.extend(theme, {
3939		PluginInViewportStyle
3940	});
3941
3942    // jquery plugin
3943    $.fn.themePluginInViewportStyle = function(opts) {
3944		return this.map(function() {
3945			const $this = $(this);
3946
3947			if ($this.data(instanceName)) {
3948				return $this.data(instanceName);
3949			} else {
3950				return new PluginInViewportStyle($this, opts);
3951			}
3952
3953		});
3954	}
3955})).apply(this, [window.theme, jQuery]);
3956
3957// Lightbox
3958(((theme = {}, $) => {
3959    const instanceName = '__lightbox';
3960
3961    class PluginLightbox {
3962        constructor($el, opts) {
3963            return this.initialize($el, opts);
3964        }
3965
3966        initialize($el, opts) {
3967			if ($el.data(instanceName)) {
3968				return this;
3969			}
3970
3971			this.$el = $el;
3972
3973			this
3974				.setData()
3975				.setOptions(opts)
3976				.build();
3977
3978			return this;
3979		}
3980
3981        setData() {
3982			this.$el.data(instanceName, this);
3983
3984			return this;
3985		}
3986
3987        setOptions(opts) {
3988			this.options = $.extend(true, {}, PluginLightbox.defaults, opts, {
3989				wrapper: this.$el
3990			});
3991
3992			return this;
3993		}
3994
3995        build() {
3996			if (!($.isFunction($.fn.magnificPopup))) {
3997				return this;
3998			}
3999
4000			this.options.wrapper.magnificPopup(this.options);
4001
4002			return this;
4003		}
4004    }
4005
4006    PluginLightbox.defaults = {
4007		tClose: 'Close (Esc)', // Alt text on close button
4008		tLoading: 'Loading...', // Text that is displayed during loading. Can contain %curr% and %total% keys
4009		gallery: {
4010			tPrev: 'Previous (Left arrow key)', // Alt text on left arrow
4011			tNext: 'Next (Right arrow key)', // Alt text on right arrow
4012			tCounter: '%curr% of %total%' // Markup for "1 of 7" counter
4013		},
4014		image: {
4015			tError: '<a href="%url%">The image</a> could not be loaded.' // Error message when image could not be loaded
4016		},
4017		ajax: {
4018			tError: '<a href="%url%">The content</a> could not be loaded.' // Error message when ajax request failed
4019		},
4020		callbacks: {
4021			open() {
4022				$('html').addClass('lightbox-opened');
4023			},
4024			close() {
4025				$('html').removeClass('lightbox-opened');
4026			}
4027		}
4028	};
4029
4030    // expose to scope
4031    $.extend(theme, {
4032		PluginLightbox
4033	});
4034
4035    // jquery plugin
4036    $.fn.themePluginLightbox = function(opts) {
4037		return this.map(function() {
4038			const $this = $(this);
4039
4040			if ($this.data(instanceName)) {
4041				return $this.data(instanceName);
4042			} else {
4043				return new PluginLightbox($this, opts);
4044			}
4045
4046		});
4047	}
4048})).apply(this, [window.theme, jQuery]);
4049
4050// Loading Overlay
4051(((theme = {}, $) => {
4052    // Default
4053    const loadingOverlayDefaultTemplate = [
4054		'<div class="loading-overlay">',
4055			'<div class="bounce-loader"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>',
4056		'</div>'
4057	].join('');
4058
4059    // Percentage
4060    const loadingOverlayPercentageTemplate = [
4061		'<div class="loading-overlay loading-overlay-percentage">',
4062			'<div class="page-loader-progress-wrapper"><span class="page-loader-progress">0</span><span class="page-loader-progress-symbol">%</span></div>',
4063		'</div>'
4064	].join('');
4065
4066    // Cubes
4067    const loadingOverlayCubesTemplate = [
4068		'<div class="loading-overlay">',
4069			'<div class="bounce-loader"><div class="cssload-thecube"><div class="cssload-cube cssload-c1"></div><div class="cssload-cube cssload-c2"></div><div class="cssload-cube cssload-c4"></div><div class="cssload-cube cssload-c3"></div></div></div>',
4070		'</div>'
4071	].join('');
4072
4073    // Cube Progress
4074    const loadingOverlayCubeProgressTemplate = [
4075		'<div class="loading-overlay">',
4076			'<div class="bounce-loader"><span class="cssload-cube-progress"><span class="cssload-cube-progress-inner"></span></span></div>',
4077		'</div>'
4078	].join('');
4079
4080    // Float Rings
4081    const loadingOverlayFloatRingsTemplate = [
4082		'<div class="loading-overlay">',
4083			'<div class="bounce-loader"><div class="cssload-float-rings-loader"><div class="cssload-float-rings-inner cssload-one"></div><div class="cssload-float-rings-inner cssload-two"></div><div class="cssload-float-rings-inner cssload-three"></div></div></div>',
4084		'</div>'
4085	].join('');
4086
4087    // Floating Bars
4088    const loadingOverlayFloatBarsTemplate = [
4089		'<div class="loading-overlay">',
4090			'<div class="bounce-loader"><div class="cssload-float-bars-container"><ul class="cssload-float-bars-flex-container"><li><span class="cssload-float-bars-loading"></span></li></div></div></div>',
4091		'</div>'
4092	].join('');
4093
4094    // Speeding Wheel
4095    const loadingOverlaySpeedingWheelTemplate = [
4096		'<div class="loading-overlay">',
4097			'<div class="bounce-loader"><div class="cssload-speeding-wheel-container"><div class="cssload-speeding-wheel"></div></div></div>',
4098		'</div>'
4099	].join('');
4100
4101    // Zenith
4102    const loadingOverlayZenithTemplate = [
4103		'<div class="loading-overlay">',
4104			'<div class="bounce-loader"><div class="cssload-zenith-container"><div class="cssload-zenith"></div></div></div>',
4105		'</div>'
4106	].join('');
4107
4108    // Spinning Square
4109    const loadingOverlaySpinningSquareTemplate = [
4110		'<div class="loading-overlay">',
4111			'<div class="bounce-loader"><div class="cssload-spinning-square-loading"></div></div>',
4112		'</div>'
4113	].join('');
4114
4115    // Pulse
4116    const loadingOverlayPulseTemplate = [
4117		'<div class="loading-overlay">',
4118			'<div class="bounce-loader"><div class="wrapper-pulse"><div class="cssload-pulse-loader"></div></div></div>',
4119		'</div>'
4120	].join('');
4121
4122    const LoadingOverlay = function( $wrapper, options, noInheritOptions ) {
4123		return this.initialize( $wrapper, options, noInheritOptions );
4124	};
4125
4126    LoadingOverlay.prototype = {
4127
4128		options: {
4129			css: {},
4130			hideDelay: 500,
4131			progressMinTimeout: 0,
4132			effect: 'default'
4133		},
4134
4135		initialize($wrapper, options, noInheritOptions) {
4136			this.$wrapper = $wrapper;
4137
4138			this
4139				.setVars()
4140				.setOptions( options, noInheritOptions )
4141				.build()
4142				.events()
4143				.dynamicShowHideEvents();
4144
4145			this.$wrapper.data( 'loadingOverlay', this );
4146		},
4147
4148		setVars() {
4149			this.$overlay = this.$wrapper.find('.loading-overlay');
4150			this.pageStatus = null;
4151			this.progress = null;
4152			this.animationInterval = 33;
4153
4154			return this;
4155		},
4156
4157		setOptions(options, noInheritOptions) {
4158			if ( !this.$overlay.get(0) ) {
4159				this.matchProperties();
4160			}
4161			
4162			if( noInheritOptions ) {
4163				this.options     = $.extend( true, {}, this.options, options );
4164			} else {
4165				this.options     = $.extend( true, {}, this.options, options, theme.fn.getOptions(this.$wrapper.data('plugin-options')) );
4166			}
4167
4168			this.loaderClass = this.getLoaderClass( this.options.css.backgroundColor );
4169
4170			return this;
4171		},
4172
4173		build() {
4174			const _self = this;
4175
4176			if ( !this.$overlay.closest(document.documentElement).get(0) ) {
4177				if ( !this.$cachedOverlay ) {
4178
4179					switch ( _self.options.effect ) {
4180						case 'percentageProgress1':
4181							this.$overlay = $( loadingOverlayPercentageTemplate ).clone();
4182							break;
4183
4184						case 'percentageProgress2':
4185							this.$overlay = $( loadingOverlayPercentageTemplate ).clone();
4186							this.$overlay
4187								.addClass('loading-overlay-percentage-effect-2')
4188								.prepend('<div class="loading-overlay-background-layer"></div>');
4189							break;
4190
4191						case 'cubes':
4192							this.$overlay = $( loadingOverlayCubesTemplate ).clone();
4193							break;
4194
4195						case 'cubeProgress':
4196							this.$overlay = $( loadingOverlayCubeProgressTemplate ).clone();
4197							break;
4198
4199						case 'floatRings':
4200							this.$overlay = $( loadingOverlayFloatRingsTemplate ).clone();
4201							break;
4202
4203						case 'floatBars':
4204							this.$overlay = $( loadingOverlayFloatBarsTemplate ).clone();
4205							break;
4206
4207						case 'speedingWheel':
4208							this.$overlay = $( loadingOverlaySpeedingWheelTemplate ).clone();
4209							break;
4210
4211						case 'zenith':
4212							this.$overlay = $( loadingOverlayZenithTemplate ).clone();
4213							break;
4214
4215						case 'spinningSquare':
4216							this.$overlay = $( loadingOverlaySpinningSquareTemplate ).clone();
4217							break;
4218
4219						case 'pulse':
4220							this.$overlay = $( loadingOverlayPulseTemplate ).clone();
4221							break;
4222
4223						case 'default':
4224						default:
4225							this.$overlay = $( loadingOverlayDefaultTemplate ).clone();
4226							break;
4227					}
4228					
4229					if ( this.options.css ) {
4230						this.$overlay.css( this.options.css );
4231						this.$overlay.find( '.loader' ).addClass( this.loaderClass );
4232					}
4233				} else {
4234					this.$overlay = this.$cachedOverlay.clone();
4235				}
4236
4237				this.$wrapper.prepend( this.$overlay );
4238			}
4239
4240			if ( !this.$cachedOverlay ) {
4241				this.$cachedOverlay = this.$overlay.clone();
4242			}
4243
4244			if( ['percentageProgress1', 'percentageProgress2'].includes(_self.options.effect) ) {
4245				_self.updateProgress();
4246
4247				if( _self.options.isDynamicHideShow ) {
4248					setTimeout(() => {
4249						_self.progress = 'complete';
4250						
4251						$('.page-loader-progress').text(100);
4252
4253						if( ['percentageProgress2'].includes(_self.options.effect) ) {
4254			            	$('.loading-overlay-background-layer').css({
4255			            		width: '100%'
4256			            	});
4257			            }
4258					}, 2800);
4259				}
4260			}
4261
4262			return this;
4263		},
4264
4265		events() {
4266			const _self = this;
4267
4268			if ( this.options.startShowing ) {
4269				_self.show();
4270			}
4271
4272			if ( this.$wrapper.is('body') || this.options.hideOnWindowLoad ) {
4273				$( window ).on( 'load error', () => {
4274					setTimeout(() => {
4275						_self.hide();
4276					}, _self.options.progressMinTimeout);
4277				});
4278			}
4279
4280			if ( this.options.listenOn ) {
4281				$( this.options.listenOn )
4282					.on( 'loading-overlay:show beforeSend.ic', e => {
4283						e.stopPropagation();
4284						_self.show();
4285					})
4286					.on( 'loading-overlay:hide complete.ic', e => {
4287						e.stopPropagation();
4288						_self.hide();
4289					});
4290			}
4291
4292			this.$wrapper
4293				.on( 'loading-overlay:show beforeSend.ic', e => {
4294					if ( e.target === _self.$wrapper.get(0) ) {
4295						e.stopPropagation();
4296						_self.show();
4297						return true;
4298					}
4299					return false;
4300				})
4301				.on( 'loading-overlay:hide complete.ic', e => {
4302					if ( e.target === _self.$wrapper.get(0) ) {
4303						e.stopPropagation();
4304						_self.hide();
4305						return true;
4306					}
4307					return false;
4308				});
4309
4310			if( ['percentageProgress1', 'percentageProgress2'].includes(_self.options.effect) ) {
4311				$(window).on('load', () => {
4312		            setTimeout(() => {
4313			            _self.pageStatus = "complete";
4314
4315			            $('.page-loader-progress').text(100);
4316
4317			            if( ['percentageProgress2'].includes(_self.options.effect) ) {
4318			            	$('.loading-overlay-background-layer').css({
4319			            		width: '100%'
4320			            	});
4321			            }
4322		            }, _self.options.progressMinTimeout);
4323				});
4324			}
4325		        
4326			return this;
4327		},
4328
4329		show() {
4330			this.build();
4331
4332			this.position = this.$wrapper.css( 'position' ).toLowerCase();
4333			if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
4334				this.$wrapper.css({
4335					position: 'relative'
4336				});
4337			}
4338			this.$wrapper.addClass( 'loading-overlay-showing' );
4339		},
4340
4341		hide() {
4342			const _self = this;
4343
4344			setTimeout(function() {
4345				_self.$wrapper.removeClass( 'loading-overlay-showing' );
4346				
4347				if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
4348					_self.$wrapper.css({ position: '' });
4349				}
4350
4351				$(window).trigger('loading.overlay.ready');
4352			}, _self.options.hideDelay);
4353		},
4354
4355		updateProgress() {
4356			const _self = this;
4357
4358			const render = () => {
4359				if(_self.pageStatus == "complete"){
4360		            $('.page-loader-progress').text(100);
4361		            setTimeout(() => {
4362		                $('.page-loader-progress').addClass('d-none');    
4363		            }, 700);
4364		        }
4365		        else{            
4366		            if(_self.progress == null){
4367		                _self.progress = 1;
4368		            }
4369		           
4370		            _self.progress = _self.progress + 1;
4371		            if(_self.progress >= 0 && _self.progress <= 30){
4372		                _self.animationInterval += 1;
4373		                $('.page-loader-progress').text(_self.progress);
4374		            }
4375		            else if(_self.progress > 30 && _self.progress <= 60){
4376		                _self.animationInterval += 2;
4377		                $('.page-loader-progress').text(_self.progress);
4378		            }
4379		            else if(_self.progress > 60 && _self.progress <= 80){
4380		                _self.animationInterval += 40;
4381		                $('.page-loader-progress').text(_self.progress);
4382		            }
4383		            else if(_self.progress > 80 && _self.progress <= 90){
4384		                _self.animationInterval += 80;
4385		                $('.page-loader-progress').text(_self.progress);
4386		            }
4387		            else if(_self.progress > 90 && _self.progress <= 95){
4388		                _self.animationInterval += 150;
4389		                $('.page-loader-progress').text(_self.progress);
4390		            }
4391		            else if(_self.progress > 95 && _self.progress <= 99){
4392		                _self.animationInterval += 400;
4393		                $('.page-loader-progress').text(_self.progress);
4394		            }
4395		            else if(_self.progress >= 100){
4396		                $('.page-loader-progress').text(99);
4397		            }
4398
4399		            if( ['percentageProgress2'].includes(_self.options.effect) ) {
4400		            	$('.loading-overlay-background-layer').css({
4401		            		width: _self.progress + '%'
4402		            	});
4403		            }
4404		              
4405					self.loopInside = setTimeout(render, _self.animationInterval);
4406		        }
4407
4408			};
4409			render();
4410
4411			return this;
4412		},
4413
4414		matchProperties() {
4415			let i, l, properties;
4416
4417			properties = [
4418				'backgroundColor',
4419				'borderRadius'
4420			];
4421
4422			l = properties.length;
4423
4424			for( i = 0; i < l; i++ ) {
4425				const obj = {};
4426				obj[ properties[ i ] ] = this.$wrapper.css( properties[ i ] );
4427
4428				$.extend( this.options.css, obj );
4429			}
4430		},
4431
4432		getLoaderClass(backgroundColor) {
4433			if ( !backgroundColor || backgroundColor === 'transparent' || backgroundColor === 'inherit' ) {
4434				return 'black';
4435			}
4436
4437			let hexColor, r, g, b, yiq;
4438
4439			const colorToHex = color => {
4440				let hex, rgb;
4441
4442				if( color.includes('#') ){
4443					hex = color.replace('#', '');
4444				} else {
4445					rgb = color.match(/\d+/g);
4446					hex = ('0' + parseInt(rgb[0], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2);
4447				}
4448
4449				if ( hex.length === 3 ) {
4450					hex = hex + hex;
4451				}
4452
4453				return hex;
4454			};
4455
4456			hexColor = colorToHex( backgroundColor );
4457
4458			r = parseInt( hexColor.substr( 0, 2), 16 );
4459			g = parseInt( hexColor.substr( 2, 2), 16 );
4460			b = parseInt( hexColor.substr( 4, 2), 16 );
4461			yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
4462
4463			return ( yiq >= 128 ) ? 'black' : 'white';
4464		},
4465
4466		dynamicShowHide(effect) {
4467			const _self = this;
4468
4469			// Remove Loading Overlay Data
4470			$('body').removeData('loadingOverlay');
4471
4472			// Remove Html Of Loading Overlay
4473			$('.loading-overlay').remove();
4474
4475			if( effect == '' ) {
4476				return this;
4477			}
4478
4479			// Initialize New Loading Overlay (second parameter is to NO inherit data-plugin-options)
4480			$('body').loadingOverlay({
4481				effect: effect ? effect : 'pulse',
4482				isDynamicHideShow: true
4483			}, true);
4484
4485			// Show Loading Overlay Loader
4486			$('body').data('loadingOverlay').show();
4487
4488			// Hide Loading Overlay Loader
4489			setTimeout(() => {
4490				$('body').data('loadingOverlay').hide();
4491			}, 3000);
4492
4493			return this;
4494		},
4495
4496		dynamicShowHideEvents() {
4497			const _self = this;
4498
4499			// Button
4500			$(document).off('click.loading-overlay-button').on('click.loading-overlay-button', '.loading-overlay-button', function(e){
4501				e.preventDefault();
4502
4503				_self.dynamicShowHide( $(this).data('effect') );
4504			});
4505
4506			// Select
4507			$(document).off('change.loading-overlay-select').on('change.loading-overlay-select', '.loading-overlay-select', function(){
4508				_self.dynamicShowHide( $(this).val() );
4509			});
4510
4511			return this;
4512		}
4513
4514	};
4515
4516    // expose to scope
4517    $.extend(theme, {
4518		LoadingOverlay
4519	});
4520
4521    // expose as a jquery plugin
4522    $.fn.loadingOverlay = function( opts, noInheritOptions ) {
4523		return this.each(function() {
4524			const $this = $( this );
4525
4526			const loadingOverlay = $this.data( 'loadingOverlay' );
4527			if ( loadingOverlay ) {
4528				return loadingOverlay;
4529			} else {
4530				const options = opts || $this.data( 'loading-overlay-options' ) || {};
4531				return new LoadingOverlay( $this, options, noInheritOptions );
4532			}
4533		});
4534	}
4535
4536    // auto init
4537    $('[data-loading-overlay]').loadingOverlay();
4538})).apply(this, [window.theme, jQuery]);
4539
4540// Masonry
4541(((theme = {}, $) => {
4542    const instanceName = '__masonry';
4543
4544    class PluginMasonry {
4545        constructor($el, opts) {
4546            return this.initialize($el, opts);
4547        }
4548
4549        initialize($el, opts) {
4550			if ($el.data(instanceName)) {
4551				return this;
4552			}
4553
4554			this.$el = $el;
4555
4556			this
4557				.setData()
4558				.setOptions(opts)
4559				.build();
4560
4561			return this;
4562		}
4563
4564        setData() {
4565			this.$el.data(instanceName, this);
4566
4567			return this;
4568		}
4569
4570        setOptions(opts) {
4571			this.options = $.extend(true, {}, PluginMasonry.defaults, opts, {
4572				wrapper: this.$el
4573			});
4574
4575			return this;
4576		}
4577
4578        build() {
4579			if (!($.isFunction($.fn.isotope))) {
4580				return this;
4581			}
4582
4583			const self = this, $window = $(window);
4584
4585			self.$loader = false;
4586
4587			if (self.options.wrapper.parents('.masonry-loader').get(0)) {
4588				self.$loader = self.options.wrapper.parents('.masonry-loader');
4589				self.createLoader();
4590			}
4591
4592			self.options.wrapper.one('layoutComplete', (event, laidOutItems) => {
4593				self.removeLoader();
4594			});
4595
4596			self.options.wrapper.waitForImages(() => {
4597				self.options.wrapper.isotope(self.options);	
4598			});
4599
4600			$(window).on('resize', () => {
4601				setTimeout(() => {
4602					self.options.wrapper.isotope('layout');
4603				}, 300);
4604			});
4605
4606			setTimeout(() => {
4607				self.removeLoader();
4608			}, 3000);
4609
4610			return this;
4611		}
4612
4613        createLoader() {
4614			const self = this;
4615
4616			const loaderTemplate = [
4617				'<div class="bounce-loader">',
4618					'<div class="bounce1"></div>',
4619					'<div class="bounce2"></div>',
4620					'<div class="bounce3"></div>',
4621				'</div>'
4622			].join('');
4623
4624			self.$loader.append(loaderTemplate);
4625
4626			return this;
4627		}
4628
4629        removeLoader() {
4630
4631			const self = this;
4632
4633			if (self.$loader) {
4634
4635				self.$loader.removeClass('masonry-loader-showing');
4636
4637				setTimeout(() => {
4638					self.$loader.addClass('masonry-loader-loaded');
4639				}, 300);
4640
4641			}
4642
4643		}
4644    }
4645
4646    PluginMasonry.defaults = {
4647
4648	};
4649
4650    // expose to scope
4651    $.extend(theme, {
4652		PluginMasonry
4653	});
4654
4655    // jquery plugin
4656    $.fn.themePluginMasonry = function(opts) {
4657		return this.map(function() {
4658			const $this = $(this);
4659
4660			if ($this.data(instanceName)) {
4661				return $this.data(instanceName);
4662			} else {
4663				return new PluginMasonry($this, opts);
4664			}
4665
4666		});
4667	}
4668})).apply(this, [window.theme, jQuery]);
4669
4670// Match Height
4671(((theme = {}, $) => {
4672    const instanceName = '__matchHeight';
4673
4674    class PluginMatchHeight {
4675        constructor($el, opts) {
4676            return this.initialize($el, opts);
4677        }
4678
4679        initialize($el, opts) {
4680			if ($el.data(instanceName)) {
4681				return this;
4682			}
4683
4684			this.$el = $el;
4685
4686			this
4687				.setData()
4688				.setOptions(opts)
4689				.build();
4690
4691			return this;
4692		}
4693
4694        setData() {
4695			this.$el.data(instanceName, this);
4696
4697			return this;
4698		}
4699
4700        setOptions(opts) {
4701			this.options = $.extend(true, {}, PluginMatchHeight.defaults, opts, {
4702				wrapper: this.$el
4703			});
4704
4705			return this;
4706		}
4707
4708        build() {
4709			if (!($.isFunction($.fn.matchHeight))) {
4710				return this;
4711			}
4712
4713			const self = this;
4714
4715			self.options.wrapper.matchHeight(self.options);
4716
4717			return this;
4718		}
4719    }
4720
4721    PluginMatchHeight.defaults = {
4722		byRow: true,
4723		property: 'height',
4724		target: null,
4725		remove: false
4726	};
4727
4728    // expose to scope
4729    $.extend(theme, {
4730		PluginMatchHeight
4731	});
4732
4733    // jquery plugin
4734    $.fn.themePluginMatchHeight = function(opts) {
4735		return this.map(function() {
4736			const $this = $(this);
4737
4738			if ($this.data(instanceName)) {
4739				return $this.data(instanceName);
4740			} else {
4741				return new PluginMatchHeight($this, opts);
4742			}
4743
4744		});
4745	}
4746})).apply(this, [window.theme, jQuery]);
4747
4748// Parallax
4749(((theme = {}, $) => {
4750    const instanceName = '__parallax';
4751
4752    class PluginParallax {
4753        constructor($el, opts) {
4754            return this.initialize($el, opts);
4755        }
4756
4757        initialize($el, opts) {
4758			if ($el.data(instanceName)) {
4759				return this;
4760			}
4761
4762			this.$el = $el;
4763
4764			this
4765				.setData()
4766				.setOptions(opts)
4767				.build();
4768
4769			return this;
4770		}
4771
4772        setData() {
4773			this.$el.data(instanceName, this);
4774
4775			return this;
4776		}
4777
4778        setOptions(opts) {
4779			this.options = $.extend(true, {}, PluginParallax.defaults, opts, {
4780				wrapper: this.$el
4781			});
4782
4783			return this;
4784		}
4785
4786        build() {
4787            const self = this;
4788            const $window = $(window);
4789            let offset;
4790            let yPos;
4791            let plxPos;
4792            let background;
4793            let rotateY;
4794
4795            // Mouse Parallax
4796            if( self.options.mouseParallax ) {
4797
4798				$window.mousemove(({clientX, clientY}) => {
4799
4800					$('.parallax-mouse-object', self.options.wrapper).each(function() {
4801
4802				        const moving_value = $( this ).attr('data-value');
4803				        const x = (clientX * moving_value) / 250;
4804				        const y = (clientY * moving_value) / 250;
4805
4806				        $( this ).css('transform', 'translateX(' + x + 'px) translateY(' + y + 'px)');
4807				    });
4808
4809				});
4810
4811				return this;
4812
4813			}
4814
4815            // Scrollable
4816            if( self.options.scrollableParallax && $(window).width() > self.options.scrollableParallaxMinWidth ) {
4817				const $scrollableWrapper = self.options.wrapper.find('.scrollable-parallax-wrapper');
4818
4819				if( $scrollableWrapper.get(0) ) {
4820                    let progress 	 = ( $(window).scrollTop() > ( self.options.wrapper.offset().top + $(window).outerHeight() ) ) ? self.options.cssValueEnd : self.options.cssValueStart;
4821                    const cssValueUnit = self.options.cssValueUnit ? self.options.cssValueUnit : '';
4822
4823                    $scrollableWrapper.css({
4824						'background-image' : 'url(' + self.options.wrapper.data('image-src') + ')',
4825						'background-size' : 'cover',
4826						'background-position' : 'center',
4827						'background-attachment' : 'fixed',
4828						'transition' : 'ease '+ self.options.cssProperty +' '+ self.options.transitionDuration,
4829						'width' : progress + '%'
4830					});
4831
4832                    $(window).on('scroll', e => {
4833						if( self.options.wrapper.visible( true ) ) {
4834							const $window = $(window), scrollTop = $window.scrollTop(), elementOffset = self.options.wrapper.offset().top, currentElementOffset = (elementOffset - scrollTop);
4835
4836						   	const scrollPercent = Math.abs( +( currentElementOffset - $window.height() ) / (self.options.startOffset ? self.options.startOffset : 7) );
4837						 	
4838						 	// Increment progress value according scroll position
4839						 	if( scrollPercent <= self.options.cssValueEnd && progress <= self.options.cssValueEnd ) {
4840						 		progress = self.options.cssValueStart + scrollPercent;
4841						 	}
4842
4843						 	// Adjust CSS end value
4844						 	if( progress > self.options.cssValueEnd ) {
4845						 		progress = self.options.cssValueEnd;
4846						 	}
4847
4848						 	// Adjust CSS start value
4849						 	if( progress < self.options.cssValueStart ) {
4850						 		progress = self.options.cssValueStart;
4851						 	}
4852
4853						 	const styles = {};
4854						 	styles[self.options.cssProperty] = progress + cssValueUnit;
4855
4856							$scrollableWrapper.css(styles);
4857						}
4858					});
4859                }
4860
4861				return;
4862			}
4863
4864            // Create Parallax Element
4865            if( self.options.fadeIn ) {
4866				background = $('<div class="parallax-background fadeIn animated"></div>');
4867			} else {
4868				background = $('<div class="parallax-background"></div>');
4869			}
4870
4871            // Set Style for Parallax Element
4872            background.css({
4873				'background-image' : 'url(' + self.options.wrapper.data('image-src') + ')',
4874				'background-size' : 'cover',
4875				'position' : 'absolute',
4876				'top' : 0,
4877				'left' : 0,
4878				'width' : '100%',
4879				'height' : self.options.parallaxHeight
4880			});
4881
4882            if( self.options.parallaxScale ) {
4883				background.css({
4884					'transition' : 'transform 500ms ease-out'
4885				});
4886			}
4887
4888            // Add Parallax Element on DOM
4889            self.options.wrapper.prepend(background);
4890
4891            // Set Overlfow Hidden and Position Relative to Parallax Wrapper
4892            self.options.wrapper.css({
4893				'position' : 'relative',
4894				'overflow' : 'hidden'
4895			});
4896
4897            // Parallax Effect on Scroll & Resize
4898            const parallaxEffectOnScrolResize = () => {
4899				$window.on('scroll resize', () => {
4900					offset  = self.options.wrapper.offset();
4901					yPos    = -($window.scrollTop() - (offset.top - 100)) / ((self.options.speed + 2 ));
4902					plxPos  = (yPos < 0) ? Math.abs(yPos) : -Math.abs(yPos);
4903					rotateY = ( $('html[dir="rtl"]').get(0) ) ? ' rotateY(180deg)' : ''; // RTL
4904					
4905					offset  = self.options.wrapper.offset();
4906					yPos    = -($window.scrollTop() - (offset.top - 100)) / ((self.options.speed + 2 ));
4907					plxPos  = (yPos < 0) ? Math.abs(yPos) : -Math.abs(yPos);
4908					rotateY = ( $('html[dir="rtl"]').get(0) ) ? ' rotateY(180deg)' : ''; // RTL
4909
4910					if( !self.options.parallaxScale ) {
4911
4912						if( self.options.parallaxDirection == 'bottom' ) {
4913							self.options.offset = 250;
4914						}
4915
4916						let y = ( (plxPos - 50) + (self.options.offset) );
4917						if( self.options.parallaxDirection == 'bottom' ) {
4918							y = ( y < 0 ) ? Math.abs( y ) : -Math.abs( y );
4919						}
4920
4921						background.css({
4922							'transform' : 'translate3d(0, '+ y +'px, 0)' + rotateY,
4923							'background-position-x' : self.options.horizontalPosition
4924						});
4925
4926					} else {
4927                        const scrollTop = $window.scrollTop();
4928                        const elementOffset = self.options.wrapper.offset().top;
4929                        const currentElementOffset = (elementOffset - scrollTop);
4930                        let scrollPercent = Math.abs( +( currentElementOffset - $window.height() ) / (self.options.startOffset ? self.options.startOffset : 7) );
4931
4932                        scrollPercent = parseInt((scrollPercent >= 100) ? 100 : scrollPercent);
4933
4934                        const currentScale = (scrollPercent / 100) * 50;
4935
4936                        if ( !self.options.parallaxScaleInvert ) {
4937							background.css({
4938								'transform' : 'scale(1.' + String(currentScale).padStart(2, '0') + ', 1.' + String(currentScale).padStart(2, '0') + ')'
4939							});
4940						} else {
4941							background.css({
4942								'transform' : 'scale(1.' + String(50 - currentScale).padStart(2, '0') + ', 1.' + String(50 - currentScale).padStart(2, '0') + ')'
4943							});
4944						}
4945                    }
4946				});
4947
4948				$window.trigger('scroll');
4949			};
4950
4951            if (!$.browser.mobile) {
4952				parallaxEffectOnScrolResize();
4953			} else {
4954				if( self.options.enableOnMobile == true ) {
4955					parallaxEffectOnScrolResize();
4956				} else {
4957					self.options.wrapper.addClass('parallax-disabled');
4958				}
4959			}
4960
4961            return this;
4962        }
4963    }
4964
4965    PluginParallax.defaults = {
4966		speed: 1.5,
4967		horizontalPosition: '50%',
4968		offset: 0,
4969		parallaxDirection: 'top',
4970		parallaxHeight: '180%',
4971		parallaxScale: false,
4972		parallaxScaleInvert: false,
4973		scrollableParallax: false,
4974		scrollableParallaxMinWidth: 991,
4975		startOffset: 7,
4976		transitionDuration: '200ms',
4977		cssProperty: 'width',
4978		cssValueStart: 40,
4979		cssValueEnd: 100,
4980		cssValueUnit: 'vw',
4981		mouseParallax: false,
4982		enableOnMobile: true
4983	};
4984
4985    // expose to scope
4986    $.extend(theme, {
4987		PluginParallax
4988	});
4989
4990    // jquery plugin
4991    $.fn.themePluginParallax = function(opts) {
4992		return this.map(function() {
4993			const $this = $(this);
4994
4995			if ($this.data(instanceName)) {
4996				return $this.data(instanceName);
4997			} else {
4998				return new PluginParallax($this, opts);
4999			}
5000
5001		});
5002	}
5003})).apply(this, [window.theme, jQuery]);
5004
5005// Progress Bar
5006(((theme = {}, $) => {
5007    const instanceName = '__progressBar';
5008
5009    class PluginProgressBar {
5010        constructor($el, opts) {
5011            return this.initialize($el, opts);
5012        }
5013
5014        initialize($el, opts) {
5015			if ($el.data(instanceName)) {
5016				return this;
5017			}
5018
5019			this.$el = $el;
5020
5021			this
5022				.setData()
5023				.setOptions(opts)
5024				.build();
5025
5026			return this;
5027		}
5028
5029        setData() {
5030			this.$el.data(instanceName, this);
5031
5032			return this;
5033		}
5034
5035        setOptions(opts) {
5036			this.options = $.extend(true, {}, PluginProgressBar.defaults, opts, {
5037				wrapper: this.$el
5038			});
5039
5040			return this;
5041		}
5042
5043        build() {
5044            const self = this;
5045            const $el = this.options.wrapper;
5046            let delay = 1;
5047
5048            delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
5049
5050            $el.addClass($el.attr('data-appear-animation'));
5051
5052            setTimeout(() => {
5053
5054				$el.animate({
5055					width: $el.attr('data-appear-progress-animation')
5056				}, 1500, 'easeOutQuad', () => {
5057					$el.find('.progress-bar-tooltip').animate({
5058						opacity: 1
5059					}, 500, 'easeOutQuad');
5060				});
5061
5062			}, delay);
5063
5064            return this;
5065        }
5066    }
5067
5068    PluginProgressBar.defaults = {
5069		accX: 0,
5070		accY: -50,
5071		delay: 1
5072	};
5073
5074    // expose to scope
5075    $.extend(theme, {
5076		PluginProgressBar
5077	});
5078
5079    // jquery plugin
5080    $.fn.themePluginProgressBar = function(opts) {
5081		return this.map(function() {
5082			const $this = $(this);
5083
5084			if ($this.data(instanceName)) {
5085				return $this.data(instanceName);
5086			} else {
5087				return new PluginProgressBar($this, opts);
5088			}
5089
5090		});
5091	}
5092})).apply(this, [window.theme, jQuery]);
5093
5094// Random Images
5095(((theme = {}, $) => {
5096    const instanceName = '__randomimages';
5097
5098    class PluginRandomImages {
5099        constructor($el, opts) {
5100            return this.initialize($el, opts);
5101        }
5102
5103        initialize($el, opts) {
5104			this.$el = $el;
5105            this.st = '';
5106			this.times = 0;
5107			this.perImageIndex = 0;
5108
5109            if( $el.is('img') && typeof opts.imagesListURL == 'undefined' ) {
5110                return false;
5111            }
5112
5113            this
5114				.setData()
5115				.setOptions(opts)
5116				.build();
5117
5118			return this;
5119		}
5120
5121        setData() {
5122			this.$el.data(instanceName, this);
5123
5124			return this;
5125		}
5126
5127        setOptions(opts) {
5128			this.options = $.extend(true, {}, PluginRandomImages.defaults, opts, {
5129				wrapper: this.$el
5130			});
5131
5132			return this;
5133		}
5134
5135        build() {
5136            const self = this;
5137			
5138			// Control the screens size we want to have the plugin working
5139			if( $(window).width() < self.options.minWindowWidth  ) {
5140				return false;
5141			}
5142
5143			// Check if is single image or wrapper with images inside
5144            if( self.$el.is('img') ) {
5145				
5146				// Check it's inside a lightbox
5147				self.isInsideLightbox = self.$el.closest('.lightbox').length ? true : false;
5148
5149				// Push the initial image to lightbox list/array
5150				if( self.isInsideLightbox && self.options.lightboxImagesListURL ) {
5151					self.options.lightboxImagesListURL.push( self.$el.closest('.lightbox').attr('href') );
5152				}
5153	
5154				// Push the current image src to the array
5155				self.options.imagesListURL.push( self.$el.attr('src') );
5156
5157				// Start with lastIndex as the first image loaded on the page
5158				self.lastIndex = self.options.imagesListURL.length - 1;
5159
5160				// Identify the last random image element (if has more than one on the page)
5161				if( self.options.random == false ) {
5162					$('.plugin-random-images').each(function(i){
5163						if( i == $('.plugin-random-images').length - 1 ) {
5164							$(this).addClass('the-last');
5165						}
5166					});
5167				}
5168
5169				// Start the recursive timeout
5170				setTimeout(() => {
5171					self.recursiveTimeout( 
5172						self.perImageTag, 
5173						self.options.delay == null ? 3000 : self.options.delay
5174					);
5175				}, self.options.delay == null ? 300 : self.options.delay / 3);
5176
5177			} else {
5178				
5179				// Start the recursive timeout
5180				setTimeout( self.recursiveTimeout( 
5181					self.perWrapper, 
5182					self.options.delay ? self.options.delay : getPerWrapperHighDelay(), 
5183					false 
5184				), 300);
5185
5186			}
5187
5188			// Stop After Few Seconds
5189			if( self.options.stopAfterFewSeconds ) {
5190				setTimeout(() => {
5191					clearTimeout(self.st);
5192				}, self.options.stopAfterFewSeconds);
5193			}
5194			
5195			return this;
5196
5197		}
5198
5199        perImageTag() {
5200			const self = this;
5201
5202			// Generate a random index to make the images rotate randomly
5203			let index = self.options.random ? Math.floor(Math.random() * self.options.imagesListURL.length) : self.lastIndex;
5204
5205			// Avoid repeat the same image
5206			if( self.lastIndex !== '' && self.lastIndex == index ) {
5207				if( self.options.random ) {
5208					while( index == self.lastIndex ) {
5209						index = Math.floor(Math.random() * self.options.imagesListURL.length);
5210					}
5211				} else {
5212					index = index - 1;
5213					if( index == -1 ) {
5214						index = self.options.imagesListURL.length - 1;
5215					}
5216				}
5217			}
5218
5219			// Turn the image ready for animations
5220			self.$el.addClass('animated');
5221
5222			// Remove the entrance animation class and add the out animation class
5223			self.$el.removeClass( self.options.animateIn ).addClass( self.options.animateOut );
5224			
5225			// Change the image src and add the class for entrance animation
5226			setTimeout( () => {
5227				self.$el.attr('src', self.options.imagesListURL[index]).removeClass( self.options.animateOut ).addClass(self.options.animateIn);
5228
5229				if( self.isInsideLightbox && self.options.lightboxImagesListURL ) {
5230					self.$el.closest('.lightbox').attr('href', self.options.lightboxImagesListURL[index]);
5231				}
5232			}, 1000);
5233			
5234			// Save the last index for future checks
5235			self.lastIndex = index;
5236			
5237			// Increment the times var
5238			self.times++;
5239
5240			// Save the index for stopAtImageIndex option
5241			self.perImageIndex = index;
5242
5243			return this;
5244		}
5245
5246        // Iterate the imaes loop and get the higher value
5247        getPerWrapperHighDelay() {
5248            const self = this;
5249            const $wrapper = self.$el;
5250            let delay = 0;
5251
5252            $wrapper.find('img').each(function(){
5253				const $image = $(this);
5254				
5255				if( $image.data('rimage-delay') && parseInt( $image.data('rimage-delay') ) > delay ) {
5256					delay = parseInt( $image.data('rimage-delay') );
5257				}
5258			});
5259
5260            return delay;
5261        }
5262
5263        perWrapper() {
5264			const self = this, $wrapper = self.$el;
5265
5266			// Turns the imageLlistURL into an array
5267			self.options.imagesListURL = [];
5268
5269			// Find all images inside the element wrapper and push their sources to image list array
5270			$wrapper.find('img').each(function(){
5271				const $image = $(this);
5272				self.options.imagesListURL.push( $image.attr('src') ); 
5273			});
5274
5275			// Shuffle the images list array (random effect)
5276			self.options.imagesListURL = self.shuffle( self.options.imagesListURL );
5277
5278			// Iterate over each image and make some checks like delay for each image, animations, etc...
5279			$wrapper.find('img').each(function(index){
5280				const $image = $(this), animateIn  = $image.data('rimage-animate-in') ? $image.data('rimage-animate-in') : self.options.animateIn, animateOut = $image.data('rimage-animate-out') ? $image.data('rimage-animate-out') : self.options.animateOut, delay      = $image.data('rimage-delay') ? $image.data('rimage-delay') : 2000;
5281
5282				$image.addClass('animated');
5283
5284				setTimeout( () => {
5285					$image.removeClass( animateIn ).addClass( animateOut );
5286				}, delay / 2);
5287
5288				setTimeout( () => {
5289					$image.attr('src', self.options.imagesListURL[index]).removeClass( animateOut ).addClass(animateIn);
5290				}, delay);
5291
5292			});
5293			
5294			// Increment the times variable
5295			self.times++;
5296
5297			return this;
5298		}
5299
5300        recursiveTimeout(callback, delay) {
5301			const self = this;
5302
5303			const timeout = () => {
5304
5305				if( callback !== null ) {
5306					callback.call(self);
5307				}
5308
5309				// Recursive
5310				self.st = setTimeout(timeout, delay == null ? 1000 : delay);
5311
5312				if( self.options.random == false ) {
5313					if( self.$el.hasClass('the-last') ) {
5314						$('.plugin-random-images').trigger('rimages.start');
5315					} else {
5316						clearTimeout(self.st);
5317					}
5318				}
5319
5320				// Stop At Image Index
5321				if( self.options.stopAtImageIndex && parseInt(self.options.stopAtImageIndex) == self.perImageIndex ) {
5322					clearTimeout(self.st);
5323				}
5324
5325				// Stop After X Timers
5326				if( self.options.stopAfterXTimes == self.times ) {
5327					clearTimeout(self.st);
5328				}
5329			};
5330			timeout();
5331
5332			self.$el.on('rimages.start', () => {
5333				clearTimeout(self.st);
5334				self.st = setTimeout(timeout, delay == null ? 1000 : delay);
5335			});
5336
5337		}
5338
5339        shuffle(array) {
5340			for (let i = array.length - 1; i > 0; i--) {
5341				const j = Math.floor(Math.random() * (i + 1));
5342				const temp = array[i];
5343				array[i] = array[j];
5344				array[j] = temp;
5345			}
5346
5347			return array;
5348		}
5349    }
5350
5351    PluginRandomImages.defaults = {
5352		minWindowWidth: 0,
5353		random: true,
5354		imagesListURL: null,
5355		lightboxImagesListURL: null,
5356        delay: null,
5357        animateIn: 'fadeIn',
5358		animateOut: 'fadeOut',
5359		stopAtImageIndex: false, // The value shoudl be the index value of array with images as string. Eg: '2' 
5360		stopAfterFewSeconds: false, // The value should be in mili-seconds. Eg: 10000 = 10 seconds
5361		stopAfterXTimes: false,
5362		accY: 0
5363	};
5364
5365    // expose to scope
5366    $.extend(theme, {
5367		PluginRandomImages
5368	});
5369
5370    // jquery plugin
5371    $.fn.themePluginRandomImages = function(opts) {
5372		return this.map(function() {
5373			const $this = $(this);
5374
5375			if ($this.data(instanceName)) {
5376				return $this.data(instanceName);
5377			} else {
5378				return new PluginRandomImages($this, opts);
5379			}
5380
5381		});
5382	}
5383})).apply(this, [window.theme, jQuery]);
5384
5385// Read More
5386(((theme = {}, $) => {
5387    const instanceName = '__readmore';
5388
5389    class PluginReadMore {
5390        constructor($el, opts) {
5391            return this.initialize($el, opts);
5392        }
5393
5394        initialize($el, opts) {
5395			const self = this;
5396
5397			this.$el = $el;
5398
5399			this
5400				.setData()
5401				.setOptions(opts)
5402				.build()
5403				.events();
5404
5405			if( self.options.startOpened ) {
5406				self.options.wrapper.find('.readmore-button-wrapper > a').trigger('click');
5407			}
5408
5409			return this;
5410		}
5411
5412        setData() {
5413			this.$el.data(instanceName, this);
5414
5415			return this;
5416		}
5417
5418        setOptions(opts) {
5419			this.options = $.extend(true, {}, PluginReadMore.defaults, opts, {
5420				wrapper: this.$el
5421			});
5422
5423			return this;
5424		}
5425
5426        build() {
5427			const self = this;
5428
5429			self.options.wrapper.addClass('position-relative');
5430
5431			// Overlay
5432			self.options.wrapper.append( '<div class="readmore-overlay"></div>' );
5433
5434			// Check if is Safari
5435			let backgroundCssValue = 'linear-gradient(180deg, rgba(2, 0, 36, 0) 0%, '+ self.options.overlayColor +' 100%)';
5436			if( $('html').hasClass('safari') ) {
5437				backgroundCssValue = '-webkit-linear-gradient(top, rgba(2, 0, 36, 0) 0%, '+ self.options.overlayColor +' 100%)'
5438			}
5439			
5440			self.options.wrapper.find('.readmore-overlay').css({
5441				background: backgroundCssValue,
5442				position: 'absolute',
5443				bottom: 0,
5444				left: 0,
5445				width: '100%',
5446				height: self.options.overlayHeight,
5447				'z-index': 1
5448			});
5449
5450			// Read More Button
5451			self.options.wrapper.find('.readmore-button-wrapper').removeClass('d-none').css({
5452				position: 'absolute',
5453				bottom: 0,
5454				left: 0,
5455				width: '100%',
5456				'z-index': 2
5457			});	
5458
5459			// Button Label
5460			self.options.wrapper.find('.readmore-button-wrapper > a').html( self.options.buttonOpenLabel );
5461
5462			self.options.wrapper.css({
5463				'height': self.options.maxHeight,
5464				'overflow-y': 'hidden'
5465			});
5466
5467			// Alignment
5468			switch ( self.options.align ) {
5469				case 'center':
5470					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-center');
5471					break;
5472
5473				case 'end':
5474					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-end');
5475					break;
5476
5477				case 'start':
5478				default:
5479					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-start');
5480					break;
5481			}
5482
5483			return this;
5484
5485		}
5486
5487        events() {
5488			const self = this;
5489
5490			// Read More
5491			self.readMore = () => {
5492				self.options.wrapper.find('.readmore-button-wrapper > a:not(.readless)').on('click', function(e){
5493					e.preventDefault();
5494
5495					const $this = $(this);
5496
5497					setTimeout(() => {
5498						self.options.wrapper.animate({
5499							'height': self.options.wrapper[0].scrollHeight
5500						}, () => {
5501							if( !self.options.enableToggle ) {
5502								$this.fadeOut();
5503							}
5504
5505							$this.html( self.options.buttonCloseLabel ).addClass('readless').off('click');
5506
5507							self.readLess();
5508
5509							self.options.wrapper.find('.readmore-overlay').fadeOut();
5510							self.options.wrapper.css({
5511								'max-height': 'none',
5512								'overflow': 'visible'
5513							});
5514
5515							self.options.wrapper.find('.readmore-button-wrapper').animate({
5516								bottom: -20
5517							});
5518						});
5519					}, 200);
5520				});
5521			}
5522
5523			// Read Less
5524			self.readLess = () => {
5525				self.options.wrapper.find('.readmore-button-wrapper > a.readless').on('click', function(e){
5526					e.preventDefault();
5527
5528					const $this = $(this);
5529
5530					// Button
5531					self.options.wrapper.find('.readmore-button-wrapper').animate({
5532						bottom: 0
5533					});
5534
5535					// Overlay
5536					self.options.wrapper.find('.readmore-overlay').fadeIn();
5537
5538					setTimeout(() => {
5539						self.options.wrapper.height(self.options.wrapper[0].scrollHeight).animate({
5540							'height': self.options.maxHeight
5541						}, () => {
5542							$this.html( self.options.buttonOpenLabel ).removeClass('readless').off('click');
5543
5544							self.readMore();
5545
5546							self.options.wrapper.css({
5547								'overflow': 'hidden'
5548							});
5549						});
5550					}, 200);
5551				});
5552			}
5553
5554			// First Load
5555			self.readMore();
5556
5557			return this;
5558		}
5559    }
5560
5561    PluginReadMore.defaults = {
5562		buttonOpenLabel: 'Read More <i class="fas fa-chevron-down text-2 ms-1"></i>',
5563		buttonCloseLabel: 'Read Less <i class="fas fa-chevron-up text-2 ms-1"></i>',
5564		enableToggle: true,
5565		maxHeight: 110,
5566		overlayColor: '#FFF',
5567		overlayHeight: 100,
5568		startOpened: false,
5569		align: 'left'
5570	};
5571
5572    // expose to scope
5573    $.extend(theme, {
5574		PluginReadMore
5575	});
5576
5577    // jquery plugin
5578    $.fn.themePluginReadMore = function(opts) {
5579		return this.map(function() {
5580			const $this = $(this);
5581
5582			if ($this.data(instanceName)) {
5583				return $this.data(instanceName);
5584			} else {
5585				return new PluginReadMore($this, opts);
5586			}
5587
5588		});
5589	}
5590})).apply(this, [window.theme, jQuery]);
5591
5592// Revolution Slider
5593(((theme = {}, $) => {
5594    const instanceName = '__revolution';
5595
5596    class PluginRevolutionSlider {
5597        constructor($el, opts) {
5598            return this.initialize($el, opts);
5599        }
5600
5601        initialize($el, opts) {
5602			if ($el.data(instanceName)) {
5603				return this;
5604			}
5605
5606			this.$el = $el;
5607
5608			this
5609				.setData()
5610				.setOptions(opts)
5611				.build()
5612				.events();
5613
5614			return this;
5615		}
5616
5617        setData() {
5618			this.$el.data(instanceName, this);
5619
5620			return this;
5621		}
5622
5623        setOptions(opts) {
5624			this.options = $.extend(true, {}, PluginRevolutionSlider.defaults, opts, {
5625				wrapper: this.$el
5626			});
5627
5628			return this;
5629		}
5630
5631        build() {
5632			if (!($.isFunction($.fn.revolution))) {
5633				return this;
5634			}
5635
5636			// Single Slider Class
5637			if(this.options.wrapper.find('> ul > li').length == 1) {
5638				this.options.wrapper.addClass('slider-single-slide');
5639
5640				// Remove Bullets
5641				// this.options.navigation.bullets.enable = false;
5642				$.extend(this.options.navigation, {
5643					bullets: {
5644						enable: false
5645					}
5646				});
5647
5648			}
5649
5650			// Full Screen Class
5651			if(this.options.sliderLayout == 'fullscreen') {
5652				this.options.wrapper.closest('.slider-container').addClass('fullscreen-slider');
5653			}
5654			
5655			// Initialize Revolution Slider
5656			this.options.wrapper.revolution(this.options);
5657
5658			// Addon Init - Typewriter
5659			if(this.options.addOnTypewriter.enable) {
5660				RsTypewriterAddOn($, this.options.wrapper);
5661			}
5662
5663			// Addon Init - Whiteboard
5664			if(this.options.addOnWhiteboard.enable) {
5665				this.options.wrapper.rsWhiteBoard();
5666			}
5667
5668			// Addon Init - Particles
5669			if(this.options.addOnParticles.enable) {
5670				RsParticlesAddOn(this.options.wrapper);
5671			}
5672
5673			// Addon Init - Countdown
5674			if(this.options.addOnCountdown.enable) {
5675				tp_countdown(this.options.wrapper, this.options.addOnCountdown.targetdate, this.options.addOnCountdown.slidechanges);
5676			}
5677
5678			// Addon Init - Slicey
5679			if(this.options.addOnSlicey.enable) {
5680				this.options.wrapper.revSliderSlicey();
5681			}
5682
5683			// Addon Init - Filmstrip
5684			if(this.options.addOnFilmstrip.enable) {
5685				RsFilmstripAddOn($, this.options.wrapper, '../vendor/rs-plugin/revolution-addons/filmstrip/', false);
5686			}
5687
5688			// Addon Init - Before After
5689			if(this.options.addOnBeforeAfter.enable) {
5690				RevSliderBeforeAfter($, this.options.wrapper, this.options.addOnBeforeAfter.options);
5691			}
5692
5693			// Addon Init - Panorama
5694			if(this.options.addOnPanorama.enable) {
5695				RsAddonPanorama($, this.options.wrapper);
5696			}
5697
5698			// Addon Init - Revealer
5699			if(this.options.addOnRevealer.enable) {
5700				RsRevealerAddOn($, this.options.wrapper, this.options.revealer.spinnerHtml);
5701			}
5702
5703			// Addon Init - Duotone
5704			if(this.options.addOnDuotone.enable) {
5705				RsAddonDuotone($, this.options.wrapper, true, "cubic-bezier(0.645, 0.045, 0.355, 1.000)", "1000");
5706			}
5707
5708			// Addon Init - Bubblemorph
5709			if(this.options.addOnBubblemorph.enable) {
5710				BubbleMorphAddOn($, this.options.wrapper, false);
5711			}
5712
5713			// Addon Init - Distortion
5714			if(this.options.addOnDistortion.enable) {
5715				RsLiquideffectAddOn($, this.options.wrapper);
5716			}
5717
5718			return this;
5719		}
5720
5721        events() {
5722
5723			return this;
5724		}
5725    }
5726
5727    PluginRevolutionSlider.defaults = {
5728		sliderType: 'standard',
5729		sliderLayout: 'fullwidth',
5730		delay: 9000,
5731		gridwidth: 1170,
5732		gridheight: 500,
5733		spinner: 'spinner3',
5734		disableProgressBar: 'on',
5735		parallax: {
5736			type: 'off',
5737			bgparallax: 'off'
5738		},
5739		navigation: {
5740			keyboardNavigation: 'off',
5741			keyboard_direction: 'horizontal',
5742			mouseScrollNavigation: 'off',
5743			onHoverStop: 'off',
5744			touch: {
5745				touchenabled: 'on',
5746				swipe_threshold: 75,
5747				swipe_min_touches: 1,
5748				swipe_direction: 'horizontal',
5749				drag_block_vertical: false
5750			},
5751			arrows: {
5752				enable: true,
5753				hide_onmobile: false,
5754				hide_under: 0,
5755				hide_onleave: true,
5756				hide_delay: 200,
5757				hide_delay_mobile: 1200,
5758				left: {
5759					h_align: 'left',
5760					v_align: 'center',
5761					h_offset: 30,
5762					v_offset: 0
5763				},
5764				right: {
5765					h_align: 'right',
5766					v_align: 'center',
5767					h_offset: 30,
5768					v_offset: 0
5769				}
5770			}
5771		},
5772
5773		/* ADDONS */
5774	    addOnTypewriter: {
5775			enable: false
5776		},
5777		addOnWhiteboard: {
5778			enable: false,
5779
5780		},
5781	    whiteboard: {
5782	        movehand: {
5783	            src: '../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/hand_point_right.png',
5784	            width: 400,
5785	            height: 1000,
5786	            handtype: 'right',
5787	            transform: {
5788	                transformX: 50,
5789	                transformY: 50
5790	            },
5791	            jittering: {
5792	                distance: '80',
5793	                distance_horizontal: '100',
5794	                repeat: '5',
5795	                offset: '10',
5796	                offset_horizontal: '0'
5797	            },
5798	            rotation: {
5799	                angle: '10',
5800	                repeat: '3'
5801	            }
5802	        },
5803	        writehand: {
5804	            src: '../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/write_right_angle.png',
5805	            width: 572,
5806	            height: 691,
5807	            handtype: 'right',
5808	            transform: {
5809	                transformX: 50,
5810	                transformY: 50
5811	            },
5812	            jittering: {
5813	                distance: '80',
5814	                distance_horizontal: '100',
5815	                repeat: '5',
5816	                offset: '10',
5817	                offset_horizontal: '0'
5818	            },
5819	            rotation:{
5820	                angle: '10',
5821	                repeat: '3'
5822	            }
5823	        }
5824	    },
5825	    addOnParticles: {
5826	    	enable: false
5827	    },
5828	    particles: {
5829			startSlide: "first", 
5830			endSlide: "last", 
5831			zIndex: "1",
5832			particles: {
5833				number: {value: 80}, color: {value: "#ffffff"},
5834				shape: {
5835					type: "circle", stroke: {width: 0, color: "#ffffff", opacity: 1},
5836					image: {src: ""}
5837				},
5838				opacity: {value: 0.5, random: true, min: 0.25, anim: {enable: false, speed: 3, opacity_min: 0, sync: false}},
5839				size: {value: 2, random: false, min: 30, anim: {enable: false, speed: 40, size_min: 1, sync: false}},
5840				line_linked: {enable: true, distance: 150, color: "#ffffff", opacity: 0.4, width: 1},
5841				move: {enable: true, speed: 6, direction: "none", random: true, min_speed: 6, straight: false, out_mode: "out"}
5842			},
5843			interactivity: {
5844				events: {onhover: {enable: false, mode: "repulse"}, onclick: {enable: false, mode: "repulse"}},
5845				modes: {grab: {distance: 400, line_linked: {opacity: 0.5}}, bubble: {distance: 400, size: 40, opacity: 0.4}, repulse: {distance: 200}}
5846			}
5847		},
5848		addOnCountdown: {
5849			enable: false,
5850			targetdate: new Date().getTime() + 864000000, // http://www.freeformatter.com/epoch-timestamp-to-date-converter.html
5851			slidechanges: [{days: 0, hours: 0, minutes: 0, seconds: 0, slide: 2}]
5852		},
5853		addOnSlicey: {
5854			enable: false
5855		},
5856		addOnFilmstrip: {
5857			enable: false
5858		},
5859		addOnBeforeAfter : {
5860			enable: false,
5861			options: {
5862				cursor: "move",
5863			    carousel: false,
5864			    arrowStyles: {
5865			        leftIcon: "fa-icon-caret-left",
5866			        rightIcon: "fa-icon-caret-right",
5867			        topIcon: "fa-icon-caret-up",
5868			        bottomIcon: "fa-icon-caret-down",
5869			        size: "35",
5870			        color: "#ffffff",
5871			        spacing: "10",
5872			        bgColor: "transparent",
5873			        padding: "0",
5874			        borderRadius: "0"
5875			    },
5876			    dividerStyles: {
5877			        width: "1",
5878			        color: "rgba(255, 255, 255, 0.5)"
5879			    }
5880			}
5881		},
5882		addOnPanorama: {
5883			enable: false
5884		},
5885		addOnRevealer: {
5886			enable: false,
5887		},
5888		revealer: {
5889			direction: "open_horizontal",
5890			color: "#ffffff",
5891			duration: "1500",
5892			delay: "0",
5893			easing: "Power2.easeInOut",
5894			overlay_enabled: true,
5895			overlay_color: "#000000",
5896			overlay_duration: "1500",
5897			overlay_delay: "0",
5898			overlay_easing: "Power2.easeInOut",
5899			spinner: "1",
5900			spinnerColor: "#006dd2",
5901			spinnerHtml: "<div class='rsaddon-revealer-spinner rsaddon-revealer-spinner-1'><div class='rsaddon-revealer-1'><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><\/div><\/div \/>"
5902		},
5903		addOnDuotone: {
5904			enable: false
5905		},
5906		addOnBubblemorph: {
5907			enable: false
5908		},
5909		addOnDistortion: {
5910			enable: false
5911		}
5912		
5913	};
5914
5915    // expose to scope
5916    $.extend(theme, {
5917		PluginRevolutionSlider
5918	});
5919
5920    // jquery plugin
5921    $.fn.themePluginRevolutionSlider = function(opts) {
5922		return this.map(function() {
5923			const $this = $(this);
5924
5925			if ($this.data(instanceName)) {
5926				return $this.data(instanceName);
5927			} else {
5928				return new PluginRevolutionSlider($this, opts);
5929			}
5930
5931		});
5932	}
5933})).apply(this, [window.theme, jQuery]);
5934
5935// Scroll Spy
5936(((theme = {}, $) => {
5937    const instanceName = '__scrollSpy';
5938
5939    class PluginScrollSpy {
5940        constructor($el, opts) {
5941            return this.initialize($el, opts);
5942        }
5943
5944        initialize($el, opts) {
5945
5946			if( document.querySelector( opts.target ) == null ) {
5947				return false;
5948			}
5949
5950			this.$el = $el;
5951
5952			this
5953				.setData()
5954				.setOptions(opts);
5955			
5956			this.build();
5957
5958			return this;
5959		}
5960
5961        setData() {
5962			this.$el.data(instanceName, this);
5963
5964			return this;
5965		}
5966
5967        setOptions(opts) {
5968			this.options = $.extend(true, {}, PluginScrollSpy.defaults, opts, {
5969				wrapper: this.$el
5970			});
5971
5972			return this;
5973		}
5974
5975        build() {
5976            const self = this, target = document.querySelector( self.options.target ) != null ? document.querySelector( self.options.target ) : false, navItems = target == '#header' || target == '.wrapper-spy' ? target.querySelectorAll('.header-nav .nav > li a') : target.querySelectorAll('.nav > li a');
5977
5978			// Get all section ID's
5979			let sectionIDs = Object.keys(navItems).map((key, index) => navItems[key].hash);
5980
5981			// Remove empty values from sectionIDs array
5982			sectionIDs = sectionIDs.filter(value => value != '');
5983
5984			// Store in a global variable
5985			self.sectionIDs = sectionIDs;
5986
5987			for( let i = 0; i < sectionIDs.length; i++ ) {
5988
5989				// Default Root Margin
5990				let rootMargin = '-20% 0px -79.9% 0px';
5991				
5992				// Spy Offset
5993				if( $( sectionIDs[i] ).data('spy-offset') ) {
5994					const rootMarginOffset = $( sectionIDs[i] ).data('spy-offset'), isNegativeOffset = parseInt( rootMarginOffset ) < 0 ? true : false;
5995
5996					// Mount a new rootMargin based on offset value
5997					rootMargin = rootMargin.split(' ').map((element, index) => {
5998						if( element.indexOf('%') > 0 ) {
5999                            const valueToInt = parseInt( element.replace('%','') );
6000                            let newValue = 0;
6001
6002                            switch ( index ) {
6003								case 0:
6004									if( isNegativeOffset ) {
6005										newValue = valueToInt - rootMarginOffset;
6006									} else {
6007										newValue = Math.abs(valueToInt) + rootMarginOffset;
6008									}
6009									break;
6010
6011								case 2:
6012									if( isNegativeOffset ) {
6013										newValue = valueToInt + rootMarginOffset;
6014									} else {
6015										newValue = Math.abs(valueToInt) - rootMarginOffset;
6016									}
6017									break;
6018							
6019							}
6020
6021                            if( isNegativeOffset ) {
6022								newValue = newValue + '%';
6023							} else {
6024								newValue = '-' + newValue + '%';
6025							}
6026
6027                            return newValue;
6028                        } else {
6029							return element;
6030						}
6031					}).join(' ');
6032				}
6033
6034				const selector = sectionIDs[i],
6035                      callback = function() {
6036                          const $section = $(this);
6037
6038                          if( target == '#header' || target == '.wrapper-spy' ) {
6039                              $('#header .header-nav .nav > li a').removeClass('active');
6040                              $('#header .header-nav .nav > li a[href="#'+ $section[0].id +'"]').addClass('active');
6041                          } else {
6042                              $( target ).find('.nav > li a').removeClass('active');
6043                              $( target ).find('.nav > li a[href="#'+ $section[0].id +'"]').addClass('active');
6044                          }
6045                          
6046                      };
6047
6048				this.scrollSpyIntObs( selector, callback, { 
6049					rootMargin,
6050					threshold: 0
6051				}, true, i, true);
6052
6053            }
6054
6055            return this;
6056
6057		}
6058
6059        scrollSpyIntObs(selector, functionName, intObsOptions, al
6059waysObserve, index, firstLoad) {
6060			const self = this;
6061
6062			const $el = document.querySelectorAll( selector );
6063			let intersectionObserverOptions = {
6064				rootMargin: '0px 0px 200px 0px'
6065			};
6066
6067			if( Object.keys(intObsOptions).length ) {
6068				intersectionObserverOptions = $.extend(intersectionObserverOptions, intObsOptions);
6069			}
6070
6071			const observer = new IntersectionObserver(entries => {
6072                for (const entry of entries) {
6073                    if (entry.intersectionRatio > 0 ) {
6074						if( typeof functionName === 'string' ) {
6075							const func = Function( 'return ' + functionName )();
6076						} else {
6077							const callback = functionName;
6078
6079							callback.call( $(entry.target) );
6080						}
6081
6082						// Unobserve
6083						if( !alwaysObserve ) {
6084							observer.unobserve(entry.target);   
6085						}
6086
6087					} else {
6088						if( firstLoad == false ) {
6089							if( index == self.sectionIDs.length - 1 ) {
6090								$('#header .header-nav .nav > li a').removeClass('active');
6091								$('#header .header-nav .nav > li a[href="#'+ entry.target.id +'"]').parent().prev().find('a').addClass('active');
6092							}
6093						}
6094						firstLoad = false;
6095
6096					}
6097                }
6098            }, intersectionObserverOptions);
6099			
6100			$( $el ).each(function(){
6101				observer.observe( $(this)[0] );
6102			});
6103
6104			return this;
6105		}
6106    }
6107
6108    PluginScrollSpy.defaults = {
6109		target: '#header'
6110	};
6111
6112    // expose to scope
6113    $.extend(theme, {
6114		PluginScrollSpy
6115	});
6116
6117    // jquery plugin
6118    $.fn.themePluginScrollSpy = function(opts) {
6119		return this.map(function() {
6120			const $this = $(this);
6121
6122			if ($this.data(instanceName)) {
6123				return $this.data(instanceName);
6124			} else {
6125				return new PluginScrollSpy($this, opts);
6126			}
6127
6128		});
6129	}
6130})).apply(this, [window.theme, jQuery]);
6131
6132// Scroll to Top
6133(((theme = {}, $) => {
6134    $.extend(theme, {
6135
6136		PluginScrollToTop: {
6137
6138			defaults: {
6139				wrapper: $('body'),
6140				offset: 150,
6141				buttonClass: 'scroll-to-top',
6142				buttonAriaLabel: 'Scroll To Top',
6143				iconClass: 'fas fa-chevron-up',
6144				delay: 1000,
6145				visibleMobile: false,
6146				label: false,
6147				easing: 'easeOutBack'
6148			},
6149
6150			initialize(opts) {
6151				initialized = true;
6152
6153				// Don't initialize if the page has Section Scroll
6154				if( $('body[data-plugin-section-scroll]').get(0) ) {
6155					return;
6156				}
6157
6158				this
6159					.setOptions(opts)
6160					.build()
6161					.events();
6162
6163				return this;
6164			},
6165
6166			setOptions(opts) {
6167				this.options = $.extend(true, {}, this.defaults, opts);
6168
6169				return this;
6170			},
6171
6172			build() {
6173                const self = this;
6174                let $el;
6175
6176                // Base HTML Markup
6177                $el = $('<a />')
6178					.addClass(self.options.buttonClass)
6179					.attr({
6180						'href': '#',
6181						'aria-label': self.options.buttonAriaLabel
6182					})
6183					.append(
6184						$('<i />')
6185						.addClass(self.options.iconClass)
6186				);
6187
6188                // Visible Mobile
6189                if (!self.options.visibleMobile) {
6190					$el.addClass('hidden-mobile');
6191				}
6192
6193                // Label
6194                if (self.options.label) {
6195					$el.append(
6196						$('<span />').html(self.options.label)
6197					);
6198				}
6199
6200                this.options.wrapper.append($el);
6201
6202                this.$el = $el;
6203
6204                return this;
6205            },
6206
6207			events() {
6208                const self = this;
6209                let _isScrolling = false;
6210
6211                // Click Element Action
6212                self.$el.on('click', e => {
6213					e.preventDefault();
6214					$('html').animate({
6215						scrollTop: 0
6216					}, self.options.delay, self.options.easing);
6217					return false;
6218				});
6219
6220                // Show/Hide Button on Window Scroll event.
6221                $(window).scroll(() => {
6222
6223					if (!_isScrolling) {
6224
6225						_isScrolling = true;
6226
6227						if ($(window).scrollTop() > self.options.offset) {
6228
6229							self.$el.stop(true, true).addClass('visible');
6230							_isScrolling = false;
6231
6232						} else {
6233
6234							self.$el.stop(true, true).removeClass('visible');
6235							_isScrolling = false;
6236
6237						}
6238
6239					}
6240
6241				});
6242
6243                return this;
6244            }
6245
6246		}
6247
6248	});
6249})).apply(this, [window.theme, jQuery]);
6250
6251// Scrollable
6252(((theme = {}, $) => {
6253    const instanceName = '__scrollable';
6254
6255    class PluginScrollable {
6256        constructor($el, opts) {
6257            return this.initialize($el, opts);
6258        }
6259
6260        static updateModals() {
6261            PluginScrollable.updateBootstrapModal();
6262        }
6263
6264        static updateBootstrapModal() {
6265            let updateBoostrapModal;
6266
6267            updateBoostrapModal = typeof $.fn.modal !== 'undefined';
6268            updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor !== 'undefined';
6269            updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor.prototype !== 'undefined';
6270            updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor.prototype.enforceFocus !== 'undefined';
6271
6272            if ( !updateBoostrapModal ) {
6273                return false;
6274            }
6275
6276            const originalFocus = $.fn.modal.Constructor.prototype.enforceFocus;
6277            $.fn.modal.Constructor.prototype.enforceFocus = function() {
6278                originalFocus.apply( this );
6279
6280                const $scrollable = this.$element.find('.scrollable');
6281                if ( $scrollable ) {
6282                    if ( $.isFunction($.fn['themePluginScrollable'])  ) {
6283                        $scrollable.themePluginScrollable();
6284                    }
6285
6286                    if ( $.isFunction($.fn['nanoScroller']) ) {
6287                        $scrollable.nanoScroller();
6288                    }
6289                }
6290            };
6291        }
6292
6293        initialize($el, opts) {
6294			if ( $el.data( instanceName ) ) {
6295				return this;
6296			}
6297
6298			this.$el = $el;
6299
6300			this
6301				.setData()
6302				.setOptions(opts)
6303				.build();
6304
6305			return this;
6306		}
6307
6308        setData() {
6309			this.$el.data(instanceName, this);
6310
6311			return this;
6312		}
6313
6314        setOptions(opts) {
6315			this.options = $.extend(true, {}, PluginScrollable.defaults, opts, {
6316				wrapper: this.$el
6317			});
6318
6319			return this;
6320		}
6321
6322        build() {
6323			this.options.wrapper.nanoScroller(this.options);
6324
6325			return this;
6326		}
6327    }
6328
6329    PluginScrollable.defaults = {
6330		contentClass: 'scrollable-content',
6331		paneClass: 'scrollable-pane',
6332		sliderClass: 'scrollable-slider',
6333		alwaysVisible: true,
6334		preventPageScrolling: true
6335	};
6336
6337    // expose to scope
6338    $.extend(theme, {
6339		PluginScrollable
6340	});
6341
6342    // jquery plugin
6343    $.fn.themePluginScrollable = function(opts) {
6344		return this.each(function() {
6345			const $this = $(this);
6346
6347			if ($this.data(instanceName)) {
6348				return $this.data(instanceName);
6349			} else {
6350				return new PluginScrollable($this, opts);
6351			}
6352
6353		});
6354	};
6355
6356    $(() => {
6357		PluginScrollable.updateModals();
6358	});
6359})).apply(this, [window.theme, jQuery]);
6360
6361// Section Scroll
6362(((theme = {}, $) => {
6363    const instanceName = '__sectionScroll';
6364
6365    class PluginSectionScroll {
6366        constructor($el, opts) {
6367            return this.initialize($el, opts);
6368        }
6369
6370        initialize($el, opts) {
6371			if ($el.data(instanceName)) {
6372				return this;
6373			}
6374
6375			this.$el = $el;
6376
6377			this
6378				.setData()
6379				.setOptions(opts)
6380				.build()
6381				.events();
6382
6383			return this;
6384		}
6385
6386        setData() {
6387			this.$el.data(instanceName, this);
6388
6389			return this;
6390		}
6391
6392        setOptions(opts) {
6393			this.options = $.extend(true, {}, PluginSectionScroll.defaults, opts, {
6394				wrapper: this.$el
6395			});
6396
6397			return this;
6398		}
6399
6400        build() {
6401			const self = this, $el = this.options.wrapper;
6402
6403			// Check type of header and change the target for header (by change header color purpose)
6404			if( $('html').hasClass('side-header-overlay-full-screen') ) {
6405				self.$header = $('.sticky-wrapper');
6406			} else {
6407				self.$header = $('#header');
6408			}
6409
6410			// Turn the section full height or not depeding on the content size
6411			self.updateSectionsHeight();
6412
6413			// Wrap all sections in a section wrapper
6414			$( this.options.targetClass ).wrap('<div class="section-wrapper"></div>');
6415
6416			// Set the section wrapper height
6417	  		$('.section-wrapper').each(function(){
6418	  			$(this).height( $(this).find('.section-scroll').outerHeight() );
6419	  		});
6420
6421	  		// Add active class to the first section on page load
6422	  		$('.section-wrapper').first().addClass('active');
6423			
6424	        let flag = false, scrollableFlag = false, touchDirection = '', touchstartY = 0, touchendY = 0;
6425
6426	        $(window).on('touchstart', ({changedTouches}) => {
6427			    touchstartY = changedTouches[0].screenY;
6428			});
6429
6430	        let wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll';
6431	        if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6432	        	wheelEvent = 'onwheel' in document ? 'wheel touchend' : document.onmousewheel !== undefined ? 'mousewheel touchend' : 'DOMMouseScroll touchend';
6433	        }
6434
6435        	if( $(window).width() < 992 ) {
6436	    		$('html').removeClass('overflow-hidden');
6437			    $(window).on('scroll', () => {
6438
6439		    		let index = 0;
6440		    		$('.section-scroll').each(function(){
6441		    			if( $(this).offset().top <= $(window).scrollTop() + 50 ) {
6442		    				const $currentSection2 = $('.section-wrapper').eq( index ).find('.section-scroll');
6443
6444			            	$('.section-scroll-dots-navigation > ul > li').removeClass('active');
6445							$('.section-scroll-dots-navigation > ul > li').eq( index ).addClass('active');
6446
6447							$(window).trigger({
6448								type: 'section.scroll.mobile.change.header.color',
6449								currentSection: $currentSection2
6450							});
6451		    			}
6452
6453		    			index++;
6454		    		});
6455		    		
6456			    });
6457
6458			    $(window).on('section.scroll.mobile.change.header.color', ({currentSection}) => {
6459			    	if( typeof currentSection == 'undefined' ) {
6460			    		return;
6461			    	}
6462
6463			    	const $currentSection = currentSection, headerColor     = $currentSection.data('section-scroll-header-color');
6464								    	
6465			    	$('#header .header-nav').removeClass('header-nav-light-text header-nav-dark-text').addClass('header-nav-' + headerColor + '-text');
6466			    	$('#header .header-nav-features').removeClass('header-nav-features-dark header-nav-features-light').addClass('header-nav-features-' + headerColor);
6467			    	$('#header .header-social-icons').removeClass('social-icons-icon-dark social-icons-icon-light').addClass('social-icons-icon-' + headerColor);
6468
6469			    	// Change Logo
6470			    	if( self.options.changeHeaderLogo && headerColor != undefined ) {
6471				    	if( headerColor == 'light' ) {
6472				    		$('#header .header-logo img').attr('src', self.options.headerLogoLight);
6473				    	} else if( headerColor == 'dark' ) {
6474				    		$('#header .header-logo img').attr('src', self.options.headerLogoDark);
6475				    	}
6476			    	}
6477
6478			    	self.$header.css({
6479			    		opacity: 1
6480			    	});
6481
6482			    });
6483        	}
6484
6485	        $(window).on(wheelEvent, ({target, originalEvent}) => {
6486                if( $(window).width() < 992 ) {
6487	        		return;
6488	        	}
6489
6490                if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6491		        	if( $(target).closest('.section-scroll-dots-navigation').get(0) || $(target).closest('.header-body').get(0) || $(target).closest('.owl-carousel').get(0) ) {
6492		        		return;
6493		        	}
6494		        }
6495
6496                // Side Header Overlay Full Screen
6497                if( $('html.side-header-overlay-full-screen.side-header-hide').get(0) ) {
6498		        	return;
6499		        }
6500
6501                const wheelDirection = originalEvent.wheelDelta == undefined ? originalEvent.deltaY > 0 : originalEvent.wheelDelta < 0;
6502                if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6503		        	touchendY = event.changedTouches[0].screenY;
6504	        		
6505				    if( touchendY <= touchstartY ) {
6506				    	touchDirection = 'up';
6507				    }
6508
6509				    if( touchendY >= touchstartY ) {
6510				    	touchDirection = 'down';
6511				    }
6512
6513				    if( touchendY == touchstartY ) {
6514				    	return;
6515				    }
6516	        	}
6517
6518                const $currentSection = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll');
6519                const $nextSection = self.getNextSection(wheelDirection, touchDirection);
6520                let nextSectionOffsetTop;
6521
6522                // If is the last section, then change the offsetTop value
6523                if( self.getCurrentIndex() == $('.section-wrapper').length - 1 ) {
6524            		nextSectionOffsetTop = $(document).height();
6525            	} else {
6526            		nextSectionOffsetTop = $nextSection.offset().top;
6527            	}
6528
6529                if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6530				    setTimeout(() => {
6531					    if( $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').hasClass('section-scroll-scrollable') ) {
6532					    	$('html').removeClass('overflow-hidden');
6533					    } else {
6534					    	$('html').addClass('overflow-hidden');
6535					    }
6536				    }, 1200);
6537				}
6538
6539                // For non full height sections
6540                if( $currentSection.hasClass('section-scroll-scrollable') ) {
6541	        		if( !flag && !scrollableFlag ) {
6542
6543		        		// Scroll Direction
6544		        		if(wheelDirection || touchDirection == 'up') {
6545		        			if( ( $(window).scrollTop() + $(window).height() ) >= nextSectionOffsetTop ) {
6546		        				flag = true;
6547								setTimeout(() => {
6548									$(window).trigger('section.scroll.change.header.color');
6549
6550					            	setTimeout(() => {
6551										flag = false;
6552									}, 500);
6553								}, 1000);
6554
6555		        				if( self.getCurrentIndex() == ( $('.section-wrapper').length - 1 )  ) {
6556						    		return false;
6557						    	}
6558
6559		        				// Move to the next section
6560		        				self.moveTo( $currentSection.offset().top + $currentSection.outerHeight() );
6561
6562		        				// Change Section Active Class
6563					   			self.changeSectionActiveState( $nextSection );
6564
6565					   			self.$header.css({
6566							    	opacity: 0,
6567							    	transition: 'ease opacity 500ms'
6568							    });
6569					        }
6570
6571			        		if( !$('html').hasClass('touch') ) {
6572				        		for( var i = 1; i < 100; i++ ) {
6573					        		$('body, html').scrollTop( $(window).scrollTop() + 1 );
6574
6575					        		if( ( $(window).scrollTop() + $(window).height() ) >= nextSectionOffsetTop ) {
6576					        			scrollableFlag = true;
6577										setTimeout(() => {
6578											$(window).trigger('section.scroll.change.header.color');
6579							            	scrollableFlag = false;
6580										}, 500);
6581					        			break;
6582					        		}
6583				        		}
6584				        	}
6585					    } else {
6586					    	if( $(window).scrollTop() <= $currentSection.offset().top ) {
6587					    		flag = true;
6588								setTimeout(() => {
6589									$(window).trigger('section.scroll.change.header.color');
6590
6591					            	setTimeout(() => {
6592										flag = false;
6593									}, 500);
6594								}, 1000);
6595
6596					    		if( self.getCurrentIndex() == 0  ) {
6597						    		return false;
6598						    	}
6599
6600					   			// Move to the next section
6601		        				self.moveTo( $currentSection.offset().top - $(window).height() );
6602
6603		        				// Change Section Active Class
6604					   			self.changeSectionActiveState( $nextSection );
6605
6606					   			self.$header.css({
6607							    	opacity: 0,
6608							    	transition: 'ease opacity 500ms'
6609							    });
6610					        }
6611
6612					    	if( !$('html').hasClass('touch') ) {
6613				        		for( var i = 1; i < 100; i++ ) {
6614					        		$('body, html').scrollTop( $(window).scrollTop() - 1 );
6615
6616					        		if( $(window).scrollTop() <= $currentSection.offset().top ) {
6617					        			scrollableFlag = true;
6618										setTimeout(() => {
6619											$(window).trigger('section.scroll.change.header.color');
6620							            	scrollableFlag = false;
6621										}, 500);
6622					        			break;
6623					        		}
6624				        		}
6625				        	}
6626					    }
6627
6628			   			// Change Dots Active Class
6629				        self.changeDotsActiveState();
6630
6631		        		return;
6632
6633		        	}
6634	        	}
6635
6636                // For full height sections
6637                if( !flag && !scrollableFlag ) {
6638				    if(wheelDirection || touchDirection == 'up') {
6639				    	if( self.getCurrentIndex() == ( $('.section-wrapper').length - 1 )  ) {
6640				    		return false;
6641				    	}
6642
6643				   		// Change Section Active Class
6644			   			self.changeSectionActiveState( $nextSection );
6645
6646				   		setTimeout(() => {
6647				   			// Move to the next section
6648	        				self.moveTo( $nextSection.offset().top );
6649
6650				   		}, 150);
6651				    } else {
6652				    	if( self.getCurrentIndex() == 0  ) {
6653				    		return false;
6654				    	}
6655
6656				   		// Change Section Active Class
6657			   			self.changeSectionActiveState( $nextSection );
6658
6659				   		if( $nextSection.height() > $(window).height() ) {
6660				   			// Move to the next section
6661	        				self.moveTo( $currentSection.offset().top - $(window).height() );
6662				   		} else {
6663					        setTimeout(() => {
6664					   			// Move to the next section
6665		        				self.moveTo( $nextSection.offset().top );
6666
6667					   		}, 150);
6668				   		}
6669				    }
6670
6671				    // Change Dots Active Class
6672			        self.changeDotsActiveState();
6673
6674				    self.$header.css({
6675				    	opacity: 0,
6676				    	transition: 'ease opacity 500ms'
6677				    });
6678
6679				    // Style next section
6680	            	$nextSection.css({
6681	            		position: 'relative',
6682	            		opacity: 1,
6683	            		'z-index': 1,
6684	            		transform: 'translate3d(0,0,0) scale(1)'
6685	            	});
6686
6687	            	// Style previous section
6688	            	$currentSection.css({
6689	            		position: 'fixed',
6690	            		width: '100%',
6691	            		top: 0,
6692	            		left: 0,
6693	            		opacity: 0,
6694	            		'z-index': 0,
6695	            		transform: 'translate3d(0,0,-10px) scale(0.7)',
6696	            		transition: 'ease transform 600ms, ease opacity 600ms',
6697	            	});
6698
6699					setTimeout(() => {
6700						$currentSection.css({
6701		            		position: 'relative',
6702		            		opacity: 1,
6703		            		transform: 'translate3d(0,0,-10px) scale(1)'
6704		            	});
6705
6706						$(window).trigger('section.scroll.change.header.color');
6707
6708		            	setTimeout(() => {
6709							flag = false;
6710						}, 500);
6711					}, 1000);
6712
6713					flag = true;
6714
6715				}
6716
6717                return;
6718            });
6719
6720	        // Dots Navigation
6721	        if( this.options.dotsNav ) {
6722	        	self.dotsNavigation();
6723	        }
6724
6725	        // First Load
6726	        setTimeout(() => {
6727		        if( $(window.location.hash).get(0) ) {
6728		        	self.moveTo( $(window.location.hash).parent().offset().top );
6729
6730		        	self.changeSectionActiveState( $(window.location.hash) );
6731
6732		        	// Change Dots Active Class
6733			        self.changeDotsActiveState();
6734
6735		        	self.updateHash( true );
6736		        } else {
6737                    const hash  = window.location.hash;
6738                    let index = hash.replace('#','');
6739
6740                    if( !hash ) {
6741		        		index = 1;
6742		        	}
6743
6744                    self.moveTo( $('.section-wrapper').eq( index - 1 ).offset().top );
6745
6746                    self.changeSectionActiveState( $('.section-wrapper').eq( index - 1 ).find('.section-scroll') );
6747
6748                    // Change Dots Active Class
6749                    self.changeDotsActiveState();
6750
6751                    self.updateHash( true );
6752                }
6753
6754				$(window).trigger('section.scroll.ready');
6755				$(window).trigger('section.scroll.change.header.color');
6756			}, 500);
6757
6758			return this;
6759		}
6760
6761        updateSectionsHeight() {
6762			const self = this;
6763
6764			$('.section-scroll').css({ height: '' });
6765
6766			$('.section-scroll').each(function(){
6767				if( $(this).outerHeight() < ( $(window).height() + 3 ) ) {
6768					$(this).css({ height: '100vh' });		
6769				} else {
6770					$(this).addClass('section-scroll-scrollable');
6771				}
6772			});
6773
6774			// Set the section wrapper height
6775	  		$('.section-wrapper').each(function(){
6776	  			$(this).height( $(this).find('.section-scroll').outerHeight() );
6777	  		});
6778
6779			return this;
6780		}
6781
6782        updateHash(first_load) {
6783			const self = this;
6784
6785			if( !window.location.hash ) {
6786				window.location.hash = 1;
6787			} else {
6788				if(!first_load) {
6789					const $section = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll'), section_id = $section.attr('id') ? $section.attr('id') : $section.parent().index() + 1;
6790
6791					window.location.hash = section_id;
6792				}
6793			}
6794
6795			return this;
6796		}
6797
6798        getCurrentIndex() {
6799            const self = this;
6800            let currentIndex = 0;
6801
6802            currentIndex = $('.section-wrapper.active').index();
6803
6804            return currentIndex;
6805        }
6806
6807        moveTo($scrollTopValue, first_load) {
6808			const self = this;
6809
6810			$('body, html').animate({
6811   				scrollTop: $scrollTopValue
6812   			}, 1000, 'easeOutQuint');
6813
6814   			setTimeout(() => {
6815	   			self.updateHash();
6816   			}, 500);
6817
6818			return this;
6819		}
6820
6821        getNextSection(wheelDirection, touchDirection) {
6822            const self = this;
6823            let $nextSection = '';
6824
6825            // Scroll Direction
6826            if(wheelDirection || touchDirection == 'up') {
6827				$nextSection = $('.section-wrapper').eq( self.getCurrentIndex() + 1 ).find('.section-scroll');
6828        	} else {
6829        		$nextSection = $('.section-wrapper').eq( self.getCurrentIndex() - 1 ).find('.section-scroll');
6830        	}
6831
6832            return $nextSection;
6833        }
6834
6835        changeSectionActiveState($nextSection) {
6836			const self = this;
6837
6838			$('.section-wrapper').removeClass('active');
6839	   		$nextSection.parent().addClass('active');
6840
6841			return this;
6842		}
6843
6844        changeDotsActiveState() {
6845			const self = this;
6846
6847			$('.section-scroll-dots-navigation > ul > li').removeClass('active');
6848			$('.section-scroll-dots-navigation > ul > li').eq( self.getCurrentIndex() ).addClass('active');
6849
6850			return this;
6851		}
6852
6853        dotsNavigation() {
6854			const self = this;
6855
6856			const dotsNav = $('<div class="section-scroll-dots-navigation"><ul class="list list-unstyled"></ul></div>'), currentSectionIndex = self.getCurrentIndex();
6857
6858        	if( self.options.dotsClass ) {
6859        		dotsNav.addClass( self.options.dotsClass );
6860        	}
6861
6862        	for( let i = 0; i < $('.section-scroll').length; i++ ) {
6863        		const title = $('.section-wrapper').eq( i ).find('.section-scroll').data('section-scroll-title');
6864
6865        		dotsNav.find('> ul').append( '<li'+ ( ( currentSectionIndex == i ) ? ' class="active"' : '' ) +'><a href="#'+ i +'" data-nav-id="'+ i +'"><span>'+ title +'</span></a></li>' );
6866        	}
6867
6868        	$('.body').append( dotsNav );
6869
6870        	dotsNav.find('a[data-nav-id]').on('click touchstart', function(e){
6871        		e.preventDefault();
6872        		const $this = $(this);
6873
6874        		$('.section-scroll').css({
6875        			opacity: 0,
6876        			transition: 'ease opacity 300ms'
6877        		});
6878
6879        		self.$header.css({
6880			    	opacity: 0,
6881			    	transition: 'ease opacity 500ms'
6882			    });
6883
6884        		setTimeout(() => {
6885	        		self.moveTo( $('.section-wrapper').eq( $this.data('nav-id') ).offset().top )
6886
6887		   			$('.section-wrapper').removeClass('active');
6888			   		$('.section-wrapper').eq( $this.data('nav-id') ).addClass('active');
6889
6890	        		$('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').css({
6891	        			opacity: 1
6892	        		});
6893
6894	        		setTimeout(() => {
6895		        		$('.section-scroll').css({ opacity: 1 });
6896
6897		        		$(window).trigger('section.scroll.change.header.color');
6898	        		}, 500);
6899
6900	        		if( $(window).width() > 991 ) {
6901		        		self.changeDotsActiveState();
6902	        		}
6903        		}, 500);
6904        	});
6905
6906			return this;
6907		}
6908
6909        events() {
6910			const self = this;
6911
6912			$(window).on('section.scroll.ready', () => {
6913				$(window).scrollTop(0);
6914			});
6915
6916			$(window).on('section.scroll.change.header.color', () => {
6917		    	const headerColor = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').data('section-scroll-header-color');
6918		    	
6919		    	$('#header .header-nav').removeClass('header-nav-light-text header-nav-dark-text').addClass('header-nav-' + headerColor + '-text');
6920		    	$('#header .header-nav-features').removeClass('header-nav-features-dark header-nav-features-light').addClass('header-nav-features-' + headerColor);
6921		    	$('#header .header-social-icons').removeClass('social-icons-icon-dark social-icons-icon-light').addClass('social-icons-icon-' + headerColor);
6922
6923		    	// Change Logo
6924		    	if( self.options.changeHeaderLogo && headerColor != undefined ) {
6925			    	if( headerColor == 'light' ) {
6926			    		$('#header .header-logo img').attr('src', self.options.headerLogoLight);
6927			    	} else if( headerColor == 'dark' ) {
6928			    		$('#header .header-logo img').attr('src', self.options.headerLogoDark);
6929			    	}
6930		    	}
6931
6932		    	self.$header.css({
6933		    		opacity: 1
6934		    	});
6935		    });
6936
6937			$(document).ready(() => {
6938			    $(window).afterResize(() => {
6939			    	self.updateSectionsHeight();
6940
6941			    	if( $(window).width() < 992 ) {
6942			    		$('html').removeClass('overflow-hidden');
6943			    	}
6944			    });
6945			});
6946
6947		    return this;
6948		}
6949    }
6950
6951    PluginSectionScroll.defaults = {
6952		targetClass: '.section',
6953		dotsNav: true,
6954		changeHeaderLogo: true,
6955		headerLogoDark: 'img/logo-default-slim.png',
6956		headerLogoLight: 'img/logo-default-slim-dark.png'
6957	};
6958
6959    // expose to scope
6960    $.extend(theme, {
6961		PluginSectionScroll
6962	});
6963
6964    // jquery plugin
6965    $.fn.themePluginSectionScroll = function(opts) {
6966		return this.map(function() {
6967			const $this = $(this);
6968
6969			if ($this.data(instanceName)) {
6970				return $this.data(instanceName);
6971			} else {
6972				return new PluginSectionScroll($this, opts);
6973			}
6974
6975		});
6976	};
6977})).apply(this, [window.theme, jQuery]);
6978
6979// Sort
6980(((theme = {}, $) => {
6981    const instanceName = '__sort';
6982
6983    class PluginSort {
6984        constructor($el, opts) {
6985            return this.initialize($el, opts);
6986        }
6987
6988        initialize($el, opts) {
6989			if ($el.data(instanceName)) {
6990				return this;
6991			}
6992
6993			this.$el = $el;
6994
6995			this
6996				.setData()
6997				.setOptions(opts)
6998				.build();
6999
7000			return this;
7001		}
7002
7003        setData() {
7004			this.$el.data(instanceName, this);
7005
7006			return this;
7007		}
7008
7009        setOptions(opts) {
7010			this.options = $.extend(true, {}, PluginSort.defaults, opts, {
7011				wrapper: this.$el
7012			});
7013
7014			return this;
7015		}
7016
7017        build() {
7018			if (!($.isFunction($.fn.isotope))) {
7019				return this;
7020			}
7021
7022			const self = this, $source = this.options.wrapper, $destination = $('.sort-destination[data-sort-id="' + $source.attr('data-sort-id') + '"]'), $window = $(window);
7023
7024			if ($destination.get(0)) {
7025
7026				self.$source = $source;
7027				self.$destination = $destination;
7028				self.$loader = false;
7029
7030				self.setParagraphHeight($destination);
7031
7032				if (self.$destination.parents('.sort-destination-loader').get(0)) {
7033					self.$loader = self.$destination.parents('.sort-destination-loader');
7034					self.createLoader();
7035				}
7036
7037				$destination.attr('data-filter', '*');
7038
7039				$destination.one('layoutComplete', (event, laidOutItems) => {
7040					self.removeLoader();
7041
7042					// If has data-plugin-sticky on the page we need recalculate sticky position
7043					if( $('[data-plugin-sticky]').length ) {
7044						setTimeout(() => {
7045							$('[data-plugin-sticky]').each(function(){
7046								$(this).data('__sticky').build();
7047								$(window).trigger('resize');
7048							});
7049						}, 500);
7050					}
7051				});
7052
7053				if ( $('#' + self.options.filterFieldId).length ) {
7054
7055					const $filterField = $('#' + self.options.filterFieldId);
7056
7057					$filterField.keyup(function() {
7058						self.options.filterFieldText = $(this).val();
7059						self.setFilter(self.options.filter);
7060					});
7061
7062				}
7063
7064				$destination.waitForImages(() => {
7065					$destination.isotope(self.options);
7066					self.events();
7067				});
7068
7069				setTimeout(() => {
7070					self.removeLoader();
7071				}, 3000);
7072
7073			}
7074
7075			return this;
7076		}
7077
7078        events() {
7079            const self = this;
7080            let filter = null;
7081            const $window = $(window);
7082
7083            self.$source.find('a').click(function(e) {
7084				e.preventDefault();
7085
7086				filter = $(this).parent().data('option-value');
7087
7088				self.setFilter(filter);
7089
7090				if (e.originalEvent) {
7091					self.$source.trigger('filtered');
7092				}
7093
7094				return this;
7095			});
7096
7097            self.$destination.trigger('filtered');
7098            self.$source.trigger('filtered');
7099
7100            if (self.options.useHash) {
7101				self.hashEvents();
7102			}
7103
7104            $window.on('resize sort.resize', () => {
7105				setTimeout(() => {
7106					self.$destination.isotope('layout');
7107				}, 300);
7108			});
7109
7110            setTimeout(() => {
7111				$window.trigger('sort.resize');
7112			}, 300);
7113
7114            return this;
7115        }
7116
7117        setFilter(filter) {
7118            const self = this;
7119            const page = false;
7120            let currentFilter = filter;
7121
7122            self.$source.find('.active').removeClass('active');
7123            self.$source.find('li[data-option-value="' + filter + '"], li[data-option-value="' + filter + '"] > a').addClass('active');
7124
7125            self.options.filter = currentFilter;
7126
7127            if (self.$destination.attr('data-current-page')) {
7128				currentFilter = currentFilter + '[data-page-rel=' + self.$destination.attr('data-current-page') + ']';
7129			}
7130
7131            if (self.options.filterFieldText != '') {
7132				currentFilter = currentFilter + '[data-sort-search*=' + self.options.filterFieldText.toLowerCase() + ']';
7133			}
7134
7135            self.$destination.attr('data-filter', filter).isotope({
7136				filter: currentFilter
7137			}).one('arrangeComplete', (event, filteredItems) => {
7138				
7139				if (self.options.useHash) {
7140					if (window.location.hash != '' || self.options.filter.replace('.', '') != '*') {
7141						window.location.hash = self.options.filter.replace('.', '');
7142					}
7143				}
7144				
7145				$(window).trigger('scroll');
7146
7147			}).trigger('filtered');
7148
7149            return this;
7150        }
7151
7152        hashEvents() {
7153            const self = this;
7154            let hash = null;
7155            let hashFilter = null;
7156            let initHashFilter = '.' + location.hash.replace('#', '');
7157
7158            // Check if has scroll to section trough URL hash and prevent the sort plugin from show nothing
7159            if( $(location.hash).length ) {
7160				initHashFilter = '.';
7161			}
7162
7163            if (initHashFilter != '.' && initHashFilter != '.*') {
7164				self.setFilter(initHashFilter);
7165			}
7166
7167            $(window).on('hashchange', e => {
7168
7169				hashFilter = '.' + location.hash.replace('#', '');
7170				hash = (hashFilter == '.' || hashFilter == '.*' ? '*' : hashFilter);
7171
7172				self.setFilter(hash);
7173
7174			});
7175
7176            return this;
7177        }
7178
7179        setParagraphHeight() {
7180            const self = this;
7181            let minParagraphHeight = 0;
7182            const paragraphs = $('span.thumb-info-caption p', self.$destination);
7183
7184            paragraphs.each(function() {
7185				if ($(this).height() > minParagraphHeight) {
7186					minParagraphHeight = ($(this).height() + 10);
7187				}
7188			});
7189
7190            paragraphs.height(minParagraphHeight);
7191
7192            return this;
7193        }
7194
7195        createLoader() {
7196			const self = this;
7197
7198			const loaderTemplate = [
7199				'<div class="bounce-loader">',
7200					'<div class="bounce1"></div>',
7201					'<div class="bounce2"></div>',
7202					'<div class="bounce3"></div>',
7203				'</div>'
7204			].join('');
7205
7206			self.$loader.append(loaderTemplate);
7207
7208			return this;
7209		}
7210
7211        removeLoader() {
7212
7213			const self = this;
7214
7215			if (self.$loader) {
7216
7217				self.$loader.removeClass('sort-destination-loader-showing');
7218
7219				setTimeout(() => {
7220					self.$loader.addClass('sort-destination-loader-loaded');
7221				}, 300);
7222
7223			}
7224
7225		}
7226    }
7227
7228    PluginSort.defaults = {
7229		useHash: true,
7230		itemSelector: '.isotope-item',
7231		layoutMode: 'masonry',
7232		filter: '*',
7233		filterFieldId: false,
7234		filterFieldText: '',
7235		hiddenStyle: {
7236			opacity: 0
7237		},
7238		visibleStyle: {
7239			opacity: 1
7240		},
7241		stagger: 30,
7242		isOriginLeft: ($('html').attr('dir') == 'rtl' ? false : true)
7243	};
7244
7245    // expose to scope
7246    $.extend(theme, {
7247		PluginSort
7248	});
7249
7250    // jquery plugin
7251    $.fn.themePluginSort = function(opts) {
7252		return this.map(function() {
7253			const $this = $(this);
7254
7255			if ($this.data(instanceName)) {
7256				return $this.data(instanceName);
7257			} else {
7258				return new PluginSort($this, opts);
7259			}
7260
7261		});
7262	}
7263})).apply(this, [window.theme, jQuery]);
7264
7265// Star Rating
7266(((theme = {}, $) => {
7267    const instanceName = '__starrating';
7268
7269    class PluginStarRating {
7270        constructor($el, opts) {
7271            return this.initialize($el, opts);
7272        }
7273
7274        initialize($el, opts) {
7275			this.$el = $el;
7276
7277			this
7278				.setData()
7279				.setOptions(opts)
7280				.build();
7281
7282			return this;
7283		}
7284
7285        setData() {
7286			this.$el.data(instanceName, this);
7287
7288			return this;
7289		}
7290
7291        setOptions(opts) {
7292			this.options = $.extend(true, {}, PluginStarRating.defaults, opts, {
7293				wrapper: this.$el
7294			});
7295
7296			return this;
7297		}
7298
7299        build() {
7300
7301			if (!($.isFunction($.fn.rating))) {
7302				return this;
7303			}
7304
7305			const self = this;
7306
7307			self.options.wrapper
7308				.rating(self.options);
7309
7310			self.options.wrapper.parents('.rating-container')
7311				.addClass('rating-' + self.options.color);
7312
7313			if( self.options.extraClass ) {
7314				self.options.wrapper.parents('.rating-container')
7315					.addClass(self.options.extraClass);
7316			}
7317
7318			return this;
7319
7320		}
7321    }
7322
7323    PluginStarRating.defaults = {
7324		theme: 'krajee-fas',
7325		color: 'primary',
7326		showClear: false,
7327		showCaption: false
7328	};
7329
7330    // expose to scope
7331    $.extend(theme, {
7332		PluginStarRating
7333	});
7334
7335    // jquery plugin
7336    $.fn.themePluginStarRating = function(opts) {
7337		return this.map(function() {
7338			const $this = $(this);
7339
7340			if ($this.data(instanceName)) {
7341				return $this.data(instanceName);
7342			} else {
7343				return new PluginStarRating($this, opts);
7344			}
7345
7346		});
7347	}
7348})).apply(this, [window.theme, jQuery]);
7349
7350// Sticky
7351(((theme = {}, $) => {
7352    const instanceName = '__sticky';
7353
7354    class PluginSticky {
7355        constructor($el, opts) {
7356            return this.initialize($el, opts);
7357        }
7358
7359        initialize($el, opts) {
7360			if ( $el.data( instanceName ) ) {
7361				return this;
7362			}
7363
7364			this.$el = $el;
7365
7366			this
7367				.setData()
7368				.setOptions(opts)
7369				.build()
7370				.events();
7371
7372			return this;
7373		}
7374
7375        setData() {
7376			this.$el.data(instanceName, this);
7377
7378			return this;
7379		}
7380
7381        setOptions(opts) {
7382			this.options = $.extend(true, {}, PluginSticky.defaults, opts, {
7383				wrapper: this.$el
7384			});
7385
7386			return this;
7387		}
7388
7389        build() {
7390			if (!($.isFunction($.fn.pin))) {
7391				return this;
7392			}
7393
7394			const self = this, $window = $(window);
7395			
7396			self.options.wrapper.pin(self.options);
7397
7398			if( self.options.wrapper.hasClass('sticky-wrapper-transparent') ) {
7399				self.options.wrapper.parent().addClass('position-absolute w-100');
7400			}
7401
7402			$window.afterResize(() => {
7403				self.options.wrapper.removeAttr('style').removeData('pin');
7404				self.options.wrapper.pin(self.options);
7405				$window.trigger('scroll');
7406			});
7407
7408			// Change Logo Src
7409			if( self.options.wrapper.find('img').attr('data-change-src') ) {
7410				const $logo = self.options.wrapper.find('img'), logoSrc = $logo.attr('src'), logoNewSrc = $logo.attr('data-change-src');
7411
7412				self.changeLogoSrc = activate => {
7413					if(activate) {
7414						$logo.attr('src', logoNewSrc);
7415					} else {
7416						$logo.attr('src', logoSrc);
7417					}
7418				}
7419			}
7420			
7421			return this;
7422		}
7423
7424        events() {
7425            const self = this;
7426            const $window = $(window);
7427            const $logo = self.options.wrapper.find('img');
7428			const classToCheck = ( self.options.wrapper.hasClass('sticky-wrapper-effect-1') ) ? 'sticky-effect-active' : 'sticky-active';
7429            let stickyActivateFlag = true;
7430            let stickyDeactivateFlag = false;
7431
7432            $window.on('scroll sticky.effect.active', () => {
7433				if( self.options.wrapper.hasClass( classToCheck ) ) {		
7434					if( stickyActivateFlag ) {			
7435						if( $logo.attr('data-change-src') ) {
7436							self.changeLogoSrc(true);
7437						}
7438
7439						stickyActivateFlag = false;
7440						stickyDeactivateFlag = true;
7441					}
7442				} else {	
7443					if( stickyDeactivateFlag ) {				
7444						if( $logo.attr('data-change-src') ) {
7445							self.changeLogoSrc(false);
7446						}
7447
7448						stickyDeactivateFlag = false;
7449						stickyActivateFlag = true;
7450					}
7451				}
7452			});
7453
7454            let isGoingUp = false;
7455            if( self.options.stickyStartEffectAt ) {
7456
7457				// First Load
7458				if( self.options.stickyStartEffectAt < $window.scrollTop() ) {
7459					self.options.wrapper.addClass('sticky-effect-active');
7460
7461					$window.trigger('sticky.effect.active');
7462				}
7463
7464				$window.on('scroll', () => {
7465					if( self.options.stickyStartEffectAt < $window.scrollTop() ) {	
7466						self.options.wrapper.addClass('sticky-effect-active');
7467						isGoingUp = true;
7468
7469						$window.trigger('sticky.effect.active');
7470					} else {	
7471						if( isGoingUp ) {
7472							self.options.wrapper.find('.sticky-body').addClass('position-fixed');
7473							isGoingUp = false;
7474						}
7475
7476						if( $window.scrollTop() == 0 ) {
7477							self.options.wrapper.find('.sticky-body').removeClass('position-fixed');
7478						}
7479
7480						self.options.wrapper.removeClass('sticky-effect-active');
7481					}
7482				});
7483			}
7484
7485            // Refresh Sticky Plugin if click in a data-toggle="collapse"
7486            if( $('[data-bs-toggle="collapse"]').get(0) ) {
7487
7488				$('[data-bs-toggle="collapse"]').on('click', () => {
7489					setTimeout(() => {
7490						self.build();
7491						$(window).trigger('scroll');
7492					}, 1000);
7493				});
7494
7495			}
7496
7497			// Visibility Issue
7498			document.addEventListener('visibilitychange', () => {
7499				$(window).trigger('resize');
7500			});
7501
7502			setInterval(() => {
7503				$(window).trigger('resize');
7504			}, 1000);
7505
7506        }
7507    }
7508
7509    PluginSticky.defaults = {
7510		minWidth: 991,
7511		activeClass: 'sticky-active'
7512	};
7513
7514    // expose to scope
7515    $.extend(theme, {
7516		PluginSticky
7517	});
7518
7519    // jquery plugin
7520    $.fn.themePluginSticky = function(opts) {
7521		return this.map(function() {
7522			const $this = $(this);
7523
7524			if ($this.data(instanceName)) {
7525				return $this.data(instanceName);
7526			} else {
7527				return new PluginSticky($this, opts);
7528			}
7529			
7530		});
7531	}
7532})).apply(this, [ window.theme, jQuery ]);
7533
7534// Toggle
7535(((theme = {}, $) => {
7536    const instanceName = '__toggle';
7537
7538    class PluginToggle {
7539        constructor($el, opts) {
7540            return this.initialize($el, opts);
7541        }
7542
7543        initialize($el, opts) {
7544			if ($el.data(instanceName)) {
7545				return this;
7546			}
7547
7548			this.$el = $el;
7549
7550			this
7551				.setData()
7552				.setOptions(opts)
7553				.build();
7554
7555			return this;
7556		}
7557
7558        setData() {
7559			this.$el.data(instanceName, this);
7560
7561			return this;
7562		}
7563
7564        setOptions(opts) {
7565			this.options = $.extend(true, {}, PluginToggle.defaults, opts, {
7566				wrapper: this.$el
7567			});
7568
7569			return this;
7570		}
7571
7572        build() {
7573            const self = this;
7574            const $wrapper = this.options.wrapper;
7575            const $items = $wrapper.find('> .toggle');
7576            let $el = null;
7577
7578            $items.each(function() {
7579				$el = $(this);
7580
7581				if ($el.hasClass('active')) {
7582					$el.find('> p').addClass('preview-active');
7583					$el.find('> .toggle-content').slideDown(self.options.duration);
7584				}
7585
7586				self.events($el);
7587			});
7588
7589            if (self.options.isAccordion) {
7590				self.options.duration = self.options.duration / 2;
7591			}
7592
7593            return this;
7594        }
7595
7596        events($el) {
7597            const self = this;
7598            let previewParCurrentHeight = 0;
7599            let previewParAnimateHeight = 0;
7600            let toggleContent = null;
7601
7602            $el.find('> label, > .toggle-title').click(function({originalEvent}) {
7603                const $this = $(this);
7604                const parentSection = $this.parent();
7605                const parentWrapper = $this.parents('.toggle');
7606                let previewPar = null;
7607                let closeElement = null;
7608
7609                if (self.options.isAccordion && typeof(originalEvent) != 'undefined') {
7610					closeElement = parentWrapper.find('.toggle.active > label, .toggle.active > .toggle-title');
7611
7612					if (closeElement[0] == $this[0]) {
7613						return;
7614					}
7615				}
7616
7617                parentSection.toggleClass('active');
7618
7619                // Preview Paragraph
7620                if (parentSection.find('> p').get(0)) {
7621
7622					previewPar = parentSection.find('> p');
7623					previewParCurrentHeight = previewPar.css('height');
7624					previewPar.css('height', 'auto');
7625					previewParAnimateHeight = previewPar.css('height');
7626					previewPar.css('height', previewParCurrentHeight);
7627
7628				}
7629
7630                // Content
7631                toggleContent = parentSection.find('> .toggle-content');
7632
7633                if (parentSection.hasClass('active')) {
7634
7635					$(previewPar).animate({
7636						height: previewParAnimateHeight
7637					}, self.options.duration, function() {
7638						$(this).addClass('preview-active');
7639					});
7640
7641					toggleContent.slideDown(self.options.duration, () => {
7642						if (closeElement) {
7643							closeElement.trigger('click');
7644						}
7645					});
7646
7647				} else {
7648
7649					$(previewPar).animate({
7650						height: 0
7651					}, self.options.duration, function() {
7652						$(this).removeClass('preview-active');
7653					});
7654
7655					toggleContent.slideUp(self.options.duration);
7656
7657				}
7658            });
7659        }
7660    }
7661
7662    PluginToggle.defaults = {
7663		duration: 350,
7664		isAccordion: false
7665	};
7666
7667    // expose to scope
7668    $.extend(theme, {
7669		PluginToggle
7670	});
7671
7672    // jquery plugin
7673    $.fn.themePluginToggle = function(opts) {
7674		return this.map(function() {
7675			const $this = $(this);
7676
7677			if ($this.data(instanceName)) {
7678				return $this.data(instanceName);
7679			} else {
7680				return new PluginToggle($this, opts);
7681			}
7682
7683		});
7684	}
7685})).apply(this, [window.theme, jQuery]);
7686
7687// Validation
7688(((theme = {}, $) => {
7689    $.extend(theme, {
7690
7691		PluginValidation: {
7692
7693			defaults: {
7694				formClass: 'needs-validation',
7695				validator: {
7696					highlight(element) {
7697						$(element)
7698							.addClass('is-invalid')
7699							.removeClass('is-valid')
7700							.parent()
7701							.removeClass('has-success')
7702							.addClass('has-danger');
7703					},
7704					success(label, element) {
7705						$(element)
7706							.removeClass('is-invalid')
7707							.addClass('is-valid')
7708							.parent()
7709							.removeClass('has-danger')
7710							.addClass('has-success')
7711							.find('label.error')
7712							.remove();
7713					},
7714					errorPlacement(error, element) {
7715						if (element.attr('type') == 'radio' || element.attr('type') == 'checkbox') {
7716							error.appendTo(element.parent().parent());
7717						} else {
7718							error.insertAfter(element);
7719						}
7720					}
7721				}
7722			},
7723
7724			initialize(opts) {
7725				initialized = true;
7726
7727				this
7728					.setOptions(opts)
7729					.build();
7730
7731				return this;
7732			},
7733
7734			setOptions(opts) {
7735				this.options = $.extend(true, {}, this.defaults, opts);
7736
7737				return this;
7738			},
7739
7740			build() {
7741				const self = this;
7742
7743				if (!($.isFunction($.validator))) {
7744					return this;
7745				}
7746
7747				self.setMessageGroups();
7748
7749				$.validator.setDefaults(self.options.validator);
7750
7751				$('.' + self.options.formClass).validate();
7752
7753				return this;
7754			},
7755
7756			setMessageGroups() {
7757
7758				$('.checkbox-group[data-msg-required], .radio-group[data-msg-required]').each(function() {
7759					const message = $(this).data('msg-required');
7760					$(this).find('input').attr('data-msg-required', message);
7761				});
7762
7763			}
7764
7765		}
7766
7767	});
7768})).apply(this, [window.theme, jQuery]);
7769
7770// Video Background
7771(((theme = {}, $) => {
7772    const instanceName = '__videobackground';
7773
7774    class PluginVideoBackground {
7775        constructor($el, opts) {
7776            return this.initialize($el, opts);
7777        }
7778
7779        initialize($el, opts) {
7780			this.$el = $el;
7781
7782			this
7783				.setData()
7784				.setOptions(opts)
7785				.build()
7786				.events();
7787
7788			return this;
7789		}
7790
7791        setData() {
7792			this.$el.data(instanceName, this);
7793
7794			return this;
7795		}
7796
7797        setOptions(opts) {
7798			this.options = $.extend(true, {}, PluginVideoBackground.defaults, opts, {
7799				path: this.$el.data('video-path'),
7800				wrapper: this.$el
7801			});
7802
7803			return this;
7804		}
7805
7806        build() {
7807			const self = this;
7808
7809			if (!($.isFunction($.fn.vide)) || (!this.options.path)) {
7810				return this;
7811			}
7812
7813			if (this.options.overlay) {
7814
7815				const overlayClass = this.options.overlayClass;
7816
7817				this.options.wrapper.prepend(
7818					$('<div />').addClass(overlayClass)
7819				);
7820			}
7821
7822			this.options.wrapper
7823				.vide(this.options.path, this.options)
7824				.first()
7825				.css('z-index', 0);
7826
7827			// Change Poster
7828			self.changePoster();
7829
7830			// Initialize Vide inside a carousel
7831			if( self.options.wrapper.closest('.owl-carousel').get(0) ) {
7832				self.options.wrapper.closest('.owl-carousel').on('initialized.owl.carousel', () => {
7833					$('.owl-item.cloned')
7834						.find('[data-plugin-video-background] .vide-video-wrapper')
7835						.remove();
7836
7837					$('.owl-item.cloned')
7838						.find('[data-plugin-video-background]')
7839						.vide(self.options.path, self.options)
7840						.first()
7841						.css('z-index', 0);
7842
7843					self.changePoster( self.options.wrapper.closest('.owl-carousel') );
7844				});
7845			}
7846
7847			// Play Video Button
7848			const $playButton = self.options.wrapper.find('.video-background-play');
7849
7850			if( $playButton.get(0) ) {
7851				const $playWrapper = self.options.wrapper.find('.video-background-play-wrapper');
7852
7853				self.options.wrapper.find('.video-background-play').on('click', e => {
7854					e.preventDefault();
7855
7856					if( $playWrapper.get(0) ) {
7857						$playWrapper.animate({
7858							opacity: 0
7859						}, 300, () => {
7860							$playWrapper.parent().height( $playWrapper.outerHeight() );
7861							$playWrapper.remove();
7862						});
7863					} else {
7864						$playButton.animate({
7865							opacity: 0
7866						}, 300, () => {
7867							$playButton.remove();
7868						});
7869					}
7870
7871					setTimeout(() => {
7872						self.options.wrapper.find('video')[0].play();
7873					}, 500)
7874				});
7875			}
7876
7877			$(window).trigger('vide.video.inserted.on.dom');
7878
7879			return this;
7880		}
7881
7882        changePoster($carousel) {
7883			const self = this;
7884
7885			// If it's inside carousel
7886			if( $carousel && self.options.changePoster ) {
7887				$carousel.find('.owl-item [data-plugin-video-background] .vide-video-wrapper').css({
7888					'background-image': 'url(' + self.options.changePoster + ')'
7889				});
7890
7891				return this;
7892			}
7893
7894			if( self.options.changePoster ) {
7895				self.options.wrapper.find('.vide-video-wrapper').css({
7896					'background-image': 'url(' + self.options.changePoster + ')'
7897				});
7898			}
7899
7900			return this;
7901		}
7902
7903        events() {
7904			const self = this;
7905
7906			// Initialize
7907			self.options.wrapper.on('video.background.initialize', () => {
7908				self.build();
7909			});
7910
7911			return this;
7912		}
7913    }
7914
7915    PluginVideoBackground.defaults = {
7916		overlay: false,
7917		volume: 1,
7918		playbackRate: 1,
7919		muted: true,
7920		loop: true,
7921		autoplay: true,
7922		position: '50% 50%',
7923		posterType: 'detect',
7924		className: 'vide-video-wrapper'
7925	};
7926
7927    // expose to scope
7928    $.extend(theme, {
7929		PluginVideoBackground
7930	});
7931
7932    // jquery plugin
7933    $.fn.themePluginVideoBackground = function(opts) {
7934		return this.map(function() {
7935			const $this = $(this);
7936
7937			if ($this.data(instanceName)) {
7938				return $this.data(instanceName);
7939			} else {
7940				return new PluginVideoBackground($this, opts);
7941			}
7942
7943		});
7944	}
7945})).apply(this, [window.theme, jQuery]);
7946
7947// Account
7948(((theme = {}, $) => {
7949    let initialized = false;
7950
7951    $.extend(theme, {
7952
7953		Account: {
7954
7955			defaults: {
7956				wrapper: $('#headerAccount')
7957			},
7958
7959			initialize($wrapper, opts) {
7960				if (initialized) {
7961					return this;
7962				}
7963
7964				initialized = true;
7965				this.$wrapper = ($wrapper || this.defaults.wrapper);
7966
7967				this
7968					.setOptions(opts)
7969					.events();
7970
7971				return this;
7972			},
7973
7974			setOptions(opts) {
7975				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
7976
7977				return this;
7978			},
7979
7980			events() {
7981				const self = this;
7982
7983				$(window).on('load', () => {
7984					$(document).ready(() => {
7985						setTimeout(() => {
7986
7987							self.$wrapper.find('input').on('focus', () => {
7988								self.$wrapper.addClass('open');
7989
7990								$(document).mouseup(({target}) => {
7991									if (!self.$wrapper.is(target) && self.$wrapper.has(target).length === 0) {
7992										self.$wrapper.removeClass('open');
7993									}
7994								});
7995							});
7996
7997						}, 1500);
7998					});
7999				});
8000
8001				$('#headerSignUp').on('click', e => {
8002					e.preventDefault();
8003					self.$wrapper.addClass('signup').removeClass('signin').removeClass('recover');
8004					self.$wrapper.find('.signup-form input:first').focus();
8005				});
8006
8007				$('#headerSignIn').on('click', e => {
8008					e.preventDefault();
8009					self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
8010					self.$wrapper.find('.signin-form input:first').focus();
8011				});
8012
8013				$('#headerRecover').on('click', e => {
8014					e.preventDefault();
8015					self.$wrapper.addClass('recover').removeClass('signup').removeClass('signin');
8016					self.$wrapper.find('.recover-form input:first').focus();
8017				});
8018
8019				$('#headerRecoverCancel').on('click', e => {
8020					e.preventDefault();
8021					self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
8022					self.$wrapper.find('.signin-form input:first').focus();
8023				});
8024			}
8025
8026		}
8027
8028	});
8029})).apply(this, [window.theme, jQuery]);
8030
8031// Nav
8032(((theme = {}, $) => {
8033    let initialized = false;
8034
8035    $.extend(theme, {
8036
8037		Nav: {
8038
8039			defaults: {
8040				wrapper: $('#mainNav'),
8041				scrollDelay: 600,
8042				scrollAnimation: 'easeOutQuad'
8043			},
8044
8045			initialize($wrapper, opts) {
8046				if (initialized) {
8047					return this;
8048				}
8049
8050				initialized = true;
8051				this.$wrapper = ($wrapper || this.defaults.wrapper);
8052
8053				this
8054					.setOptions(opts)
8055					.build()
8056					.events();
8057
8058				return this;
8059			},
8060
8061			setOptions(opts) {
8062				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
8063
8064				return this;
8065			},
8066
8067			build() {
8068                const self = this;
8069                const $html = $('html');
8070                const $header = $('#header');
8071                const $headerNavMain = $('#header .header-nav-main');
8072                let thumbInfoPreview;
8073
8074                // Preview Thumbs
8075                if( self.$wrapper.find('a[data-thumb-preview]').length ) {
8076					self.$wrapper.find('a[data-thumb-preview]').each(function() {
8077						thumbInfoPreview = $('<span />').addClass('thumb-info thumb-info-preview')
8078												.append($('<span />').addClass('thumb-info-wrapper')
8079													.append($('<span />').addClass('thumb-info-image').css('background-image', 'url(' + $(this).data('thumb-preview') + ')')
8080											   )
8081										   );
8082
8083						$(this).append(thumbInfoPreview);
8084					});
8085				}
8086
8087                // Side Header / Side Header Hamburguer Sidebar (Reverse Dropdown)
8088                if($html.hasClass('side-header') || $html.hasClass('side-header-hamburguer-sidebar')) {
8089					
8090					// Side Header Right / Side Header Hamburguer Sidebar Right
8091					if($html.hasClass('side-header-right') || $html.hasClass('side-header-hamburguer-sidebar-right')) {
8092						if(!$html.hasClass('side-header-right-no-reverse')) {
8093							$header.find('.dropdown-submenu').addClass('dropdown-reverse');
8094						}
8095					}
8096
8097				} else {
8098					
8099					// Reverse
8100					let checkReverseFlag = false;
8101					self.checkReverse = () => {
8102						if( !checkReverseFlag ) {
8103							self.$wrapper.find('.dropdown, .dropdown-submenu').removeClass('dropdown-reverse');
8104
8105							self.$wrapper.find('.dropdown:not(.manual):not(.dropdown-mega), .dropdown-submenu:not(.manual)').each(function() {
8106								if(!$(this).find('.dropdown-menu').visible( false, true, 'horizontal' )  ) {
8107									$(this).addClass('dropdown-reverse');
8108								}
8109							});
8110
8111							checkReverseFlag = true;
8112						}
8113					}
8114
8115					$(window).on('resize', () => {
8116						checkReverseFlag = false;
8117					});
8118
8119					$header.on('mouseover', () => {
8120						self.checkReverse();
8121					});
8122
8123				}
8124
8125                // Clone Items
8126                if($headerNavMain.hasClass('header-nav-main-clone-items')) {
8127
8128			    	$headerNavMain.find('nav > ul > li > a').each(function(){
8129				    	const parent = $(this).parent(), clone  = $(this).clone(), clone2 = $(this).clone(), wrapper = $('<span class="wrapper-items-cloned"></span>');
8130
8131				    	// Config Classes
8132				    	$(this).addClass('item-original');
8133				    	clone2.addClass('item-two');
8134
8135				    	// Insert on DOM
8136				    	parent.prepend(wrapper);
8137				    	wrapper.append(clone).append(clone2);
8138				    });
8139
8140				}
8141
8142                // Floating
8143                if($('#header.header-floating-icons').length && $(window).width() > 991) {
8144
8145					const menuFloatingAnim = {
8146						$menuFloating: $('#header.header-floating-icons .header-container > .header-row'),
8147
8148						build() {
8149							const self = this;
8150
8151							self.init();
8152						},
8153						init() {
8154                            const self  = this;
8155                            let divisor = 0;
8156
8157                            $(window).scroll(function() {
8158							    const scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height()), st = $(this).scrollTop();
8159
8160								divisor = $(document).height() / $(window).height();
8161
8162							    self.$menuFloating.find('.header-column > .header-row').css({
8163							    	transform : 'translateY( calc('+ scrollPercent +'vh - '+ st / divisor +'px) )' 
8164							    });
8165							});
8166                        }
8167					};
8168
8169					menuFloatingAnim.build();
8170
8171				}
8172
8173                // Slide
8174                if($('.header-nav-links-vertical-slide').length) {
8175					const slideNavigation = {
8176						$mainNav: $('#mainNav'),
8177						$mainNavItem: $('#mainNav li'),
8178
8179						build() {
8180							const self = this;
8181
8182							self.menuNav();
8183						},
8184						menuNav() {
8185							const self = this;
8186
8187							self.$mainNavItem.on('click', function(e){
8188								const currentMenuItem 	= $(this), currentMenu 		= $(this).parent(), nextMenu        	= $(this).find('ul').first(), prevMenu        	= $(this).closest('.next-menu'), isSubMenu       	= currentMenuItem.hasClass('dropdown') || currentMenuItem.hasClass('dropdown-submenu'), isBack          	= currentMenuItem.hasClass('back-button'), nextMenuHeightDiff  = ( ( nextMenu.find('> li').length * nextMenu.find('> li').outerHeight() ) - nextMenu.outerHeight() ), prevMenuHeightDiff  = ( ( prevMenu.find('> li').length * prevMenu.find('> li').outerHeight() ) - prevMenu.outerHeight() );
8189
8190								if( isSubMenu ) {
8191									currentMenu.addClass('next-menu');
8192									nextMenu.addClass('visible');
8193									currentMenu.css({
8194										overflow: 'visible',
8195										'overflow-y': 'visible'
8196									});
8197									
8198									if( nextMenuHeightDiff > 0 ) {
8199										nextMenu.css({
8200											overflow: 'hidden',
8201											'overflow-y': 'scroll'
8202										});
8203									}
8204
8205									for( i = 0; i < nextMenu.find('> li').length; i++ ) {
8206										if( nextMenu.outerHeight() < ($('.header-row-side-header').outerHeight() - 100) ) {
8207											nextMenu.css({
8208												height: nextMenu.outerHeight() + nextMenu.find('> li').outerHeight()
8209											});
8210										}
8211									}
8212
8213									nextMenu.css({
8214										'padding-top': nextMenuHeightDiff + 'px'
8215									});
8216								}
8217
8218								if( isBack ) {
8219									currentMenu.parent().parent().removeClass('next-menu');
8220									currentMenu.removeClass('visible');
8221
8222									if( prevMenuHeightDiff > 0 ) {
8223										prevMenu.css({
8224											overflow: 'hidden',
8225											'overflow-y': 'scroll'
8226										});
8227									}
8228								}
8229
8230								e.stopPropagation();
8231							});
8232						}
8233					};
8234
8235					$(window).trigger('resize');
8236					
8237					if( $(window).width() > 991 ) {
8238						slideNavigation.build();
8239					}
8240
8241					$(document).ready(() => {
8242						$(window).afterResize(() => {
8243							if( $(window).width() > 991 ) {
8244								slideNavigation.build();
8245							}
8246						});
8247					});
8248				}
8249
8250                // Header Nav Main Mobile Dark
8251                if($('.header-nav-main-mobile-dark').length) {
8252					$('#header:not(.header-transparent-dark-bottom-border):not(.header-transparent-light-bottom-border)').addClass('header-no-border-bottom');
8253				}
8254
8255                // Keyboard Navigation / Accessibility
8256                if( $(window).width() > 991 ) {
8257					let focusFlag = false;
8258					$header.find('.header-nav-main nav > ul > li > a').on('focus', function(){
8259						
8260						if( $(window).width() > 991 ) {
8261							if( !focusFlag ) {
8262								focusFlag = true;
8263								$(this).trigger('blur');
8264								
8265								self.focusMenuWithChildren();
8266							}
8267						}
8268
8269					});
8270				}
8271
8272                return this;
8273            },
8274
8275			focusMenuWithChildren() {
8276                // Get all the link elements within the primary menu.
8277                let links;
8278
8279                let i;
8280                let len;
8281                const menu = document.querySelector( 'html:not(.side-header):not(.side-header-hamburguer-sidebar):not(.side-header-overlay-full-screen) .header-nav-main > nav' );
8282
8283                if ( ! menu ) {
8284					return false;
8285				}
8286
8287                links = menu.getElementsByTagName( 'a' );
8288
8289                // Each time a menu link is focused or blurred, toggle focus.
8290                for ( i = 0, len = links.length; i < len; i++ ) {
8291					links[i].addEventListener( 'focus', toggleFocus, true );
8292					links[i].addEventListener( 'blur', toggleFocus, true );
8293				}
8294
8295                //Sets or removes the .focus class on an element.
8296                function toggleFocus() {
8297					let self = this;
8298
8299					// Move up through the ancestors of the current link until we hit .primary-menu.
8300					while ( !self.className.includes('header-nav-main') ) {
8301						// On li elements toggle the class .focus.
8302						if ( 'li' === self.tagName.toLowerCase() ) {
8303							if ( self.className.includes('accessibility-open') ) {
8304								self.className = self.className.replace( ' accessibility-open', '' );
8305							} else {
8306								self.className += ' accessibility-open';
8307							}
8308						}
8309						self = self.parentElement;
8310					}
8311				}
8312            },
8313
8314			events() {
8315                const self    = this;
8316                const $html   = $('html');
8317                let $header = $('#header');
8318                const $window = $(window);
8319                let headerBodyHeight = $('.header-body').outerHeight();
8320
8321                if( $header.hasClass('header') ) {
8322					$header = $('.header');
8323				}
8324
8325                $header.find('a[href="#"]').on('click', e => {
8326					e.preventDefault();
8327				});
8328
8329                // Mobile Arrows
8330                if( $html.hasClass('side-header-hamburguer-sidebar') ) {
8331					$header.find('.dropdown-toggle, .dropdown-submenu > a')
8332						.append('<i class="fas fa-chevron-down fa-chevron-right"></i>');
8333				} else {
8334					$header.find('.dropdown-toggle, .dropdown-submenu > a')
8335						.append('<i class="fas fa-chevron-down"></i>');
8336				}
8337
8338                $header.find('.dropdown-toggle[href="#"], .dropdown-submenu a[href="#"], .dropdown-toggle[href!="#"] .fa-chevron-down, .dropdown-submenu a[href!="#"] .fa-chevron-down').on('click', function(e) {
8339					e.preventDefault();
8340					if ($window.width() < 992) {
8341						$(this).closest('li').toggleClass('open');
8342
8343						// Adjust Header Body Height
8344						const height = ( $header.hasClass('header-effect-shrink') && $html.hasClass('sticky-header-active') ) ? theme.StickyHeader.options.stickyHeaderContainerHeight : headerBodyHeight;
8345						$('.header-body').animate({
8346					 		height: ($('.header-nav-main nav').outerHeight(true) + height) + 10
8347					 	}, 0);
8348					}
8349				});
8350
8351                $header.find('li a.active').addClass('current-page-active');
8352
8353                // Add Open Class
8354                $header.find('.header-nav-click-to-open .dropdown-toggle[href="#"], .header-nav-click-to-open .dropdown-submenu a[href="#"], .header-nav-click-to-open .dropdown-toggle > i').on('click', function(e) {
8355					if( !$('html').hasClass('side-header-hamburguer-sidebar') && $window.width() > 991 ) {
8356						e.preventDefault();
8357						e.stopPropagation();
8358					}
8359
8360					if ($window.width() > 991) {
8361						e.preventDefault();
8362						e.stopPropagation();
8363
8364						$header.find('li a.active').removeClass('active');
8365
8366						if( $(this).prop('tagName') == 'I' ) {
8367							$(this).parent().addClass('active');
8368						} else {
8369							$(this).addClass('active');
8370						}
8371
8372						if (!$(this).closest('li').hasClass('open')) {
8373                            const $li = $(this).closest('li');
8374                            let isSub = false;
8375
8376                            if( $(this).prop('tagName') == 'I' ) {
8377								$('#header .dropdown.open').removeClass('open');
8378								$('#header .dropdown-menu .dropdown-submenu.open').removeClass('open');
8379							}
8380
8381                            if ( $(this).parent().hasClass('dropdown-submenu') ) {
8382								isSub = true;
8383							}
8384
8385                            $(this).closest('.dropdown-menu').find('.dropdown-submenu.open').removeClass('open');
8386                            $(this).parent('.dropdown').parent().find('.dropdown.open').removeClass('open');
8387
8388                            if (!isSub) {
8389								$(this).parent().find('.dropdown-submenu.open').removeClass('open');
8390							}
8391
8392                            $li.addClass('open');
8393
8394                            $(document).off('click.nav-click-to-open').on('click.nav-click-to-open', ({target}) => {
8395								if (!$li.is(target) && $li.has(target).length === 0) {
8396									$li.removeClass('open');
8397									$li.parents('.open').removeClass('open');
8398									$header.find('li a.active').removeClass('active');
8399									$header.find('li a.current-page-active').addClass('active');
8400								}
8401							});
8402                        } else {
8403							$(this).closest('li').removeClass('open');
8404							$header.find('li a.active').removeClass('active');
8405							$header.find('li a.current-page-active').addClass('active');
8406						}
8407
8408						$window.trigger({
8409							type: 'resize',
8410							from: 'header-nav-click-to-open'
8411						});
8412					}
8413				});
8414
8415                // Collapse Nav
8416                $header.find('[data-collapse-nav]').on('click', function(e) {
8417					$(this).parents('.collapse').removeClass('show');
8418				});
8419
8420                // Top Features
8421                $header.find('.header-nav-features-toggle').on('click', function(e) {
8422					e.preventDefault();
8423
8424					const $toggleParent = $(this).parent();
8425
8426					if (!$(this).siblings('.header-nav-features-dropdown').hasClass('show')) {
8427
8428						const $dropdown = $(this).siblings('.header-nav-features-dropdown');
8429
8430						$('.header-nav-features-dropdown.show').removeClass('show');
8431
8432						$dropdown.addClass('show');
8433
8434						$(document).off('click.header-nav-features-toggle').on('click.header-nav-features-toggle', ({target}) => {
8435							if (!$toggleParent.is(target) && $toggleParent.has(target).length === 0) {
8436								$('.header-nav-features-dropdown.show').removeClass('show');
8437							}
8438						});
8439
8440						if ($(this).attr('data-focus')) {
8441							$('#' + $(this).attr('data-focus')).focus();
8442						}
8443
8444					} else {
8445						$(this).siblings('.header-nav-features-dropdown').removeClass('show');
8446					}
8447				});
8448
8449                // Hamburguer Menu
8450                const $hamburguerMenuBtn = $('.hamburguer-btn:not(.side-panel-toggle)'), $hamburguerSideHeader = $('#header.side-header, #header.side-header-overlay-full-screen');
8451
8452                $hamburguerMenuBtn.on('click', function(){
8453					if($(this).attr('data-set-active') != 'false') {
8454						$(this).toggleClass('active');
8455					}
8456					$hamburguerSideHeader.toggleClass('side-header-hide');
8457					$html.toggleClass('side-header-hide');
8458
8459					$window.trigger('resize');
8460				});
8461
8462                // Toggle Side Header
8463                $('.toggle-side-header').on('click', () => {
8464					$('.hamburguer-btn-side-header.active').trigger('click');
8465				});
8466
8467                $('.hamburguer-close:not(.side-panel-toggle)').on('click', () => {
8468					$('.hamburguer-btn:not(.hamburguer-btn-side-header-mobile-show)').trigger('click');
8469				});
8470
8471                // Set Header Body Height when open mobile menu
8472                $('.header-nav-main nav').on('show.bs.collapse', function () {
8473				 	$(this).removeClass('closed');
8474
8475				 	// Add Mobile Menu Opened Class
8476				 	$('html').addClass('mobile-menu-opened');
8477
8478			 		$('.header-body').animate({
8479				 		height: ($('.header-body').outerHeight() + $('.header-nav-main nav').outerHeight(true)) + 10
8480				 	});
8481
8482				 	// Header Below Slider / Header Bottom Slider - Scroll to menu position
8483				 	if( $('#header').is('.header-bottom-slider, .header-below-slider') && !$('html').hasClass('sticky-header-active') ) {
8484				 		self.scrollToTarget( $('#header'), 0 );
8485				 	}
8486				});
8487
8488                // Set Header Body Height when collapse mobile menu
8489                $('.header-nav-main nav').on('hide.bs.collapse', function () {
8490				 	$(this).addClass('closed');
8491
8492				 	// Remove Mobile Menu Opened Class
8493				 	$('html').removeClass('mobile-menu-opened');
8494
8495			 		$('.header-body').animate({
8496				 		height: ($('.header-body').outerHeight() - $('.header-nav-main nav').outerHeight(true))
8497				 	}, function(){
8498				 		$(this).height('auto');
8499				 	});
8500				});
8501
8502                // Header Effect Shrink - Adjust header body height on mobile
8503                $window.on('stickyHeader.activate', () => {
8504					if( $window.width() < 992 && $header.hasClass('header-effect-shrink') ) {
8505						if( $('.header-btn-collapse-nav').attr('aria-expanded') == 'true' ) {
8506							$('.header-body').animate({
8507						 		height: ( $('.header-nav-main nav').outerHeight(true) + theme.StickyHeader.options.stickyHeaderContainerHeight ) + ( ($('.header-nav-bar').length) ? $('.header-nav-bar').outerHeight() : 0 ) 
8508						 	});
8509						}
8510					}
8511				});
8512
8513                $window.on('stickyHeader.deactivate', () => {
8514					if( $window.width() < 992 && $header.hasClass('header-effect-shrink') ) {
8515						if( $('.header-btn-collapse-nav').attr('aria-expanded') == 'true' ) {
8516							$('.header-body').animate({
8517						 		height: headerBodyHeight + $('.header-nav-main nav').outerHeight(true) + 10
8518						 	});
8519						}
8520					}
8521				});
8522
8523                // Remove Open Class on Resize		
8524                $window.on('resize.removeOpen', ({from}) => {
8525					if( from == 'header-nav-click-to-open' ) {
8526						return;
8527					}
8528					
8529					setTimeout(() => {
8530						if( $window.width() > 991 ) {
8531							$header.find('.dropdown.open').removeClass('open');
8532						}
8533					}, 100);
8534				});
8535
8536                // Side Header - Change value of initial header body height
8537                $(document).ready(() => {
8538					if( $window.width() > 991 ) {
8539						let flag = false;
8540						
8541						$window.on('resize', ({from}) => {
8542							if( from == 'header-nav-click-to-open' ) {
8543								return;
8544							}
8545
8546							$header.find('.dropdown.open').removeClass('open');
8547
8548							if( $window.width() < 992 && flag == false ) {
8549								headerBodyHeight = $('.header-body').outerHeight();
8550								flag = true;
8551
8552								setTimeout(() => {
8553									flag = false;
8554								}, 500);
8555							}
8556						});
8557					}
8558				});
8559
8560                // Side Header - Set header height on mobile
8561                if( $html.hasClass('side-header') ) {
8562					if( $window.width() < 992 ) {
8563						$header.css({
8564							height: $('.header-body .header-container').outerHeight() + (parseInt( $('.header-body').css('border-top-width') ) + parseInt( $('.header-body').css('border-bottom-width') ))
8565						});
8566					}
8567
8568					$(document).ready(() => {
8569						$window.afterResize(() => {
8570							if( $window.width() < 992 ) {
8571								$header.css({
8572									height: $('.header-body .header-container').outerHeight() + (parseInt( $('.header-body').css('border-top-width') ) + parseInt( $('.header-body').css('border-bottom-width') ))
8573								});
8574							} else {
8575								$header.css({
8576									height: ''
8577								});
8578							}
8579						});
8580					});
8581				}
8582
8583                // Anchors Position
8584                if( $('[data-hash]').length ) {
8585					$('[data-hash]').on('mouseover', function(){
8586						const $this = $(this);
8587
8588						if( !$this.data('__dataHashBinded') ) {
8589                            let target = $this.attr('href');
8590                            let offset = ($this.is("[data-hash-offset]") ? $this.data('hash-offset') : 0);
8591                            const delay  = ($this.is("[data-hash-delay]") ? $this.data('hash-delay') : 0);
8592                            const force  = ($this.is("[data-hash-force]") ? true : false);
8593                            const windowWidth = $(window).width();
8594
8595                            // Hash Offset SM
8596                            if ($this.is("[data-hash-offset-sm]") && windowWidth > 576) {
8597								offset = $this.data('hash-offset-sm');
8598							}
8599
8600                            // Hash Offset MD
8601                            if ($this.is("[data-hash-offset-md]") && windowWidth > 768) {
8602								offset = $this.data('hash-offset-md');
8603							}
8604
8605                            // Hash Offset LG
8606                            if ($this.is("[data-hash-offset-lg]") && windowWidth > 992) {
8607								offset = $this.data('hash-offset-lg');
8608							}
8609
8610                            // Hash Offset XL
8611                            if ($this.is("[data-hash-offset-xl]") && windowWidth > 1200) {
8612								offset = $this.data('hash-offset-xl');
8613							}
8614
8615                            // Hash Offset XXL
8616                            if ($this.is("[data-hash-offset-xxl]") && windowWidth > 1400) {
8617								offset = $this.data('hash-offset-xxl');
8618							}
8619
8620                            if( !$(target).length ) {
8621								target = target.split('#');
8622								target = '#'+target[1];
8623							}
8624
8625                            if( target.includes('#') && $(target).length) {
8626								$this.on('click', e => {
8627									e.preventDefault();
8628
8629									if( !$(e.target).is('i') || force ) {
8630
8631										setTimeout(() => {
8632
8633											// Close Collapse if open
8634											$this.parents('.collapse.show').collapse('hide');
8635
8636											// Close Side Header
8637											$hamburguerSideHeader.addClass('side-header-hide');
8638											$html.addClass('side-header-hide');
8639											
8640											$window.trigger('resize');
8641
8642											self.scrollToTarget(target, offset);
8643
8644											// Data Hash Trigger Click
8645											if( $this.data('hash-trigger-click') ) {
8646
8647												const $clickTarget = $( $this.data('hash-trigger-click') ), clickDelay = $this.data('hash-trigger-click-delay') ? $this.data('hash-trigger-click-delay') : 0;
8648
8649												if( $clickTarget.length ) {
8650
8651													setTimeout(() => {
8652														// If is a "Tabs" plugin link
8653														if( $clickTarget.closest('.nav-tabs').length ) {
8654															new bootstrap.Tab( $clickTarget[0] ).show();
8655														} else {
8656															$clickTarget.trigger('click');
8657														}
8658														
8659													}, clickDelay);
8660												}
8661
8662											}
8663
8664										}, delay);
8665										
8666									}
8667
8668									return;
8669								});
8670							}
8671
8672                            $(this).data('__dataHashBinded', true);
8673                        }
8674					});
8675				}
8676
8677                // Floating
8678                if($('#header.header-floating-icons').length) {
8679
8680					$('#header.header-floating-icons [data-hash]').off().each(function() {
8681
8682						const target = $(this).attr('href'), offset = ($(this).is("[data-hash-offset]") ? $(this).data('hash-offset') : 0);
8683
8684						if($(target).length) {
8685							$(this).on('click', e => {
8686								e.preventDefault();
8687
8688									$('html, body').animate({
8689										scrollTop: $(target).offset().top - offset
8690									}, 600, 'easeOutQuad', () => {
8691
8692									});
8693
8694								return;
8695							});
8696						}
8697
8698					});
8699
8700				}
8701
8702                // Side Panel Toggle
8703                if( $('.side-panel-toggle').length ) {
8704					const init_html_class = $('html').attr('class');
8705
8706					$('.side-panel-toggle').on('click', function(e){
8707						const extra_class = $(this).data('extra-class'), delay       = ( extra_class ) ? 100 : 0, isActive    = $(this).data('is-active') ? $(this).data('is-active') : false;
8708
8709						e.preventDefault();
8710
8711						if( isActive ) {
8712							$('html').removeClass('side-panel-open');
8713							$(this).data('is-active', false);
8714							return false;
8715						}
8716
8717						if( extra_class ) {
8718							$('.side-panel-wrapper').css('transition','none');
8719							$('html')
8720								.removeClass()
8721								.addClass( init_html_class )
8722								.addClass( extra_class );
8723						}
8724						setTimeout(() => {
8725							$('.side-panel-wrapper').css('transition','');
8726							$('html').toggleClass('side-panel-open');
8727						}, delay);
8728
8729						$(this).data('is-active', true);						
8730					});
8731
8732					$(document).on('click', ({target}) => {
8733						if( !$(target).closest('.side-panel-wrapper').length && !$(target).hasClass('side-panel-toggle') ) {
8734							$('.hamburguer-btn.side-panel-toggle:not(.side-panel-close)').removeClass('active');
8735							$('html').removeClass('side-panel-open');
8736							$('.side-panel-toggle').data('is-active', false);
8737						}
8738					});
8739				}
8740
8741				// OffCanvas
8742				self.offCanvasMenu();
8743
8744                return this;
8745            },
8746
8747			scrollToTarget(target, offset) {
8748				const self = this, targetPosition = $(target).offset().top;
8749
8750				$('body').addClass('scrolling');
8751
8752				$('html, body').animate({
8753					scrollTop: $(target).offset().top - offset
8754				}, self.options.scrollDelay, self.options.scrollAnimation, () => {
8755					$('body').removeClass('scrolling');
8756
8757					// If by some reason the scroll finishes in a wrong position, this code will run the scrollToTarget() again until get the correct position
8758					// We need do it just one time to prevent infinite recursive loop at scrollToTarget() function
8759					if( $(target).offset().top !=  targetPosition) {
8760						$('html, body').animate({
8761							scrollTop: $(target).offset().top - offset
8762						}, 1, self.options.scrollAnimation, () => {});
8763					}
8764				});
8765
8766				return this;
8767
8768			},
8769
8770			offCanvasMenu() {
8771                const $headerNavMain = $('#header .header-nav-main');
8772				const $offCanvasNav = $('.offcanvas-nav');
8773
8774				if($offCanvasNav.length > 0) {
8775					const $navToClone = $headerNavMain.find('nav');
8776
8777					if($navToClone.length > 0) {
8778						$offCanvasNav.html($offCanvasNav.html() + $navToClone.html());
8779						$offCanvasNav.find('#mainNav').removeAttr('id').removeClass().addClass('nav flex-column w-100');
8780
8781						// Clean Classes
8782						$offCanvasNav.find('.dropdown').removeClass().addClass('dropdown');
8783
8784						$offCanvasNav.find('.dropdown-item:not(.dropdown-toggle)').removeClass().addClass('dropdown-item');
8785						$offCanvasNav.find('.dropdown-item.dropdown-toggle').removeClass().addClass('dropdown-item dropdown-toggle');
8786
8787						$offCanvasNav.find('.nav-link:not(.dropdown-toggle)').removeClass().addClass('nav-link');
8788						$offCanvasNav.find('.nav-link.dropdown-toggle').removeClass().addClass('nav-link dropdown-toggle');
8789
8790						$offCanvasNav.find('.dropdown-menu').removeClass().addClass('dropdown-menu');
8791
8792						// Dropdowns
8793						$offCanvasNav.find('.dropdown-toggle').each(function() {
8794							const $el = $(this);
8795							const $arrow = $el.find('i');
8796
8797							$arrow.on('click', function(e) {
8798								e.preventDefault();
8799								e.stopPropagation();
8800								$el.parents('li').toggleClass('open');
8801							})
8802
8803							if ($el.attr('href') == '#') {
8804								$el.on('click', function() {
8805									$arrow.trigger('click');
8806								});
8807							}
8808						});
8809					}
8810				}
8811
8812				return this;
8813			}
8814
8815		}
8816
8817	});
8818})).apply(this, [window.theme, jQuery]);
8819
8820
8821// Newsletter
8822(((theme = {}, $) => {
8823    let initialized = false;
8824
8825    $.extend(theme, {
8826
8827		Newsletter: {
8828
8829			defaults: {
8830				wrapper: $('#newsletterForm')
8831			},
8832
8833			initialize($wrapper, opts) {
8834				if (initialized) {
8835					return this;
8836				}
8837
8838				initialized = true;
8839				this.$wrapper = ($wrapper || this.defaults.wrapper);
8840
8841				this
8842					.setOptions(opts)
8843					.build();
8844
8845				return this;
8846			},
8847
8848			setOptions(opts) {
8849				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
8850
8851				return this;
8852			},
8853
8854			build() {
8855				if (!($.isFunction($.fn.validate))) {
8856					return this;
8857				}
8858
8859				const self = this, $email = self.$wrapper.find('#newsletterEmail'), $success = $('#newsletterSuccess'), $error = $('#newsletterError');
8860
8861				self.$wrapper.validate({
8862					submitHandler(form) {
8863
8864						$.ajax({
8865							type: 'POST',
8866							url: self.$wrapper.attr('action'),
8867							data: {
8868								'email': $email.val()
8869							},
8870							dataType: 'json',
8871							success({response, message}) {
8872								if (response == 'success') {
8873
8874									$success.removeClass('d-none');
8875									$error.addClass('d-none');
8876
8877									$email
8878										.val('')
8879										.blur()
8880										.closest('.control-group')
8881										.removeClass('success')
8882										.removeClass('error');
8883
8884								} else {
8885
8886									$error.html(message);
8887									$error.removeClass('d-none');
8888									$success.addClass('d-none');
8889
8890									$email
8891										.blur()
8892										.closest('.control-group')
8893										.removeClass('success')
8894										.addClass('error');
8895
8896								}
8897							}
8898						});
8899
8900					},
8901					rules: {
8902						newsletterEmail: {
8903							required: true,
8904							email: true
8905						}
8906					},
8907					errorPlacement(error, element) {
8908
8909					}
8910				});
8911
8912				return this;
8913			}
8914
8915		}
8916
8917	});
8918})).apply(this, [window.theme, jQuery]);
8919
8920// Search
8921(((theme = {}, $) => {
8922    let initialized = false;
8923
8924    $.extend(theme, {
8925
8926		Search: {
8927
8928			defaults: {
8929				wrapper: $('#searchForm')
8930			},
8931
8932			initialize($wrapper, opts) {
8933				if (initialized) {
8934					return this;
8935				}
8936
8937				initialized = true;
8938				this.$wrapper = ($wrapper || this.defaults.wrapper);
8939
8940				this
8941					.setOptions(opts)
8942					.build();
8943
8944				return this;
8945			},
8946
8947			setOptions(opts) {
8948				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
8949
8950				return this;
8951			},
8952
8953			build() {
8954				if (!($.isFunction($.fn.validate))) {
8955					return this;
8956				}
8957
8958				this.$wrapper.validate({
8959					errorPlacement(error, element) {}
8960				});
8961
8962				// Search Reveal
8963				theme.fn.execOnceTroughEvent( '#header', 'mouseover.search.reveal', () => {
8964					$('.header-nav-features-search-reveal').each(function() {
8965						const $el = $(this), $header = $('#header'), $html = $('html');
8966
8967						$el.find('.header-nav-features-search-show-icon').on('click', () => {
8968							$el.addClass('show');
8969							$header.addClass('search-show');
8970							$html.addClass('search-show');
8971							$('#headerSearch').focus();
8972						});
8973
8974						$el.find('.header-nav-features-search-hide-icon').on('click', () => {
8975							$el.removeClass('show');
8976							$header.removeClass('search-show');
8977							$html.removeClass('search-show');
8978						});
8979					});
8980				} );
8981
8982				return this;
8983			}
8984
8985		}
8986
8987	});
8988})).apply(this, [window.theme, jQuery]);
8989
8990// Sticky Header
8991(((theme = {}, $) => {
8992    let initialized = false;
8993
8994    $.extend(theme, {
8995
8996		StickyHeader: {
8997
8998			defaults: {
8999				wrapper: $('#header'),
9000				headerBody: $('#header .header-body'),
9001				stickyEnabled: true,
9002				stickyEnableOnBoxed: true,
9003				stickyEnableOnMobile: false,
9004				stickyStartAt: 0,
9005				stickyStartAtElement: false,
9006				stickySetTop: 0,
9007				stickyEffect: '',
9008				stickyHeaderContainerHeight: false,
9009				stickyChangeLogo: false,
9010				stickyChangeLogoWrapper: true,
9011				stickyForce: false,
9012				stickyScrollUp: false,
9013				stickyScrollValue: 0
9014			},
9015
9016			initialize($wrapper, opts) {
9017				if (initialized) {
9018					return this;
9019				}				
9020
9021				initialized = true;
9022				this.$wrapper = ($wrapper || this.defaults.wrapper);
9023
9024				if( this.$wrapper.hasClass('header') ) {
9025					this.$wrapper = $('.header[data-plugin-options]');
9026				}
9027
9028				this
9029					.setOptions(opts)
9030					.build()
9031					.events();
9032
9033				return this;
9034			},
9035
9036			setOptions(opts) {
9037				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
9038				return this;
9039			},
9040
9041			build() {
9042                if( $(window).width() < 992 && this.options.stickyEnableOnMobile == false ) {
9043					$('html').addClass('sticky-header-mobile-disabled');
9044					return this;
9045				}
9046
9047                if (!this.options.stickyEnableOnBoxed && $('html').hasClass('boxed') || $('html').hasClass('side-header-hamburguer-sidebar') && !this.options.stickyForce || !this.options.stickyEnabled) {
9048					return this;
9049				}
9050
9051                const self = this;
9052
9053                if( self.options.wrapper.hasClass('header') ) {
9054					self.options.wrapper = $('.header');
9055					self.options.headerBody = $('.header .header-body');
9056				}
9057
9058                const $html = $('html');
9059                const $window = $(window);
9060                const sideHeader = $html.hasClass('side-header');
9061                const initialHeaderTopHeight = self.options.wrapper.find('.header-top').outerHeight();
9062                const initialHeaderContainerHeight = self.options.wrapper.find('.header-container').outerHeight();
9063                let minHeight;
9064
9065                // HTML Classes
9066                $html.addClass('sticky-header-enabled');
9067
9068                if (parseInt(self.options.stickySetTop) < 0) {
9069					$html.addClass('sticky-header-negative');
9070				}
9071
9072                if (self.options.stickyScrollUp) {
9073					$html.addClass('sticky-header-scroll-direction');
9074				}
9075
9076                // Notice Top Bar First Load
9077                if( $('.notice-top-bar').get(0) ) {
9078					if (parseInt(self.options.stickySetTop) == 1 || self.options.stickyEffect == 'shrink') {
9079						$('.body').on('transitionend webkitTransitionEnd oTransitionEnd', () => {
9080						    setTimeout(() => {
9081								if( !$html.hasClass('sticky-header-active') ) {
9082								    self.options.headerBody.animate({
9083								    	top: $('.notice-top-bar').outerHeight()
9084								    }, 300, () => {
9085								    	if( $html.hasClass('sticky-header-active') ) {
9086								    		self.options.headerBody.css('top', 0);
9087								    	}
9088								    });
9089								}
9090						    }, 0);
9091						});
9092					}					
9093				}
9094
9095                // Set Start At
9096                if(self.options.stickyStartAtElement) {
9097
9098					const $stickyStartAtElement = $(self.options.stickyStartAtElement);
9099
9100					$(window).on('scroll resize sticky.header.resize', () => {
9101						self.options.stickyStartAt = $stickyStartAtElement.offset().top;
9102					});
9103
9104					$(window).trigger('sticky.header.resize');
9105				}
9106
9107                // Define Min Height value
9108                if( self.options.wrapper.find('.header-top').get(0) ) {
9109					minHeight = ( initialHeaderTopHeight + initialHeaderContainerHeight );
9110				} else {
9111					minHeight = initialHeaderContainerHeight;
9112				}
9113
9114                // Set Wrapper Min-Height
9115                if( !sideHeader ) {
9116					if( !$('.header-logo-sticky-change').get(0) ) {
9117						self.options.wrapper.css('height', self.options.headerBody.outerHeight());
9118					} else {
9119						$window.on('stickyChangeLogo.loaded', () => {
9120							self.options.wrapper.css('height', self.options.headerBody.outerHeight());
9121						});
9122					}
9123
9124					if( self.options.stickyEffect == 'shrink' ) {
9125						
9126						// Prevent wrong visualization of header when reload on middle of page
9127						$(document).ready(() => {
9128							if( $window.scrollTop() >= self.options.stickyStartAt ) {
9129								self.options.wrapper.find('.header-container').on('transitionend webkitTransitionEnd oTransitionEnd', () => {
9130									self.options.headerBody.css('position', 'fixed');
9131								});
9132							} else {
9133								if( !$html.hasClass('boxed') ) {
9134									self.options.headerBody.css('position', 'fixed');
9135								}
9136							}
9137						});
9138
9139						self.options.wrapper.find('.header-container').css('height', initialHeaderContainerHeight);
9140						self.options.wrapper.find('.header-top').css('height', initialHeaderTopHeight);
9141					}
9142				}
9143
9144                // Sticky Header Container Height
9145                if( self.options.stickyHeaderContainerHeight ) {
9146					self.options.wrapper.find('.header-container').css('height', self.options.wrapper.find('.header-container').outerHeight());
9147				}
9148
9149                // Boxed
9150                if($html.hasClass('boxed') && self.options.stickyEffect == 'shrink') {
9151					self.boxedLayout();
9152				}
9153
9154                // Check Sticky Header / Flags prevent multiple runs at same time
9155                let activate_flag   	 = true;
9156
9157                let deactivate_flag 	 = false;
9158                const initialStickyStartAt = self.options.stickyStartAt;
9159
9160                self.checkStickyHeader = () => {
9161
9162					// Notice Top Bar
9163					const $noticeTopBar = $('.notice-top-bar');
9164					if ( $noticeTopBar.get(0) ) {
9165						self.options.stickyStartAt = ( $noticeTopBar.data('sticky-start-at') ) ? $noticeTopBar.data('sticky-start-at') : $('.notice-top-bar').outerHeight();
9166					} else {
9167						if( $html.hasClass('boxed') ) {
9168							self.options.stickyStartAt = initialStickyStartAt + 25;
9169						} else {
9170							self.options.stickyStartAt = initialStickyStartAt;
9171						}
9172					}
9173
9174					if( $window.width() > 991 && $html.hasClass('side-header') ) {
9175						$html.removeClass('sticky-header-active');
9176						activate_flag = true;
9177						return;
9178					}
9179
9180					if ($window.scrollTop() >= parseInt(self.options.stickyStartAt)) {
9181						if( activate_flag ) {
9182							self.activateStickyHeader();
9183							activate_flag = false;
9184							deactivate_flag = true;
9185						}
9186					} else {
9187						if( deactivate_flag ) {
9188							self.deactivateStickyHeader();
9189							deactivate_flag = false;
9190							activate_flag = true;
9191						}
9192					}
9193
9194					// Scroll Up
9195					if (self.options.stickyScrollUp) {
9196						
9197					    // Get the new Value
9198					    self.options.stickyScrollNewValue = window.pageYOffset;
9199
9200					    //Subtract the two and conclude
9201					    if(self.options.stickyScrollValue - self.options.stickyScrollNewValue < 0){
9202					        $html.removeClass('sticky-header-scroll-up').addClass('sticky-header-scroll-down');
9203					    } else if(self.options.stickyScrollValue - self.options.stickyScrollNewValue > 0){
9204					        $html.removeClass('sticky-header-scroll-down').addClass('sticky-header-scroll-up');
9205					    }
9206
9207					    // Update the old value
9208					    self.options.stickyScrollValue = self.options.stickyScrollNewValue;
9209
9210					}
9211				};
9212
9213                // Activate Sticky Header
9214                self.activateStickyHeader = () => {
9215					if ($window.width() < 992) {
9216						if (self.options.stickyEnableOnMobile == false) {
9217							self.deactivateStickyHeader();
9218							self.options.headerBody.css({
9219								position: 'relative'
9220							});
9221							return false;
9222						}
9223					} else {
9224						if (sideHeader) {
9225							self.deactivateStickyHeader();
9226							return;
9227						}
9228					}
9229
9230					$html.addClass('sticky-header-active');
9231
9232					// Sticky Effect - Reveal
9233					if( self.options.stickyEffect == 'reveal' ) {
9234
9235						self.options.headerBody.css('top','-' + self.options.stickyStartAt + 'px');
9236
9237						self.options.headerBody.animate({
9238							top: self.options.stickySetTop
9239						}, 400, () => {});
9240
9241					}
9242
9243					// Sticky Effect - Shrink
9244					if( self.options.stickyEffect == 'shrink' ) {
9245
9246						// If Header Top
9247						if( self.options.wrapper.find('.header-top').get(0) ) {
9248							self.options.wrapper.find('.header-top').css({
9249								height: 0,
9250								'min-height': 0,
9251								overflow: 'hidden'
9252							});
9253						}
9254
9255						// Header Container
9256						if( self.options.stickyHeaderContainerHeight ) {
9257							self.options.wrapper.find('.header-container').css({
9258								height: self.options.stickyHeaderContainerHeight,
9259								'min-height': 0
9260							});
9261						} else {
9262							self.options.wrapper.find('.header-container').css({
9263								height: (initialHeaderContainerHeight / 3) * 2, // two third of container height
9264								'min-height': 0
9265							});
9266
9267							const y = initialHeaderContainerHeight - ((initialHeaderContainerHeight / 3) * 2);
9268							$('.main').css({
9269								transform: 'translate3d(0, -'+ y +'px, 0)',
9270								transition: 'ease transform 300ms'
9271							}).addClass('has-sticky-header-transform');
9272
9273							if($html.hasClass('boxed')) {
9274								self.options.headerBody.css('position','fixed');
9275							}
9276						}
9277
9278					}
9279
9280					self.options.headerBody.css('top', self.options.stickySetTop);
9281
9282					if (self.options.stickyChangeLogo) {
9283						self.changeLogo(true);
9284					}
9285
9286					// Set Elements Style
9287					if( $('[data-sticky-header-style]').length ) {
9288						$('[data-sticky-header-style]').each(function() {
9289							const $el = $(this), css = theme.fn.getOptions($el.data('sticky-header-style-active')), opts = theme.fn.getOptions($el.data('sticky-header-style'));
9290
9291							if( $window.width() > opts.minResolution ) {
9292								$el.css(css);
9293							}
9294						});
9295					}
9296
9297					$.event.trigger({
9298						type: 'stickyHeader.activate'
9299					});
9300				};
9301
9302                // Deactivate Sticky Header
9303                self.deactivateStickyHeader = () => {
9304					$html.removeClass('sticky-header-active');
9305
9306					if ( $(window).width() < 992 && self.options.stickyEnableOnMobile == false) {
9307						return false;
9308					}
9309
9310					// Sticky Effect - Shrink
9311					if( self.options.stickyEffect == 'shrink' ) {
9312
9313						// Boxed Layout
9314						if( $html.hasClass('boxed') ) {
9315
9316							// Set Header Body Position Absolute
9317							self.options.headerBody.css('position','absolute');
9318
9319							if( $window.scrollTop() > $('.body').offset().top ) {
9320								// Set Header Body Position Fixed
9321								self.options.headerBody.css('position','fixed');								
9322							}
9323
9324						} else {
9325							// Set Header Body Position Fixed
9326							self.options.headerBody.css('position','fixed');
9327						}
9328
9329						// If Header Top
9330						if( self.options.wrapper.find('.header-top').get(0) ) {
9331							self.options.wrapper.find('.header-top').css({
9332								height: initialHeaderTopHeight,
9333								overflow: 'visible'
9334							});
9335
9336							// Fix [data-icon] issue when first load is on middle of the page
9337							if( self.options.wrapper.find('.header-top [data-icon]').length ) {
9338								theme.fn.intObsInit( '.header-top [data-icon]:not(.svg-inline--fa)', 'themePluginIcon' );
9339							}
9340						}
9341
9342						// Header Container
9343						self.options.wrapper.find('.header-container').css({
9344							height: initialHeaderContainerHeight
9345						});
9346
9347					}
9348
9349					self.options.headerBody.css('top', 0);
9350
9351					if (self.options.stickyChangeLogo) {
9352						self.changeLogo(false);
9353					}
9354
9355					// Set Elements Style
9356					if( $('[data-sticky-header-style]').length ) {
9357						$('[data-sticky-header-style]').each(function() {
9358							const $el = $(this), css = theme.fn.getOptions($el.data('sticky-header-style-deactive')), opts = theme.fn.getOptions($el.data('sticky-header-style'));
9359
9360							if( $window.width() > opts.minResolution ) {
9361								$el.css(css);
9362							}
9363						});
9364					}
9365
9366					$.event.trigger({
9367						type: 'stickyHeader.deactivate'
9368					});
9369				};
9370
9371                // Always Sticky
9372                if (parseInt(self.options.stickyStartAt) <= 0) {
9373					self.activateStickyHeader();
9374				}
9375
9376                // Set Logo
9377                if (self.options.stickyChangeLogo) {
9378
9379					const $logoWrapper = self.options.wrapper.find('.header-logo'), $logo = $logoWrapper.find('img'), logoWidth = $logo.attr('width'), logoHeight = $logo.attr('height'), logoSmallTop = parseInt($logo.attr('data-sticky-top') ? $logo.attr('data-sticky-top') : 0), logoSmallWidth = parseInt($logo.attr('data-sticky-width') ? $logo.attr('data-sticky-width') : 'auto'), logoSmallHeight = parseInt($logo.attr('data-sticky-height') ? $logo.attr('data-sticky-height') : 'auto');
9380
9381					if (self.options.stickyChangeLogoWrapper) {
9382						$logoWrapper.css({
9383							'width': $logo.outerWidth(true),
9384							'height': $logo.outerHeight(true)
9385						});
9386					}
9387
9388					self.changeLogo = activate => {
9389						if(activate) {
9390							
9391							$logo.css({
9392								'top': logoSmallTop,
9393								'width': logoSmallWidth,
9394								'height': logoSmallHeight
9395							});
9396
9397						} else {
9398							
9399							$logo.css({
9400								'top': 0,
9401								'width': logoWidth,
9402								'height': logoHeight
9403							});
9404
9405						}
9406					}
9407
9408					$.event.trigger({
9409						type: 'stickyChangeLogo.loaded'
9410					});
9411
9412				}
9413
9414                // Side Header
9415                let headerBodyHeight, flag = false;
9416
9417                self.checkSideHeader = () => {
9418					if($window.width() < 992 && flag == false) {
9419						headerBodyHeight = self.options.headerBody.height();
9420						flag = true;
9421					}
9422
9423					if(self.options.stickyStartAt == 0 && sideHeader) {
9424						self.options.wrapper.css('min-height', 0);
9425					}
9426
9427					if(self.options.stickyStartAt > 0 && sideHeader && $window.width() < 992) {
9428						self.options.wrapper.css('min-height', headerBodyHeight);
9429					}
9430				}
9431
9432                return this;
9433            },
9434
9435			events() {
9436				const self = this;
9437
9438				if( $(window).width() < 992 && this.options.stickyEnableOnMobile == false ) {
9439					return this;
9440				}
9441
9442				if (!this.options.stickyEnableOnBoxed && $('body').hasClass('boxed') || $('html').hasClass('side-header-hamburguer-sidebar') && !this.options.stickyForce || !this.options.stickyEnabled) {
9443					return this;
9444				}
9445
9446				if (!self.options.alwaysStickyEnabled) {
9447					$(window).on('scroll resize', () => {
9448						if ( $(window).width() < 992 && self.options.stickyEnableOnMobile == false) {
9449							self.options.headerBody.css({
9450								position: ''
9451							});
9452
9453							if( self.options.stickyEffect == 'shrink' ) {
9454								self.options.wrapper.find('.header-top').css({
9455									height: ''
9456								});
9457							}
9458
9459							self.deactivateStickyHeader();
9460						} else {
9461							self.checkStickyHeader();
9462						}
9463					});
9464				} else {
9465					self.activateStickyHeader();
9466				}
9467
9468				$(window).on('load resize', () => {
9469					self.checkSideHeader();
9470				});
9471
9472				$(window).on('layout.boxed', () => {
9473					self.boxedLayout();
9474				});
9475
9476				return this;
9477			},
9478
9479			boxedLayout() {
9480				const self = this, $window = $(window);
9481
9482				if($('html').hasClass('boxed') && self.options.stickyEffect == 'shrink') {
9483					if( (parseInt(self.options.stickyStartAt) == 0) && $window.width() > 991) {
9484						self.options.stickyStartAt = 30;
9485					}
9486
9487					// Set Header Body Position Absolute
9488					self.options.headerBody.css({
9489						position: 'absolute',
9490						top: 0
9491					});
9492
9493					// Set position absolute because top margin from boxed layout
9494					$window.on('scroll', () => {
9495						if( $window.scrollTop() > $('.body').offset().top ) {
9496							self.options.headerBody.css({
9497								'position' : 'fixed',
9498								'top' : 0
9499							});								
9500						} else {
9501							self.options.headerBody.css({
9502								'position' : 'absolute',
9503								'top' : 0
9504							});
9505						}
9506					});
9507				}
9508
9509				return this;
9510			}
9511
9512		}
9513
9514	});
9515})).apply(this, [window.theme, 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.