PageSourceSearch

https://assets.shepherdess.co.nz/uploads/bb-plugin/cache/81359e972…71049-layout-bundle.js?ver=2.10.0.6-1.5.2.1

js shepherdess.co.nz collected 2026-09-29 12:14:07 UTC 124,855 bytes, 4,220 lines download raw bytes

1var wpAjaxUrl = 'https://shepherdess.co.nz/wp-admin/admin-ajax.php';var flBuilderUrl = 'https://shepherdess.co.nz/wp-content/plugins/bb-plugin/';var FLBuilderLayoutConfig = {
2	anchorLinkAnimations : {
3		duration 	: 1000,
4		easing		: 'swing',
5		offset 		: 100
6	},
7	paths : {
8		pluginUrl : 'https://shepherdess.co.nz/wp-content/plugins/bb-plugin/',
9		wpAjaxUrl : 'https://shepherdess.co.nz/wp-admin/admin-ajax.php'
10	},
11	breakpoints : {
12		small  : 768,
13		medium : 1024,
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 buttons.
52			FLBuilderLayout._initButtons();
53
54			// Init row shape layer height.
55			FLBuilderLayout._initRowShapeLayerHeight();
56
57			// Only init if the builder isn't active.
58			if ( 0 === $('.fl-builder-edit').length ) {
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			$('body').removeClass( 'fl-no-js' );
75		},
76
77		/**
78		 * Public method for refreshing Wookmark or MosaicFlow galleries
79		 * within an element.
80		 *
81		 * @since 1.7.4
82		 * @method refreshGalleries
83		 */
84		refreshGalleries: function( element )
85		{
86			var $element  = 'undefined' == typeof element ? $( 'body' ) : $( element ),
87				mfContent = $element.find( '.fl-mosaicflow-content' ),
88				wmContent = $element.find( '.fl-gallery' ),
89				mfObject  = null;
90
91			if ( mfContent ) {
92
93				mfObject = mfContent.data( 'mosaicflow' );
94
95				if ( mfObject ) {
96					mfObject.columns = $( [] );
97					mfObject.columnsHeights = [];
98					mfContent.data( 'mosaicflow', mfObject );
99					mfContent.mosaicflow( 'refill' );
100				}
101			}
102			if ( wmContent ) {
103				wmContent.trigger( 'refreshWookmark' );
104			}
105		},
106
107		/**
108		 * Public method for refreshing Masonry within an element
109		 *
110		 * @since 1.8.1
111		 * @method refreshGridLayout
112		 */
113		refreshGridLayout: function( element )
114		{
115			var $element 		= 'undefined' == typeof element ? $( 'body' ) : $( element ),
116				msnryContent	= $element.find('.masonry');
117
118			if ( msnryContent.length )	{
119				msnryContent.masonry('layout');
120			}
121		},
122
123		/**
124		 * Public method for reloading BxSlider within an element
125		 *
126		 * @since 1.8.1
127		 * @method reloadSlider
128		 */
129		reloadSlider: function( content )
130		{
131			var $content = 'undefined' == typeof content ? $('body') : $(content);
132
133			// reload sliders.
134			if ($content.find('.bx-viewport > div').length > 0) {
135				$.each($content.find('.bx-viewport > div'), function (key, slider) {
136					setTimeout(function () {
137						$(slider).data('bxSlider').reloadSlider();
138					}, 100);
139				});
140			}
141		},
142
143		/**
144		 * Public method for resizing WP audio player
145		 *
146		 * @since 1.8.2
147		 * @method resizeAudio
148		 */
149		resizeAudio: function( element )
150		{
151			var $element 	 	= 'undefined' == typeof element ? $( 'body' ) : $( element ),
152				audioPlayers 	= $element.find('.wp-audio-shortcode.mejs-audio'),
153				player 		 	= null,
154				mejsPlayer 	 	= null,
155				rail 			= null,
156				railWidth 		= 400;
157
158			if ( audioPlayers.length && typeof mejs !== 'undefined' ) {
159            	audioPlayers.each(function(){
160	            	player 		= $(this);
161	            	mejsPlayer 	= mejs.players[player.attr('id')];
162	            	rail 		= player.find('.mejs-controls .mejs-time-rail');
163	            	var innerMejs = player.find('.mejs-inner'),
164	            		total 	  = player.find('.mejs-controls .mejs-time-total');
165
166	            	if ( typeof mejsPlayer !== 'undefined' ) {
167	            		railWidth = Math.ceil(player.width() * 0.8);
168
169	            		if ( innerMejs.length ) {
170
171		            		rail.css('width', railWidth +'px!important');
172		            		//total.width(rail.width() - 10);
173
174		            		mejsPlayer.options.autosizeProgress = true;
175
176		            		// webkit has trouble doing this without a delay
177							setTimeout(function () {
178								mejsPlayer.setControlsSize();
179							}, 50);
180
181			            	player.find('.mejs-inner').css({
182			            		visibility: 'visible',
183			            		height: 'inherit'
184			            	});
185		            	}
186		           	}
187	            });
188	        }
189		},
190
191		/**
192		 * Public method for preloading WP audio player when it's inside the hidden element
193		 *
194		 * @since 1.8.2
195		 * @method preloadAudio
196		 */
197		preloadAudio: function(element)
198		{
199			var $element 	 = 'undefined' == typeof element ? $( 'body' ) : $( element ),
200				contentWrap  = $element.closest('.fl-accordion-item'),
201				audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio');
202
203			if ( ! contentWrap.hasClass('fl-accordion-item-active') && audioPlayers.find('.mejs-inner').length ) {
204				audioPlayers.find('.mejs-inner').css({
205					visibility : 'hidden',
206					height: 0
207				});
208			}
209		},
210
211		/**
212		 * Public method for resizing slideshow momdule within the tab
213		 *
214		 * @since 1.10.5
215		 * @method resizeSlideshow
216		 */
217		resizeSlideshow: function(){
218			if(typeof YUI !== 'undefined') {
219				YUI().use('node-event-simulate', function(Y) {
220					Y.one(window).simulate("resize");
221				});
222			}
223		},
224
225		/**
226		 * Public method for reloading an embedded Google Map within the tabs or hidden element.
227		 *
228		 * @since 2.2
229		 * @method reloadGoogleMap
230		 */
231		reloadGoogleMap: function(element){
232			var $element  = 'undefined' == typeof element ? $( 'body' ) : $( element ),
233			    googleMap = $element.find( 'iframe[src*="google.com/maps"]' );
234
235			if ( googleMap.length ) {
236			    googleMap.attr( 'src', function(i, val) {
237			        return val;
238			    });
239			}
240		},
241
242		/**
243		 * Unbinds builder layout events.
244		 *
245		 * @since 1.0
246		 * @access private
247		 * @method _destroy
248		 */
249		_destroy: function()
250		{
251			var win = $(window);
252
253			win.off('scroll.fl-bg-parallax');
254			win.off('resize.fl-bg-video');
255		},
256
257		/**
258		 * Checks to see if the current device has touch enabled.
259		 *
260		 * @since 1.0
261		 * @access private
262		 * @method _isTouch
263		 * @return {Boolean}
264		 */
265		_isTouch: function()
266		{
267			if(('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) {
268				return true;
269			}
270
271			return false;
272		},
273
274		/**
275		 * Checks to see if the current device is mobile.
276		 *
277		 * @since 1.7
278		 * @access private
279		 * @method _isMobile
280		 * @return {Boolean}
281		 */
282		_isMobile: function()
283		{
284			return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent );
285		},
286
287		/**
288		 * Initializes builder body classes.
289		 *
290		 * @since 1.0
291		 * @access private
292		 * @method _initClasses
293		 */
294		_initClasses: function()
295		{
296			var body = $( 'body' ),
297				ua   = navigator.userAgent;
298
299			// Add the builder body class.
300			if ( ! body.hasClass( 'archive' ) && $( '.fl-builder-content-primary' ).length > 0 ) {
301				body.addClass('fl-builder');
302			}
303
304			// Add the builder touch body class.
305			if(FLBuilderLayout._isTouch()) {
306				body.addClass('fl-builder-touch');
307			}
308
309			// Add the builder mobile body class.
310			if(FLBuilderLayout._isMobile()) {
311				body.addClass('fl-builder-mobile');
312			}
313
314			if ( $(window).width() < FLBuilderLayoutConfig.breakpoints.small ) {
315				body.addClass( 'fl-builder-breakpoint-small' );
316			}
317
318			if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.small && $(window).width() < FLBuilderLayoutConfig.breakpoints.medium ) {
319				body.addClass( 'fl-builder-breakpoint-medium' );
320			}
321
322			if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.medium && $(window).width() < FLBuilderLayoutConfig.breakpoints.large ) {
323				body.addClass( 'fl-builder-breakpoint-large' );
324			}
325
326			if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.large ) {
327				body.addClass( 'fl-builder-breakpoint-default' );
328			}
329
330			// IE11 body class.
331			if ( ua.indexOf( 'Trident/7.0' ) > -1 && ua.indexOf( 'rv:11.0' ) > -1 ) {
332				body.addClass( 'fl-builder-ie-11' );
333			}
334		},
335
336		/**
337		 * Initializes builder node backgrounds that require
338		 * additional JavaScript logic such as parallax.
339		 *
340		 * @since 1.1.4
341		 * @access private
342		 * @method _initBackgrounds
343		 */
344		_initBackgrounds: function()
345		{
346			var win = $(window);
347
348			// Init parallax backgrounds.
349			if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isMobile()) {
350				FLBuilderLayout._scrollParallaxBackgrounds();
351				FLBuilderLayout._initParallaxBackgrounds();
352				win.on('resize.fl-bg-parallax', FLBuilderLayout._initParallaxBackgrounds);
353				win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds);
354			}
355
356			// Init video backgrounds.
357			if($('.fl-bg-video').length > 0) {
358				FLBuilderLayout._initBgVideos();
359				FLBuilderLayout._resizeBgVideos();
360
361				// Ensure FLBuilderLayout._resizeBgVideos() is only called once on window resize.
362				var resizeBGTimer = null;
363				win.on('resize.fl-bg-video', function(e){
364					clearTimeout( resizeBGTimer );
365					resizeBGTimer = setTimeout(function() {
366						FLBuilderLayout._resizeBgVideos(e);
367					}, 100 );
368				});
369			}
370		},
371
372		/**
373		 * Initializes all buttons in a layout.
374		 *
375		 * @since 2.10
376		 * @access private
377		 * @method _initButtons
378		 */
379		_initButtons: function()
380		{
381			// Trigger click event on Enter or Space key press for deprecated button markup.
382			$('a.fl-button[role="button"]').on('keydown', function(event) {
383				if (event.key === 'Enter' || event.key === ' ') {
384					// Necessary to prevent the default behavior of the space key from scrolling the page
385					event.preventDefault();
386					$(this).trigger('click');
387				}
388			});
389		},
390
391		/**
392		 * Initializes all parallax backgrounds in a layout.
393		 *
394		 * @since 1.1.4
395		 * @access private
396		 * @method _initParallaxBackgrounds
397		 */
398		_initParallaxBackgrounds: function()
399		{
400			$('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground);
401		},
402
403		/**
404		 * Initializes a single parallax background.
405		 *
406		 * @since 1.1.4
407		 * @access private
408		 * @method _initParallaxBackgrounds
409		 */
410		_initParallaxBackground: function()
411		{
412			var row     = $(this),
413				content = row.find('> .fl-row-content-wrap'),
414				winWidth = $(window).width(),
415				screenSize = '',
416				imageSrc = {
417					default: '',
418					medium: '',
419					responsive: '',
420				};
421
422			imageSrc.default = row.data('parallax-image') || '';
423			imageSrc.medium = row.data('parallax-image-medium') || imageSrc.default;
424			imageSrc.responsive = row.data('parallax-image-responsive') || imageSrc.medium;
425
426			if (winWidth > FLBuilderLayoutConfig.breakpoints.medium) {
427				screenSize = 'default';
428			} else if (winWidth > FLBuilderLayoutConfig.breakpoints.small && winWidth <= FLBuilderLayoutConfig.breakpoints.medium ) {
429				screenSize = 'medium';
430			} else if (winWidth <= FLBuilderLayoutConfig.breakpoints.small) {
431				screenSize = 'responsive';
432			}
433
434			content.css('background-image', 'url(' + imageSrc[screenSize] + ')');
435			row.data('current-image-loaded', screenSize );
436
437		},
438
439		/**
440		 * Fires when the window is scrolled to adjust
441		 * parallax backgrounds.
442		 *
443		 * @since 1.1.4
444		 * @access private
445		 * @method _scrollParallaxBackgrounds
446		 */
447		_scrollParallaxBackgrounds: function()
448		{
449			$('.fl-row-bg-parallax').each(FLBuilderLayout._scrollParallaxBackground);
450		},
451
452		/**
453		 * Fires when the window is scrolled to adjust
454		 * a single parallax background.
455		 *
456		 * @since 1.1.4
457		 * @access private
458		 * @method _scrollParallaxBackground
459		 */
460		_scrollParallaxBackground: function()
461		{
462			var win     	  = $(window),
463				row     	  = $(this),
464				content 	  = row.find('> .fl-row-content-wrap'),
465				speed   	  = row.data('parallax-speed'),
466				offset  	  = content.offset(),
467				yPos		  = -((win.scrollTop() - offset.top) / speed),
468				initialOffset = ( row.data('parallax-offset') != null ) ? row.data('parallax-offset') : 0,
469				totalOffset   = yPos - initialOffset;
470
471			content.css('background-position', 'center ' + totalOffset + 'px');
472		},
473
474		/**
475		 * Initializes all video backgrounds.
476		 *
477		 * @since 1.6.3.3
478		 * @access private
479		 * @method _initBgVideos
480		 */
481		_initBgVideos: function()
482		{
483			$('.fl-bg-video').each(FLBuilderLayout._initBgVideo);
484		},
485
486		/**
487		 * Initializes a video background.
488		 *
489		 * @since 1.6.3.3
490		 * @access private
491		 * @method _initBgVideo
492		 */
493		_initBgVideo: function()
494		{
495			var wrap   = $( this ),
496				width       = wrap.data( 'width' ),
497				height      = wrap.data( 'height' ),
498				mp4         = wrap.data( 'mp4' ),
499				youtube     = wrap.data( 'youtube'),
500				vimeo       = wrap.data( 'vimeo'),
501				mp4Type     = wrap.data( 'mp4-type' ),
502				webm        = wrap.data( 'webm' ),
503				webmType    = wrap.data( 'webm-type' ),
504				fallback    = wrap.data( 'fallback' ),
505				loaded      = wrap.data( 'loaded' ),
506				videoMobile = wrap.data( 'video-mobile' ),
507				playPauseButton = wrap.find('.fl-bg-video-play-pause-control'),
508				fallbackTag = '',
509				videoTag    = null,
510				mp4Tag      = null,
511				webmTag     = null;
512
513			// Return if the video has been loaded for this row.
514			if ( loaded ) {
515				return;
516			}
517
518			videoTag  = $( '<video autoplay loop muted playsinline></video>' );
519
520			/**
521			 * Add poster image (fallback image)
522			 */
523			if( 'undefined' != typeof fallback && '' != fallback ) {
524				videoTag.attr( 'poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' )
525				videoTag.css({
526					backgroundImage: 'url("' + fallback + '")',
527					backgroundColor: 'transparent',
528					backgroundRepeat: 'no-repeat',
529					backgroundSize: 'cover',
530					backgroundPosition: 'center center',
531				})
532			}
533
534			// MP4 Source Tag
535			if ( 'undefined' != typeof mp4 && '' != mp4 ) {
536
537				mp4Tag = $( '<source />' );
538				mp4Tag.attr( 'src', mp4 );
539				mp4Tag.attr( 'type', mp4Type );
540
541				videoTag.append( mp4Tag );
542			}
543			// WebM Source Tag
544			if ( 'undefined' != typeof webm && '' != webm ) {
545
546				webmTag = $( '<source />' );
547				webmTag.attr( 'src', webm );
548				webmTag.attr( 'type', webmType );
549
550				videoTag.append( webmTag );
551			}
552
553			// This is either desktop, or mobile is enabled.
554			if ( ! FLBuilderLayout._isMobile() || ( FLBuilderLayout._isMobile() && "yes" == videoMobile ) ) {
555				if ( 'undefined' != typeof youtube ) {
556					FLBuilderLayout._initYoutubeBgVideo.apply( this );
557				}
558				else if ( 'undefined' != typeof vimeo ) {
559					FLBuilderLayout._initVimeoBgVideo.apply( this );
560				}
561				else {
562					wrap.append( videoTag );
563
564					if ( playPauseButton.length > 0 ) {
565						var video = videoTag[0];
566
567						playPauseButton.on( 'click', { video: video }, function(e) {
568							var video = e.data.video;
569
570							if ( video.paused ) {
571								video.play();
572							} else {
573								video.pause();
574							}
575						} );
576
577						$( video ).on( 'play playing', function () {
578							playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' );
579						} );
580						
581						$( video ).on( 'pause ended waiting', function () {
582							playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' );
583						} );
584					}
585				}
586			}
587			else {
588				// if we are here, it means we are on mobile and NO is set so remove video src and use fallback
589				videoTag.attr('src', '')
590				wrap.append( videoTag );
591			}
592
593			// Mark this video as loaded.
594			wrap.data('loaded', true);
595		},
596
597		/**
598		 * Initializes Youtube video background
599		 *
600		 * @since 1.9
601		 * @access private
602		 * @method _initYoutubeBgVideo
603		 */
604		_initYoutubeBgVideo: function()
605		{
606			var playerWrap  = $(this),
607				videoId     = playerWrap.data('video-id'),
608				videoPlayer = playerWrap.find('.fl-bg-video-player'),
609				enableAudio = playerWrap.data('enable-audio'),
610				audioButton = playerWrap.find('.fl-bg-video-audio'),
611				playPauseButton = playerWrap.find('.fl-bg-video-play-pause-control'),
612				startTime   = 'undefined' !== typeof playerWrap.data('start') ? playerWrap.data('start') : 0,
613				startTime   = 'undefined' !== typeof playerWrap.data('t') && startTime === 0 ? playerWrap.data('t') : startTime,
614				endTime     = 'undefined' !== typeof playerWrap.data('end') ? playerWrap.data('end') : 0,
615				loop        = 'undefined' !== typeof playerWrap.data('loop') ? playerWrap.data('loop') : 1,
616				stateCount  = 0,
617				player,fallback_showing;
618
619			if ( videoId ) {
620				fallback = playerWrap.data('fallback') || false
621				if( fallback ) {
622					playerWrap.find('iframe').remove()
623					fallbackTag = $( '<div></div>' );
624					fallbackTag.addClass( 'fl-bg-video-fallback' );
625					fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' );
626					fallbackTag.css( 'background-size', 'cover' );
627					fallbackTag.css( 'transition', 'background-image 1s')
628					playerWrap.append( fallbackTag );
629					fallback_showing = true;
630				}
631				FLBuilderLayout._onYoutubeApiReady( function( YT ) {
632					setTimeout( function() {
633
634						player = new YT.Player( videoPlayer[0], {
635							videoId: videoId,
636							events: {
637								onReady: function(event) {
638									if ( "no" === enableAudio || FLBuilderLayout._isMobile() ) {
639										event.target.mute();
640									}
641									else if ( "yes" === enableAudio && event.target.isMuted ) {
642										event.target.unMute();
643									}
644
645									// Store an instance to a parent
646									playerWrap.data('YTPlayer', player);
647									FLBuilderLayout._resizeYoutubeBgVideo.apply(playerWrap);
648
649									// Queue the video.
650									event.target.playVideo();
651
652									if ( audioButton.length > 0 && ! FLBuilderLayout._isMobile() ) {
653										audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio );
654									}
655
656									if ( playPauseButton.length > 0 ) {
657										playPauseButton.on( 'click', {player: player}, function(e) {
658											var player = e.data.player;
659			
660											if ( 1 === player.getPlayerState() ) {
661												player.pauseVideo();
662											} else {
663												player.playVideo();
664											}
665										});
666									}
667								},
668								onStateChange: function( event ) {
669
670									if ( event.data === 1 ) {
671										if ( fallback_showing ) {
672											$( '.fl-bg-video-fallback' ).css( 'background-image', 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' )
673										}
674									}
675									// Manual check if video is not playable in some browsers.
676									// StateChange order: [-1, 3, -1]
677									if ( stateCount < 4 ) {
678										stateCount++;
679									}
680
681									// Comply with the audio policy in some browsers like Chrome and Safari.
682									if ( stateCount > 1 && -1 === event.data && "yes" === enableAudio ) {
683										player.mute();
684										player.playVideo();
685										audioButton.show();
686									}
687
688									if ( event.data === YT.PlayerState.ENDED && 1 === loop ) {
689										if ( startTime > 0 ) {
690											player.seekTo( startTime );
691										}
692										else {
693											player.playVideo();
694										}
695									}
696
697									if ( event.data === YT.PlayerState.PLAYING ) {
698										playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' );
699									} else if ( event.data === YT.PlayerState.PAUSED ) {
700										playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' );
701									} else if ( event.data === YT.PlayerState.BUFFERING ) {
702										playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' );
703									} else if ( event.data === YT.PlayerState.CUED ) {
704										playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' );
705									} else if ( event.data === YT.PlayerState.ENDED ) {
706										playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' );
707									}
708								},
709								onError: function(event) {
710									console.info('YT Error: ' + event.data)
711									FLBuilderLayout._onErrorYoutubeVimeo(playerWrap)
712								}
713							},
714							playerVars: {
715								playsinline: FLBuilderLayout._isMobile() ? 1 : 0,
716								controls: 0,
717								showinfo: 0,
718								rel : 0,
719								start: startTime,
720								end: endTime,
721							}
722						} );
723					}, 1 );
724				} );
725			}
726		},
727
728		/**
729		 * On youtube or vimeo error show the fallback image if available.
730		 * @since 2.0.7
731		 */
732		_onErrorYoutubeVimeo: function(playerWrap) {
733
734			fallback = playerWrap.data('fallback') || false
735			if( ! fallback ) {
736				return false;
737			}
738			playerWrap.find('iframe').remove()
739			fallbackTag = $( '<div></div>' );
740			fallbackTag.addClass( 'fl-bg-video-fallback' );
741			fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' );
742			playerWrap.append( fallbackTag );
743		},
744
745		/**
746		 * Check if Youtube API has been downloaded
747		 *
748		 * @since 1.9
749		 * @access private
750		 * @method _onYoutubeApiReady
751		 * @param  {Function} callback Method to call when YT API has been loaded
752		 */
753		_onYoutubeApiReady: function( callback ) {
754			if ( window.YT && YT.loaded ) {
755				callback( YT );
756			} else {
757				// If not ready check again by timeout..
758				setTimeout( function() {
759					FLBuilderLayout._onYoutubeApiReady( callback );
760				}, 350 );
761			}
762		},
763
764		/**
765		 * Initializes Vimeo video background
766		 *
767		 * @since 1.9
768		 * @access private
769		 * @method _initVimeoBgVideo
770		 */
771		_initVimeoBgVideo: function()
772		{
773			var playerWrap	= $(this),
774				videoId 	= playerWrap.data('video-id'),
775				videoHash 	= playerWrap.data('video-hash'),
776				videoPlayer = playerWrap.find('.fl-bg-video-player'),
777				enableAudio = playerWrap.data('enable-audio'),
778				audioButton = playerWrap.find('.fl-bg-video-audio'),
779				playPauseButton = playerWrap.find('.fl-bg-video-play-pause-control'),
780				playerState = '',
781				player,
782				width = playerWrap.outerWidth(),
783				ua    = navigator.userAgent;
784
785			if ( typeof Vimeo !== 'undefined' && videoId )	{
786				
787				const vimOptions = {
788					loop       : true,
789					title      : false,
790					portrait   : false,
791					background : true,
792					autopause  : false,
793					muted      : true,
794				};
795
796				if ( videoHash.length ) {
797					vimOptions.url = `https://player.vimeo.com/video/${ videoId }?h=${ videoHash }`;
798				} else {
799					vimOptions.id = videoId;
800				}
801
802				player = new Vimeo.Player(videoPlayer[0], vimOptions );
803				playerWrap.data('VMPlayer', player);
804				if ( "no" === enableAudio ) {
805					player.setVolume(0);
806				}
807				else if ("yes" === enableAudio ) {
808					// Chrome, Safari, Firefox have audio policy restrictions for autoplay videos.
809					if ( ua.indexOf("Safari") > -1 || ua.indexOf("Chrome") > -1 || ua.indexOf("Firefox") > -1 ) {
810						player.setVolume(0);
811						audioButton.show();
812					}
813					else {
814						player.setVolume(1);
815					}
816				}
817
818				player.play().catch(function(error) {
819					FLBuilderLayout._onErrorYoutubeVimeo(playerWrap)
820				});
821
822				if ( audioButton.length > 0 ) {
823					audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio );
824				}
825
826				player.on( 'play', function() {
827					playerState = 'play';
828					playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' );
829				} );
830				player.on( 'pause', function() {
831					playerState = 'pause';
832					playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' );
833				} );
834				player.on( 'ended', function() {
835					playerState = 'ended';
836					playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' );
837				} );
838				player.on( 'bufferstart', function() {
839					playerState = 'bufferstart';
840					playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' );
841				} );
842
843				if ( playPauseButton.length > 0 ) {
844					playPauseButton.on( 'click', { player: player }, function( e ) {
845						var player = e.data.player;
846
847						if ( playerState === 'play' ) {
848							player.pause();
849						} else {
850							player.play();
851						}
852					} );
853				}
854			}
855		},
856
857		/**
858		 * Mute / unmute audio on row's video background.
859		 * It works for both Youtube and Vimeo.
860		 *
861		 * @since 2.1.3
862		 * @access private
863		 * @method _toggleBgVideoAudio
864		 * @param {Object} e Method arguments
865		 */
866		_toggleBgVideoAudio: function( e ) {
867			var player  = e.data.player,
868			    control = e.data.button.find('.fl-audio-control');
869
870			if ( control.hasClass( 'fa-volume-off' ) ) {
871				// Unmute
872				control
873					.removeClass( 'fa-volume-off' )
874					.addClass( 'fa-volume-up' );
875				e.data.button.find( '.fa-times' ).hide();
876
877				if ( 'function' === typeof player.unMute ) {
878					player.unMute();
879				}
880				else {
881					player.setVolume( 1 );
882				}
883			}
884			else {
885				// Mute
886				control
887					.removeClass( 'fa-volume-up' )
888					.addClass( 'fa-volume-off' );
889				e.data.button.find( '.fa-times' ).show();
890
891				if ( 'function' === typeof player.unMute ) {
892					player.mute();
893				}
894				else {
895					player.setVolume( 0 );
896				}
897			}
898		},
899
900		/**
901		 * Fires when there is an error loading a video
902		 * background source and shows the fallback.
903		 *
904		 * @since 1.6.3.3
905		 * @access private
906		 * @method _videoBgSourceError
907		 * @param {Object} e An event object
908		 * @deprecated 2.0.3
909		 */
910		_videoBgSourceError: function( e )
911		{
912			var source 		= $( e.target ),
913				wrap   		= source.closest( '.fl-bg-video' ),
914				vid		    = wrap.find( 'video' ),
915				fallback  	= wrap.data( 'fallback' ),
916				fallbackTag = '';
917			source.remove();
918
919			if ( vid.find( 'source' ).length ) {
920				// Don't show the fallback if we still have other sources to check.
921				return;
922			} else if ( '' !== fallback ) {
923				fallbackTag = $( '<div></div>' );
924				fallbackTag.addClass( 'fl-bg-video-fallback' );
925				fallbackTag.css( 'background-image', 'url(' + fallback + ')' );
926				wrap.append( fallbackTag );
927				vid.remove();
928			}
929		},
930
931		/**
932		 * Fires when the window is resized to resize
933		 * all video backgrounds.
934		 *
935		 * @since 1.1.4
936		 * @access private
937		 * @method _resizeBgVideos
938		 */
939		_resizeBgVideos: function()
940		{
941			$('.fl-bg-video').each( function() {
942
943				FLBuilderLayout._resizeBgVideo.apply( this );
944
945				if ( $( this ).parent().find( 'img' ).length > 0 ) {
946					$( this ).parent().imagesLoaded( $.proxy( FLBuilderLayout._resizeBgVideo, this ) );
947				}
948			} );
949		},
950
951		/**
952		 * Fires when the window is resized to resize
953		 * a single video background.
954		 *
955		 * @since 1.1.4
956		 * @access private
957		 * @method _resizeBgVideo
958		 */
959		_resizeBgVideo: function()
960		{
961			if ( 0 === $( this ).find( 'video' ).length && 0 === $( this ).find( 'iframe' ).length ) {
962				return;
963			}
964
965			var wrap        = $(this),
966				wrapHeight  = wrap.outerHeight(),
967				wrapWidth   = wrap.outerWidth(),
968				vid         = wrap.find('video'),
969				vidHeight   = wrap.data('height'),
970				vidWidth    = wrap.data('width'),
971				newWidth    = wrapWidth,
972				newHeight   = Math.round(vidHeight * wrapWidth/vidWidth),
973				newLeft     = 0,
974				newTop      = 0,
975				iframe 		= wrap.find('iframe'),
976				isRowFullHeight = $(this).closest('.fl-row-bg-video').hasClass('fl-row-full-height'),
977				vidCSS          = {
978					top:       '50%',
979					left:      '50%',
980					transform: 'translate(-50%,-50%)',
981				};
982
983			if ( vid.length ) {
984				if(vidHeight === '' || typeof vidHeight === 'undefined' || vidWidth === '' || typeof vidWidth === 'undefined') {
985					vid.css({
986						'left'      : '0px',
987						'top'       : '0px',
988						'width'     : newWidth + 'px'
989					});
990
991					// Try to set the actual video dimension on 'loadedmetadata' when using URL as video source
992					vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta);
993
994					return;
995				}
996
997				if ( ! isRowFullHeight ) {
998					if ( newHeight < wrapHeight ) {
999						newHeight = wrapHeight;
1000						newLeft   = -((newWidth - wrapWidth) / 2);
1001						newWidth  = vidHeight ? Math.round(vidWidth * wrapHeight/vidHeight) : newWidth;
1002					}
1003					else {
1004						newTop = -((newHeight - wrapHeight)/2);
1005					}
1006					vidCSS = {
1007						left   : newLeft + 'px',
1008						top    : newTop + 'px',
1009						height : newHeight + 'px',
1010						width  : newWidth + 'px',
1011					}
1012				}
1013
1014				vid.css( vidCSS );
1015
1016			}
1017			else if ( iframe.length ) {
1018
1019				// Resize Youtube video player within iframe tag
1020				if ( typeof wrap.data('youtube') !== 'undefined' ) {
1021					FLBuilderLayout._resizeYoutubeBgVideo.apply(this);
1022				}
1023			}
1024		},
1025
1026		/**
1027		 * Fires when video meta has been loaded.
1028		 * This will be Triggered when width/height attributes were not specified during video background resizing.
1029		 *
1030		 * @since 1.8.5
1031		 * @access private
1032		 * @method _resizeOnLoadedMeta
1033		 */
1034		_resizeOnLoadedMeta: function(){
1035			var video 		= $(this),
1036				wrapHeight 	= video.parent().outerHeight(),
1037				wrapWidth 	= video.parent().outerWidth(),
1038				vidWidth 	= video[0].videoWidth,
1039				vidHeight 	= video[0].videoHeight,
1040				newHeight   = Math.round(vidHeight * wrapWidth/vidWidth),
1041				newWidth    = wrapWidth,
1042				newLeft     = 0,
1043				newTop 		= 0;
1044
1045			if(newHeight < wrapHeight) {
1046				newHeight   = wrapHeight;
1047				newWidth    = Math.round(vidWidth * wrapHeight/vidHeight);
1048				newLeft     = -((newWidth - wrapWidth)/2);
1049			}
1050			else {
1051				newTop      = -((newHeight - wrapHeight)/2);
1052			}
1053
1054			video.parent().data('width', vidWidth);
1055			video.parent().data('height', vidHeight);
1056
1057			video.css({
1058				'left'      : newLeft + 'px',
1059				'top'       : newTop + 'px',
1060				'width'     : newWidth + 'px',
1061				'height' 	: newHeight + 'px'
1062			});
1063		},
1064
1065		/**
1066		 * Fires when the window is resized to resize
1067		 * a single Youtube video background.
1068		 *
1069		 * @since 1.9
1070		 * @access private
1071		 * @method _resizeYoutubeBgVideo
1072		 */
1073		_resizeYoutubeBgVideo: function()
1074		{
1075			var wrap				= $(this),
1076				wrapWidth 			= wrap.outerWidth(),
1077				wrapHeight 			= wrap.outerHeight(),
1078				player 				= wrap.data('YTPlayer'),
1079				video 				= player ? player.getIframe() : null,
1080				aspectRatioSetting 	= '16:9', // Medium
1081				aspectRatioArray 	= aspectRatioSetting.split( ':' ),
1082				aspectRatio 		= aspectRatioArray[0] / aspectRatioArray[1],
1083				ratioWidth 			= wrapWidth / aspectRatio,
1084				ratioHeight 		= wrapHeight * aspectRatio,
1085				isWidthFixed 		= wrapWidth / wrapHeight > aspectRatio,
1086				width 				= isWidthFixed ? wrapWidth : ratioHeight,
1087				height 				= isWidthFixed ? ratioWidth : wrapHeight;
1088
1089			if ( video ) {
1090				$(video).width( width ).height( height );
1091			}
1092		},
1093
1094		/**
1095		 * Opens a tab or accordion item if the browser hash is set
1096		 * to the ID of one on the page.
1097		 *
1098		 * @since 1.6.0
1099		 * @access private
1100		 * @method _initHash
1101		 */
1102		_initHash: function()
1103		{
1104			var hash 			= window.location.hash.replace( '#', '' ).split( '/' ).shift(),
1105				element 		= null,
1106				tabs			= null,
1107				responsiveLabel	= null,
1108				tabIndex		= null,
1109				label			= null;
1110
1111			if ( '' !== hash ) {
1112
1113				try {
1114
1115					element = $( '#' + hash );
1116
1117					if ( element.length > 0 ) {
1118
1119						if ( element.hasClass( 'fl-accordion-item' ) ) {
1120							setTimeout( function() {
1121								element.find( '.fl-accordion-button' ).trigger( 'click' );
1122							}, 100 );
1123						}
1124						if ( element.hasClass( 'fl-tabs-panel' ) ) {
1125							setTimeout( function() {
1126								tabs 			= element.closest( '.fl-tabs' );
1127								responsiveLabel = element.find( '.fl-tabs-panel-label' );
1128								tabIndex 		= responsiveLabel.data( 'index' );
1129								label 			= tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' );
1130
1131								label[0].click();
1132								FLBuilderLayout._scrollToElement(element);
1133							}, 100 );
1134						}
1135					}
1136				}
1137				catch( e ) {}
1138			}
1139		},
1140
1141		/**
1142		 * Initializes all anchor links on the page for smooth scrolling.
1143		 *
1144		 * @since 1.4.9
1145		 * @access private
1146		 * @method _initAnchorLinks
1147		 */
1148		_initAnchorLinks: function()
1149		{
1150			$( 'a' ).each( FLBuilderLayout._initAnchorLink );
1151		},
1152
1153		/**
1154		 * Initializes a single anchor link for smooth scrolling.
1155		 *
1156		 * @since 1.4.9
1157		 * @access private
1158		 * @method _initAnchorLink
1159		 */
1160		_initAnchorLink: function()
1161		{
1162			var link    = $( this ),
1163				href    = link.attr( 'href' ),
1164				loc     = window.location,
1165				id      = null,
1166				element = null,
1167				flNode  = false;
1168
1169			if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) {
1170
1171				if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) {
1172
1173					try {
1174
1175						id      = href.split( '#' ).pop();
1176						// If there is no ID then we have nowhere to look
1177						// Fixes a quirk in jQuery and FireFox
1178						if( ! id ) {
1179							return;
1180						}
1181						element = $( '#' + id );
1182
1183						if ( element.length > 0 ) {
1184							flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' );
1185							if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) {
1186								$( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick );
1187							}
1188							if ( element.hasClass( 'fl-accordion-item' ) ) {
1189								$( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick );
1190							}
1191							if ( element.hasClass( 'fl-tabs-panel' ) ) {
1192								$( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick );
1193							}
1194						}
1195					}
1196					catch( e ) {}
1197				}
1198			}
1199		},
1200
1201		/**
1202		 * Scrolls to an element when an anchor link is clicked.
1203		 *
1204		 * @since 1.4.9
1205		 * @access private
1206		 * @method _scrollToElementOnLinkClick
1207		 * @param {Object} e An event object.
1208		 * @param {Function} callback A function to call when the scroll is complete.
1209		 */
1210		_scrollToElementOnLinkClick: function( e, callback )
1211		{
1212			var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() );
1213
1214			FLBuilderLayout._scrollToElement( element, callback );
1215
1216			e.preventDefault();
1217		},
1218
1219		/**
1220		 * Scrolls to an element.
1221		 *
1222		 * @since 1.6.4.5
1223		 * @access private
1224		 * @method _scrollToElement
1225		 * @param {Object} element The element to scroll to.
1226		 * @param {Function} callback A function to call when the scroll is complete.
1227		 */
1228		_scrollToElement: function( element, callback )
1229		{
1230			var config  = FLBuilderLayoutConfig.anchorLinkAnimations,
1231				dest    = 0,
1232				win     = $( window ),
1233				doc     = $( document );
1234
1235			if ( element.length > 0 ) {
1236
1237				if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) {
1238					dest = element.position().top;
1239				}
1240				else if ( element.offset().top > doc.height() - win.height() ) {
1241					dest = doc.height() - win.height();
1242				}
1243				else {
1244					dest = element.offset().top - config.offset;
1245				}
1246
1247				$( 'html, body' ).stop( true ).animate( { scrollTop: dest }, config.duration, config.easing, function() {
1248
1249					if ( 'undefined' != typeof callback ) {
1250						callback();
1251					}
1252
1253					if ( undefined != element.attr( 'id' ) && window.location.hash !== '#' + element.attr( 'id' ) ) {
1254
1255						var firefox_version = window.navigator.userAgent.match( /Firefox\/(\d+)\./ ),
1256							firefox_version = firefox_version ? parseInt( firefox_version[1], 10 ) : null;
1257
1258						if ( firefox_version !== null && firefox_version < 135 ) {
1259							window.location.hash = element.attr( 'id' );
1260						} else {
1261							if ( history.pushState ) {
1262								history.pushState( null, null, '#' + element.attr( 'id' ) );
1263							} else {
1264								window.location.hash = element.attr( 'id' );
1265							}
1266						}
1267					}
1268				} );
1269			}
1270		},
1271
1272		/**
1273		 * Scrolls to an accordion item when a link is clicked.
1274		 *
1275		 * @since 1.5.9
1276		 * @access private
1277		 * @method _scrollToAccordionOnLinkClick
1278		 * @param {Object} e An event object.
1279		 */
1280		_scrollToAccordionOnLinkClick: function( e )
1281		{
1282			var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() );
1283
1284			if ( element.length > 0 ) {
1285
1286				var callback = function() {
1287					if ( element ) {
1288						element.find( '.fl-accordion-button' ).trigger( 'click' );
1289						element = false;
1290					}
1291				};
1292
1293				FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback );
1294			}
1295		},
1296
1297		/**
1298		 * Scrolls to a tab panel when a link is clicked.
1299		 *
1300		 * @since 1.5.9
1301		 * @access private
1302		 * @method _scrollToTabOnLinkClick
1303		 * @param {Object} e An event object.
1304		 */
1305		_scrollToTabOnLinkClick: function( e )
1306		{
1307			var element 		= $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ),
1308				tabs			= null,
1309				label   		= null,
1310				responsiveLabel = null;
1311
1312			if ( element.length > 0 ) {
1313
1314				tabs 			= element.closest( '.fl-tabs' );
1315				responsiveLabel = element.find( '.fl-tabs-panel-label' );
1316				tabIndex 		= responsiveLabel.data( 'index' );
1317				label 			= tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' );
1318
1319				if ( responsiveLabel.is( ':visible' ) ) {
1320
1321					var callback = function() {
1322						if ( element ) {
1323							responsiveLabel.trigger( $.Event( 'click', { which: 1 } ) );
1324						}
1325					};
1326
1327					FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback );
1328				}
1329				else {
1330					label[0].click();
1331					FLBuilderLayout._scrollToElement( element );
1332				}
1333
1334				e.preventDefault();
1335			}
1336		},
1337
1338		/**
1339		 * Initializes all builder forms on a page.
1340		 *
1341		 * @since 1.5.4
1342		 * @access private
1343		 * @method _initForms
1344		 */
1345		_initForms: function()
1346		{
1347			if ( ! FLBuilderLayout._hasPlaceholderSupport ) {
1348				$( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback );
1349			}
1350
1351			$( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError );
1352		},
1353
1354		/**
1355		 * Checks to see if the current device has HTML5
1356		 * placeholder support.
1357		 *
1358		 * @since 1.5.4
1359		 * @access private
1360		 * @method _hasPlaceholderSupport
1361		 * @return {Boolean}
1362		 */
1363		_hasPlaceholderSupport: function()
1364		{
1365			var input = document.createElement( 'input' );
1366
1367			return 'undefined' != input.placeholder;
1368		},
1369
1370		/**
1371		 * Initializes the fallback for when placeholders aren't supported.
1372		 *
1373		 * @since 1.5.4
1374		 * @access private
1375		 * @method _initFormFieldPlaceholderFallback
1376		 */
1377		_initFormFieldPlaceholderFallback: function()
1378		{
1379			var field       = $( this ),
1380				val         = field.val(),
1381				placeholder = field.attr( 'placeholder' );
1382
1383			if ( 'undefined' != placeholder && '' === val ) {
1384				field.val( placeholder );
1385				field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback );
1386				field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback );
1387			}
1388		},
1389
1390		/**
1391		 * Hides a fallback placeholder on focus.
1392		 *
1393		 * @since 1.5.4
1394		 * @access private
1395		 * @method _hideFormFieldPlaceholderFallback
1396		 */
1397		_hideFormFieldPlaceholderFallback: function()
1398		{
1399			var field       = $( this ),
1400				val         = field.val(),
1401				placeholder = field.attr( 'placeholder' );
1402
1403			if ( val == placeholder ) {
1404				field.val( '' );
1405			}
1406		},
1407
1408		/**
1409		 * Shows a fallback placeholder on blur.
1410		 *
1411		 * @since 1.5.4
1412		 * @access private
1413		 * @method _showFormFieldPlaceholderFallback
1414		 */
1415		_showFormFieldPlaceholderFallback: function()
1416		{
1417			var field       = $( this ),
1418				val         = field.val(),
1419				placeholder = field.attr( 'placeholder' );
1420
1421			if ( '' === val ) {
1422				field.val( placeholder );
1423			}
1424		},
1425
1426		/**
1427		 * Clears a form field error message.
1428		 *
1429		 * @since 1.5.4
1430		 * @access private
1431		 * @method _clearFormFieldError
1432		 */
1433		_clearFormFieldError: function()
1434		{
1435			var field = $( this );
1436
1437			field.removeAttr( 'aria-invalid' );
1438			field.removeClass( 'fl-form-error' );
1439			const message = field.attr('aria-describedby');
1440			message ? $( '#' + message ).hide() : field.siblings( '.fl-form-error-message' ).hide();
1441		},
1442
1443		/**
1444		 * Init Row Shape Layer's height.
1445		 *
1446		 * @since 2.5.3
1447		 * @access private
1448		 * @method _initRowShapeLayerHeight
1449		 */
1450		_initRowShapeLayerHeight: function () {
1451			FLBuilderLayout._adjustRowShapeLayerHeight();
1452			$( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight );
1453		},
1454
1455		/**
1456		 * Set parent column width of nested columns when it's zero or blank.
1457		 *
1458		 * @since 2.7.4
1459		 * @access private
1460		 * @method _initNestedColsWidth
1461		 */
1462		_initNestedColsWidth: function()
1463		{
1464			var nestedCols = $( '.fl-col-has-cols' );
1465
1466			if ( nestedCols.length <= 0 ) {
1467				return;
1468			}
1469
1470			$( nestedCols ).each( function(index, col ){
1471				if ( $( col ).width() <= 0 ) {
1472					$( col ).css( 'width', FLBuilderLayoutConfig.emptyColWidth );
1473				}
1474			});
1475		},
1476
1477		/**
1478		 * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes.
1479		 *
1480		 * @since 2.5.3
1481		 * @access private
1482		 * @method _adjustRowShapeLayerHeight
1483		 */
1484		_adjustRowShapeLayerHeight: function() {
1485			var rowShapeLayers = $('.fl-builder-shape-layer');
1486
1487			$( rowShapeLayers ).each(function (index) {
1488				var rowShapeLayer = $(this),
1489					shape = $(rowShapeLayer).find('svg'),
1490					height = shape.height(),
1491					excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect';
1492
1493				if ( ! rowShapeLayer.is( excludeShapes ) ) {
1494					$(shape).css('height', Math.ceil( height ) );
1495				}
1496			});
1497		},
1498		_string_to_slug: function( str ) {
1499			str = str.replace(/^\s+|\s+$/g, ''); // trim
1500			if ( 'undefined' == typeof window._fl_string_to_slug_regex ) {
1501				regex = new RegExp('[^a-zA-Z0-9\'":() !.,-_|]', 'g');
1502			} else {
1503				regex = new RegExp('[^' + window._fl_string_to_slug_regex + '\'":\(\) !.,-_|\\\p{Letter}]', 'ug');
1504			}
1505			str = str.replace(regex, '') // remove invalid chars
1506				.replace(/\s+/g, ' '); // collapse whitespace and replace by a space
1507			return str;
1508		},
1509		_reorderMenu: function() {
1510			if ( $('#wp-admin-bar-fl-builder-frontend-edit-link-default li').length > 1 ) {
1511					$( '#wp-admin-bar-fl-builder-frontend-duplicate-link' )
1512					.appendTo('#wp-admin-bar-fl-builder-frontend-edit-link-default')
1513					.css( 'padding-top', '5px' )
1514					.css( 'border-top', '2px solid #1D2125' )
1515					.css( 'margin-top', '5px' )
1516				}
1517		}
1518	};
1519
1520	/* Initializes the builder layout. */
1521	$(function(){
1522		FLBuilderLayout.init();
1523	});
1524
1525})(jQuery);
1526(function($){
1527
1528	if(typeof FLBuilderLayoutModules !== 'undefined') {
1529		return;
1530	}
1531
1532	/**
1533	 * Helper class with generic logic for builder modules.
1534	 * If generic module code needs to work in both the block
1535	 * editor and builder, it should go here. Otherwise, it
1536	 * should go on FLBuilderLayout.
1537	 *
1538	 * @since 2.9
1539	 */
1540	FLBuilderLayoutModules = {
1541
1542		/**
1543		 * Initializes builder module logic.
1544		 *
1545		 * @since 2.9
1546		 * @method init
1547		 */
1548		init: function()
1549		{
1550			// Only init if the builder isn't active.
1551			if ( 0 === $('.fl-builder-edit').length ) {
1552
1553				// Init module animations.
1554				FLBuilderLayoutModules._initModuleAnimations();
1555			}
1556		},
1557
1558		/**
1559		 * Initializes module animations.
1560		 *
1561		 * @since 1.1.9
1562		 * @access private
1563		 * @method _initModuleAnimations
1564		 */
1565		_initModuleAnimations: function()
1566		{
1567			if(typeof jQuery.fn.waypoint !== 'undefined') {
1568				$('.fl-animation').each( function() {
1569					var node = $( this ),
1570						nodeTop = node.offset().top,
1571						winHeight = $( window ).height(),
1572						bodyHeight = $( 'body' ).height(),
1573						waypoint = FLBuilderLayoutConfig.waypoint,
1574						offset = '80%';
1575
1576					if ( typeof waypoint.offset !== undefined ) {
1577						offset = FLBuilderLayoutConfig.waypoint.offset + '%';
1578					}
1579
1580					if ( bodyHeight - nodeTop < winHeight * 0.2 ) {
1581						offset = '100%';
1582					}
1583
1584					node.waypoint({
1585						offset: offset,
1586						handler: FLBuilderLayoutModules._doModuleAnimation
1587					});
1588				} );
1589			}
1590		},
1591
1592		/**
1593		 * Runs a module animation.
1594		 *
1595		 * @since 1.1.9
1596		 * @access private
1597		 * @method _doModuleAnimation
1598		 */
1599		_doModuleAnimation: function()
1600		{
1601			var module = 'undefined' == typeof this.element ? $(this) : $(this.element),
1602				delay = parseFloat(module.data('animation-delay')),
1603				duration = parseFloat(module.data('animation-duration'));
1604
1605			if ( ! isNaN( duration ) ) {
1606				module.css( 'animation-duration', duration + 's' );
1607			}
1608
1609			if(!isNaN(delay) && delay > 0) {
1610				setTimeout(function(){
1611					module.addClass('fl-animated');
1612				}, delay * 1000);
1613			} else {
1614				setTimeout(function(){
1615					module.addClass('fl-animated');
1616				}, 1);
1617			}
1618		}
1619	};
1620
1621	/* Initializes builder module logic. */
1622	$(function(){
1623		FLBuilderLayoutModules.init();
1624	});
1625
1626})(jQuery);
1627
1628/* Start Global JS */
1629
1630/* End Global JS */
1631
1632(function($) {
1633	if ( $('.fl-node-pvxmab49ne03 .pp-photo-rollover').length > 0 ) {
1634		$('body').on( 'mouseenter.pp-rollover', '.fl-node-pvxmab49ne03 .pp-photo-rollover .pp-photo-content', function() {
1635			$(this).addClass( 'is-hover' );
1636		} ).on( 'mouseleave.pp-rollover', '.fl-node-pvxmab49ne03 .pp-photo-rollover .pp-photo-content', function() {
1637			$(this).removeClass( 'is-hover' );
1638		} );
1639	}
1640})(jQuery);
1641;/* eslint-disable no-undef */
1642(function($) {
1643
1644	/**
1645	 * Class for Menu Module
1646	 *
1647	 * @since 1.6.1
1648	 */
1649	FLBuilderMenu = function( settings ){
1650
1651		// set params
1652		this.nodeId              = settings.id;
1653		this.nodeClass           = '.fl-node-' + settings.id;
1654		this.wrapperClass        = this.nodeClass + ' .fl-menu';
1655		this.type				 				 = settings.type;
1656		this.mobileToggle		     = settings.mobile;
1657		this.mobileBelowRow		   = settings.mobileBelowRow;
1658		this.mobileFlyout		     = settings.mobileFlyout;
1659		this.breakPoints         = settings.breakPoints;
1660		this.mobileBreakpoint	 	 = settings.mobileBreakpoint;
1661		this.currentBrowserWidth = $( window ).width();
1662		this.postId              = settings.postId;
1663		this.mobileStacked       = settings.mobileStacked;
1664		this.submenuIcon         = settings.submenuIcon;
1665		this.flyoutWidth         = settings.flyoutWidth;
1666
1667		// initialize the menu
1668		this._initMenu();
1669
1670		// check if viewport is resizing
1671		$( window ).on( 'resize', $.proxy( function() {
1672
1673			var width = $( window ).width();
1674
1675			// if screen width is resized, reload the menu
1676		    if( width != this.currentBrowserWidth ){
1677
1678				this.currentBrowserWidth = width;
1679				this._initMenu( true );
1680 				this._clickOrHover( true );
1681			}
1682
1683			this._resizeFlyoutMenuPanel();
1684		}, this ) );
1685
1686		$( window ).on( 'scroll', $.proxy( function() {
1687			this._resizeFlyoutMenuPanel();
1688		}, this ) );
1689
1690		// Move focus to the first menu item if the layout is set to BelowRow
1691		$( this.wrapperClass ).on( 'keydown', '.fl-menu-mobile-toggle, .menu-item:first a:first', $.proxy( function ( event ) {
1692			// Make sure it is a tab key with both the menu toggle enabled & below row layout set
1693			if ( event.key !== 'Tab' || ! this._isMenuToggle() || ! this._isMobileBelowRowEnabled() ) {
1694				return;
1695			}
1696			// Trigger focus on the mobile toggle button if the user is shift tabbing from the first menu item
1697			if ( event.shiftKey && $( event.target ).is( 'a' ) ) {
1698				event.preventDefault();
1699				$( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).trigger( 'focus' );
1700			}
1701			// Trigger focus on the first menu item if the user is tabbing from the mobile toggle button
1702			else if ( ! event.shiftKey && $( event.target ).hasClass( 'fl-menu-mobile-toggle' ) && $( event.target ).hasClass( 'fl-active' )  ) {
1703				event.preventDefault();
1704				$( this.wrapperClass ).find( '.menu-item:first a:first' ).trigger( 'focus' );
1705			}
1706		}, this ) );
1707
1708		// Close mobile menu or accordion when tabbing out from the first or last menu item
1709		$( this.wrapperClass ).on( 'focusout', $.proxy( function ( event ) {
1710			if ( $( this.wrapperClass + ' nav' ).has( $( event.relatedTarget ) ).length === 0 ) {
1711				if ( this.type === 'accordion' ) {
1712					this._toggleSubmenu( $( event.target ).parents( '.fl-has-submenu:last' ), false );
1713				}
1714				else {
1715					this._clickOrHover( true );
1716				}
1717				const mobileToggle = $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' );
1718				if ( this._isMenuToggle() && mobileToggle.hasClass( 'fl-active' ) && ! $( event.relatedTarget ).is( mobileToggle ) && 'expanded' !== this.mobileToggle ) {
1719					mobileToggle.trigger( 'click' );
1720				}
1721			}
1722		}, this ) );
1723
1724	};
1725
1726	FLBuilderMenu.prototype = {
1727		nodeClass		: '',
1728		wrapperClass: '',
1729		type				: '',
1730		breakPoints	: {},
1731		$submenus		: null,
1732
1733		/**
1734		 * Check if the screen size fits a mobile viewport.
1735		 *
1736		 * @since  1.6.1
1737		 * @return bool
1738		 */
1739		_isMobile: function(){
1740			return this.currentBrowserWidth <= this.breakPoints.small ? true : false;
1741		},
1742
1743		/**
1744		 * Check if the device is connected to a mouse.
1745		 * 
1746		 * @since  2.9.0
1747		 * @return bool
1748		 */
1749		_isMouseAvailable: function(){
1750			return window.matchMedia("(pointer: fine) and (hover: hover)").matches;
1751		},
1752
1753		/**
1754		 * Check if the screen size fits a medium viewport.
1755		 *
1756		 * @since  1.10.5
1757		 * @return bool
1758		 */
1759		_isMedium: function(){
1760			return this.currentBrowserWidth <= this.breakPoints.medium ? true : false;
1761		},
1762
1763		/**
1764		 * Check if the screen size fits a large viewport.
1765		 *
1766		 * @since  1.10.5
1767		 * @return bool
1768		 */
1769		_isLarge: function(){
1770			return this.currentBrowserWidth <= this.breakPoints.large ? true : false;
1771		},
1772
1773		/**
1774		 * Check if the menu should toggle for the current viewport base on the selected breakpoint.
1775		 *
1776		 * @see 	 this._isMobile()
1777		 * @see 	 this._isMedium()
1778		 * @since  1.10.5
1779		 * @return bool
1780		 */
1781		_isMenuToggle: function(){
1782			if ( ( 'always' == this.mobileBreakpoint
1783				|| ( this._isMobile() && 'mobile' == this.mobileBreakpoint )
1784				|| ( this._isMedium() && 'medium-mobile' == this.mobileBreakpoint )
1785				|| ( this._isLarge() && 'large-mobile' == this.mobileBreakpoint )
1786			) && ( $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).is(':visible') || 'expanded' == this.mobileToggle ) ) {
1787				return true;
1788			}
1789
1790			return false;
1791		},
1792
1793		/**
1794		 * Initialize the toggle logic for the menu.
1795		 *
1796		 * @see    this._isMenuToggle()
1797		 * @see    this._menuOnCLick()
1798		 * @see    this._clickOrHover()
1799		 * @see    this._submenuOnRight()
1800		 * @see    this._submenuRowZindexFix()
1801		 * @see    this._toggleForMobile()
1802		 * @since  1.6.1
1803		 * @return void
1804		 */
1805		_initMenu: function( resized = false ){
1806			this._setupSubmenu();
1807			if ( ! resized ) {
1808				this._menuOnFocus();
1809				this._menuOnClick();
1810				this._menuOnEscape();
1811			}
1812			if ( $( this.nodeClass ).length && this.type == 'horizontal' ) {
1813				this._initMegaMenus();
1814			}
1815
1816			if( this._isMenuToggle() || this.type == 'accordion' ){
1817
1818				$( this.wrapperClass ).off( 'mouseenter mouseleave' );
1819				this._clickOrHover();
1820
1821			} else {
1822				this._submenuOnRight();
1823				this._submenuRowZindexFix();
1824			}
1825
1826			if( this.mobileToggle != 'expanded' ){
1827				this._toggleForMobile();
1828			}
1829
1830			if( $( this.wrapperClass ).find( '.fl-menu-search-item' ).length ){
1831				this._toggleMenuSearch();
1832			}
1833
1834			if( $( this.wrapperClass ).find( '.fl-menu-cart-item').length ){
1835				this._wooUpdateParams();
1836			}
1837		},
1838
1839		/**
1840		 * Whether the toggle behavior for submenus is through hovering or not.
1841		 *
1842		 * @since  2.5
1843		 * @return void
1844		 */
1845		_setupSubmenu: function() {
1846			if ( ! this._isMouseAvailable() || this._isMenuToggle() || this.type === 'accordion' ) {
1847				$( this.wrapperClass ).addClass( 'no-hover' );
1848			}
1849			else {
1850				$( this.wrapperClass ).removeClass( 'no-hover' );
1851			}
1852		},
1853
1854		/**
1855		 * Logic for menu items when focused.
1856		 *
1857		 * @since  1.9.0
1858		 * @return void
1859		 */
1860		_menuOnFocus: function(){
1861			$( this.wrapperClass ).on( 'focus', 'a, .fl-menu-toggle', $.proxy( function( event ) {
1862				const focusedMenuItem = $( event.target ).closest( '.menu-item' );
1863				const blurredMenuItem = $( event.relatedTarget ).closest( '.menu-item' );
1864				// In case the blurred & focused items are siblings
1865				if ( focusedMenuItem.closest( 'ul' ).is( blurredMenuItem.closest( 'ul' ) ) )	{
1866					// Check if the focus event is not between the link & submenu icon of the same menu item
1867					if ( ! focusedMenuItem.is( blurredMenuItem ) ) {
1868						this._toggleSubmenu( blurredMenuItem, false );
1869					}
1870				}
1871				// In case neither items are child & parent nor vice versa
1872				else if ( focusedMenuItem.has( blurredMenuItem ).length === blurredMenuItem.has( focusedMenuItem ).length ) {
1873					// Get the blurred item parent & is the sibling of the focused item
1874					blurredMenuItem.parents( '.fl-has-submenu' ).each( ( _, parent ) => {
1875						if ( focusedMenuItem.closest( 'ul' ).is( $( parent ).closest( 'ul' ) ) ) {
1876							this._toggleSubmenu( $( parent ), false );
1877							return false;
1878						}
1879					} );
1880				}
1881				// In case the blurred item is a child of the focused item
1882				else if ( focusedMenuItem.has( blurredMenuItem ).length ) {
1883					if ( this.type !== 'accordion' && this.submenuIcon === 'none' ) {
1884						this._toggleSubmenu( blurredMenuItem, false );
1885					}
1886				}
1887			}, this ) );
1888		},
1889
1890		/**
1891		 * Logic for menu items when Escape key is pressed.
1892		 *
1893		 * @since  2.7.1
1894		 * @return void
1895		 */
1896		_menuOnEscape: function(){
1897			$( this.wrapperClass ).on( 'keydown', $.proxy( function( event ){
1898				if ( event.key !== 'Escape' ) return;
1899				const menuItem = $( event.target ).closest( '.menu-item' );
1900				const mobileToggle = $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' );
1901				// In case there is a focused menu item
1902				if ( menuItem.length || $( event.target ).hasClass( 'fl-menu-mobile-close' ) ) {
1903					// Close all the submenus of the focused menu item
1904					if ( menuItem.hasClass( 'fl-has-submenu' ) && menuItem.find( '.sub-menu:first' ).is( ':visible' ) ) {
1905						this._toggleSubmenu( menuItem, false );
1906					}
1907					else {
1908						// Shift focus to the parent while closing all its submenus
1909						const parentMenuItem = menuItem.parents( '.fl-has-submenu' ).not( '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading' ).first();
1910						// Close the mobile menu if there is no parent menu item and the mobile toggle is active
1911						if ( parentMenuItem.length === 0 && this._isMenuToggle() && mobileToggle.hasClass( 'fl-active' ) ) {
1912							// Blur to trigger the focus-out event for closing the menu
1913							mobileToggle.trigger( 'blur' ).trigger( 'focus' );
1914						}
1915						// Close the parent submenu and shift focus to its link
1916						else if ( parentMenuItem.length !== 0 ) {
1917							this._toggleSubmenu( parentMenuItem, false );
1918							parentMenuItem.find( 'a:first' ).trigger( 'focus' );
1919						}
1920					}
1921				}
1922				// Close the mobile menu if the mobile toggle is active
1923				else if ( $( event.target ).hasClass( 'fl-menu-mobile-toggle' ) && mobileToggle.hasClass( 'fl-active' ) ) {
1924					// Blur to trigger the focus-out event for closing the menu
1925					mobileToggle.trigger( 'blur' ).trigger( 'focus' );
1926				}
1927			}, this ) );
1928		},
1929
1930		/**
1931		 * Logic for menu items when clicked.
1932		 *
1933		 * @since  1.6.1
1934		 * @return void
1935		 */
1936		_menuOnClick: function(){
1937			// Fallback for span elements with role="button" to be clickable
1938			$( this.wrapperClass ).on( 'keydown', 'span.fl-menu-toggle', $.proxy( function( event ) {
1939				if ( event.key === 'Enter' || event.key === ' ' ) {
1940					event.preventDefault();
1941					$( event.target ).trigger( 'click' );
1942				}
1943			}, this ) );
1944			$( this.wrapperClass ).on( 'click', 'a, .fl-menu-toggle', $.proxy( function( event ) {
1945				event.stopPropagation();
1946				// Only allow mouse clicks with accordion & mobile menus
1947				if ( this._isMouseAvailable() && ! this._isMenuToggle() && event.detail && this.type !== 'accordion' ) return;
1948				// Links only open & do not toggle submenus if there is either a submenu icon or an accordion layout
1949				if ( $( event.target ).is( 'a' ) && ( this.submenuIcon !== 'none' || this.type === 'accordion' ) ) return;
1950				const menuItem = $( event.target ).closest( '.menu-item' );
1951				const menuLink = menuItem.find( 'a:first' ).attr( 'href' );
1952				const submenuHidden = menuItem.find( '.sub-menu:first' ).is( ':hidden' );
1953				if ( typeof menuLink === 'undefined' || menuLink === '#' || submenuHidden ) {
1954					event.preventDefault();
1955				}
1956				if ( $( event.target ).hasClass( 'fl-menu-toggle' ) || submenuHidden ) {
1957					this._toggleSubmenu( menuItem, submenuHidden );
1958				}
1959			}, this ) );
1960		},
1961
1962		/**
1963		 * Controls toggling the visibility of all submenu items for desktop & mobile.
1964		 *
1965		 * @since  2.10
1966		 * @return void
1967		 */
1968		_toggleSubmenu: function ( menuItem, opened ) {
1969			const togglingClass = this._isMenuToggle() || this.type === 'accordion' ? 'fl-active' : 'focus';
1970			const toggleElement = this.submenuIcon === 'none' ? 'a' : '.fl-menu-toggle';
1971			const hiddenMenu = '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading';
1972			if ( opened && menuItem.hasClass( 'fl-has-submenu' ) && ! menuItem.is( hiddenMenu ) ) {
1973				menuItem.addClass( togglingClass );
1974				menuItem.find( toggleElement ).first().attr( 'aria-expanded', true );
1975				if ( this._isMenuToggle() || this.type === 'accordion' ) {
1976					menuItem.find( '.sub-menu:first:hidden' ).slideDown();
1977				}
1978			}
1979			else {
1980				menuItem.parent().find( '.menu-item' ).removeClass( togglingClass );
1981				menuItem.parent().find( '.fl-has-submenu' ).not( hiddenMenu ).find( toggleElement ).attr( 'aria-expanded', false );
1982				if ( this._isMenuToggle() || this.type === 'accordion' ) {
1983					menuItem.find( '.sub-menu:visible' ).slideUp();
1984				}
1985			}
1986		},
1987
1988		/**
1989		 * Changes general styling and behavior of menus based on mobile / desktop viewport.
1990		 *
1991		 * @see    this._isMenuToggle()
1992		 * @since  1.6.1
1993		 * @return void
1994		 */
1995		_clickOrHover: function( clear = false ){
1996			const selector = this._isMobileBelowRowEnabled() ? this.nodeClass + '-clone' : this.nodeClass;
1997			this.$submenus = this.$submenus || $( selector ).find( '.sub-menu' );
1998
1999			const className = this._isMenuToggle() || this.type === 'accordion' ? 'fl-active' : 'focus';
2000			const toggleElement = this.submenuIcon === 'none' ? 'a' : '.fl-menu-toggle';
2001			const hiddenMenu = '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading';
2002			$( selector ).find( '.fl-has-submenu' ).not( hiddenMenu ).each( function() {
2003				if( clear || ! $ ( this ).hasClass( className ) ){
2004					if ( clear ) $( this ).removeClass( className );
2005					$( this ).find( toggleElement + ':first' ).attr( 'aria-expanded', false );
2006					if ( className === 'fl-active' ) {
2007						$( this ).find( '.sub-menu' ).fadeOut();
2008					} else if ( className === 'focus' ) {
2009						$( this ).find( '.sub-menu' ).css( {
2010							'display' : '',
2011							'opacity' : ''
2012						} );
2013					}
2014				}
2015			} );
2016		},
2017
2018		/**
2019		 * Logic to prevent submenus to go outside viewport boundaries.
2020		 *
2021		 * @since  1.6.1
2022		 * @return void
2023		 */
2024		_submenuOnRight: function(){
2025
2026			$( this.wrapperClass )
2027				.on( 'mouseenter focus', '.fl-has-submenu', $.proxy( function( e ){
2028
2029					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
2030						return;
2031					}
2032
2033					var $link           = $( e.currentTarget ),
2034						$parent         = $link.parent(),
2035						$subMenu        = $link.find( '.sub-menu' ),
2036						subMenuWidth    = $subMenu.width(),
2037						subMenuPos      = 0,
2038						bodyWidth       = $( 'body' ).width();
2039
2040					if( $link.closest( '.fl-menu-submenu-right' ).length !== 0) {
2041
2042						$link.addClass( 'fl-menu-submenu-right' );
2043
2044					} else if( $( 'body' ).hasClass( 'rtl' ) ) {
2045
2046						subMenuPos = $parent.is( '.sub-menu' ) ?
2047									 $parent.offset().left - subMenuWidth:
2048									 $link.offset().left - $link.width() - subMenuWidth;
2049
2050						if( subMenuPos <= 0 ) {
2051							$link.addClass( 'fl-menu-submenu-right' );
2052						}
2053
2054					} else {
2055
2056						subMenuPos = $parent.is( '.sub-menu' ) ?
2057									 $parent.offset().left + $parent.width() + subMenuWidth :
2058									 $link.offset().left + $link.width() + subMenuWidth;
2059
2060						if( subMenuPos > bodyWidth ) {
2061							$link.addClass('fl-menu-submenu-right');
2062						}
2063					}
2064				}, this ) )
2065				.on( 'mouseleave', '.fl-has-submenu', $.proxy( function( e ){
2066					$( e.currentTarget ).removeClass( 'fl-menu-submenu-right' );
2067				}, this ) );
2068
2069		},
2070
2071		/**
2072		 * Logic to prevent submenus to go behind the next overlay row.
2073		 *
2074		 * @since  1.10.9
2075		 * @return void
2076		 */
2077		_submenuRowZindexFix: function(){
2078
2079			$( this.wrapperClass )
2080				.on( 'mouseenter', 'ul.menu > .fl-has-submenu', $.proxy( function( e ){
2081
2082					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
2083						return;
2084					}
2085
2086					$( this.nodeClass )
2087						.closest( '.fl-row' )
2088						.find( '.fl-row-content' )
2089						.css( 'z-index', '10' );
2090
2091				}, this ) )
2092				.on( 'mouseleave', 'ul.menu > .fl-has-submenu', $.proxy( function(){
2093
2094					$( this.nodeClass )
2095						.closest( '.fl-row' )
2096						.find( '.fl-row-content' )
2097						.css( 'z-index', '' );
2098
2099				}, this ) );
2100		},
2101
2102		/**
2103		 * Logic for the mobile menu button.
2104		 *
2105		 * @since  1.6.1
2106		 * @return void
2107		 */
2108		_toggleForMobile: function(){
2109
2110			var $wrapper = null,
2111				$menu    = null,
2112				self     = this;
2113
2114			$( this.wrapperClass ).find( 'ul.menu' ).attr( 'role', 'menu');
2115			$( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).attr('aria-controls', $( this.wrapperClass ).find( 'ul.menu' ).attr('id'));
2116
2117			if( this._isMenuToggle() ){
2118
2119				if ( this._isMobileBelowRowEnabled() ) {
2120					this._placeMobileMenuBelowRow();
2121					$wrapper = $( this.wrapperClass );
2122					$menu    = $( this.nodeClass + '-clone' );
2123					$menu.find( 'ul.menu' ).show();
2124				}
2125				else {
2126					$wrapper = $( this.wrapperClass );
2127					$menu    = $wrapper.find( '.menu' );
2128				}
2129
2130				if( !$wrapper.find( '.fl-menu-mobile-toggle' ).hasClass( 'fl-active' ) && ! self.mobileFlyout ){
2131					$menu.css({ display: 'none' });
2132				}
2133
2134				// Flayout Menu
2135				if ( self.mobileFlyout ) {
2136					this._initFlyoutMenu();
2137				}
2138
2139				$wrapper.on( 'click', '.fl-menu-mobile-toggle', function( e ){
2140					e.stopImmediatePropagation();
2141
2142					$( this ).toggleClass( 'fl-active' );
2143
2144					if ( self.mobileFlyout ) {
2145						self._toggleFlyoutMenu();
2146						const flyoutWrapper = $( '.fl-menu-mobile-flyout' );
2147						if ( $( this ).hasClass( 'fl-active' ) ) {
2148							flyoutWrapper.attr( 'aria-hidden', false );
2149							flyoutWrapper.find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex="-1"]' ).attr( 'tabindex', 0 );
2150						}
2151						else {
2152							flyoutWrapper.attr( 'aria-hidden', true );
2153							flyoutWrapper.find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex]:not
2153([tabindex="-1"])' ).attr( 'tabindex', -1 );
2154						}
2155					}
2156					else {
2157						var targetMenu = null;
2158
2159						if ( self.mobileBelowRow ) {
2160							var $closestCol = $( this ).parents( '.fl-col, .fl-module-box' ),
2161								$closestColGroup = $closestCol.length ? $closestCol.parent( '.fl-col-group' ) : null;
2162								targetMenu  = $closestCol.length ? $closestCol.last().next( '.fl-menu-mobile-clone' ) : null;
2163
2164							if ( $closestColGroup.length ) {
2165								if ( $closestColGroup.hasClass( 'fl-col-group-responsive-reversed' ) ) {
2166									$closestColGroup.find( '.fl-menu-mobile-clone' ).css( 'order', -1 );
2167								} else if ( $closestColGroup ) {
2168									$closestColGroup.find( '.fl-menu-mobile-clone' ).css( 'order', 2 );
2169								}
2170							}
2171						} else {
2172							targetMenu = $( this ).closest( '.fl-menu' ).find( 'ul.menu' );
2173						}
2174						
2175						if ( targetMenu.length ) {
2176							$menu = $( targetMenu );
2177						}
2178
2179						$menu.slideToggle();
2180					}
2181
2182					e.stopPropagation();
2183				} );
2184
2185				// Hide active menu when click on anchor link ID that exists on a page
2186				$menu.off().on( 'click', '.menu-item > a[href*="#"]:not([href="#"])', function(){
2187					var $href = $(this).attr('href'),
2188						$targetID = $href.split('#')[1],
2189						element = $('#' + $targetID);
2190					if ( $('body').find(element).length > 0 ) {
2191						$( this ).toggleClass( 'fl-active' );
2192						FLBuilderLayout._scrollToElement( element );
2193						if ( ! self._isMenuToggle() ) {
2194							$menu.slideToggle();
2195						}
2196					}
2197				});
2198			}
2199			else {
2200
2201				if ( this._isMobileBelowRowEnabled() ) {
2202					this._removeMenuFromBelowRow();
2203				}
2204
2205				$wrapper = $( this.wrapperClass ),
2206				$menu    = $wrapper.find( 'ul.menu' );
2207				$wrapper.find( '.fl-menu-mobile-toggle' ).removeClass( 'fl-active' );
2208				$menu.css({ display: '' });
2209
2210				if ( ! this._isMobileBelowRowEnabled() ) {
2211					$menu.off( 'click', '.menu-item > a[href*="#"]:not([href="#"])' );
2212				}
2213
2214				if ( this.mobileFlyout && $wrapper.find( '.fl-menu-mobile-flyout' ).length > 0 ) {
2215					$( 'body' ).css( 'margin', '' );
2216					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
2217					$menu.unwrap();
2218					$wrapper.find( '.fl-menu-mobile-close' ).remove();
2219					$wrapper.find( '.fl-menu-mobile-opacity' ).remove();
2220				}
2221			}
2222		},
2223
2224		/**
2225		 * Init any mega menus that exist.
2226		 *
2227		 * @see 	 this._isMenuToggle()
2228		 * @since  1.10.4
2229		 * @return void
2230		 */
2231		_initMegaMenus: function(){
2232
2233			var module     = $( this.nodeClass ),
2234				rowContent = module.closest( '.fl-row-content' ),
2235				rowWidth   = rowContent.width(),
2236				megas      = module.find( '.mega-menu' ),
2237				disabled   = module.find( '.mega-menu-disabled' ),
2238				isToggle   = this._isMenuToggle();
2239
2240			if ( isToggle ) {
2241				megas.removeClass( 'mega-menu' ).addClass( 'mega-menu-disabled' );
2242				module.find( 'li.mega-menu-disabled > ul.sub-menu' ).css( 'width', '' );
2243				rowContent.css( 'position', '' );
2244			} else {
2245				disabled.removeClass( 'mega-menu-disabled' ).addClass( 'mega-menu' );
2246				module.find( 'li.mega-menu > ul.sub-menu' ).css( 'width', rowWidth + 'px' );
2247				rowContent.css( 'position', 'relative' );
2248			}
2249		},
2250
2251		/**
2252		 * Check to see if Below Row should be enabled.
2253		 *
2254		 * @since  1.11
2255		 * @return boolean
2256		 */
2257		_isMobileBelowRowEnabled: function() {
2258			return this.mobileBelowRow && ( $( this.nodeClass ).parents( '.fl-col, .fl-module-box' ).length );
2259		},
2260
2261		/**
2262		 * Logic for putting the mobile menu below the menu's
2263		 * column so it spans the full width of the page.
2264		 *
2265		 * @since  1.10
2266		 * @return void
2267		 */
2268		_placeMobileMenuBelowRow: function(){
2269
2270			if ( $( this.nodeClass + '-clone' ).length ) {
2271				return;
2272			}
2273
2274			var module = $( this.nodeClass ),
2275				clone  = null,
2276				col    = module.parents( '.fl-col, .fl-module-box' ).last();
2277
2278			if ( module.length < 1 ) {
2279				return;
2280			}
2281
2282			clone = ( module.length > 1 ) ? $( module[0] ).clone() : module.clone();
2283			module.find( 'ul.menu' ).remove();
2284			clone.addClass( ( this.nodeClass + '-clone' ).replace( '.', '' ) );
2285			clone.addClass( 'fl-menu-mobile-clone' );
2286			clone.find( '.fl-menu-mobile-toggle' ).remove();
2287			col.after( clone );
2288
2289			// Removes animation when enabled
2290			if ( module.hasClass( 'fl-animation' ) ) {
2291				clone.removeClass( 'fl-animation' );
2292			}
2293
2294			this._menuOnFocus();
2295			this._menuOnClick();
2296			this._menuOnEscape();
2297		},
2298
2299		/**
2300		 * Logic for removing the mobile menu from below the menu's
2301		 * column and putting it back in the main wrapper.
2302		 *
2303		 * @since  1.10
2304		 * @return void
2305		 */
2306		_removeMenuFromBelowRow: function(){
2307
2308			if ( ! $( this.nodeClass + '-clone' ).length ) {
2309				return;
2310			}
2311
2312			var module = $( this.nodeClass ),
2313				clone  = $( this.nodeClass + '-clone' ),
2314				menu   = clone.find( 'ul.menu' );
2315
2316			module.find( '.fl-menu-mobile-toggle' ).after( menu );
2317			clone.remove();
2318			menu.find( 'a' ).each( FLBuilderLayout._initAnchorLink );
2319		},
2320
2321		/**
2322		 * Logic for Flyout responsive menu.
2323		 *
2324		 * @since  2.2
2325		 * @return void
2326		 */
2327		_initFlyoutMenu: function(){
2328			var wrapper = $( this.wrapperClass ),
2329				menu  	= wrapper.find( 'ul.menu' ),
2330				button	= wrapper.find( '.fl-menu-mobile-toggle' );
2331
2332			if ( 0 === wrapper.find( '.fl-menu-mobile-flyout' ).length ) {
2333				menu.wrap( '<div class="fl-menu-mobile-flyout" aria-hidden="true"></div>' );
2334			}
2335
2336			if ( 0 === wrapper.find( '.fl-menu-mobile-close' ).length ) {
2337				var close = window.fl_responsive_close || 'Close'
2338				wrapper.find( '.fl-menu-mobile-flyout' ).prepend( '<button class="fl-menu-mobile-close fl-content-ui-button" aria-label="' + close + '"><i class="fas fa-times"></i></button>' );
2339			}
2340
2341			// Push with opacity
2342			if ( wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ) && 0 === wrapper.find( '.fl-menu-mobile-opacity' ).length ) {
2343				wrapper.append( '<div class="fl-menu-mobile-opacity"></div>' );
2344			}
2345
2346			wrapper.off( 'click', '.fl-menu-mobile-opacity, .fl-menu-mobile-close' ).on( 'click', '.fl-menu-mobile-opacity, .fl-menu-mobile-close', function(e){
2347				button.trigger('focus').trigger( 'click' );
2348				e.stopPropagation();
2349			});
2350
2351			if ( 'undefined' !== typeof FLBuilder ) {
2352				FLBuilder.addHook('restartEditingSession', function(){
2353					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
2354
2355					// Toggle active menu
2356					if ( button.hasClass( 'fl-active' ) ) {
2357						button.trigger( 'click' );
2358					}
2359				});
2360			}
2361			$( '.fl-menu-mobile-flyout' ).find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex]:not([tabindex="-1"])' ).attr( 'tabindex', -1 );
2362		},
2363
2364		/**
2365		 * Logic to enable/disable the Flyout menu on button click.
2366		 *
2367		 * @since  2.2
2368		 * @return void
2369		 */
2370		_toggleFlyoutMenu: function(){
2371			var wrapper		= $( this.wrapperClass ),
2372				button		= wrapper.find( '.fl-menu-mobile-toggle' ),
2373				position 	= wrapper.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
2374				pushMenu 	= wrapper.hasClass( 'fl-menu-responsive-flyout-push' ) || wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
2375				opacity		= wrapper.find( '.fl-menu-mobile-opacity' ),
2376				marginPos	= {},
2377				fixedPos 	= {},
2378				fixedHeader	= $('header, header > div');
2379
2380			this._resizeFlyoutMenuPanel();
2381
2382			// Fix the push menu when builder ui panel is pinned
2383			if ( $( '.fl-builder-ui-pinned-content-transform' ).length > 0 && ! $( 'body' ).hasClass( 'fl-builder-edit' ) ) {
2384				$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', 'none' );
2385			}
2386
2387			if ( pushMenu ) {
2388				marginPos[ 'margin-' + position ] = button.hasClass( 'fl-active' ) ? this.flyoutWidth + 'px' : '0px';
2389				$( 'body' ).animate( marginPos, 200);
2390
2391				// Fixed header
2392				if ( fixedHeader.length > 0 ) {
2393					fixedPos[ position] = button.hasClass( 'fl-active' ) ? this.flyoutWidth + 'px' : '0px';
2394					fixedHeader.each(function(){
2395						if ( 'fixed' == $( this ).css( 'position' ) ) {
2396							$( this ).css({ 'transition' : 'none' });
2397							$( this ).animate( fixedPos, 200 );
2398						}
2399					});
2400				}
2401			}
2402
2403			if ( opacity.length > 0 && button.hasClass( 'fl-active' ) ) {
2404				opacity.show();
2405			}
2406			else {
2407				opacity.hide();
2408			}
2409		},
2410
2411		/**
2412		 * Resize or reposition the Flyout Menu Panel.
2413		 * 
2414		 * @since  2.8.1
2415		 * @return void
2416		 */
2417		_resizeFlyoutMenuPanel: function(){
2418			const wrapper    = $( this.wrapperClass );
2419			const wrapFlyout = wrapper.find( '.fl-menu-mobile-flyout' );
2420				
2421			if ( wrapFlyout.length > 0 ) {
2422				wrapFlyout.css( this._getFlyoutMenuPanelPosition() );
2423			}
2424		},
2425
2426		/**
2427		 * Compute the Flyout Menu Panel's position on the screen.
2428		 * 
2429		 * @since  2.8.1
2430		 * @return object
2431		 */
2432		_getFlyoutMenuPanelPosition: function() {
2433			var wrapper        = $( this.wrapperClass ),
2434				button         = wrapper.find( '.fl-menu-mobile-toggle' ),
2435				side           = wrapper.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
2436				winHeight      = $(window).outerHeight(),
2437				winTop         = $(window).scrollTop(),
2438				adminBarHeight = $( '#wpadminbar' ).length ? $( '#wpadminbar' ).height() : 0,
2439				flyoutPosition = {};
2440
2441			flyoutPosition[ side ]  = '-' + ( parseInt( this.flyoutWidth ) + 15 ) + 'px';
2442			if ( ! button.hasClass( 'fl-active' ) ) {
2443				return flyoutPosition;
2444			}
2445
2446			flyoutPosition[ side ]  = '0px';
2447			flyoutPosition[ 'height' ]  = winHeight + 'px';
2448			flyoutPosition[ 'top' ] = '0px';
2449			
2450			if ( adminBarHeight > 0 ) {
2451				const diff = adminBarHeight - winTop;
2452				flyoutPosition[ 'top' ] = diff <= 0 ? '0px' : (diff) + 'px';
2453			}
2454
2455			return flyoutPosition;
2456		},
2457
2458		/**
2459		 * Shows or hides the nav search form.
2460		 *
2461		 * @since  2.5
2462		 * @method _toggleMenuSearch
2463		 */
2464		_toggleMenuSearch: function(){
2465			var wrapper = $( this.wrapperClass ).find('.fl-menu-search-item'),
2466				button  = wrapper.find('.fl-button:is(a, button)'),
2467				form    = wrapper.find('.fl-search-form-input-wrap'),
2468				self    = this;
2469
2470			button.attr( 'tabindex', 0 );
2471			button.attr( 'aria-label', 'Search' );
2472			button.on('click', function(e){
2473				e.preventDefault();
2474
2475				if(form.is(':visible')) {
2476					form.stop().fadeOut(200);
2477				}
2478				else {
2479					form.stop().fadeIn(200);
2480					$('body').on('click.fl-menu-search', $.proxy(self._hideMenuSearch, self));
2481					form.find('.fl-search-text').focus();
2482				}
2483			});
2484		},
2485
2486		/**
2487		 * Hides the nav search form.
2488		 *
2489		 * @since  2.5
2490		 * @method _hideMenuSearch
2491		 */
2492		_hideMenuSearch: function(e){
2493			var form = $( this.wrapperClass ).find('.fl-search-form-input-wrap');
2494
2495			if(e !== undefined) {
2496				if($(e.target).closest('.fl-menu-search-item').length > 0) {
2497					return;
2498				}
2499			}
2500
2501			form.stop().fadeOut(200);
2502			$('body').off('click.fl-menu-search');
2503		},
2504
2505		/**
2506		 * Adds menu node and post ID to WooCommerce ajax URL requests.
2507		 *
2508		 * @since  2.5
2509		 * @return void
2510		 */
2511		_wooUpdateParams: function() {
2512			if ( 'undefined' !== typeof wc_cart_fragments_params ) {
2513				wc_cart_fragments_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
2514			}
2515			if ( 'undefined' !== typeof wc_add_to_cart_params ) {
2516				wc_add_to_cart_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
2517			}
2518		},
2519	};
2520
2521})(jQuery);
2522
2523(function($) {
2524
2525	$(function() {
2526
2527		new FLBuilderMenu({
2528			id: 'okf2zve5btrs',
2529			type: 'horizontal',
2530			mobile: 'expanded',
2531			mobileBelowRow: false,
2532			mobileFlyout: false,
2533			breakPoints: {
2534				large: 1200,
2535				medium: 1024,
2536				small: 768			},
2537			mobileBreakpoint: 'mobile',
2538			postId : '44',
2539			mobileStacked: true,
2540			submenuIcon: 'none',
2541			flyoutWidth: '250',
2542		});
2543
2544	});
2545
2546})(jQuery);
2547(function($) {
2548	if ( $('.fl-node-w5bugk8427ny .pp-photo-rollover').length > 0 ) {
2549		$('body').on( 'mouseenter.pp-rollover', '.fl-node-w5bugk8427ny .pp-photo-rollover .pp-photo-content', function() {
2550			$(this).addClass( 'is-hover' );
2551		} ).on( 'mouseleave.pp-rollover', '.fl-node-w5bugk8427ny .pp-photo-rollover .pp-photo-content', function() {
2552			$(this).removeClass( 'is-hover' );
2553		} );
2554	}
2555})(jQuery);
2556;(function($) {
2557
2558	PPSearchForm = function(settings) {
2559		this.id 	= settings.id;
2560		this.node 	= $('.fl-node-' + this.id);
2561		this.form	= this.node.find('.pp-search-form');
2562		this.selectors = {
2563			input: '.fl-node-' + this.id + ' .pp-search-form__input',
2564			toggle: '.fl-node-' + this.id + ' .pp-search-form__toggle',
2565			container: '.fl-node-' + this.id + ' .pp-search-form__container',
2566		};
2567
2568		this._init();
2569	};
2570
2571	PPSearchForm.prototype = {
2572		id  : '',
2573		node: '',
2574		form: '',
2575
2576		_init: function() {
2577			$( this.selectors.input ).on( 'focus', function() {
2578				this.form.addClass('pp-search-form--focus');
2579			}.bind( this ) ).on( 'blur', function() {
2580				this.form.removeClass('pp-search-form--focus');
2581			}.bind( this ) );
2582
2583			$( this.selectors.toggle ).on( 'click', function() {
2584				$( this.selectors.container ).addClass('pp-search-form--lightbox').find('.pp-search-form__input').trigger( 'focus' );
2585				this._focus( this.form );
2586			}.bind( this ) );
2587
2588			this.form.find('.pp-search-form--lightbox-close').on( 'click', function() {
2589				$( this.selectors.container ).removeClass('pp-search-form--lightbox');
2590			}.bind( this ) );
2591
2592			// close modal box on Esc key press.
2593			$(document).on( 'keyup', function(e) {
2594                if ( 27 == e.which && this.form.find('.pp-search-form--lightbox').length > 0 ) {
2595                    $( this.selectors.container ).removeClass('pp-search-form--lightbox');
2596                }
2597			}.bind( this ) );
2598		},
2599
2600		_focus: function( form ) {
2601			var $el = form.find('.pp-search-form__input');
2602
2603			// If this function exists... (IE 9+)
2604			if ( $el[0].setSelectionRange ) {
2605				// Double the length because Opera is inconsistent about whether a carriage return is one character or two.
2606				var len = $el.val().length * 2;
2607
2608				// Timeout seems to be required for Blink
2609				setTimeout(function() {
2610					$el[0].setSelectionRange( len, len );
2611				}, 1);
2612			} else {
2613				// As a fallback, replace the contents with itself
2614				// Doesn't work in Chrome, but Chrome supports setSelectionRange
2615				$el.val( $el.val() );
2616			}
2617		}
2618	};
2619
2620})(jQuery);(function($) {
2621	
2622	new PPSearchForm({
2623		id: 'uy4hvsaj8n93',
2624	});
2625
2626})(jQuery);(function($) {
2627	if ( $('.fl-node-dnu7zsk4ehv1 .pp-photo-rollover').length > 0 ) {
2628		$('body').on( 'mouseenter.pp-rollover', '.fl-node-dnu7zsk4ehv1 .pp-photo-rollover .pp-photo-content', function() {
2629			$(this).addClass( 'is-hover' );
2630		} ).on( 'mouseleave.pp-rollover', '.fl-node-dnu7zsk4ehv1 .pp-photo-rollover .pp-photo-content', function() {
2631			$(this).removeClass( 'is-hover' );
2632		} );
2633	}
2634})(jQuery);(function($) {
2635	if ( $('.fl-node-duo7a3160wip .pp-photo-rollover').length > 0 ) {
2636		$('body').on( 'mouseenter.pp-rollover', '.fl-node-duo7a3160wip .pp-photo-rollover .pp-photo-content', function() {
2637			$(this).addClass( 'is-hover' );
2638		} ).on( 'mouseleave.pp-rollover', '.fl-node-duo7a3160wip .pp-photo-rollover .pp-photo-content', function() {
2639			$(this).removeClass( 'is-hover' );
2640		} );
2641	}
2642})(jQuery);(function($) {
2643	
2644	new PPSearchForm({
2645		id: 'nkofz5gsl76h',
2646	});
2647
2648})(jQuery);
2649;(function($) {
2650
2651	PPModalBox = function(settings) {
2652		this.id 			= settings.id;
2653		this.settings 		= settings;
2654		this.type			= settings.type;
2655		this.cookieKey		= 'pp_modal_' + this.id;
2656		this.cookieTime 	= settings.display_after;
2657		this.cookieValue 	= settings.cookie_value ? settings.cookie_value : this.cookieTime;
2658		this.triggerType 	= settings.trigger_type;
2659		this.layout			= settings.layout;
2660		this.wrap 			= $('#modal-' + this.id);
2661		this.container 		= this.wrap.find('.pp-modal-container');
2662		this.element 		= this.wrap.find('.pp-modal');
2663		this.isPreviewing 	= settings.previewing;
2664		this.isVisible		= settings.visible;
2665		this.eventClose		= false;
2666
2667		this.initCookieApi();
2668		this.init();
2669	};
2670
2671	PPModalBox.prototype = {
2672		id			: '',
2673		settings	: {},
2674		type		: '',
2675		cookieKey	: '',
2676		cookieTime	: 0,
2677		triggerType	: '',
2678		layout		: '',
2679		wrap		: '',
2680		element		: '',
2681		prevFocusedEl: '',
2682		isActive	: false,
2683		isPreviewing: false,
2684		isVisible	: false,
2685		eventClose  : false,
2686
2687		init: function()
2688		{
2689			if ( parseInt( this.cookieTime ) === 0 || this.cookieTime < 0 || this.cookieTime === '' ) {
2690				this.removeCookie();
2691			}
2692			if ( ( 'exit_intent' === this.triggerType || 'auto' === this.triggerType ) && this.getCookie() && ! this.isPreviewing ) {
2693				return;
2694			}
2695			if ( ! this.isPreviewing && 'undefined' !== typeof this.isVisible && ! this.isVisible ) {
2696				return;
2697			}
2698			if ( this.isActive ) {
2699				return;
2700			}
2701
2702			this.setResponsive();
2703			this.bindEvents();
2704			this.show();
2705		},
2706
2707		setResponsive: function()
2708		{
2709			if ( window.innerWidth <= this.settings.breakpoint ) {
2710                this.element.removeClass('layout-standard').addClass('layout-fullscreen');
2711            }
2712            if ( window.innerWidth < this.element.width() ) {
2713				this.element.css('width', window.innerWidth + 'px');
2714            }
2715		},
2716
2717		bindEvents: function()
2718		{
2719			var self = this;
2720
2721			$( this.element ).on( 'beforeload', this.beforeLoad.bind( this ) );
2722
2723			$(document).on( 'keyup', function(e) {
2724				// close modal box on Esc key press.
2725                if ( self.settings.esc_exit && 27 == e.which && self.isActive && $('form[data-type="pp-modal-box"]').length === 0 ) {
2726					self.eventClose = true;
2727                    self.hide();
2728                }
2729			}).on( 'keydown', function(e) {
2730				// trap focus inside the modal element.
2731				if ( (e.key === 'Tab' || e.keyCode === 9) && self.isActive ) {
2732					if ( e.shiftKey && $(document.activeElement).is( self.element ) ) {
2733						e.preventDefault();
2734					}
2735					if ( $(document.activeElement).closest( self.element ).length === 0 ) {
2736						self.element.trigger('focus');
2737						e.preventDefault();
2738					}
2739				}
2740			} );
2741
2742			// close modal box by clicking on outside of modal box element in document.
2743			$(document).on( 'click', function(e) {
2744                if ( self.settings.click_exit && $(e.target).parents('.pp-modal').length === 0 && self.isActive && ! self.isPreviewing && ! self.element.is(e.target) && self.element.has(e.target).length === 0 && ! $(e.target).hasClass('modal-' + self.id) && $(e.target).parents('.modal
2744-' + self.id).length === 0 && e.which ) {
2745					self.eventClose = true;
2746                    self.hide();
2747                }
2748			});
2749			
2750			// close modal box by clicking on the close button.
2751            $(self.wrap).find('.pp-modal-close, .pp-modal-close-custom').on('keypress click', function(e) {
2752				e.preventDefault();
2753				e.stopPropagation();
2754				if (e.which == 1 || e.which == 13 || e.which == 32 || e.which == undefined) {
2755					self.eventClose = true;
2756					self.hide();
2757				}
2758			});
2759
2760			// close the modal box on clicking on inner links start with hash.
2761			$('body').on( 'click', '#modal-' + self.id + ' .pp-modal-content a[href*="#"]:not([href="#"])', function() {
2762				if ( $('.fl-node-' + self.id).hasClass('anchor-click-no-event') ) {
2763					return;
2764				}
2765				self.eventClose = true;
2766                self.hide();
2767			} );
2768
2769			$(window).on( 'resize', this.setResponsive.bind( this ) );
2770			$(window).on( 'resize', this.setPosition.bind( this ) );
2771		},
2772
2773		setPosition: function()
2774		{
2775			if ( 'fullscreen' !== this.layout ) {
2776                if ( typeof this.settings.height === 'undefined' ) {
2777
2778                    this.wrap.addClass('pp-modal-height-auto');
2779                    var modalHeight = this.element.outerHeight();
2780                    this.wrap.removeClass('pp-modal-height-auto');
2781
2782                    if ( 'photo' === this.type ) {
2783                        this.element.find( '.pp-modal-content-inner img' ).css( 'max-width', '100%' );
2784                    }
2785
2786                    var topPos = ( window.innerHeight - modalHeight ) / 2;
2787                    if ( topPos < 0 ) {
2788                        topPos = 0;
2789                    }
2790                    this.element.css( 'top', topPos + 'px' );
2791                } else {
2792                    var topPos = ( window.innerHeight - this.settings.height ) / 2;
2793					if ( topPos < 0 ) {
2794                        topPos = 0;
2795                    }
2796                    this.element.css( 'top', topPos + 'px' );
2797                }
2798			}
2799		},
2800
2801		beforeLoad: function() {
2802			if ( this.settings.clickedElement ) {
2803				var clickedElement = this.settings.clickedElement;
2804				var postId = clickedElement.attr( 'data-pp-modal-post' ) || clickedElement.closest( '[data-pp-modal-post]' ).attr( 'data-pp-modal-post' ) || clickedElement.parents( '.pp-content-post' ).attr( 'data-id' );
2805				var self = this;
2806
2807				if ( 'undefined' === typeof postId || '' === postId ) {
2808					return;
2809				}
2810
2811				if ( 'html' === self.settings.type && '' !== self.settings.content ) {
2812					self.element.find( '.pp-modal-content-inner' ).html('<div style="text-align: center;"><img src="' + self.settings.loaderImg + '" /></div>');
2813					self.setPosition();
2814					$.ajax({
2815						url: bb_powerpack.getAjaxUrl(),
2816						type: 'post',
2817						data: {
2818							action: 'pp_modal_dynamic_content',
2819							content: self.settings.content,
2820							postId: postId
2821						},
2822						success: function( response ) {
2823							if ( ! response.success ) {
2824								return;
2825							}
2826
2827							self.element.find( '.pp-modal-content-inner' ).html( response.data );
2828							self.setPosition();
2829						}
2830					});
2831				}
2832			}
2833		},
2834
2835		show: function()
2836		{
2837			if ( this.element.length === 0 ) {
2838				return;
2839			}
2840
2841			this.setPosition();
2842
2843			var self = this;
2844
2845			if ( 'photo' === this.type ) {
2846				this.element.find( '.pp-modal-content-inner img' ).css( 'max-width', '100%' );
2847			}
2848
2849			this.prevFocusedEl = $( document.activeElement );
2850
2851			//this.element.find( '.pp-modal-content' ).scrollTop(0);
2852			
2853			setTimeout( function() {
2854				self.element.trigger('beforeload');
2855
2856				if ( ! self.isPreviewing ) {
2857					setTimeout(function() {
2858						self.element.attr( 'tabindex', '0' ).trigger( 'focus' );
2859					}, 100);
2860				}
2861
2862				$('html').addClass( 'pp-modal-active-' + self.id );
2863
2864				self.wrap.addClass( 'pp-modal-active' );
2865
2866				self.container
2867					.removeClass( self.settings.animation_load + ' animated' )
2868					.addClass( 'modal-visible' )
2869					.addClass( self.settings.animation_load + ' animated' );
2870
2871				if ( ! $('body').hasClass('wp-admin') ) {
2872					self.container.one( 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
2873						self.eventClose = false;
2874						$(this).removeClass( self.settings.animation_load + ' animated' );
2875						self.setup();
2876					} );
2877				} else {
2878					self.setup();
2879				}
2880
2881				self.isActive = true;
2882				
2883                if ( 'exit_intent' === self.triggerType || 'auto' === self.triggerType ){
2884                    if ( ! self.isPreviewing ) {
2885                        self.setCookie();
2886                    }
2887				}
2888				
2889                self.restruct();
2890				self.setPosition();
2891
2892				self.element.trigger('afterload');
2893				$(document).trigger( 'pp_modal_box_rendered', [self.element] );
2894				
2895            }, self.settings.auto_load ? parseFloat(self.settings.delay) * 1000 : 0);
2896		},
2897
2898		setup: function()
2899		{
2900			if ( this.element.find('.pp-modal-iframe').length > 0 ) {
2901				var original_src = this.element.find('.pp-modal-iframe').attr('src');
2902				var src = this.element.find('.pp-modal-iframe').data('url');
2903				if ( original_src === undefined || original_src === '' ) {
2904					this.element.find('.pp-modal-iframe').attr( 'src', src );
2905				}
2906			}
2907
2908			var iframeAndSource = this.element.find('iframe, source');
2909			if ( iframeAndSource.length > 0 && iframeAndSource.closest( '.fl-module' ).length === 0 ) {
2910				var src = '';
2911				var m_src = iframeAndSource.attr('src');
2912				
2913				if ( m_src === undefined || m_src === '' ) {
2914					src = iframeAndSource.data('url');
2915				} else {
2916					src = iframeAndSource.attr('src');
2917				}
2918
2919				if ( src ) {
2920					if ( ( src.search('youtube') !== -1 || src.search('vimeo') !== -1) && src.search('autoplay=1') == -1 ) {
2921						if ( typeof src.split('?')[1] === 'string' ) {
2922							src = src + '&autoplay=1&rel=0';
2923						} else {
2924							src = src + '?autoplay=1&rel=0';
2925						}
2926					}
2927					iframeAndSource.attr('src', src);
2928				}
2929			}
2930
2931			if ( this.element.find('video').length ) {
2932				this.element.find('video')[0].play();
2933			}
2934		},
2935
2936		reset: function()
2937		{
2938            var iframeAndSource = this.element.find('iframe, source');
2939			if ( iframeAndSource.length > 0 && iframeAndSource.closest( '.fl-module' ).length === 0 ) {
2940				var src = iframeAndSource.attr('src');
2941				if ( '' !== src ) {
2942					iframeAndSource.attr('data-url', src).attr('src', '');
2943				}
2944            }
2945			if ( this.element.find('video').length > 0 ) {
2946				this.element.find('video')[0].pause();
2947			}
2948			if ( this.element.find('mux-player').length > 0 ) {
2949				this.element.find('mux-player')[0].pause();
2950			}
2951
2952			this.element.attr( 'tabindex', '-1' );
2953			var self = this;
2954			
2955			setTimeout(function() {
2956				if ( self.settings.clickedElement ) {
2957					var $clickedElement = self.settings.clickedElement;
2958					if ( $clickedElement.closest( '.modal-' + self.id ).length ) {
2959						$clickedElement.closest( '.modal-' + self.id ).trigger( 'focus' );
2960					} else if ( $clickedElement.closest( '#trigger-' + self.id ).length ) {
2961						$clickedElement.closest( '#trigger-' + self.id ).trigger( 'focus' );
2962					}
2962 else if ( '' !== self.settings.customTrigger ) {
2963						if ( $clickedElement.is( self.settings.customTrigger ) ) {
2964							$clickedElement.trigger( 'focus' );
2965						} else if ( $clickedElement.closest( self.settings.customTrigger ).length ) {
2966							$clickedElement.closest( self.settings.customTrigger ).trigger( 'focus' );
2967						}
2968					}
2969				}
2970			}, 100);
2971        },
2972
2973		restruct: function()
2974		{
2975			var mH = 0, hH = 0, cH = 0, eq = 0;
2976			var self = this;
2977
2978            setTimeout( function() {
2979                if ( self.isActive ) {
2980                    if ( 'fullscreen' === self.layout ) {
2981                        var marginTop 		= parseInt( self.element.css('margin-top') );
2982                        var marginBottom 	= parseInt( self.element.css('margin-bottom') );
2983                        var modalHeight 	= $(window).height() - (marginTop + marginBottom);
2984						
2985						self.element.css( 'height', modalHeight + 'px' );
2986                    }
2987                    eq = 6;
2988                    mH = self.element.outerHeight(); // Modal height.
2989                    hH = self.element.find('.pp-modal-header').outerHeight(); // Header height.
2990
2991                    if ( self.settings.auto_height && 'fullscreen' !== self.layout ) {
2992                        return;
2993					}
2994					
2995					var cP = parseInt( self.element.find('.pp-modal-content').css('padding') ); // Content padding.
2996					
2997					self.element.find('.pp-modal-content').css( 'height', mH - (hH + eq) + 'px' );
2998					
2999                    if ( ! self.settings.auto_height && self.element.find('.pp-modal-header').length === 0) {
3000                        self.element.find('.pp-modal-content').css('height', mH + 'px');
3001                    }
3002				   
3003					// Adjust iframe height.
3004                    if ( 'url' === self.type && self.element.find( '.pp-modal-video-embed' ).length === 0 ) {
3005                        self.element.find('.pp-modal-iframe').css('height', self.element.find('.pp-modal-content-inner').outerHeight() + 'px');
3006                    }
3007                    if ( 'video' === self.type ) {
3008                        self.element.find('iframe').css({'height':'100%', 'width':'100%'});
3009                    }
3010                }
3011            }, self.settings.auto_load ? parseFloat(self.settings.delay) * 1000 : 1);
3012		},
3013
3014		hide: function()
3015		{
3016			var self = this;
3017
3018			this.element.trigger('beforeclose');
3019
3020            this.container
3021                .removeClass( self.settings.animation_exit + ' animated' )
3022				.addClass( self.settings.animation_exit + ' animated' );
3023				
3024			if ( ! $('body').hasClass('wp-admin') ) {
3025				this.container.one( 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
3026					if ( self.eventClose ) {
3027						self.close();
3028					}
3029				});
3030			} else {
3031				self.close();
3032			}
3033				
3034            if ( window.location.hash ) {
3035				var hashVal = window.location.hash.replace('/', '');
3036                if ( '#modal-' + self.id === hashVal ) {
3037                    var scrollTop = self.settings.scrollTop || $(window).scrollTop();
3038                    window.location.href = window.location.href.split('#')[0] + '#';
3039                    $(window).scrollTop(scrollTop);
3040                }
3041			}
3042
3043			if ( ! this.isPreviewing ) {
3044				this.element.attr( 'tabindex', '-1' ).trigger( 'blur' );
3045				if ( this.prevFocusedEl && this.prevFocusedEl.length > 0 ) {
3046					this.prevFocusedEl.trigger( 'focus' );
3047				}
3048			}
3049			
3050			this.element.trigger('afterclose');
3051			$(document).trigger( 'pp_modal_box_after_close', [this.element, this] );
3052		},
3053
3054		close: function()
3055		{
3056			this.container.removeClass( this.settings.animation_exit + ' animated' ).removeClass('modal-visible');
3057			this.container.find('.pp-modal-content').removeAttr('style');
3058			this.wrap.removeClass( 'pp-modal-active' );
3059
3060			$('html').removeClass( 'pp-modal-active-' + this.id );
3061
3062			this.isActive = false;
3063			this.eventClose = false;
3064			this.reset();
3065		},
3066
3067		initCookieApi: function() {
3068			if ( 'undefined' === typeof $.cookie ) {
3069				/*!
3070				 * jQuery Cookie Plugin v1.4.1
3071				 * https://github.com/carhartl/jquery-cookie
3072				 *
3073				 * Copyright 2013 Klaus Hartl
3074				 * Released under the MIT license
3075				*/
3076				!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}});
3077			}
3078		},
3079
3080		setCookie: function()
3081		{
3082			if ( parseInt( this.cookieTime ) > 0 ) {
3083				return $.cookie( this.cookieKey, this.cookieValue, {expires: this.cookieTime, path: '/'} );
3084			} else {
3085				this.removeCookie();
3086			}
3087		},
3088
3089		getCookie: function()
3090		{
3091			// Reset cookie when module settings change.
3092			if ( this.cookieValue != $.cookie( this.cookieKey ) ) {
3093				this.removeCookie();
3094			}
3095			return $.cookie( this.cookieKey );
3096		},
3097
3098		removeCookie: function()
3099		{
3100			$.cookie( this.cookieKey, 0, {expires: 0, path: '/'} );
3101		}
3102	};
3103})(jQuery);
3104
3105var pp_modal_b0hytrzd9g6c = false;
3106var pp_modal_b0hytrzd9g6c_config = false;
3107
3108;(function($) {
3109
3110    pp_modal_b0hytrzd9g6c_config = {
3111        id: 'b0hytrzd9g6c',
3112        type: 'templates',
3113		trigger_type: 'onclick',
3114        auto_load: false,
3115        exit_intent: false,
3116                		        delay: 1,
3117        animation_load: 'fadeIn',
3118        animation_exit: 'fadeOut',
3119		overlay_animation: true,
3120        esc_exit: true,
3121        click_exit: true,
3122        layout: 'fullscreen',
3123        auto_height: true,
3124                width: 550,
3125        breakpoint: 0,
3126        		loaderImg: 'https://shepherdess.co.nz/wp-content/plugins/bbpowerpack/assets/images/ajax-loader.gif',
3127        previewing: false    };
3128
3129	
3130    $(document).on('click', function(e) {
3131        if ( e && e.target.tagName === 'A' && e.target.href.indexOf('#modal-b0hytrzd9g6c') !== -1 ) {
3132            pp_modal_b0hytrzd9g6c_config['scrollTop'] = $(window).scrollTop();
3133        }
3134    });
3135
3136        $(function() {
3137        $('#modal-b0hytrzd9g6c').appendTo(document.body);
3138
3139        var tabHash     = window.location.hash ? window.location.hash.replace('/', '') : false;
3140        var modalId     = window.location.hash.split('#modal-')[1];
3141
3142        // If the URL contains a hash beginning with modal, trigger that modal box.
3143        if ( tabHash && tabHash.indexOf('modal-') >= 0 ) {
3144            if ( modalId === 'b0hytrzd9g6c' ) {
3145                pp_modal_b0hytrzd9g6c = new PPModalBox(pp_modal_b0hytrzd9g6c_config);
3146            }
3147        }
3148
3149        $(window).on('hashchange', function() {
3150            var tabHash     = window.location.hash;
3151            var modalId     = window.location.hash.split('#modal-')[1];
3152
3153            // If the URL contains a hash beginning with modal, trigger that modal box.
3154            if ( tabHash && tabHash.indexOf('modal-') >= 0 ) {
3155                if ( modalId === 'b0hytrzd9g6c' ) {
3156					if ( pp_modal_b0hytrzd9g6c instanceof PPModalBox ) {
3157						pp_modal_b0hytrzd9g6c.show();
3158					} else {
3159                    	pp_modal_b0hytrzd9g6c = new PPModalBox(pp_modal_b0hytrzd9g6c_config);
3160					}
3161                }
3162            }
3163        });
3164
3165    });
3166
3167		
3168		    
3169	// Bind the click event to any element with the class.
3170	pp_modal_b0hytrzd9g6c_config.customTrigger = '';
3171    $(document).on('click keydown', '.modal-b0hytrzd9g6c', function(e) {
3172		var valid = (e.which == 1 || e.which == 13 || e.which == 32 || e.which == undefined);
3173		if ( ! valid ) {
3174			return;
3175		}
3176        e.preventDefault();
3177		if ( pp_modal_b0hytrzd9g6c instanceof PPModalBox ) {
3178			pp_modal_b0hytrzd9g6c.settings.clickedElement = $( e.target );
3179			pp_modal_b0hytrzd9g6c.show();
3180        } else {
3181			pp_modal_b0hytrzd9g6c_config.clickedElement = $( e.target );
3182        	pp_modal_b0hytrzd9g6c = new PPModalBox(pp_modal_b0hytrzd9g6c_config);
3183        }
3184    });
3185
3186    
3187})(jQuery);
3188
3189var pp_modal_dwtkhgenzj2p = false;
3190var pp_modal_dwtkhgenzj2p_config = false;
3191
3192;(function($) {
3193
3194    pp_modal_dwtkhgenzj2p_config = {
3195        id: 'dwtkhgenzj2p',
3196        type: 'templates',
3197		trigger_type: 'onclick',
3198        auto_load: false,
3199        exit_intent: false,
3200                		        delay: 1,
3201        animation_load: 'fadeIn',
3202        animation_exit: 'fadeOut',
3203		overlay_animation: true,
3204        esc_exit: true,
3205        click_exit: true,
3206        layout: 'fullscreen',
3207        auto_height: true,
3208                width: 550,
3209        breakpoint: 0,
3210        		loaderImg: 'https://shepherdess.co.nz/wp-content/plugins/bbpowerpack/assets/images/ajax-loader.gif',
3211        previewing: false    };
3212
3213	
3214    $(document).on('click', function(e) {
3215        if ( e && e.target.tagName === 'A' && e.target.href.indexOf('#modal-dwtkhgenzj2p') !== -1 ) {
3216            pp_modal_dwtkhgenzj2p_config['scrollTop'] = $(window).scrollTop();
3217        }
3218    });
3219
3220        $(function() {
3221        $('#modal-dwtkhgenzj2p').appendTo(document.body);
3222
3223        var tabHash     = window.location.hash ? window.location.hash.replace('/', '') : false;
3224        var modalId     = window.location.hash.split('#modal-')[1];
3225
3226        // If the URL contains a hash beginning with modal, trigger that modal box.
3227        if ( tabHash && tabHash.indexOf('modal-') >= 0 ) {
3228            if ( modalId === 'dwtkhgenzj2p' ) {
3229                pp_modal_dwtkhgenzj2p = new PPModalBox(pp_modal_dwtkhgenzj2p_config);
3230            }
3231        }
3232
3233        $(window).on('hashchange', function() {
3234            var tabHash     = window.location.hash;
3235            var modalId     = window.location.hash.split('#modal
3235-')[1];
3236
3237            // If the URL contains a hash beginning with modal, trigger that modal box.
3238            if ( tabHash && tabHash.indexOf('modal-') >= 0 ) {
3239                if ( modalId === 'dwtkhgenzj2p' ) {
3240					if ( pp_modal_dwtkhgenzj2p instanceof PPModalBox ) {
3241						pp_modal_dwtkhgenzj2p.show();
3242					} else {
3243                    	pp_modal_dwtkhgenzj2p = new PPModalBox(pp_modal_dwtkhgenzj2p_config);
3244					}
3245                }
3246            }
3247        });
3248
3249    });
3250
3251		
3252		    
3253	// Bind the click event to any element with the class.
3254	pp_modal_dwtkhgenzj2p_config.customTrigger = '';
3255    $(document).on('click keydown', '.modal-dwtkhgenzj2p', function(e) {
3256		var valid = (e.which == 1 || e.which == 13 || e.which == 32 || e.which == undefined);
3257		if ( ! valid ) {
3258			return;
3259		}
3260        e.preventDefault();
3261		if ( pp_modal_dwtkhgenzj2p instanceof PPModalBox ) {
3262			pp_modal_dwtkhgenzj2p.settings.clickedElement = $( e.target );
3263			pp_modal_dwtkhgenzj2p.show();
3264        } else {
3265			pp_modal_dwtkhgenzj2p_config.clickedElement = $( e.target );
3266        	pp_modal_dwtkhgenzj2p = new PPModalBox(pp_modal_dwtkhgenzj2p_config);
3267        }
3268    });
3269
3270    
3271})(jQuery);
3272
3273/* Start Global Node Custom JS */
3274
3275/* End Global Node Custom JS */
3276
3277
3278/* Start Layout Custom JS */
3279jQuery('#fl-main-content').on('click', function(e){
3280  jQuery('.search-bar').fadeOut('fast');
3281});
3282
3283const body = document.body;
3284const scrollUp = "nav-up";
3285const scrollDown = "nav-down";
3286let lastScroll = 0;
3287
3288
3289window.addEventListener("scroll", () => {
3290  const currentScroll = window.scrollY;
3291  if (currentScroll <= 0) {
3292    body.classList.remove(scrollUp);
3293    return;
3294  }
3295
3296  if (currentScroll > lastScroll && !body.classList.contains(scrollDown)) {
3297    // down
3298    body.classList.remove(scrollUp);
3299    body.classList.add(scrollDown);
3300  } else if ( currentScroll < lastScroll && body.classList.contains(scrollDown) ) {
3301    // up
3302    body.classList.remove(scrollDown);
3303    body.classList.add(scrollUp);
3304  }
3305  lastScroll = currentScroll;
3306});
3307/* End Layout Custom JS */
3308
3309(function($){
3310
3311	/**
3312	 * Helper class for header layout logic.
3313	 *
3314	 * @since 1.0
3315	 * @class FLThemeBuilderHeaderLayout
3316	 */
3317	FLThemeBuilderHeaderLayout = {
3318
3319		/**
3320		 * A reference to the window object for this page.
3321		 *
3322		 * @since 1.0
3323		 * @property {Object} win
3324		 */
3325		win : null,
3326
3327		/**
3328		 * A reference to the body object for this page.
3329		 *
3330		 * @since 1.0
3331		 * @property {Object} body
3332		 */
3333		body : null,
3334
3335		/**
3336		 * A reference to the header object for this page.
3337		 *
3338		 * @since 1.0
3339		 * @property {Object} header
3340		 */
3341		header : null,
3342
3343		/**
3344		 * Whether this header overlays the content or not.
3345		 *
3346		 * @since 1.0
3347		 * @property {Boolean} overlay
3348		 */
3349		overlay : false,
3350
3351		/**
3352		 * Whether the page has the WP admin bar or not.
3353		 *
3354		 * @since 1.0
3355		 * @property {Boolean} hasAdminBar
3356		 */
3357		hasAdminBar : false,
3358
3359		/**
3360		 * Breakpoint for when the sticky header should apply.
3361		 *
3362		 * @since 1.4
3363		 * @property {String} stickyOn
3364		 */
3365		stickyOn: '',
3366
3367		/**
3368		 * A reference of the sticky and shrink header breakpoint.
3369		 *
3370		 * @since 1.2.5
3371		 * @property {Number} breakpointWidth
3372		 */
3373		breakpointWidth: 0,
3374
3375		/**
3376		 * Initializes header layout logic.
3377		 *
3378		 * @since 1.0
3379		 * @method init
3380		 */
3381		init: function()
3382		{
3383			var editing          = $( 'html.fl-builder-edit' ).length,
3384				header           = $( '.fl-builder-content[data-type=header]' ),
3385				menuModule       = header.find( '.fl-module-menu' ),
3386				breakpoint       = null;
3387
3388			if ( ! editing && header.length ) {
3389
3390				header.imagesLoaded( $.proxy( function() {
3391
3392					this.win         = $( window );
3393					this.body        = $( 'body' );
3394					this.header      = header.eq( 0 );
3395					this.overlay     = !! Number( header.attr( 'data-overlay' ) );
3396					this.hasAdminBar = !! $( 'body.admin-bar' ).length;
3397					this.stickyOn    = this.header.data( 'sticky-on' );
3398					breakpoint       = this.header.data( 'sticky-breakpoint' );
3399
3400					if ( '' == this.stickyOn ) {
3401						if ( typeof FLBuilderLayoutConfig.breakpoints[ breakpoint ] !== undefined ) {
3402							this.breakpointWidth = FLBuilderLayoutConfig.breakpoints[ breakpoint ];
3403						}
3404						else {
3405							this.breakpointWidth = FLBuilderLayoutConfig.breakpoints.medium;
3406						}
3407					}
3408
3409					if ( Number( header.attr( 'data-sticky' ) ) ) {
3410
3411						this.header.data( 'original-top', this.header.offset().top );
3412						this.win.on( 'resize', $.throttle( 500, $.proxy( this._initSticky, this ) ) );
3413						this._initSticky();
3414
3415					}
3416
3417				}, this ) );
3418			}
3419		},
3420
3421		/**
3422		 * Initializes sticky logic for a header.
3423		 *
3424		 * @since 1.0
3425		 * @access private
3426		 * @method _initSticky
3427		 */
3428		_initSticky: function( e )
3429		{
3430			var header     = $('.fl-builder-content[data-type=header]'),
3431				windowSize = this.win.width(),
3432				makeSticky = false;
3433
3434			makeSticky = this._makeWindowSticky( windowSize );
3435			if ( makeSticky || ( this.breakpointWidth > 0 && windowSize >= this.breakpointWidth ) ) {
3436				this.win.on( 'scroll.fl-theme-builder-header-sticky', $.proxy( this._doSticky, this ) );
3437				//
3438				// Check if Event Type is 'resize' then invoke this._doSticky()
3439				// only if the 'fl-theme-builder-header-sticky' class is already present.
3440				//
3441				if ( e && 'resize' === e.type ) {
3442					if ( this.header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
3443						this._doSticky( e );
3444					}
3445					this._adjustStickyHeaderWidth();
3446				}
3447
3448				if ( Number( header.attr( 'data-shrink' ) ) ) {
3449					this.header.data( 'original-height', this.header.outerHeight() );
3450					this.win.on( 'resize', $.throttle( 500, $.proxy( this._initShrink, this ) ) );
3451					this._initShrink();
3452				}
3453
3454				this._initFlyoutMenuFix( e );
3455			} else {
3456				this.win.off( 'scroll.fl-theme-builder-header-sticky' );
3457				this.win.off( 'resize.fl-theme-builder-header-sticky' );
3458
3459				this.header.removeClass( 'fl-theme-builder-header-sticky' );
3460				this.header.removeAttr( 'style' );
3461				this.header.parent().css( 'padding-top', '0' );
3462			}
3463		},
3464
3465		/**
3466		 * Check if Header should be sticky at a particular Window size.
3467		 *
3468		 * @since 1.4
3469		 * @access private
3470		 * @param  widowSize
3471		 * @method _makeWindowSticky
3472		 */
3473		_makeWindowSticky: function ( windowSize )
3474		{
3475			var makeSticky = false;
3476
3477			switch (this.stickyOn) {
3478				case 'xl':
3479					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['large'];
3480					break;
3481				case '': // Default
3482				case 'desktop':
3483					makeSticky = windowSize >= FLBuilderLayoutConfig.breakpoints['medium'];
3484					break;
3485				case 'desktop-medium':
3486					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'];
3487					break;
3488				case 'large':
3489					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['medium'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
3490					break;
3491				case 'large-medium':
3492					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
3493					break;
3494				case 'medium':
3495					makeSticky = ( windowSize <= FLBuilderLayoutConfig.breakpoints['medium'] && windowSize > FLBuilderLayoutConfig.breakpoints['small'] );
3496					break;
3497				case 'medium-mobile':
3498					makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['medium']);
3499					break;
3500				case 'mobile':
3501					makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['small']);
3502					break;
3503				case 'all':
3504					makeSticky = true;
3505					break;
3506			}
3507
3508			return makeSticky;
3509		},
3510
3511		/**
3512		 * Sticks the header when the page is scrolled.
3513		 *
3514		 * @since 1.0
3515		 * @access private
3516		 * @method _doSticky
3517		 */
3518		_doSticky: function( e )
3519		{
3520			var winTop    		  = Math.floor( this.win.scrollTop() ),
3521				headerTop 		  = Math.floor( this.header.data( 'original-top' ) ),
3522				hasStickyClass    = this.header.hasClass( 'fl-theme-builder-header-sticky' ),
3523				hasScrolledClass  = this.header.hasClass( 'fl-theme-builder-header-scrolled' ),
3524				beforeHeader      = this.header.prevAll( '.fl-builder-content' ),
3525				bodyTopPadding    = parseInt( jQuery('body').css('padding-top') ),
3526				winBarHeight      = $('#wpadminbar').length ? $('#wpadminbar').outerHeight() : 0,
3527				headerHeight      = 0;
3528
3529			if ( isNaN( bodyTopPadding ) ) {
3530				bodyTopPadding = 0;
3531			}
3532
3533			if ( this.hasAdminBar && this.win.width() > 600 ) {
3534				winTop += Math.floor( winBarHeight );
3535			}
3536
3537			if ( winTop > headerTop ) {
3538				if ( ! hasStickyClass ) {
3539					if ( e && ( 'scroll' === e.type || 'smartscroll' === e.type ) ) {
3540					 	this.header.addClass( 'fl-theme-builder-header-sticky' );
3541						if ( this.overlay && beforeHeader.length ) {
3542							this.header.css( 'top', winBarHeight);
3543						}
3544					}
3545
3546					if ( ! this.overlay ) {
3547						this._adjustHeaderHeight();
3548					}
3549				}
3550			}
3551			else if ( hasStickyClass ) {
3552				this.header.removeClass( 'fl-theme-builder-header-sticky' );
3553				this.header.removeAttr( 'style' );
3554				this.header.parent().css( 'padding-top', '0' );
3555			}
3556
3557			this._adjustStickyHeaderWidth();
3558
3559			if ( winTop > headerTop ) {
3560				if ( ! hasScrolledClass ) {
3561					this.header.addClass( 'fl-theme-builder-header-scrolled' );
3562				}
3563			} else if ( hasScrolledClass ) {
3564				this.header.removeClass( 'fl-theme-builder-header-scrolled' );
3565			}
3566
3567			this._flyoutMenuFix( e );
3568		},
3569
3570		/**
3571		 * Initializes flyout menu fixes on sticky header.
3572		 *
3573		 * @since 1.4.1
3574		 * @method _initFlyoutMenuFix
3575		 */
3576		_initFlyoutMenuFix: function( e ) {
3577			var header       = this.header,
3578				menuModule   = header.closest( '.fl-menu' ),
3579				flyoutMenu   = menuModule.find( '.fl-menu-mobile-flyout' ),
3580				isPushMenu   = menuModule.hasClass( 'fl-menu-responsive-flyout-push' ) || menuModule.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
3581				isOverlay    = menuModule.hasClass( 'fl-menu-responsive-flyout-overlay' ),
3582				flyoutPos    = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
3583				flyoutParent = header.parent().is( 'header' ) ? header.parent().parent() : header.parent();
3584				isFullWidth  = this.win.width() === header.width(),
3585				flyoutLayout = '',
3586				activePos    = 250,
3587				headerPos    = 0;
3588
3589			if ( ! flyoutMenu.length ) {
3590				return;
3591			}
3592
3593			if ( this.win.width() > header.parent().width() ) {
3594				headerPos = ( this.win.width() - header.width() ) / 2;
3595			}
3596
3597			if ( isOverlay ) {
3598				activePos = headerPos;
3599			}
3600			else if ( isPushMenu ) {
3601				activePos = activePos + headerPos;
3602			}
3603			flyoutMenu.data( 'activePos', activePos );
3604
3605			if ( isPushMenu ) {
3606				flyoutLayout = 'push-' + flyoutPos;
3607			}
3608			else if ( isOverlay ) {
3609				flyoutLayout = 'overlay-' + flyoutPos;
3610			}
3611
3612			if ( isPushMenu && ! $( 'html' ).hasClass( 'fl-theme-builder-has-flyout-menu' ) ) {
3613				$( 'html' ).addClass( 'fl-theme-builder-has-flyout-menu' );
3614			}
3615
3616			if ( ! flyoutParent.hasClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout ) ) {
3617				flyoutParent.addClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout );
3618			}
3619
3620			if ( ! header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && isOverlay ) {
3621				header.addClass( 'fl-theme-builder-flyout-menu-overlay' );
3622			}
3623
3624			if ( ! header.hasClass( 'fl-theme-builder-header-full-width' ) && isFullWidth ) {
3625			   header.addClass( 'fl-theme-builder-header-full-width' );
3626		    }
3627			else if ( ! isFullWidth ) {
3628				header.removeClass( 'fl-theme-builder-header-full-width' );
3629			}
3630
3631			menuModule.on( 'click', '.fl-menu-mobile-toggle', $.proxy( function( event ){
3632				if ( menuModule.find( '.fl-menu-mobile-toggle.fl-active' ).length ) {
3633					$( 'html' ).addClass( 'fl-theme-builder-flyout-menu-active' );
3634					event.stopImmediatePropagation();
3635				}
3636				else {
3637					$( 'html' ).removeClass( 'fl-theme-builder-flyout-menu-active' );
3638				}
3639
3640				this._flyoutMenuFix( event );
3641			}, this ) );
3642		},
3643
3644		/**
3645		 * Fix flyout menu inside the sticky header.
3646		 *
3647		 * @since 1.4.1
3648		 * @method _flyoutMenuFix
3649		 */
3650		_flyoutMenuFix: function( e ){
3651			var header      = this.header,
3652			    menuModule  = $( e.target ).closest( '.fl-menu' ),
3653				flyoutMenu  = menuModule.find( '.fl-menu-mobile-flyout' ),
3654				flyoutPos   = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
3655				menuOpacity = menuModule.find( '.fl-menu-mobile-opacity' ),
3656				isScroll    = 'undefined' !== typeof e && 'scroll' === e.handleObj.type,
3657				activePos   = 'undefined' !== typeof flyoutMenu.data( 'activePos' ) ? flyoutMenu.data( 'activePos' ) : 0,
3658				headerPos   = ( this.win.width() - header.width() ) / 2,
3659				inactivePos = headerPos > 0 ? activePos + 4 : 254;
3660
3661			if ( ! flyoutMenu.length ) {
3662				return;
3663			}
3664
3665			if ( this.overlay ) {
3666				return;
3667			}
3668
3669			if( $( '.fl-theme-builder-flyout-menu-active' ).length ) {
3670
3671				if ( isScroll && ! flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
3672					flyoutMenu.addClass( 'fl-menu-disable-transition' );
3673				}
3674
3675				if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
3676					if ( ! isScroll ) {
3677						setTimeout( $.proxy( function(){
3678							flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
3679						}, this ), 1 );
3680					}
3681					else {
3682						flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
3683					}
3684				}
3685				else {
3686					flyoutMenu.css( flyoutPos, '0px' );
3687				}
3688			}
3689			else {
3690				if ( flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
3691					flyoutMenu.removeClass( 'fl-menu-disable-transition' );
3692				}
3693
3694				if ( header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && headerPos > 0 && headerPos < 250 ) {
3695					if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
3696						inactivePos = headerPos + 254;
3697					}
3698					else {
3699						inactivePos = 254;
3700					}
3701				}
3702
3703				if ( e && e.type === 'resize' ) {
3704					inactivePos = headerPos + 254;
3705				}
3706
3707				flyoutMenu.css( flyoutPos, '-' + inactivePos + 'px' );
3708			}
3709
3710			if ( e && menuModule.is('.fl-menu-responsive-flyout-overlay') && $.infinitescroll ) {
3711				e.stopImmediatePropagation();
3712			}
3713
3714			if( menuOpacity.length ) {
3715				if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
3716					if ( '0px' === menuOpacity.css( 'left' ) ) {
3717						menuOpacity.css( 'left', '-' + headerPos + 'px' );
3718					}
3719				}
3720				else {
3721					menuOpacity.css( 'left', '' );
3722				}
3723			}
3724		},
3725
3726		/**
3727		 * Adjust sticky header width if BB Theme Boxed Layout is used.
3728		 *
3729		 * @since 1.4
3730		 * @access private
3731		 * @method _adjustStickyHeaderWidth
3732		 */
3733		_adjustStickyHeaderWidth: function () {
3734			if ( $('body').hasClass( 'fl-fixed-width' ) ) {
3735				var parentWidth = this.header.parent().width();
3736
3737				// Better if this is set in the stylesheet file.
3738				if ( this.win.width() >= 992 ) {
3739					this.header.css({
3740						'margin': '0 auto',
3741						'max-width': parentWidth,
3742					});
3743				}
3744				else {
3745					this.header.css({
3746						'margin': '',
3747						'max-width': '',
3748					});
3749				}
3750			}
3751		},
3752
3753		/**
3754		 * Adjust Sticky Header Height
3755		 *
3756		 * @since 1.4
3757		 * @access private
3758		 * @method _adjustHeaderHeight
3759		 */
3760		_adjustHeaderHeight: function () {
3761			var beforeHeader = this.header.prevAll('.fl-builder-content'),
3762				beforeHeaderHeight = 0,
3763				beforeHeaderFix = 0,
3764				headerHeight = Math.floor( this.header.outerHeight() ),
3765				bodyTopPadding = parseInt( $( 'body' ).css( 'padding-top' ) ),
3766				wpAdminBarHeight = 0,
3767				totalHeaderHeight = 0;
3768
3769			if ( isNaN( bodyTopPadding ) ) {
3770				bodyTopPadding = 0;
3771			}
3772
3773			if ( beforeHeader.length ) {
3774				$.each( beforeHeader, function() {
3775					beforeHeaderHeight += Math.floor( $(this).outerHeight() );
3776				});
3777				// Subtract this value from the header parent's top padding.
3778				beforeHeaderFix = 2;
3779			}
3780
3781			if ( this.hasAdminBar && this.win.width() <= 600 ) {
3782				wpAdminBarHeight = Math.floor( $('#wpadminbar').outerHeight() );
3783			}
3784
3785			totalHeaderHeight = Math.floor( beforeHeaderHeight + headerHeight);
3786
3787			if ( headerHeight > 0 ) {
3788				var headerParent = this.header.parent(),
3789					headerParentTopPadding = 0;
3790
3791				// If the header's parent container is the BODY tag ignore its top padding.
3792				if ( $( headerParent ).is('body') ) {
3793					headerParentTopPadding = Math.floor( headerHeight - wpAdminBarHeight );
3794				} else {
3795					headerParentTopPadding = Math.floor( headerHeight - bodyTopPadding - wpAdminBarHeight );
3796				}
3797
3798				$( headerParent ).css( 'padding-top',  ( headerParentTopPadding - beforeHeaderFix ) + 'px' );
3799
3800				this.header.css({
3801					'-webkit-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
3802					'-ms-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
3803					'transform': 'translate(0px, -' + totalHeaderHeight + 'px)'
3804				});
3805
3806			}
3807
3808		},
3809
3810		/**
3811		 * Initializes shrink logic for a header.
3812		 *
3813		 * @since 1.0
3814		 * @access private
3815		 * @method _initShrink
3816		 */
3817		_initShrink: function( e )
3818		{
3819			if ( this.win.width() >= this.breakpointWidth ) {
3820				this.win.on( 'scroll.fl-theme-builder-header-shrink', $.proxy( this._doShrink, this ) );
3821				this._setImageMaxHeight();
3822
3823				if ( this.win.scrollTop() > 0 ){
3824					this._doShrink();
3825				}
3826
3827			} else {
3828				this.header.parent().css( 'padding-top', '0' );
3829				this.win.off( 'scroll.fl-theme-builder-header-shrink' );
3830				this._removeShrink();
3831				this._removeImageMaxHeight();
3832			}
3833		},
3834
3835		/**
3836		 * Shrinks the header when the page is scrolled.
3837		 *
3838		 * @since 1.0
3839		 * @access private
3840		 * @method _doShrink
3841		 */
3842		_doShrink: function( e )
3843		{
3844			var winTop 			  = this.win.scrollTop(),
3845				headerTop 		  = this.header.data('original-top'),
3846				headerHeight 	  = this.header.data('original-height'),
3847				shrinkImageHeight = this.header.data('shrink-image-height'),
3848				windowSize   	  = this.win.width(),
3849				makeSticky   	  = this._makeWindowSticky( windowSize ),
3850				hasClass     	  = this.header.hasClass( 'fl-theme-builder-header-shrink' );
3851
3852
3853			if ( this.hasAdminBar ) {
3854				winTop += 32;
3855			}
3856
3857			if ( makeSticky && ( winTop > headerTop + headerHeight ) ) {
3858				if ( ! hasClass ) {
3859
3860					this.header.addClass( 'fl-theme-builder-header-shrink' );
3861
3862					// Shrink images but don't include lightbox and menu images.
3863					this.header.find('img').each( function( i ) {
3864						var image           = $( this ),
3865							maxMegaMenu     = image.closest( '.max-mega-menu' ).length,
3866							imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
3867							imageInNavMenu  = image.closest( 'li.menu-item' ).length;
3868
3869						if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu ) ) {
3870							image.css( 'max-height', shrinkImageHeight );
3871						}
3872
3873					});
3874
3875					this.header.find( '.fl-row-content-wrap' ).each( function() {
3876
3877						var row = $( this );
3878
3879						if ( parseInt( row.css( 'padding-bottom' ) ) > 5 ) {
3880							row.addClass( 'fl-theme-builder-header-shrink-row-bottom' );
3881						}
3882
3883						if ( parseInt( row.css( 'padding-top' ) ) > 5 ) {
3884							row.addClass( 'fl-theme-builder-header-shrink-row-top' );
3885						}
3886					} );
3887
3888					this.header.find( '.fl-module' ).each( function() {
3889
3890						var module = $( this ).find( '.fl-module-content' ).length ? $( this ).find( '.fl-module-content' ) : $( this );
3891
3892						if ( parseInt( module.css( 'margin-bottom' ) ) > 5 ) {
3893							module.addClass( 'fl-theme-builder-header-shrink-module-bottom' );
3894						}
3895
3896						if ( parseInt( module.css( 'margin-top' ) ) > 5 ) {
3897							module.addClass( 'fl-theme-builder-header-shrink-module-top' );
3898						}
3899					} );
3900				}
3901			} else if (hasClass) {
3902				this.header.find( 'img' ).css( 'max-height', '' );
3903				this._removeShrink();
3904			}
3905
3906			// Fixes Shrink header issue with BB Theme when window is scrolled then resized and back.
3907			if ( 'undefined' === typeof( e ) && $('body').hasClass( 'fl-fixed-width' ) ) {
3908				if ( ! this.overlay ) {
3909					this._adjustHeaderHeight();
3910				}
3911			}
3912
3913		},
3914
3915		/**
3916		 * Removes the header shrink effect.
3917		 *
3918		 * @since 1.0
3919		 * @access private
3920		 * @method _removeShrink
3921		 */
3922		_removeShrink: function()
3923		{
3924			var rows    = this.header.find( '.fl-row-content-wrap' ),
3925				modules = this.header.find('.fl-module, .fl-module-content');
3926
3927			rows.removeClass( 'fl-theme-builder-header-shrink-row-bottom' );
3928			rows.removeClass( 'fl-theme-builder-header-shrink-row-top' );
3929			modules.removeClass( 'fl-theme-builder-header-shrink-module-bottom' );
3930			modules.removeClass( 'fl-theme-builder-header-shrink-module-top' );
3931			this.header.removeClass( 'fl-theme-builder-header-shrink' );
3932		},
3933
3934		/**
3935		 * Adds max height to images in modules for smooth scrolling.
3936		 *
3937		 * @since 1.1.1
3938		 * @access private
3939		 * @method _setImageMaxHeight
3940		 */
3941		_setImageMaxHeight: function()
3942		{
3943			var head = $( 'head' ),
3944				stylesId = 'fl-header-styles-' + this.header.data( 'post-id' ),
3945				styles = '',
3946				images = this.header.find( '.fl-module img' );
3947
3948			if ( $( '#' + stylesId ).length ) {
3949				return;
3950			}
3951
3952			images.each( function( i ) {
3953				var image           = $( this ),
3954					height          = image.height(),
3955					node            = image.closest( '.fl-module' ).data( 'node' ),
3956					className       = 'fl-node-' + node + '-img-' + i,
3957					maxMegaMenu     = image.closest( '.max-mega-menu' ).length,
3958					imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
3959					imageInNavMenu  = image.closest( 'li.menu-item' ).length;
3960
3961				if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu  ) ) {
3962					image.addClass( className );
3963					styles += '.' + className + ' { max-height: ' + ( height ? height : image[0].height )  + 'px }';
3964				}
3965
3966			} );
3967
3968			if ( '' !== styles ) {
3969				head.append( '<style id="' + stylesId + '">' + styles + '</style>' );
3970			}
3971		},
3972
3973		/**
3974		 * Removes max height on images in modules for smooth scrolling.
3975		 *
3976		 * @since 1.1.1
3977		 * @access private
3978		 * @method _removeImageMaxHeight
3979		 */
3980		_removeImageMaxHeight: function()
3981		{
3982			$( '#fl-header-styles-' + this.header.data( 'post-id' ) ).remove();
3983		},
3984	};
3985
3986	$( function() { FLThemeBuilderHeaderLayout.init(); } );
3987
3988})(jQuery);
3989
3990
3991(function($) {
3992
3993	$(function() {
3994
3995		new FLBuilderMenu({
3996			id: 'wpl8on6d19qt',
3997			type: 'vertical',
3998			mobile: 'expanded',
3999			mobileBelowRow: false,
4000			mobileFlyout: false,
4001			breakPoints: {
4002				large: 1200,
4003				medium: 1024,
4004				small: 768			},
4005			mobileBreakpoint: 'mobile',
4006			postId : '3032',
4007			mobileStacked: true,
4008			submenuIcon: 'none',
4009			flyoutWidth: '250',
4010		});
4011
4012	});
4013
4014})(jQuery);
4015
4016(function($) {
4017
4018	$(function() {
4019
4020		new FLBuilderMenu({
4021			id: '1t9anvk2zfeu',
4022			type: 'vertical',
4023			mobile: 'expanded',
4024			mobileBelowRow: false,
4025			mobileFlyout: false,
4026			breakPoints: {
4027				large: 1200,
4028				medium: 1024,
4029				small: 768			},
4030			mobileBreakpoint: 'mobile',
4031			postId : '3032',
4032			mobileStacked: true,
4033			submenuIcon: 'none',
4034			flyoutWidth: '250',
4035		});
4036
4037	});
4038
4039})(jQuery);
4040
4041(function($) {
4042
4043	$(function() {
4044
4045		new FLBuilderMenu({
4046			id: 'zlj0yxmghadu',
4047			type: 'vertical',
4048			mobile: 'expanded',
4049			mobileBelowRow: false,
4050			mobileFlyout: false,
4051			breakPoints: {
4052				large: 1200,
4053				medium: 1024,
4054				small: 768			},
4055			mobileBreakpoint: 'mobile',
4056			postId : '3032',
4057			mobileStacked: true,
4058			submenuIcon: 'none',
4059			flyoutWidth: '250',
4060		});
4061
4062	});
4063
4064})(jQuery);
4065
4066(function($) {
4067
4068	$(function() {
4069
4070		new FLBuilderMenu({
4071			id: 'asxbu0zor596',
4072			type: 'vertical',
4073			mobile: 'expanded',
4074			mobileBelowRow: false,
4075			mobileFlyout: false,
4076			breakPoints: {
4077				large: 1200,
4078				medium: 1024,
4079				small: 768			},
4080			mobileBreakpoint: 'mobile',
4081			postId : '3032',
4082			mobileStacked: true,
4083			submenuIcon: 'none',
4084			flyoutWidth: '250',
4085		});
4086
4087	});
4088
4089})(jQuery);
4090
4091(function($) {
4092
4093	$(function() {
4094
4095		new FLBuilderMenu({
4096			id: 'myht20x41w8k',
4097			type: 'vertical',
4098			mobile: 'expanded',
4099			mobileBelowRow: false,
4100			mobileFlyout: false,
4101			breakPoints: {
4102				large: 1200,
4103				medium: 1024,
4104				small: 768			},
4105			mobileBreakpoint: 'mobile',
4106			postId : '3032',
4107			mobileStacked: true,
4108			submenuIcon: 'none',
4109			flyoutWidth: '250',
4110		});
4111
4112	});
4113
4114})(jQuery);
4115
4116/* Start Layout Custom JS */
4117
4118/* End Layout Custom JS */
4119
4120
4121(function($) {
4122	if ( $('.fl-node-r52yxpbsnmwq .pp-photo-rollover').length > 0 ) {
4123		$('body').on( 'mouseenter.pp-rollover', '.fl-node-r52yxpbsnmwq .pp-photo-rollover .pp-photo-content', function() {
4124			$(this).addClass( 'is-hover' );
4125		} ).on( 'mouseleave.pp-rollover', '.fl-node-r52yxpbsnmwq .pp-photo-rollover .pp-photo-content', function() {
4126			$(this).removeClass( 'is-hover' );
4127		} );
4128	}
4129})(jQuery);(function($) {
4130	if ( $('.fl-node-c6vu14kpsqyo .pp-photo-rollover').length > 0 ) {
4131		$('body').on( 'mouseenter.pp-rollover', '.fl-node-c6vu14kpsqyo .pp-photo-rollover .pp-photo-content', function() {
4132			$(this).addClass( 'is-hover' );
4133		} ).on( 'mouseleave.pp-rollover', '.fl-node-c6vu14kpsqyo .pp-photo-rollover .pp-photo-content', function() {
4134			$(this).removeClass( 'is-hover' );
4135		} );
4136	}
4137})(jQuery);(function($) {
4138	if ( $('.fl-node-qw7pk3fmbjrz .pp-photo-rollover').length > 0 ) {
4139		$('body').on( 'mouseenter.pp-rollover', '.fl-node-qw7pk3fmbjrz .pp-photo-rollover .pp-photo-content', function() {
4140			$(this).addClass( 'is-hover' );
4141		} ).on( 'mouseleave.pp-rollover', '.fl-node-qw7pk3fmbjrz .pp-photo-rollover .pp-photo-content', function() {
4142			$(this).removeClass( 'is-hover' );
4143		} );
4144	}
4145})(jQuery);(function($){
4146	})(jQuery);
4147(function($){
4148	})(jQuery);
4149(function($){
4150	})(jQuery);
4151(function($) {
4152	if ( $('.fl-node-5jd8ukyeqvs4 .pp-photo-rollover').length > 0 ) {
4153		$('body').on( 'mouseenter.pp-rollover', '.fl-node-5jd8ukyeqvs4 .pp-photo-rollover .pp-photo-content', function() {
4154			$(this).addClass( 'is-hover' );
4155		} ).on( 'mouseleave.pp-rollover', '.fl-node-5jd8ukyeqvs4 .pp-photo-rollover .pp-photo-content', function() {
4156			$(this).removeClass( 'is-hover' );
4157		} );
4158	}
4159})(jQuery);(function($) {
4160	if ( $('.fl-node-ka9b8nocuj2q .pp-photo-rollover').length > 0 ) {
4161		$('body').on( 'mouseenter.pp-rollover', '.fl-node-ka9b8nocuj2q .pp-photo-rollover .pp-photo-content', function() {
4162			$(this).addClass( 'is-hover' );
4163		} ).on( 'mouseleave.pp-rollover', '.fl-node-ka9b8nocuj2q .pp-photo-rollover .pp-photo-content', function() {
4164			$(this).removeClass( 'is-hover' );
4165		} );
4166	}
4167})(jQuery);
4168;/**
4169 * This file should contain frontend logic for 
4170 * all module instances.
4171 */(function($){
4172	})(jQuery);
4173(function($){
4174	})(jQuery);
4175(function($) {
4176	if ( $('.fl-node-nmdekqry3ul9 .pp-photo-rollover').length > 0 ) {
4177		$('body').on( 'mouseenter.pp-rollover', '.fl-node-nmdekqry3ul9 .pp-photo-rollover .pp-photo-content', function() {
4178			$(this).addClass( 'is-hover' );
4179		} ).on( 'mouseleave.pp-rollover', '.fl-node-nmdekqry3ul9 .pp-photo-rollover .pp-photo-content', function() {
4180			$(this).removeClass( 'is-hover' );
4181		} );
4182	}
4183})(jQuery);(function($) {
4184	if ( $('.fl-node-41tybsmd6ila .pp-photo-rollover').length > 0 ) {
4185		$('body').on( 'mouseenter.pp-rollover', '.fl-node-41tybsmd6ila .pp-photo-rollover .pp-photo-content', function() {
4186			$(this).addClass( 'is-hover' );
4187		} ).on( 'mouseleave.pp-rollover', '.fl-node-41tybsmd6ila .pp-photo-rollover .pp-photo-content', function() {
4188			$(this).removeClass( 'is-hover' );
4189		} );
4190	}
4191})(jQuery);(function($){
4192	})(jQuery);
4193(function($){
4194	})(jQuery);
4195(function($) {
4196	if ( $('.fl-node-h0olzwbt37ae .pp-photo-rollover').length > 0 ) {
4197		$('body').on( 'mouseenter.pp-rollover', '.fl-node-h0olzwbt37ae .pp-photo-rollover .pp-photo-content', function() {
4198			$(this).addClass( 'is-hover' );
4199		} ).on( 'mouseleave.pp-rollover', '.fl-node-h0olzwbt37ae .pp-photo-rollover .pp-photo-content', function() {
4200			$(this).removeClass( 'is-hover' );
4201		} );
4202	}
4203})(jQuery);(function($) {
4204	if ( $('.fl-node-q2citxwlkg3f .pp-photo-rollover').length > 0 ) {
4205		$('body').on( 'mouseenter.pp-rollover', '.fl-node-q2citxwlkg3f .pp-photo-rollover .pp-photo-content', function() {
4206			$(this).addClass( 'is-hover' );
4207		} ).on( 'mouseleave.pp-rollover', '.fl-node-q2citxwlkg3f .pp-photo-rollover .pp-photo-content', function() {
4208			$(this).removeClass( 'is-hover' );
4209		} );
4210	}
4211})(jQuery);(function($){
4212	})(jQuery);
4213(function($){
4214	})(jQuery);
4215
4216/* Start Layout Custom JS */
4217
4218/* End Layout Custom JS */
4219
4220

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.