PageSourceSearch

https://luthervillelax.com/wp-content/uploads/sites/60/bb-plugin/c…?ver=f6f4adaa5a4da88a24e1e4b0a7b6864d

js luthervillelax.com collected 2026-10-06 20:55:38 UTC 69,581 bytes, 2,571 lines download raw bytes

1var wpAjaxUrl = 'https://luthervillelax.com/wp-admin/admin-ajax.php';var flBuilderUrl = 'https://luthervillelax.com/wp-content/plugins/bb-plugin/';var FLBuilderLayoutConfig = {
2	anchorLinkAnimations : {
3		duration 	: 1000,
4		easing		: 'swing',
5		offset 		: 100
6	},
7	paths : {
8		pluginUrl : 'https://luthervillelax.com/wp-content/plugins/bb-plugin/',
9		wpAjaxUrl : 'https://luthervillelax.com/wp-admin/admin-ajax.php'
10	},
11	breakpoints : {
12		small  : 768,
13		medium : 992,
14		large : 1200	},
15	waypoint: {
16		offset: 80
17	},
18	emptyColWidth: '0%'
19};
20(function($){
21
22	if(typeof FLBuilderLayout != 'undefined') {
23		return;
24	}
25
26	/**
27	 * Helper class with generic logic for a builder layout.
28	 *
29	 * @class FLBuilderLayout
30	 * @since 1.0
31	 */
32	FLBuilderLayout = {
33
34		/**
35		 * Initializes a builder layout.
36		 *
37		 * @since 1.0
38		 * @method init
39		 */
40		init: function()
41		{
42			// Destroy existing layout events.
43			FLBuilderLayout._destroy();
44
45			// Init CSS classes.
46			FLBuilderLayout._initClasses();
47
48			// Init backgrounds.
49			FLBuilderLayout._initBackgroun
49ds();
50
51			// Init row shape layer height.
52			FLBuilderLayout._initRowShapeLayerHeight();
53
54			// Only init if the builder isn't active.
55			if ( 0 === $('.fl-builder-edit').length ) {
56
57				// Init module animations.
58				FLBuilderLayout._initModuleAnimations();
59
60				// Init anchor links.
61				FLBuilderLayout._initAnchorLinks();
62
63				// Init the browser hash.
64				FLBuilderLayout._initHash();
65
66				// Init forms.
67				FLBuilderLayout._initForms();
68
69				FLBuilderLayout._reorderMenu();
70			}
71			else {
72				FLBuilderLayout._initNestedColsWidth();
73			}
74		},
75
76		/**
77		 * Public method for refreshing Wookmark or MosaicFlow galleries
78		 * within an element.
79		 *
80		 * @since 1.7.4
81		 * @method refreshGalleries
82		 */
83		refreshGalleries: function( element )
84		{
85			var $element  = 'undefined' == typeof element ? $( 'body' ) : $( element ),
86				mfContent = $element.find( '.fl-mosaicflow-content' ),
87				wmContent = $element.find( '.fl-gallery' ),
88				mfObject  = null;
89
90			if ( mfContent ) {
91
92				mfObject = mfContent.data( 'mosaicflow' );
93
94				if ( mfObject ) {
95					mfObject.columns = $( [] );
96					mfObject.columnsHeights = [];
97					mfContent.data( 'mosaicflow', mfObject );
98					mfContent.mosaicflow( 'refill' );
99				}
100			}
101			if ( wmContent ) {
102				wmContent.trigger( 'refreshWookmark' );
103			}
104		},
105
106		/**
107		 * Public method for refreshing Masonry within an element
108		 *
109		 * @since 1.8.1
110		 * @method refreshGridLayout
111		 */
112		refreshGridLayout: function( element )
113		{
114			var $element 		= 'undefined' == typeof element ? $( 'body' ) : $( element ),
115				msnryContent	= $element.find('.masonry');
116
117			if ( msnryContent.length )	{
118				msnryContent.masonry('layout');
119			}
120		},
121
122		/**
123		 * Public method for reloading BxSlider within an element
124		 *
125		 * @since 1.8.1
126		 * @method reloadSlider
127		 */
128		reloadSlider: function( content )
129		{
130			var $content = 'undefined' == typeof content ? $('body') : $(content);
131
132			// reload sliders.
133			if ($content.find('.bx-viewport > div').length > 0) {
134				$.each($content.find('.bx-viewport > div'), function (key, slider) {
135					setTimeout(function () {
136						$(slider).data('bxSlider').reloadSlider();
137					}, 100);
138				});
139			}
140		},
141
142		/**
143		 * Public method for resizing WP audio player
144		 *
145		 * @since 1.8.2
146		 * @method resizeAudio
147		 */
148		resizeAudio: function( element )
149		{
150			var $element 	 	= 'undefined' == typeof element ? $( 'body' ) : $( element ),
151				audioPlayers 	= $element.find('.wp-audio-shortcode.mejs-audio'),
152				player 		 	= null,
153				mejsPlayer 	 	= null,
154				rail 			= null,
155				railWidth 		= 400;
156
157			if ( audioPlayers.length && typeof mejs !== 'undefined' ) {
158            	audioPlayers.each(function(){
159	            	player 		= $(this);
160	            	mejsPlayer 	= mejs.players[player.attr('id')];
161	            	rail 		= player.find('.mejs-controls .mejs-time-rail');
162	            	var innerMejs = player.find('.mejs-inner'),
163	            		total 	  = player.find('.mejs-controls .mejs-time-total');
164
165	            	if ( typeof mejsPlayer !== 'undefined' ) {
166	            		railWidth = Math.ceil(player.width() * 0.8);
167
168	            		if ( innerMejs.length ) {
169
170		            		rail.css('width', railWidth +'px!important');
171		            		//total.width(rail.width() - 10);
172
173		            		mejsPlayer.options.autosizeProgress = true;
174
175		            		// webkit has trouble doing this without a delay
176							setTimeout(function () {
177								mejsPlayer.setControlsSize();
178							}, 50);
179
180			            	player.find('.mejs-inner').css({
181			            		visibility: 'visible',
182			            		height: 'inherit'
183			            	});
184		            	}
185		           	}
186	            });
187	        }
188		},
189
190		/**
191		 * Public method for preloading WP audio player when it's inside the hidden element
192		 *
193		 * @since 1.8.2
194		 * @method preloadAudio
195		 */
196		preloadAudio: function(element)
197		{
198			var $element 	 = 'undefined' == typeof element ? $( 'body' ) : $( element ),
199				contentWrap  = $element.closest('.fl-accordion-item'),
200				audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio');
201
202			if ( ! contentWrap.hasClass('fl-accordion-item-active') && audioPlayers.find('.mejs-inner').length ) {
203				audioPlayers.find('.mejs-inner').css({
204					visibility : 'hidden',
205					height: 0
206				});
207			}
208		},
209
210		/**
211		 * Public method for resizing slideshow momdule within the tab
212		 *
213		 * @since 1.10.5
214		 * @method resizeSlideshow
215		 */
216		resizeSlideshow: function(){
217			if(typeof YUI !== 'undefined') {
218				YUI().use('node-event-simulate', function(Y) {
219					Y.one(window).simulate("resize");
220				});
221			}
222		},
223
224		/**
225		 * Public method for reloading an embedded Google Map within the tabs or hidden element.
226		 *
227		 * @since 2.2
228		 * @method reloadGoogleMap
229		 */
230		reloadGoogleMap: function(element){
231			var $element  = 'undefined' == typeof element ? $( 'body' ) : $( element ),
232			    googleMap = $element.find( 'iframe[src*="google.com/maps"]' );
233
234			if ( googleMap.length ) {
235			    googleMap.attr( 'src', function(i, val) {
236			        return val;
237			    });
238			}
239		},
240
241		/**
242		 * Unbinds builder layout events.
243		 *
244		 * @since 1.0
245		 * @access private
246		 * @method _destroy
247		 */
248		_destroy: function()
249		{
250			var win = $(window);
251
252			win.off('scroll.fl-bg-parallax');
253			win.off('resize.fl-bg-video');
254		},
255
256		/**
257		 * Checks to see if the current device has touch enabled.
258		 *
259		 * @since 1.0
260		 * @access private
261		 * @method _isTouch
262		 * @return {Boolean}
263		 */
264		_isTouch: function()
265		{
266			if(('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) {
267				return true;
268			}
269
270			return false;
271		},
272
273		/**
274		 * Checks to see if the current device is mobile.
275		 *
276		 * @since 1.7
277		 * @access private
278		 * @method _isMobile
279		 * @return {Boolean}
280		 */
281		_isMobile: function()
282		{
283			return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent );
284		},
285
286		/**
287		 * Initializes builder body classes.
288		 *
289		 * @since 1.0
290		 * @access private
291		 * @method _initClasses
292		 */
293		_initClasses: function()
294		{
295			var body = $( 'body' ),
296				ua   = navigator.userAgent;
297
298			// Add the builder body class.
299			if ( ! body.hasClass( 'archive' ) && $( '.fl-builder-content-primary' ).length > 0 ) {
300				body.addClass('fl-builder');
301			}
302
303			// Add the builder touch body class.
304			if(FLBuilderLayout._isTouch()) {
305				body.addClass('fl-builder-touch');
306			}
307
308			// Add the builder mobile body class.
309			if(FLBuilderLayout._isMobile()) {
310				body.addClass('fl-builder-mobile');
311			}
312
313			if ( $(window).width() < FLBuilderLayoutConfig.breakpoints.small ) {
314				body.addClass( 'fl-builder-breakpoint-small' );
315			}
316
317			if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.small && $(window).width() < FLBuilderLayoutConfig.breakpoints.medium ) {
318				body.addClass( 'fl-builder-breakpoint-medium' );
319			}
320
321			if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.medium && $(window).width() < FLBuilderLayoutConfig.breakpoints.large ) {
322				body.addClass( 'fl-builder-breakpoint-large' );
323			}
324
325			if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.large ) {
326				body.addClass( 'fl-builder-breakpoint-default' );
327			}
328
329			// IE11 body class.
330			if ( ua.indexOf( 'Trident/7.0' ) > -1 && ua.indexOf( 'rv:11.0' ) > -1 ) {
331				body.addClass( 'fl-builder-ie-11' );
332			}
333		},
334
335		/**
336		 * Initializes builder node backgrounds that require
337		 * additional JavaScript logic such as parallax.
338		 *
339		 * @since 1.1.4
340		 * @access private
341		 * @method _initBackgrounds
342		 */
343		_initBackgrounds: function()
344		{
345			var win = $(window);
346
347			// Init parallax backgrounds.
348			if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isMobile()) {
349				FLBuilderLayout._scrollParallaxBackgrounds();
350				FLBuilderLayout._initParallaxBackgrounds();
351				win.on('resize.fl-bg-parallax', FLBuilderLayout._initParallaxBackgrounds);
352				win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds);
353			}
354
355			// Init video backgrounds.
356			if($('.fl-bg-video').length > 0) {
357				FLBuilderLayout._initBgVideos();
358				FLBuilderLayout._resizeBgVideos();
359
360				// Ensure FLBuilderLayout._resizeBgVideos() is only called once on window resize.
361				var resizeBGTimer = null;
362				win.on('resize.fl-bg-video', function(e){
363					clearTimeout( resizeBGTimer );
364					resizeBGTimer = setTimeout(function() {
365						FLBuilderLayout._resizeBgVideos(e);
366					}, 100 );
367				});
368			}
369		},
370
371		/**
372		 * Initializes all parallax backgrounds in a layout.
373		 *
374		 * @since 1.1.4
375		 * @access private
376		 * @method _initParallaxBackgrounds
377		 */
378		_initParallaxBackgrounds: function()
379		{
380			$('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground);
381		},
382
383		/**
384		 * Initializes a single parallax background.
385		 *
386		 * @since 1.1.4
387		 * @access private
388		 * @method _initParallaxBackgrounds
389		 */
390		_initParallaxBackground: function()
391		{
392			var row     = $(this),
393				content = row.find('> .fl-row-content-wrap'),
394				winWidth = $(window).width(),
395				screenSize = '',
396				imageSrc = {
397					default: '',
398					medium: '',
399					responsive: '',
400				};
401
402			imageSrc.default = row.data('parallax-image') || '';
403			imageSrc.medium = row.data('parallax-image-medium') || imageSrc.default;
404			imageSrc.responsive = row.data('parallax-image-responsive') || imageSrc.medium;
405
406			if (winWidth > FLBuilderLayoutConfig.breakpoints.medium) {
407				screenSize = 'default';
408			} else if (winWidth > FLBuilderLayoutConfig.breakpoints.small && winWidth <= FLBuilderLayoutConfig.breakpoints.medium ) {
409				screenSize = 'medium';
410			} else if (winWidth <= FLBuilderLayoutConfig.breakpoints.small) {
411				screenSize = 'responsive';
412			}
413
414			content.css('background-image', 'url(' + imageSrc[screenSize] + ')');
415			row.data('current-image-loaded', screenSize );
416
417		},
418
419		/**
420		 * Fires when the window is scrolled to adjust
421		 * parallax backgrounds.
422		 *
423		 * @since 1.1.4
424		 * @access private
425		 * @method _scrollParallaxBackgrounds
426		 */
427		_scrollParallaxBackgrounds: function()
428		{
429			$('.fl-row-bg-parallax').each(FLBuilderLayout._scrollParallaxBackground);
430		},
431
432		/**
433		 * Fires when the window is scrolled to adjust
434		 * a single parallax background.
435		 *
436		 * @since 1.1.4
437		 * @access private
438		 * @method _scrollParallaxBackground
439		 */
440		_scrollParallaxBackground: function()
441		{
442			var win     	  = $(window),
443				row     	  = $(this),
444				content 	  = row.find('> .fl-row-content-wrap'),
445				speed   	  = row.data('parallax-speed'),
446				offset  	  = content.offset(),
447				yPos		  = -((win.scrollTop() - offset.top) / speed),
448				initialOffset = ( row.data('parallax-offset') != null ) ? row.data('parallax-offset') : 0,
449				totalOffset   = yPos - initialOffset;
450
451			content.css('background-position', 'center ' + totalOffset + 'px');
452		},
453
454		/**
455		 * Initializes all video backgrounds.
456		 *
457		 * @since 1.6.3.3
458		 * @access private
459		 * @method _initBgVideos
460		 */
461		_initBgVideos: function()
462		{
463			$('.fl-bg-video').each(FLBuilderLayout._initBgVideo);
464		},
465
466		/**
467		 * Initializes a video background.
468		 *
469		 * @since 1.6.3.3
470		 * @access private
471		 * @method _initBgVideo
472		 */
473		_initBgVideo: function()
474		{
475			var wrap   = $( this ),
476				width       = wrap.data( 'width' ),
477				height      = wrap.data( 'height' ),
478				mp4         = wrap.data( 'mp4' ),
479				youtube     = wrap.data( 'youtube'),
480				vimeo       = wrap.data( 'vimeo'),
481				mp4Type     = wrap.data( 'mp4-type' ),
482				webm        = wrap.data( 'webm' ),
483				webmType    = wrap.data( 'webm-type' ),
484				fallback    = wrap.data( 'fallback' ),
485				loaded      = wrap.data( 'loaded' ),
486				videoMobile = wrap.data( 'video-mobile' ),
487				fallbackTag = '',
488				videoTag    = null,
489				mp4Tag      = null,
490				webmTag     = null;
491
492			// Return if the video has been loaded for this row.
493			if ( loaded ) {
494				return;
495			}
496
497			videoTag  = $( '<video autoplay loop muted playsinline></video>' );
498
499			/**
500			 * Add poster image (fallback image)
501			 */
502			if( 'undefined' != typeof fallback && '' != fallback ) {
503				videoTag.attr( 'poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' )
504				videoTag.css({
505					backgroundImage: 'url("' + fallback + '")',
506					backgroundColor: 'transparent',
507					backgroundRepeat: 'no-repeat',
508					backgroundSize: 'cover',
509					backgroundPosition: 'center center',
510				})
511			}
512
513			// MP4 Source Tag
514			if ( 'undefined' != typeof mp4 && '' != mp4 ) {
515
516				mp4Tag = $( '<source />' );
517				mp4Tag.attr( 'src', mp4 );
518				mp4Tag.attr( 'type', mp4Type );
519
520				videoTag.append( mp4Tag );
521			}
522			// WebM Source Tag
523			if ( 'undefined' != typeof webm && '' != webm ) {
524
525				webmTag = $( '<source />' );
526				webmTag.attr( 'src', webm );
527				webmTag.attr( 'type', webmType );
528
529				videoTag.append( webmTag );
530			}
531
532			// This is either desktop, or mobile is enabled.
533			if ( ! FLBuilderLayout._isMobile() || ( FLBuilderLayout._isMobile() && "yes" == videoMobile ) ) {
534				if ( 'undefined' != typeof youtube ) {
535					FLBuilderLayout._initYoutubeBgVideo.apply( this );
536				}
537				else if ( 'undefined' != typeof vimeo ) {
538					FLBuilderLayout._initVimeoBgVideo.apply( this );
539				}
540				else {
541					wrap.append( videoTag );
542				}
543			}
544			else {
545				// if we are here, it means we are on mobile and NO is set so remove video src and use fallback
546				videoTag.attr('src', '')
547				wrap.append( videoTag );
548			}
549
550			// Mark this video as loaded.
551			wrap.data('loaded', true);
552		},
553
554		/**
555		 * Initializes Youtube video background
556		 *
557		 * @since 1.9
558		 * @access private
559		 * @method _initYoutubeBgVideo
560		 */
561		_initYoutubeBgVideo: function()
562		{
563			var playerWrap  = $(this),
564				videoId     = playerWrap.data('video-id'),
565				videoPlayer = playerWrap.find('.fl-bg-video-player'),
566				enableAudio = playerWrap.data('enable-audio'),
567				audioButton = playerWrap.find('.fl-bg-video-audio'),
568				startTime   = 'undefined' !== typeof playerWrap.data('start') ? playerWrap.data('start') : 0,
569				startTime   = 'undefined' !== typeof playerWrap.data('t') && startTime === 0 ? playerWrap.data('t') : startTime,
570				endTime     = 'undefined' !== typeof playerWrap.data('end') ? playerWrap.data('end') : 0,
571				loop        = 'undefined' !== typeof playerWrap.data('loop') ? playerWrap.data('loop') : 1,
572				stateCount  = 0,
573				player,fallback_showing;
574
575			if ( videoId ) {
576				fallback = playerWrap.data('fallback') || false
577				if( fallback ) {
578					playerWrap.find('iframe').remove()
579					fallbackTag = $( '<div></div>' );
580					fallbackTag.addClass( 'fl-bg-video-fallback' );
581					fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' );
582					fallbackTag.css( 'background-size', 'cover' );
583					fallbackTag.css( 'transition', 'background-image 1s')
584					playerWrap.append( fallbackTag );
585					fallback_showing = true;
586				}
587				FLBuilderLayout._onYoutubeApiReady( function( YT ) {
588					setTimeout( function() {
589
590						player = new YT.Player( videoPlayer[0], {
591							videoId: videoId,
592							events: {
593								onReady: function(event) {
594									if ( "no" === enableAudio || FLBuilderLayout._isMobile() ) {
595										event.target.mute();
596									}
597									else if ( "yes" === enableAudio && event.target.isMuted ) {
598										event.target.unMute();
599									}
600
601									// Store an instance to a parent
602									playerWrap.data('YTPlayer', player);
603									FLBuilderLayout._resizeYoutubeBgVideo.apply(playerWrap);
604
605									// Queue the video.
606									event.target.playVideo();
607
608									if ( audioButton.length > 0 && ! FLBuilderLayout._isMobile() ) {
609										audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio );
610									}
611								},
612								onStateChange: function( event ) {
613
614									if ( event.data === 1 ) {
615										if ( fallback_showing ) {
616											$( '.fl-bg-video-fallback' ).css( 'background-image', 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' )
617										}
618									}
619									// Manual check if video is not playable in some browsers.
620									// StateChange order: [-1, 3, -1]
621									if ( stateCount < 4 ) {
622										stateCount++;
623									}
624
625									// Comply with the audio policy in some browsers like Chrome and Safari.
626									if ( stateCount > 1 && (-1 === event.data || 2 === event.data) && "yes" === enableAudio ) {
627										player.mute();
628										player.playVideo();
629										audioButton.show();
630									}
631
632									if ( event.data === YT.PlayerState.ENDED && 1 === loop ) {
633										if ( startTime > 0 ) {
634											player.seekTo( startTime );
635										}
636										else {
637											player.playVideo();
638										}
639									}
640								},
641								onError: function(event) {
642									console.info('YT Error: ' + event.data)
643									FLBuilderLayout._onErrorYoutubeVimeo(playerWrap)
644								}
645							},
646							playerVars: {
647								playsinline: FLBuilderLayout._isMobile() ? 1 : 0,
648								controls: 0,
649								showinfo: 0,
650								rel : 0,
651								start: startTime,
652								end: endTime,
653							}
654						} );
655					}, 1 );
656				} );
657			}
658		},
659
660		/**
661		 * On youtube or vimeo error show the fallback image if available.
662		 * @since 2.0.7
663		 */
664		_onErrorYoutubeVimeo: function(playerWrap) {
665
666			fallback = playerWrap.data('fallback') || false
667			if( ! fallback ) {
668				return false;
669			}
670			playerWrap.find('iframe').remove()
671			fallbackTag = $( '<div></div>' );
672			fallbackTag.addClass( 'fl-bg-video-fallback' );
673			fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' );
674			playerWrap.append( fallbackTag );
675		},
676
677		/**
678		 * Check if Youtube API has been downloaded
679		 *
680		 * @since 1.9
681		 * @access private
682		 * @method _onYoutubeApiReady
683		 * @param  {Function} callback Method to call when YT API has been loaded
684		 */
685		_onYoutubeApiReady: function( callback ) {
686			if ( window.YT && YT.loaded ) {
687				callback( YT );
688			} else {
689				// If not ready check again by timeout..
690				setTimeout( function() {
691					FLBuilderLayout._onYoutubeApiReady( callback );
692				}, 350 );
693			}
694		},
695
696		/**
697		 * Initializes Vimeo video background
698		 *
699		 * @since 1.9
700		 * @access private
701		 * @method _initVimeoBgVideo
702		 */
703		_initVimeoBgVideo: function()
704		{
705			var playerWrap	= $(this),
706				videoId 	= playerWrap.data('video-id'),
707				videoPlayer = playerWrap.find('.fl-bg-video-player'),
708				enableAudio = playerWrap.data('enable-audio'),
709				audioButton = playerWrap.find('.fl-bg-video-audio'),
710				player,
711				width = playerWrap.outerWidth(),
712				ua    = navigator.userAgent;
713
714			if ( typeof Vimeo !== 'undefined' && videoId )	{
715				player = new Vimeo.Player(videoPlayer[0], {
716					id         : videoId,
717					loop       : true,
718					title      : false,
719					portrait   : false,
720					background : true,
721					autopause  : false,
722					muted      : true
723				});
724
725				playerWrap.data('VMPlayer', player);
726				if ( "no" === enableAudio ) {
727					player.setVolume(0);
728				}
729				else if ("yes" === enableAudio ) {
730					// Chrome, Safari, Firefox have audio policy restrictions for autoplay videos.
731					if ( ua.indexOf("Safari") > -1 || ua.indexOf("Chrome") > -1 || ua.indexOf("Firefox") > -1 ) {
732						player.setVolume(0);
733						audioButton.show();
734					}
735					else {
736						player.setVolume(1);
737					}
738				}
739
740				player.play().catch(function(error) {
741					FLBuilderLayout._onErrorYoutubeVimeo(playerWrap)
742				});
743
744				if ( audioButton.length > 0 ) {
745					audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio );
746				}
747			}
748		},
749
750		/**
751		 * Mute / unmute audio on row's video background.
752		 * It works for both Youtube and Vimeo.
753		 *
754		 * @since 2.1.3
755		 * @access private
756		 * @method _toggleBgVideoAudio
757		 * @param {Object} e Method arguments
758		 */
759		_toggleBgVideoAudio: function( e ) {
760			var player  = e.data.player,
761			    control = e.data.button.find('.fl-audio-control');
762
763			if ( control.hasClass( 'fa-volume-off' ) ) {
764				// Unmute
765				control
766					.removeClass( 'fa-volume-off' )
767					.addClass( 'fa-volume-up' );
768				e.data.button.find( '.fa-times' ).hide();
769
770				if ( 'function' === typeof player.unMute ) {
771					player.unMute();
772				}
773				else {
774					player.setVolume( 1 );
775				}
776			}
777			else {
778				// Mute
779				control
780					.removeClass( 'fa-volume-up' )
781					.addClass( 'fa-volume-off' );
782				e.data.button.find( '.fa-times' ).show();
783
784				if ( 'function' === typeof player.unMute ) {
785					player.mute();
786				}
787				else {
788					player.setVolume( 0 );
789				}
790			}
791		},
792
793		/**
794		 * Fires when there is an error loading a video
795		 * background source and shows the fallback.
796		 *
797		 * @since 1.6.3.3
798		 * @access private
799		 * @method _videoBgSourceError
800		 * @param {Object} e An event object
801		 * @deprecated 2.0.3
802		 */
803		_videoBgSourceError: function( e )
804		{
805			var source 		= $( e.target ),
806				wrap   		= source.closest( '.fl-bg-video' ),
807				vid		    = wrap.find( 'video' ),
808				fallback  	= wrap.data( 'fallback' ),
809				fallbackTag = '';
810			source.remove();
811
812			if ( vid.find( 'source' ).length ) {
813				// Don't show the fallback if we still have other sources to check.
814				return;
815			} else if ( '' !== fallback ) {
816				fallbackTag = $( '<div></div>' );
817				fallbackTag.addClass( 'fl-bg-video-fallback' );
818				fallbackTag.css( 'background-image', 'url(' + fallback + ')' );
819				wrap.append( fallbackTag );
820				vid.remove();
821			}
822		},
823
824		/**
825		 * Fires when the window is resized to resize
826		 * all video backgrounds.
827		 *
828		 * @since 1.1.4
829		 * @access private
830		 * @method _resizeBgVideos
831		 */
832		_resizeBgVideos: function()
833		{
834			$('.fl-bg-video').each( function() {
835
836				FLBuilderLayout._resizeBgVideo.apply( this );
837
838				if ( $( this ).parent().find( 'img' ).length > 0 ) {
839					$( this ).parent().imagesLoaded( $.proxy( FLBuilderLayout._resizeBgVideo, this ) );
840				}
841			} );
842		},
843
844		/**
845		 * Fires when the window is resized to resize
846		 * a single video background.
847		 *
848		 * @since 1.1.4
849		 * @access private
850		 * @method _resizeBgVideo
851		 */
852		_resizeBgVideo: function()
853		{
854			if ( 0 === $( this ).find( 'video' ).length && 0 === $( this ).find( 'iframe' ).length ) {
855				return;
856			}
857
858			var wrap        = $(this),
859				wrapHeight  = wrap.outerHeight(),
860				wrapWidth   = wrap.outerWidth(),
861				vid         = wrap.find('video'),
862				vidHeight   = wrap.data('height'),
863				vidWidth    = wrap.data('width'),
864				newWidth    = wrapWidth,
865				newHeight   = Math.round(vidHeight * wrapWidth/vidWidth),
866				newLeft     = 0,
867				newTop      = 0,
868				iframe 		= wrap.find('iframe'),
869				isRowFullHeight = $(this).closest('.fl-row-bg-video').hasClass('fl-row-full-height'),
870				vidCSS          = {
871					top:       '50%',
872					left:      '50%',
873					transform: 'translate(-50%,-50%)',
874				};
875
876			if ( vid.length ) {
877				if(vidHeight === '' || typeof vidHeight === 'undefined' || vidWidth === '' || typeof vidWidth === 'undefined') {
878					vid.css({
879						'left'      : '0px',
880						'top'       : '0px',
881						'width'     : newWidth + 'px'
882					});
883
884					// Try to set the actual video dimension on 'loadedmetadata' when using URL as video source
885					vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta);
886
887					return;
888				}
889
890				if ( ! isRowFullHeight ) {
891					if ( newHeight < wrapHeight ) {
892						newHeight = wrapHeight;
893						newLeft   = -((newWidth - wrapWidth) / 2);
894						newWidth  = vidHeight ? Math.round(vidWidth * wrapHeight/vidHeight) : newWidth;
895					}
896					else {
897						newTop = -((newHeight - wrapHeight)/2);
898					}
899					vidCSS = {
900						left   : newLeft + 'px',
901						top    : newTop + 'px',
902						height : newHeight + 'px',
903						width  : newWidth + 'px',
904					}
905				}
906
907				vid.css( vidCSS );
908
909			}
910			else if ( iframe.length ) {
911
912				// Resize Youtube video player within iframe tag
913				if ( typeof wrap.data('youtube') !== 'undefined' ) {
914					FLBuilderLayout._resizeYoutubeBgVideo.apply(this);
915				}
916			}
917		},
918
919		/**
920		 * Fires when video meta has been loaded.
921		 * This will be Triggered when width/height attributes were not specified during video background resizing.
922		 *
923		 * @since 1.8.5
924		 * @access private
925		 * @method _resizeOnLoadedMeta
926		 */
927		_resizeOnLoadedMeta: function(){
928			var video 		= $(this),
929				wrapHeight 	= video.parent().outerHeight(),
930				wrapWidth 	= video.parent().outerWidth(),
931				vidWidth 	= video[0].videoWidth,
932				vidHeight 	= video[0].videoHeight,
933				newHeight   = Math.round(vidHeight * wrapWidth/vidWidth),
934				newWidth    = wrapWidth,
935				newLeft     = 0,
936				newTop 		= 0;
937
938			if(newHeight < wrapHeight) {
939				newHeight   = wrapHeight;
940				newWidth    = Math.round(vidWidth * wrapHeight/vidHeight);
941				newLeft     = -((newWidth - wrapWidth)/2);
942			}
943			else {
944				newTop      = -((newHeight - wrapHeight)/2);
945			}
946
947			video.parent().data('width', vidWidth);
948			video.parent().data('height', vidHeight);
949
950			video.css({
951				'left'      : newLeft + 'px',
952				'top'       : newTop + 'px',
953				'width'     : newWidth + 'px',
954				'height' 	: newHeight + 'px'
955			});
956		},
957
958		/**
959		 * Fires when the window is resized to resize
960		 * a single Youtube video background.
961		 *
962		 * @since 1.9
963		 * @access private
964		 * @method _resizeYoutubeBgVideo
965		 */
966		_resizeYoutubeBgVideo: function()
967		{
968			var wrap				= $(this),
969				wrapWidth 			= wrap.outerWidth(),
970				wrapHeight 			= wrap.outerHeight(),
971				player 				= wrap.data('YTPlayer'),
972				video 				= player ? player.getIframe() : null,
973				aspectRatioSetting 	= '16:9', // Medium
974				aspectRatioArray 	= aspectRatioSetting.split( ':' ),
975				aspectRatio 		= aspectRatioArray[0] / aspectRatioArray[1],
976				ratioWidth 			= wrapWidth / aspectRatio,
977				ratioHeight 		= wrapHeight * aspectRatio,
978				isWidthFixed 		= wrapWidth / wrapHeight > aspectRatio,
979				width 				= isWidthFixed ? wrapWidth : ratioHeight,
980				height 				= isWidthFixed ? ratioWidth : wrapHeight;
981
982			if ( video ) {
983				$(video).width( width ).height( height );
984			}
985		},
986
987		/**
988		 * Initializes module animations.
989		 *
990		 * @since 1.1.9
991		 * @access private
992		 * @method _initModuleAnimations
993		 */
994		_initModuleAnimations: function()
995		{
996			if(typeof jQuery.fn.waypoint !== 'undefined') {
997				$('.fl-animation').each( function() {
998					var node = $( this ),
999						nodeTop = node.offset().top,
1000						winHeight = $( window ).height(),
1001						bodyHeight = $( 'body' ).height(),
1002						waypoint = FLBuilderLayoutConfig.waypoint,
1003						offset = '80%';
1004
1005					if ( typeof waypoint.offset !== undefined ) {
1006						offset = FLBuilderLayoutConfig.waypoint.offset + '%';
1007					}
1008
1009					if ( bodyHeight - nodeTop < winHeight * 0.2 ) {
1010						offset = '100%';
1011					}
1012
1013					node.waypoint({
1014						offset: offset,
1015						handler: FLBuilderLayout._doModuleAnimation
1016					});
1017				} );
1018			}
1019		},
1020
1021		/**
1022		 * Runs a module animation.
1023		 *
1024		 * @since 1.1.9
1025		 * @access private
1026		 * @method _doModuleAnimation
1027		 */
1028		_doModuleAnimation: function()
1029		{
1030			var module = 'undefined' == typeof this.element ? $(this) : $(this.element),
1031				delay = parseFloat(module.data('animation-delay')),
1032				duration = parseFloat(module.data('animation-duration'));
1033
1034			if ( ! isNaN( duration ) ) {
1035				module.css( 'animation-duration', duration + 's' );
1036			}
1037
1038			if(!isNaN(delay) && delay > 0) {
1039				setTimeout(function(){
1040					module.addClass('fl-animated');
1041				}, delay * 1000);
1042			} else {
1043				setTimeout(function(){
1044					module.addClass('fl-animated');
1045				}, 1);
1046			}
1047		},
1048
1049		/**
1050		 * Opens a tab or accordion item if the browser hash is set
1051		 * to the ID of one on the page.
1052		 *
1053		 * @since 1.6.0
1054		 * @access private
1055		 * @method _initHash
1056		 */
1057		_initHash: function()
1058		{
1059			var hash 			= window.location.hash.replace( '#', '' ).split( '/' ).shift(),
1060				element 		= null,
1061				tabs			= null,
1062				responsiveLabel	= null,
1063				tabIndex		= null,
1064				label			= null;
1065
1066			if ( '' !== hash ) {
1067
1068				try {
1069
1070					element = $( '#' + hash );
1071
1072					if ( element.length > 0 ) {
1073
1074						if ( element.hasClass( 'fl-accordion-item' ) ) {
1075							setTimeout( function() {
1076								element.find( '.fl-accordion-button' ).trigger( 'click' );
1077							}, 100 );
1078						}
1079						if ( element.hasClass( 'fl-tabs-panel' ) ) {
1080							setTimeout( function() {
1081								tabs 			= element.closest( '.fl-tabs' );
1082								responsiveLabel = element.find( '.fl-tabs-panel-label' );
1083								tabIndex 		= responsiveLabel.data( 'index' );
1084								label 			= tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' );
1085
1086								label[0].click();
1087								FLBuilderLayout._scrollToElement(element);
1088							}, 100 );
1089						}
1090					}
1091				}
1092				catch( e ) {}
1093			}
1094		},
1095
1096		/**
1097		 * Initializes all anchor links on the page for smooth scrolling.
1098		 *
1099		 * @since 1.4.9
1100		 * @access private
1101		 * @method _initAnchorLinks
1102		 */
1103		_initAnchorLinks: function()
1104		{
1105			$( 'a' ).each( FLBuilderLayout._initAnchorLink );
1106		},
1107
1108		/**
1109		 * Initializes a single anchor link for smooth scrolling.
1110		 *
1111		 * @since 1.4.9
1112		 * @access private
1113		 * @method _initAnchorLink
1114		 */
1115		_initAnchorLink: function()
1116		{
1117			var link    = $( this ),
1118				href    = link.attr( 'href' ),
1119				loc     = window.location,
1120				id      = null,
1121				element = null,
1122				flNode  = false;
1123
1124			if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) {
1125
1126				if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) {
1127
1128					try {
1129
1130						id      = href.split( '#' ).pop();
1131						// If there is no ID then we have nowhere to look
1132						// Fixes a quirk in jQuery and FireFox
1133						if( ! id ) {
1134							return;
1135						}
1136						element = $( '#' + id );
1137
1138						if ( element.length > 0 ) {
1139							flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' );
1140							if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) {
1141								$( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick );
1142							}
1143							if ( element.hasClass( 'fl-accordion-item' ) ) {
1144								$( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick );
1145							}
1146							if ( element.hasClass( 'fl-tabs-panel' ) ) {
1147								$( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick );
1148							}
1149						}
1150					}
1151					catch( e ) {}
1152				}
1153			}
1154		},
1155
1156		/**
1157		 * Scrolls to an element when an anchor link is clicked.
1158		 *
1159		 * @since 1.4.9
1160		 * @access private
1161		 * @method _scrollToElementOnLinkClick
1162		 * @param {Object} e An event object.
1163		 * @param {Function} callback A function to call when the scroll is complete.
1164		 */
1165		_scrollToElementOnLinkClick: function( e, callback )
1166		{
1167			var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() );
1168
1169			FLBuilderLayout._scrollToElement( element, callback );
1170
1171			e.preventDefault();
1172		},
1173
1174		/**
1175		 * Scrolls to an element.
1176		 *
1177		 * @since 1.6.4.5
1178		 * @access private
1179		 * @method _scrollToElement
1180		 * @param {Object} element The element to scroll to.
1181		 * @param {Function} callback A function to call when the scroll is complete.
1182		 */
1183		_scrollToElement: function( element, callback )
1184		{
1185			var config  = FLBuilderLayoutConfig.anchorLinkAnimations,
1186				dest    = 0,
1187				win     = $( window ),
1188				doc     = $( document );
1189
1190			if ( element.length > 0 ) {
1191
1192				if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) {
1193					dest = element.position().top;
1194				}
1195				else if ( element.offset().top > doc.height() - win.height() ) {
1196					dest = doc.height() - win.height();
1197				}
1198				else {
1199					dest = element.offset().top - config.offset;
1200				}
1201
1202				$( 'html, body' ).animate( { scrollTop: dest }, config.duration, config.easing, function() {
1203
1204					if ( 'undefined' != typeof callback ) {
1205						callback();
1206					}
1207
1208					if ( undefined != element.attr( 'id' ) ) {
1209
1210						if ( history.pushState ) {
1211							history.pushState( null, null, '#' + element.attr( 'id' ) );
1212						}
1213						else {
1214							window.location.hash = element.attr( 'id' );
1215						}
1216					}
1217				} );
1218			}
1219		},
1220
1221		/**
1222		 * Scrolls to an accordion item when a link is clicked.
1223		 *
1224		 * @since 1.5.9
1225		 * @access private
1226		 * @method _scrollToAccordionOnLinkClick
1227		 * @param {Object} e An event object.
1228		 */
1229		_scrollToAccordionOnLinkClick: function( e )
1230		{
1231			var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() );
1232
1233			if ( element.length > 0 ) {
1234
1235				var callback = function() {
1236					if ( element ) {
1237						element.find( '.fl-accordion-button' ).trigger( 'click' );
1238						element = false;
1239					}
1240				};
1241
1242				FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback );
1243			}
1244		},
1245
1246		/**
1247		 * Scrolls to a tab panel when a link is clicked.
1248		 *
1249		 * @since 1.5.9
1250		 * @access private
1251		 * @method _scrollToTabOnLinkClick
1252		 * @param {Object} e An event object.
1253		 */
1254		_scrollToTabOnLinkClick: function( e )
1255		{
1256			var element 		= $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ),
1257				tabs			= null,
1258				label   		= null,
1259				responsiveLabel = null;
1260
1261			if ( element.length > 0 ) {
1262
1263				tabs 			= element.closest( '.fl-tabs' );
1264				responsiveLabel = element.find( '.fl-tabs-panel-label' );
1265				tabIndex 		= responsiveLabel.data( 'index' );
1266				label 			= tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' );
1267
1268				if ( responsiveLabel.is( ':visible' ) ) {
1269
1270					var callback = function() {
1271						if ( element ) {
1272							responsiveLabel.trigger( $.Event( 'click', { which: 1 } ) );
1273						}
1274					};
1275
1276					FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback );
1277				}
1278				else {
1279					label[0].click();
1280					FLBuilderLayout._scrollToElement( element );
1281				}
1282
1283				e.preventDefault();
1284			}
1285		},
1286
1287		/**
1288		 * Initializes all builder forms on a page.
1289		 *
1290		 * @since 1.5.4
1291		 * @access private
1292		 * @method _initForms
1293		 */
1294		_initForms: function()
1295		{
1296			if ( ! FLBuilderLayout._hasPlaceholderSupport ) {
1297				$( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback );
1298			}
1299
1300			$( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError );
1301		},
1302
1303		/**
1304		 * Checks to see if the current device has HTML5
1305		 * placeholder support.
1306		 *
1307		 * @since 1.5.4
1308		 * @access private
1309		 * @method _hasPlaceholderSupport
1310		 * @return {Boolean}
1311		 */
1312		_hasPlaceholderSupport: function()
1313		{
1314			var input = document.createElement( 'input' );
1315
1316			return 'undefined' != input.placeholder;
1317		},
1318
1319		/**
1320		 * Initializes the fallback for when placeholders aren't supported.
1321		 *
1322		 * @since 1.5.4
1323		 * @access private
1324		 * @method _initFormFieldPlaceholderFallback
1325		 */
1326		_initFormFieldPlaceholderFallback: function()
1327		{
1328			var field       = $( this ),
1329				val         = field.val(),
1330				placeholder = field.attr( 'placeholder' );
1331
1332			if ( 'undefined' != placeholder && '' === val ) {
1333				field.val( placeholder );
1334				field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback );
1335				field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback );
1336			}
1337		},
1338
1339		/**
1340		 * Hides a fallback placeholder on focus.
1341		 *
1342		 * @since 1.5.4
1343		 * @access private
1344		 * @method _hideFormFieldPlaceholderFallback
1345		 */
1346		_hideFormFieldPlaceholderFallback: function()
1347		{
1348			var field       = $( this ),
1349				val         = field.val(),
1350				placeholder = field.attr( 'placeholder' );
1351
1352			if ( val == placeholder ) {
1353				field.val( '' );
1354			}
1355		},
1356
1357		/**
1358		 * Shows a fallback placeholder on blur.
1359		 *
1360		 * @since 1.5.4
1361		 * @access private
1362		 * @method _showFormFieldPlaceholderFallback
1363		 */
1364		_showFormFieldPlaceholderFallback: function()
1365		{
1366			var field       = $( this ),
1367				val         = field.val(),
1368				placeholder = field.attr( 'placeholder' );
1369
1370			if ( '' === val ) {
1371				field.val( placeholder );
1372			}
1373		},
1374
1375		/**
1376		 * Clears a form field error message.
1377		 *
1378		 * @since 1.5.4
1379		 * @access private
1380		 * @method _clearFormFieldError
1381		 */
1382		_clearFormFieldError: function()
1383		{
1384			var field = $( this );
1385
1386			field.removeClass( 'fl-form-error' );
1387			field.siblings( '.fl-form-error-message' ).hide();
1388		},
1389
1390		/**
1391		 * Init Row Shape Layer's height.
1392		 *
1393		 * @since 2.5.3
1394		 * @access private
1395		 * @method _initRowShapeLayerHeight
1396		 */
1397		_initRowShapeLayerHeight: function () {
1398			FLBuilderLayout._adjustRowShapeLayerHeight();
1399			$( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight );
1400		},
1401
1402		/**
1403		 * Set parent column width of nested columns when it's zero or blank.
1404		 * 
1405		 * @since 2.7.4
1406		 * @access private
1407		 * @method _initNestedColsWidth
1408		 */
1409		_initNestedColsWidth: function()
1410		{
1411			var nestedCols = $( '.fl-col-has-cols' );
1412
1413			if ( nestedCols.length <= 0 ) {
1414				return;
1415			}
1416
1417			$( nestedCols ).each( function(index, col ){
1418				if ( $( col ).width() <= 0 ) {
1419					$( col ).css( 'width', FLBuilderLayoutConfig.emptyColWidth );
1420				}
1421			});
1422		},
1423
1424		/**
1425		 * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes.
1426		 *
1427		 * @since 2.5.3
1428		 * @access private
1429		 * @method _adjustRowShapeLayerHeight
1430		 */
1431		_adjustRowShapeLayerHeight: function() {
1432			var rowShapeLayers = $('.fl-builder-shape-layer');
1433
1434			$( rowShapeLayers ).each(function (index) {
1435				var rowShapeLayer = $(this),
1436					shape = $(rowShapeLayer).find('svg'),
1437					height = shape.height(),
1438					excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect';
1439
1440				if ( ! rowShapeLayer.is( excludeShapes ) ) {
1441					$(shape).css('height', Math.ceil( height ) );
1442				}
1443			});
1444		},
1445		_string_to_slug: function( str ) {
1446			str = str.replace(/^\s+|\s+$/g, ''); // trim
1447			if ( 'undefined' == typeof window._fl_string_to_slug_regex ) {
1448				regex = new RegExp('[^a-zA-Z0-9\'":() !.,-_|]', 'g');
1449			} else {
1450				regex = new RegExp('[^' + window._fl_string_to_slug_regex + '\'":\(\) !.,-_|\\\p{Letter}]', 'ug');
1451			}
1452			str = str.replace(regex, '') // remove invalid chars
1453				.replace(/\s+/g, ' '); // collapse whitespace and replace by a space
1454			return str;
1455		},
1456		_reorderMenu: function() {
1457			if ( $('#wp-admin-bar-fl-builder-frontend-edit-link-default li').length > 1 ) {
1458					$( '#wp-admin-bar-fl-builder-frontend-duplicate-link' )
1459					.appendTo('#wp-admin-bar-fl-builder-frontend-edit-link-default')
1460					.css( 'padding-top', '5px' )
1461					.css( 'border-top', '2px solid #1D2125' )
1462					.css( 'margin-top', '5px' )
1463				}
1464		}
1465	};
1466
1467	/* Initializes the builder layout. */
1468	$(function(){
1469		FLBuilderLayout.init();
1470	});
1471
1472})(jQuery);
1473
1474/* Start Global JS */
1475
1476/* End Global JS */
1477
1478
1479/**
1480 * This file should contain frontend logic for 
1481 * all module instances.
1482 */
1483(function($) {
1484
1485	function equalheight() {
1486
1487		if( window.navigator.userAgent.indexOf( 'MSIE ' ) > 0 ) {
1488			return;
1489		}
1490
1491		var maxHeight = 0;
1492		$('.fl-node-zxd924ua5ohq .pp-logos-wrapper .pp-logo').each(function(index) {
1493			if(($(this).find('.logo-image').outerHeight() + 0) > maxHeight) {
1494				maxHeight = $(this).find('.logo-image').outerHeight() + 0;
1495			}
1496		});
1497		$('.fl-node-zxd924ua5ohq .pp-logos-wrapper .pp-logo').css('height', maxHeight + 'px');
1498
1499				return maxHeight;
1500	}
1501
1502	$('.fl-node-zxd924ua5ohq .pp-logos-wrapper').imagesLoaded(function() {
1503			// Clear the controls in case they were already created.
1504		//$('.fl-node-zxd924ua5ohq .logo-slider-next').empty();
1505		//$('.fl-node-zxd924ua5ohq .logo-slider-prev').empty();
1506
1507		var getMinSlides = function() {
1508			var minSlides = ( $( window ).width() <= 768 ) ? parseInt( $( '.fl-node-zxd924ua5ohq' ).width() / 325) : 4;
1509
1510						if ( window.innerWidth <= 1200 ) {
1511				minSlides = 4;
1512			}
1513									if ( window.innerWidth <= 992 ) {
1514				minSlides = 4;
1515			}
1516									if ( window.innerWidth <= 768 ) {
1517				minSlides = 4;
1518			}
1519			
1520			minSlides = (minSlides === 0) ? 1 : minSlides;
1521
1522			return minSlides;
1523		}
1524
1525		var minSlides = getMinSlides();
1526
1527		var maxSlides = minSlides;
1528		var moveSlides = maxSlides;
1529
1530		
1531		var totalSlides = minSlides - 1;
1532
1533		$(window).on('resize', function() {
1534			minSlides = getMinSlides();
1535			maxSlides = minSlides;
1536			moveSlides = maxSlides;
1537
1538			
1539			totalSlides = minSlides - 1;
1540		});
1541
1542		
1543				//equalheight();
1544		
1545		var totalSlides = $('.fl-node-zxd924ua5ohq .pp-logo:not(.bx-clone)').length;
1546
1547		var options = {
1548							slideWidth: 250,
1549						moveSlides: moveSlides,
1550			slideMargin: 25,
1551			minSlides: minSlides,
1552			maxSlides: maxSlides,
1553			autoStart : 1,
1554			auto : true,
1555			autoHover: false,
1556			adaptiveHeight: false,
1557			pause : 4000,
1558			mode : 'horizontal',
1559			speed : 500,
1560			pager : 0,
1561			controls: false,
1562			ariaLive: false,
1563			onSliderLoad: function() {
1564				$('.fl-node-zxd924ua5ohq .pp-logos-wrapper').addClass('pp-logos-wrapper-loaded');
1565				$('.fl-node-zxd924ua5ohq .pp-logo').attr('role', 'group');
1566
1567				var visibleCount = 0;
1568				$('.fl-node-zxd924ua5ohq .pp-logo').each(function() {
1569					if ( ! $(this).hasClass( 'bx-clone' ) ) {
1570						visibleCount++;
1571						$(this).attr('aria-label', 'Slide ' + visibleCount + ' of ' + totalSlides );
1572					}
1573				});
1574
1575				setTimeout( function() {
1576					$(window).trigger('resize');
1577				}, 200 );
1578
1579				$(document).trigger( 'pp_logos_on_slider_load', [ $('.fl-node-zxd924ua5ohq') ] );
1580			},
1581			onSlideBefore: function( ele, oldIndex, newIndex ) {
1582				this.stopAuto( true );
1583				$('.fl-node-zxd924ua5ohq .logo-slider-nav').addClass('disabled');
1584				$('.fl-node-zxd924ua5ohq .bx-controls .bx-pager-link').addClass('disabled');
1585								this.startAuto( true );
1586				
1587				var visibleCount = 0;
1588				$('.fl-node-zxd924ua5ohq .pp-logo').each(function() {
1589					if ( ! $(this).hasClass( 'bx-clone' ) ) {
1590						visibleCount++;
1591						$(this).attr('aria-label', 'Slide ' + visibleCount + ' of ' + totalSlides );
1592					}
1593				});
1594			},
1595			onSlideAfter: function( ele, oldIndex, newIndex ) {
1596				$('.fl-node-zxd924ua5ohq .logo-slider-nav').removeClass('disabled');
1597				$('.fl-node-zxd924ua5ohq .bx-controls .bx-pager-link').removeClass('disabled');
1598			}
1599		};
1600
1601		options.onSliderResize = function(currentIndex) {
1602			options.working = false;
1603			options.minSlides = minSlides;
1604			options.maxSlides = maxSlides;
1605			options.moveSlides = moveSlides;
1606
1607			this.reloadSlider( options );
1608		};
1609
1610		// Create the slider.
1611		var slider = $('.fl-node-zxd924ua5ohq .pp-logos-wrapper').bxSlider( options );
1612
1613		// Store a reference to the slider.
1614		slider.data('bxSlider', slider);
1615
1616
1617		
1618		
1619	
1620			});
1621
1622})(jQuery);
1623jQuery(function($) {
1624	
1625		$(function() {
1626		$( '.fl-node-64e7ceb8d8404 .fl-photo-img' )
1627			.on( 'mouseenter', function( e ) {
1628				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
1629			} )
1630			.on( 'mouseleave', function( e ){
1631				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
1632			} );
1633	});
1634		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
1635});
1636jQuery(function($) {
1637	
1638		$(function() {
1639		$( '.fl-node-64e7ceb8d8403 .fl-photo-img' )
1640			.on( 'mouseenter', function( e ) {
1641				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
1642			} )
1643			.on( 'mouseleave', function( e ){
1644				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
1645			} );
1646	});
1647		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
1648});
1649jQuery(function($) {
1650	
1651		$(function() {
1652		$( '.fl-node-64e7ceb8d8402 .fl-photo-img' )
1653			.on( 'mouseenter', function( e ) {
1654				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
1655			} )
1656			.on( 'mouseleave', function( e ){
1657				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
1658			} );
1659	});
1660		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
1661});
1662jQuery(function($) {
1663	
1664		$(function() {
1665		$( '.fl-node-64e7ceb8d8401 .fl-photo-img' )
1666			.on( 'mouseenter', function( e ) {
1667				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
1668			} )
1669			.on( 'mouseleave', function( e ){
1670				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
1671			} );
1672	});
1673		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
1674});
1675
1676(function($) {
1677
1678	/**
1679	 * Class for Menu Module
1680	 *
1681	 * @since 1.6.1
1682	 */
1683	FLBuilderMenu = function( settings ){
1684
1685		// set params
1686		this.nodeId              = settings.id;
1687		this.nodeClass           = '.fl-node-' + settings.id;
1688		this.wrapperClass        = this.nodeClass + ' .fl-menu';
1689		this.type				 = settings.type;
1690		this.mobileToggle		 = settings.mobile;
1691		this.mobileBelowRow		 = settings.mobileBelowRow;
1692		this.mobileFlyout		 = settings.mobileFlyout;
1693		this.breakPoints         = settings.breakPoints;
1694		this.mobileBreakpoint	 = settings.mobileBreakpoint;
1695		this.currentBrowserWidth = $( window ).width();
1696		this.postId              = settings.postId;
1697		this.mobileStacked       = settings.mobileStacked;
1698
1699		// initialize the menu
1700		this._initMenu();
1701
1702		// check if viewport is resizing
1703		$( window ).on( 'resize', $.proxy( function( e ) {
1704
1705			var width = $( window ).width();
1706
1707			// if screen width is resized, reload the menu
1708		    if( width != this.currentBrowserWidth ){
1709
1710				this.currentBrowserWidth = width;
1711				this._initMenu();
1712 				this._clickOrHover();
1713			}
1714
1715		}, this ) );
1716
1717		$( 'body' ).on( 'click', $.proxy( function( e ) {
1718			if ( 'undefined' !== typeof FLBuilderConfig ){
1719				return;
1720			}
1721
1722			var activeMobileMenu = $(this.wrapperClass + ' .fl-menu-mobile-toggle.fl-active' );
1723			if ( activeMobileMenu.length && ( 'expanded' !== this.mobileToggle ) ){
1724				$( activeMobileMenu ).trigger('click');
1725			}
1726
1727			$( this.wrapperClass ).find( '.fl-has-submenu' ).removeClass( 'focus' );
1728			$( this.wrapperClass ).find( '.fl-has-submenu .sub-menu' ).removeClass( 'focus' );
1729
1730		}, this ) );
1731
1732		// Close Mobile menu when tabbing out from the last menu item.
1733		$( this.wrapperClass + ' ul.menu > li:last-child' ).on( 'focusout', $.proxy(function (e) {
1734			if ( $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).hasClass( 'fl-active' ) && ( 'expanded' !== this.mobileToggle ) ) {
1735				if ( ! $( e.relatedTarget ).parent().hasClass( 'menu-item' ) ) {
1736					$( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).trigger( 'click' );	
1737				}
1738			}
1739		}, this ) );
1740
1741	};
1742
1743	FLBuilderMenu.prototype = {
1744		nodeClass               : '',
1745		wrapperClass            : '',
1746		type 	                : '',
1747		breakPoints 			: {},
1748		$submenus				: null,
1749
1750		/**
1751		 * Check if the screen size fits a mobile viewport.
1752		 *
1753		 * @since  1.6.1
1754		 * @return bool
1755		 */
1756		_isMobile: function(){
1757			return this.currentBrowserWidth <= this.breakPoints.small ? true : false;
1758		},
1759
1760		/**
1761		 * Check if the screen size fits a medium viewport.
1762		 *
1763		 * @since  1.10.5
1764		 * @return bool
1765		 */
1766		_isMedium: function(){
1767			return this.currentBrowserWidth <= this.breakPoints.medium ? true : false;
1768		},
1769
1770		/**
1771		 * Check if the screen size fits a large viewport.
1772		 *
1773		 * @since  1.10.5
1774		 * @return bool
1775		 */
1776		_isLarge: function(){
1777			return this.currentBrowserWidth <= this.breakPoints.large ? true : false;
1778		},
1779
1780		/**
1781		 * Check if the menu should toggle for the current viewport base on the selected breakpoint
1782		 *
1783		 * @see 	this._isMobile()
1784		 * @see 	this._isMedium()
1785		 * @since  	1.10.5
1786		 * @return bool
1787		 */
1788		_isMenuToggle: function(){
1789			if ( ( 'always' == this.mobileBreakpoint
1790				|| ( this._isMobile() && 'mobile' == this.mobileBreakpoint )
1791				|| ( this._isMedium() && 'medium-mobile' == this.mobileBreakpoint )
1792				|| ( this._isLarge() && 'large-mobile' == this.mobileBreakpoint )
1793			) && ( $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).is(':visible') || 'expanded' == this.mobileToggle ) ) {
1794				return true;
1795			}
1796
1797			return false;
1798		},
1799
1800		/**
1801		 * Initialize the toggle logic for the menu.
1802		 *
1803		 * @see    this._isMenuToggle()
1804		 * @see    this._menuOnCLick()
1805		 * @see    this._clickOrHover()
1806		 * @see    this._submenuOnRight()
1807		 * @see    this._submenuRowZindexFix()
1808		 * @see    this._toggleForMobile()
1809		 * @since  1.6.1
1810		 * @return void
1811		 */
1812		_initMenu: function(){
1813			this._setupSubmenu();
1814			this._menuOnFocus();
1815			this._menuOnEscape();
1816			this._submenuOnClick();
1817			if ( $( this.nodeClass ).length && this.type == 'horizontal' ) {
1818				this._initMegaMenus();
1819			}
1820
1821			if( this._isMenuToggle() || this.type == 'accordion' ){
1822
1823				$( this.wrapperClass ).off( 'mouseenter mouseleave' );
1824				this._menuOnClick();
1825				this._clickOrHover();
1826
1827			} else {
1828				$( this.wrapperClass ).off( 'click' );
1829				this._submenuOnRight();
1830				this._submenuRowZindexFix();
1831			}
1832
1833			if( this.mobileToggle != 'expanded' ){
1834				this._toggleForMobile();
1835			}
1836
1837			if( $( this.wrapperClass ).find( '.fl-menu-search-item' ).length ){
1838				this._toggleMenuSearch();
1839			}
1840
1841			if( $( this.wrapperClass ).find( '.fl-menu-cart-item').length ){
1842				this._wooUpdateParams();
1843			}
1844		},
1845
1846		/**
1847		 * Initializes submenu dropdowns.
1848		 *
1849		 * @since 3.0
1850		 * @return void
1851		 */
1852		_setupSubmenu: function() {
1853			$( this.wrapperClass + ' ul.sub-menu' ).each( function(){
1854				$( this ).closest( 'li' ).attr( 'aria-haspopup', 'true' );
1855			});
1856		},
1857
1858		/**
1859		 * Adds a focus class to menu elements similar to be used similar to CSS :hover psuedo event
1860		 *
1861		 * @since  1.9.0
1862		 * @return void
1863		 */
1864		_menuOnFocus: function(){
1865			var cKey      = 0,
1866			    isShifted = false;
1867
1868			$( this.nodeClass ).off('keydown').on( 'keydown', 'a', function( e ){
1869				cKey      = e.which;
1870				isShifted = e.shiftKey;
1871			});
1872
1873			$( this.nodeClass ).off('focus').on( 'focus', 'a', $.proxy( function( e ){
1874				var $menuItem	= $( e.target ).parents( '.menu-item' ).first(),
1875					$parents	= $( e.target ).parentsUntil( this.wrapperClass );
1876
1877				$('.fl-menu .focus').removeClass('focus');
1878
1879				$parents.addClass('focus')
1880
1881				if ( ! $menuItem.closest('.fl-has-submenu').hasClass('escaped') ) {
1882					$menuItem.addClass('focus')
1883				}
1884				else {
1885					$menuItem.closest('.fl-has-submenu').removeClass('focus escaped')
1886				}
1887			}, this ) ).on( 'focusout', 'a', $.proxy( function( e ){
1888				var el            = $(e.target).parent(),
1889		            $megaMenu     = el.closest( '.mega-menu' ),
1890		            $megaLastItem = $megaMenu.find('> .sub-menu > .menu-item:last-child'),
1891					$lastItem     = el.parents('.fl-has-submenu:last').find('.menu-item:last'),
1892					isLastChild   = ! $megaMenu.length && el.is( $lastItem );
1893
1894		        if( $megaMenu.length ) {
1895					isLastChild = el.is( $megaLastItem ) || el.is( $megaLastItem.find( '.menu-item:last-child' ) );
1896				}
1897
1898				if ( isLastChild && cKey === 9 && isShifted ) {
1899					isLastChild = false;
1900					cKey       = 0;
1901					isShifted  = false;
1902				}
1903				else if ( cKey === 27 ) {
1904					isLastChild = false;
1905				}
1906
1907				if ( isLastChild ) {
1908					$( e.target ).parentsUntil( this.wrapperClass ).removeClass( 'focus' );
1909				}
1910
1911			}, this ) );
1912		},
1913
1914		/**
1915		 * Logic for submenu items when Escape key is pressed.
1916		 *
1917		 * @since  2.7.1
1918		 * @return void
1919		 */
1920		_menuOnEscape: function(){
1921			$( 'body' ).off('keydown').on( 'keydown', $.proxy( function( e ){
1922				if ( e.which !== 27 ) {
1923					return;
1924				}
1925
1926				if ( $( e.target ).closest('.menu-item').length ) {
1927					var activeSubmenu = null,
1928						menuItem      = $( e.target ).closest('.menu-item'),
1929						type          = menuItem.closest('.fl-menu-accordion').length ? 'accordion' : 'horizontal';
1930
1931					if ( 'horizontal' === type ) {
1932						if ( menuItem.hasClass( 'fl-has-submenu' ) && menuItem.hasClass( 'focus' ) ) {
1933							activeSubmenu = menuItem.find('> ul.sub-menu');
1934						}
1935						else {
1936							activeSubmenu = menuItem.closest('ul.sub-menu');
1937						}
1938						activeSubmenu.parent().addClass('escaped');
1939						activeSubmenu.parent().find('a:first').focus();
1940					}
1941					else {
1942						if ( menuItem.hasClass( 'fl-has-submenu' ) && 'accordion' === type && menuItem.hasClass( 'fl-active' ) ) {
1943							activeSubmenu = menuItem.find('> ul.sub-menu');
1944						}
1945						else {
1946							activeSubmenu = menuItem.closest('ul.sub-menu');
1947						}
1948
1949						activeSubmenu.slideUp(400, function(){
1950							if ( menuItem.hasClass( 'fl-has-submenu' ) && menuItem.hasClass( 'fl-active' ) ) {
1951								activeSubmenu.parent().last().find('a:first').focus();
1952							}
1953							else {
1954								menuItem.removeClass('focus');
1955								menuItem.parents('.menu-item').first().find('a:first').focus();
1956							}
1957							activeSubmenu.parent().last().removeClass( 'fl-active' );
1958						});
1959
1960					}
1961				}
1962				else {
1963					$('.fl-menu').find( 'li.menu-item.focus' ).last().removeClass('focus');
1964				}
1965			}, this ) );
1966		},
1967
1968		/**
1969		 * Logic for submenu toggling on accordions or mobile menus (vertical, horizontal)
1970		 *
1971		 * @since  1.6.1
1972		 * @return void
1973		 */
1974		_menuOnClick: function(){
1975			$( this.wrapperClass ).off().on( 'click', '.fl-has-submenu-container', $.proxy( function( e ){
1976
1977				var $link			= $( e.target ).parents( '.fl-has-submenu' ).first(),
1978					$subMenu 		= $link.children( '.sub-menu' ).first(),
1979					$href	 		= $link.children('.fl-has-submenu-container').first().find('> a').attr('href'),
1980					$subMenuParents = $( e.target ).parents( '.sub-menu' ),
1981					$activeParents 	= $( e.target ).parents( '.fl-has-submenu.fl-active' );
1982
1983				if( !$subMenu.is(':visible') || $(e.target).hasClass('fl-menu-toggle')
1984					|| ($subMenu.is(':visible') && (typeof $href === 'undefined' || $href == '#')) ){
1985					e.preventDefault();
1986				}
1987				else {
1988					e.stopPropagation();
1989					window.location.href = $href;
1990					return;
1991				}
1992
1993				if ($(this.wrapperClass).hasClass('fl-menu-accordion-collapse')) {
1994
1995					if ( !$link.parents('.menu-item').hasClass('fl-active') ) {
1996						$('.menu .fl-active', this.wrapperClass).not($link).removeClass('fl-active');
1997					}
1998					else if ($link.parents('.menu-item').hasClass('fl-active') && $link.parent('.sub-menu').length) {
1999						$('.menu .fl-active', this.wrapperClass).not($link).not($activeParents).removeClass('fl-active');
2000					}
2001
2002					$('.sub-menu', this.wrapperClass).not($subMenu).not($subMenuParents).slideUp('normal');
2003				}
2004
2005				if ( ! this.mobileStacked && 'horizontal' == this.type && 'expanded' == this.mobileToggle ) {
2006					$( this.wrapperClass ).find( '.fl-active' ).not($link).not($activeParents).removeClass( 'fl-active' );
2007				}
2008				else {
2009					$subMenu.slideToggle();
2010				}
2011
2012				$link.toggleClass( 'fl-active' );
2013				e.stopPropagation();
2014
2015			}, this ) );
2016
2017		},
2018
2019		/**
2020		 * Logic for submenu items click event
2021		 *
2022		 * @since  1.10.6
2023		 * @return void
2024		 */
2025		_submenuOnClick: function(){
2026			$( this.wrapperClass + ' .sub-menu' ).off().on( 'click', 'a', $.proxy( function( e ){
2027				if ( $( e.target ).parent().hasClass('focus') ) {
2028					$( e.target ).parentsUntil( this.wrapperClass ).removeClass('focus');
2029				}
2030			}, this ) );
2031		},
2032
2033		/**
2034		 * Changes general styling and behavior of menus based on mobile / desktop viewport.
2035		 *
2036		 * @see    this._isMenuToggle()
2037		 * @since  1.6.1
2038		 * @return void
2039		 */
2040		_clickOrHover: function(){
2041			this.$submenus = this.$submenus || $( this.wrapperClass ).find( '.sub-menu' );
2042			var $wrapper   = $( this.wrapperClass ),
2043				$menu      = $wrapper.find( '.menu' );
2044				$li        = $wrapper.find( '.fl-has-submenu' );
2045
2046			if( this._isMenuToggle() ){
2047				$li.each( function( el ){
2048					if( !$(this).hasClass('fl-active') ){
2049						$(this).find( '.sub-menu' ).fadeOut();
2050					}
2051				} );
2052			} else {
2053				$li.each( function( el ){
2054					if( !$(this).hasClass('fl-active') ){
2055						$(this).find( '.sub-menu' ).css( {
2056							'display' : '',
2057							'opacity' : ''
2058						} );
2059					}
2060				} );
2061			}
2062		},
2063
2064		/**
2065		 * Logic to prevent submenus to go outside viewport boundaries.
2066		 *
2067		 * @since  1.6.1
2068		 * @return void
2069		 */
2070		_submenuOnRight: function(){
2071
2072			$( this.wrapperClass )
2073				.on( 'mouseenter focus', '.fl-has-submenu', $.proxy( function( e ){
2074
2075					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
2076						return;
2077					}
2078
2079					var $link           = $( e.currentTarget ),
2080						$parent         = $link.parent(),
2081						$subMenu        = $link.find( '.sub-menu' ),
2082						subMenuWidth    = $subMenu.width(),
2083						subMenuPos      = 0,
2084						bodyWidth       = $( 'body' ).width();
2085
2086					if( $link.closest( '.fl-menu-submenu-right' ).length !== 0) {
2087
2088						$link.addClass( 'fl-menu-submenu-right' );
2089
2090					} else if( $( 'body' ).hasClass( 'rtl' ) ) {
2091
2092						subMenuPos = $parent.is( '.sub-menu' ) ?
2093									 $parent.offset().left - subMenuWidth:
2094									 $link.offset().left - $link.width() - subMenuWidth;
2095
2096						if( subMenuPos <= 0 ) {
2097							$link.addClass( 'fl-menu-submenu-right' );
2098						}
2099
2100					} else {
2101
2102						subMenuPos = $parent.is( '.sub-menu' ) ?
2103									 $parent.offset().left + $parent.width() + subMenuWidth :
2104									 $link.offset().left + $link.width() + subMenuWidth;
2105
2106						if( subMenuPos > bodyWidth ) {
2107							$link.addClass('fl-menu-submenu-right');
2108						}
2109					}
2110				}, this ) )
2111				.on( 'mouseleave', '.fl-has-submenu', $.proxy( function( e ){
2112					$( e.currentTarget ).removeClass( 'fl-menu-submenu-right' );
2113				}, this ) );
2114
2115		},
2116
2117		/**
2118		 * Logic to prevent submenus to go behind the next overlay row.
2119		 *
2120		 * @since  1.10.9
2121		 * @return void
2122		 */
2123		_submenuRowZindexFix: function( e ){
2124
2125			$( this.wrapperClass )
2126				.on( 'mouseenter', 'ul.menu > .fl-has-submenu', $.proxy( function( e ){
2127
2128					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
2129						return;
2130					}
2131
2132					$( this.nodeClass )
2133						.closest( '.fl-row' )
2134						.find( '.fl-row-content' )
2135						.css( 'z-index', '10' );
2136
2137				}, this ) )
2138				.on( 'mouseleave', 'ul.menu > .fl-has-submenu', $.proxy( function( e ){
2139
2140					$( this.nodeClass )
2141						.closest( '.fl-row' )
2142						.find( '.fl-row-content' )
2143						.css( 'z-index', '' );
2144
2145				}, this ) );
2146		},
2147
2148		/**
2149		 * Logic for the mobile menu button.
2150		 *
2151		 * @since  1.6.1
2152		 * @return void
2153		 */
2154		_toggleForMobile: function(){
2155
2156			var $wrapper = null,
2157				$menu    = null,
2158				self     = this;
2159
2160			if( this._isMenuToggle() ){
2161
2162				if ( this._isMobileBelowRowEnabled() ) {
2163					this._placeMobileMenuBelowRow();
2164					$wrapper = $( this.wrapperClass );
2165					$menu    = $( this.nodeClass + '-clone' );
2166					$menu.find( 'ul.menu' ).show();
2167				}
2168				else {
2169					$wrapper = $( this.wrapperClass );
2170					$menu    = $wrapper.find( '.menu' );
2171				}
2172
2173				if( !$wrapper.find( '.fl-menu-mobile-toggle' ).hasClass( 'fl-active' ) && ! self.mobileFlyout ){
2174					$menu.css({ display: 'none' });
2175				}
2176
2177				// Flayout Menu
2178				if ( self.mobileFlyout ) {
2179					this._initFlyoutMenu();
2180				}
2181
2182				$wrapper.on( 'click', '.fl-menu-mobile-toggle', function( e ){
2183
2184					$( this ).toggleClass( 'fl-active' );
2185
2186					if ( self.mobileFlyout ) {
2187						self._toggleFlyoutMenu();
2188					}
2189					else {
2190						var targetMenu = null;
2191						
2192						if ( self.mobileBelowRow ) {
2193							targetMenu = $( this ).closest( '.fl-col' ).next( '.fl-menu-mobile-clone' );
2194						} else {
2195							targetMenu = $( this ).closest( '.fl-menu' ).find( 'ul.menu' );
2196						}
2197						
2198						if ( targetMenu.length ) {
2199							$menu = $( targetMenu );
2200						}
2201
2202						$menu.slideToggle();
2203					}
2204
2205					e.stopPropagation();
2206				} );
2207
2208				// Hide active menu when click on anchor link ID that exists on a page.
2209				$menu.off().on( 'click', '.menu-item > a[href*="#"]:not([href="#"])', function(e){
2210					var $href = $(this).attr('href'),
2211						$targetID = $href.split('#')[1],
2212						element = $('#' + $targetID);
2213					if ( $('body').find(element).length > 0 ) {
2214						$( this ).toggleClass( 'fl-active' );
2215						FLBuilderLayout._scrollToElement( element );
2216						if ( ! self._isMenuToggle() ) {
2217							$menu.slideToggle();
2218						}
2219					}
2220				});
2221			}
2222			else {
2223
2224				if ( this._isMobileBelowRowEnabled() ) {
2225					this._removeMenuFromBelowRow();
2226				}
2227
2228				$wrapper = $( this.wrapperClass ),
2229				$menu    = $wrapper.find( 'ul.menu' );
2230				$wrapper.find( '.fl-menu-mobile-toggle' ).removeClass( 'fl-active' );
2231				$menu.css({ display: '' });
2232
2233				if ( ! this._isMobileBelowRowEnabled() ) {
2234					$menu.off( 'click', '.menu-item > a[href*="#"]:not([href="#"])' );
2235				}
2236
2237				if ( this.mobileFlyout && $wrapper.find( '.fl-menu-mobile-flyout' ).length > 0 ) {
2238					$( 'body' ).css( 'margin', '' );
2239					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
2240					$menu.unwrap();
2241					$wrapper.find( '.fl-menu-mobile-close' ).remove();
2242					$wrapper.find( '.fl-menu-mobile-opacity' ).remove();
2243				}
2244			}
2245		},
2246
2247		/**
2248		 * Init any mega menus that exist.
2249		 *
2250		 * @see 	this._isMenuToggle()
2251		 * @since  	1.10.4
2252		 * @return void
2253		 */
2254		_initMegaMenus: function(){
2255
2256			var module     = $( this.nodeClass ),
2257				rowContent = module.closest( '.fl-row-content' ),
2258				rowWidth   = rowContent.width(),
2259				megas      = module.find( '.mega-menu' ),
2260				disabled   = module.find( '.mega-menu-disabled' ),
2261				isToggle   = this._isMenuToggle();
2262
2263			if ( isToggle ) {
2264				megas.removeClass( 'mega-menu' ).addClass( 'mega-menu-disabled' );
2265				module.find( 'li.mega-menu-disabled > ul.sub-menu' ).css( 'width', '' );
2266				rowContent.css( 'position', '' );
2267			} else {
2268				disabled.removeClass( 'mega-menu-disabled' ).addClass( 'mega-menu' );
2269				module.find( 'li.mega-menu > ul.sub-menu' ).css( 'width', rowWidth + 'px' );
2270				rowContent.css( 'position', 'relative' );
2271			}
2272		},
2273
2274		/**
2275		 * Check to see if Below Row should be enabled.
2276		 *
2277		 * @since  	1.11
2278		 * @return boolean
2279		 */
2280		_isMobileBelowRowEnabled: function() {
2281			return this.mobileBelowRow && $( this.nodeClass ).closest( '.fl-col' ).length;
2282		},
2283
2284		/**
2285		 * Logic for putting the mobile menu below the menu's
2286		 * column so it spans the full width of the page.
2287		 *
2288		 * @since  1.10
2289		 * @return void
2290		 */
2291		_placeMobileMenuBelowRow: function(){
2292
2293			if ( $( this.nodeClass + '-clone' ).length ) {
2294				return;
2295			}
2296
2297			var module = $( this.nodeClass ),
2298				clone  = null,
2299				col    = module.closest( '.fl-col' );
2300
2301			if ( module.length < 1 ) {
2302				return;
2303			}
2304
2305			clone = ( module.length > 1 ) ? $( module[0] ).clone() : module.clone();
2306			module.find( 'ul.menu' ).remove();
2307			clone.addClass( ( this.nodeClass + '-clone' ).replace( '.', '' ) );
2308			clone.addClass( 'fl-menu-mobile-clone' );
2309			clone.find( '.fl-menu-mobile-toggle' ).remove();
2310			col.after( clone );
2311
2312			// Removes animation when enabled.
2313			if ( module.hasClass( 'fl-animation' ) ) {
2314				clone.removeClass( 'fl-animation' );
2315			}
2316
2317			this._menuOnClick();
2318		},
2319
2320		/**
2321		 * Logic for removing the mobile menu from below the menu's
2322		 * column and putting it back in the main wrapper.
2323		 *
2324		 * @since  1.10
2325		 * @return void
2326		 */
2327		_removeMenuFromBelowRow: function(){
2328
2329			if ( ! $( this.nodeClass + '-clone' ).length ) {
2330				return;
2331			}
2332
2333			var module = $( this.nodeClass ),
2334				clone  = $( this.nodeClass + '-clone' ),
2335				menu   = clone.find( 'ul.menu' );
2336
2337			module.find( '.fl-menu-mobile-toggle' ).after( menu );
2338			clone.remove();
2339			menu.find( 'a' ).each( FLBuilderLayout._initAnchorLink );
2340		},
2341
2342		/**
2343		 * Logic for Flyout responsive menu.
2344		 *
2345		 * @since 2.2
2346		 * @return void
2347		 */
2348		_initFlyoutMenu: function(){
2349			var win     = $( window ),
2350				wrapper = $( this.wrapperClass ),
2351				menu  	= wrapper.find( 'ul.menu' ),
2352				button	= wrapper.find( '.fl-menu-mobile-toggle' );
2353
2354			if ( 0 === wrapper.find( '.fl-menu-mobile-flyout' ).length ) {
2355				menu.wrap( '<div class="fl-menu-mobile-flyout"></div>' );
2356			}
2357
2358			if ( 0 === wrapper.find( '.fl-menu-mobile-close' ).length ) {
2359				close = window.fl_responsive_close || 'Close'
2360				wrapper.find( '.fl-menu-mobile-flyout' )
2361					.prepend( '<button class="fl-menu-mobile-close" aria-label="' + close + '"><i class="fas fa-times" aria-hidden="true"></i></button>' );
2362			}
2363
2364			// Push with opacity
2365			if ( wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ) && 0 === wrapper.find( '.fl-menu-mobile-opacity' ).length ) {
2366				wrapper.append( '<div class="fl-menu-mobile-opacity"></div>' );
2367			}
2368
2369			wrapper.on( 'click', '.fl-menu-mobile-opacity, .fl-menu-mobile-close', function(e){
2370				button.trigger( 'click' );
2371				e.stopPropagation();
2372			});
2373
2374			if ( 'undefined' !== typeof FLBuilder ) {
2375				FLBuilder.addHook('restartEditingSession', function(){
2376					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
2377
2378					// Toggle active menu.
2379					if ( button.hasClass( 'fl-active' ) ) {
2380						button.trigger( 'click' );
2381					}
2382				});
2383			}
2384		},
2385
2386		/**
2387		 * Logic to enable/disable the Flyout menu on button click.
2388		 *
2389		 * @since 2.2
2390		 * @return void
2391		 */
2392		_toggleFlyoutMenu: function(){
2393			var wrapper		= $( this.wrapperClass ),
2394				button		= wrapper.find( '.fl-menu-mobile-toggle' ),
2395				wrapFlyout	= wrapper.find( '.fl-menu-mobile-flyout' ),
2396				position 	= wrapper.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
2397				pushMenu 	= wrapper.hasClass( 'fl-menu-responsive-flyout-push' ) || wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
2398				opacity		= wrapper.find( '.fl-menu-mobile-opacity' ),
2399				marginPos	= {},
2400				posAttr		= {},
2401				fixedPos 	= {},
2402				winHeight	= $(window).height(),
2403				fixedHeader	= $('header, header > div');
2404
2405			if ( button.hasClass( 'fl-active' ) ) {
2406				posAttr[ position ]  = '0px';
2407				posAttr[ 'height' ]  = winHeight + 'px';
2408			} else {
2409				posAttr[ position ]  = '-267px';
2410			}
2411
2412			wrapFlyout.css( posAttr );
2413
2414			// Fix the push menu when builder ui panel is pinned.
2415			if ( $( '.fl-builder-ui-pinned-content-transform' ).length > 0 && ! $( 'body' ).hasClass( 'fl-builder-edit' ) ) {
2416				$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', 'none' );
2417			}
2418
2419			if ( pushMenu ) {
2420				marginPos[ 'margin-' + position ] = button.hasClass( 'fl-active' ) ? '250px' : '0px';
2421				$( 'body' ).animate( marginPos, 200);
2422
2423				// Fixed header
2424				if ( fixedHeader.length > 0 ) {
2425					fixedPos[ position] = button.hasClass( 'fl-active' ) ? '250px' : '0px';
2426					fixedHeader.each(function(){
2427						if ( 'fixed' == $( this ).css( 'position' ) ) {
2428							$( this ).css({
2429								'-webkit-transition': 'none',
2430								'-o-transition'		: 'none',
2431								'transition'		: 'none'
2432							});
2433							$( this ).animate( fixedPos, 200 );
2434						}
2435					});
2436				}
2437			}
2438
2439			if ( opacity.length > 0 && button.hasClass( 'fl-active' ) ) {
2440				opacity.show();
2441			}
2442			else {
2443				opacity.hide();
2444			}
2445		},
2446
2447		/**
2448		 * Shows or hides the nav search form.
2449		 *
2450		 * @since 2.5
2451		 * @method _toggleMenuSearch
2452		 */
2453		_toggleMenuSearch: function(){
2454			var wrapper = $( this.wrapperClass ).find('.fl-menu-search-item'),
2455				button  = wrapper.find('a.fl-button'),
2456				form    = wrapper.find('.fl-search-form-input-wrap'),
2457				self    = this;
2458
2459			button.on('click', function(e){
2460				e.preventDefault();
2461
2462				if(form.is(':visible')) {
2463					form.stop().fadeOut(200);
2464				}
2465				else {
2466					form.stop().fadeIn(200);
2467					$('body').on('click.fl-menu-search', $.proxy(self._hideMenuSearch, self));
2468					form.find('.fl-search-text').focus();
2469				}
2470			});
2471		},
2472
2473		/**
2474		 * Hides the nav search form.
2475		 *
2476		 * @since 2.5
2477		 * @method _hideMenuSearch
2478		 */
2479		_hideMenuSearch: function(e){
2480			var form = $( this.wrapperClass ).find('.fl-search-form-input-wrap');
2481
2482			if(e !== undefined) {
2483				if($(e.target).closest('.fl-menu-search-item').length > 0) {
2484					return;
2485				}
2486			}
2487
2488			form.stop().fadeOut(200);
2489			$('body').off('click.fl-menu-search');
2490		},
2491
2492		/**
2493		 * Adds menu node and post ID to WooCommerce ajax URL requests.
2494		 *
2495		 * @since  3.0
2496		 * @return void
2497		 */
2498		_wooUpdateParams: function() {
2499			if ( 'undefined' !== typeof wc_cart_fragments_params ) {
2500				wc_cart_fragments_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
2501			}
2502			if ( 'undefined' !== typeof wc_add_to_cart_params ) {
2503				wc_add_to_cart_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
2504			}
2505		},
2506	};
2507
2508})(jQuery);
2509
2510(function($) {
2511
2512	$(function() {
2513
2514		new FLBuilderMenu({
2515			id: '6390024adc4a9',
2516			type: 'horizontal',
2517			mobile: 'hamburger',
2518			mobileBelowRow: false,
2519			mobileFlyout: false,
2520			breakPoints: {
2521				large: 1200,
2522				medium: 992,
2523				small: 768			},
2524			mobileBreakpoint: 'mobile',
2525			postId : '400',
2526			mobileStacked: true,
2527		});
2528
2529	});
2530
2531})(jQuery);
2532jQuery(function($) {
2533	
2534		$(function() {
2535		$( '.fl-node-63744d7f7a670 .fl-photo-img' )
2536			.on( 'mouseenter', function( e ) {
2537				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
2538			} )
2539			.on( 'mouseleave', function( e ){
2540				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
2541			} );
2542	});
2543		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
2544});
2545
2546/**
2547 * This file should contain frontend logic for 
2548 * all module instances.
2549 */jQuery(function($) {
2550	
2551		$(function() {
2552		$( '.fl-node-5a3bf56067287 .fl-photo-img' )
2553			.on( 'mouseenter', function( e ) {
2554				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
2555			} )
2556			.on( 'mouseleave', function( e ){
2557				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
2558			} );
2559	});
2560		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
2561});
2562
2563/* Start Global Node Custom JS */
2564
2565/* End Global Node Custom JS */
2566
2567
2568/* Start Layout Custom JS */
2569
2570/* End Layout Custom JS */
2571

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.