PageSourceSearch

https://theunstuckgroup.com/wp-content/uploads/bb-plugin/cache/21d…a7187c8-layout-bundle.js?ver=2.11.1.1-1.6.1

js theunstuckgroup.com collected 2026-10-02 06:05:57 UTC 55,021 bytes, 1,824 lines download raw bytes

1		(function($){
2			$('.fl-node-6166f998914b5').each(function(){
3				var $this = $(this);
4								$this.find('#fl-node-6166f998914b5-1 .fl-button-lightbox').magnificPopup({
5					
6										type: 'inline',
7					callbacks: {
8						elementParse: function(item) {
9							item.src = $( item.el ).closest('.fl-button-wrap').find('.fl-button-lightbox-content');
10						},
11						open: function() {
12							var divWrap = $( $(this.content)[0] ).find('> div');
13							divWrap.css('display', 'block');
14
15							// Triggers select change in we have multiple forms in a page
16							if ( divWrap.find('form select').length > 0 ) {
17								divWrap.find('form select').trigger('change');
18							}
19						}
20					},
21										closeBtnInside: true,
22					fixedContentPos: true,
23					tLoading: '<i class="fas fa-spinner fa-spin fa-3x fa-fw"></i>'
24				});
25							});
26		})(jQuery);
27		jQuery(function($) {
28	
29		$(function() {
30		$( '.fl-node-xnztwfgjbr49 .fl-photo-img' )
31			.on( 'mouseenter', function( e ) {
32				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
33			} )
34			.on( 'mouseleave', function( e ){
35				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
36			} );
37	});
38		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
39});
40
41;/* eslint-disable no-undef */
42(function($) {
43
44	/**
45	 * Class for Menu Module
46	 *
47	 * @since 1.6.1
48	 */
49	FLBuilderMenu = function( settings ){
50
51		// set params
52		this.nodeId              = settings.id;
53		this.nodeClass           = '.fl-node-' + settings.id;
54		this.wrapperClass        = this.nodeClass + ' .fl-menu';
55		this.type				 				 = settings.type;
56		this.mobileToggle		     = settings.mobile;
57		this.mobileBelowRow		   = settings.mobileBelowRow;
58		this.mobileFlyout		     = settings.mobileFlyout;
59		this.breakPoints         = settings.breakPoints;
60		this.mobileBreakpoint	 	 = settings.mobileBreakpoint;
61		this.currentBrowserWidth = $( window ).width();
62		this.postId              = settings.postId;
63		this.mobileStacked       = settings.mobileStacked;
64		this.submenuIcon         = settings.submenuIcon;
65		this.flyoutWidth         = settings.flyoutWidth;
66
67		// initialize the menu
68		this._initMenu();
69
70		// check if viewport is resizing
71		$( window ).on( 'resize', $.proxy( function() {
72
73			var width = $( window ).width();
74
75			// if screen width is resized, reload the menu
76		    if( width != this.currentBrowserWidth ){
77
78				this.currentBrowserWidth = width;
79				this._initMenu( true );
80 				this._clickOrHover( true );
81			}
82
83			this._resizeFlyoutMenuPanel();
84		}, this ) );
85
86		$( window ).on( 'scroll', $.proxy( function() {
87			this._resizeFlyoutMenuPanel();
88		}, this ) );
89
90		// Move focus to the first menu item if the layout is set to BelowRow
91		$( this.wrapperClass ).on( 'keydown', '.fl-menu-mobile-toggle, .menu-item:first a:first', $.proxy( function ( event ) {
92			// Make sure it is a tab key with both the menu toggle enabled & below row layout set
93			if ( event.key !== 'Tab' || ! this._isMenuToggle() || ! this._isMobileBelowRowEnabled() ) {
94				return;
95			}
96			// Trigger focus on the mobile toggle button if the user is shift tabbing from the first menu item
97			if ( event.shiftKey && $( event.currentTarget ).is( 'a' ) ) {
98				event.preventDefault();
99				$( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).trigger( 'focus' );
100			}
101			// Trigger focus on the first menu item if the user is tabbing from the mobile toggle button
102			else if ( ! event.shiftKey && $( event.currentTarget ).hasClass( 'fl-menu-mobile-toggle' ) && $( event.currentTarget ).hasClass( 'fl-active' )  ) {
103				event.preventDefault();
104				$( this.wrapperClass ).find( '.menu-item' ).first().find( 'a' ).first().trigger( 'focus' );
105			}
106		}, this ) );
107
108		// Close mobile menu or accordion when tabbing out from the first or last menu item
109		$( this.wrapperClass ).on( 'focusout', $.proxy( function ( event ) {
110			if ( $( this.wrapperClass + ' nav' ).has( $( event.relatedTarget ) ).length === 0 ) {
111				if ( this.type === 'accordion' ) {
112					this._toggleSubmenu( $( event.target ).parents( '.fl-has-submenu' ).last(), false );
113				}
114				else {
115					this._clickOrHover( true );
116				}
117				const mobileToggle = $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' );
118				if ( this._isMenuToggle() && mobileToggle.hasClass( 'fl-active' ) && ! $( event.relatedTarget ).is( mobileToggle ) && 'expanded' !== this.mobileToggle ) {
119					mobileToggle.trigger( 'click' );
120				}
121			}
122		}, this ) );
123
124	};
125
126	FLBuilderMenu.prototype = {
127		nodeClass		: '',
128		wrapperClass: '',
129		type				: '',
130		breakPoints	: {},
131		$submenus		: null,
132
133		/**
134		 * Check if the screen size fits a mobile viewport.
135		 *
136		 * @since  1.6.1
137		 * @return bool
138		 */
139		_isMobile: function(){
140			return this.currentBrowserWidth <= this.breakPoints.small ? true : false;
141		},
142
143		/**
144		 * Check if the device is connected to a mouse.
145		 * 
146		 * @since  2.9.0
147		 * @return bool
148		 */
149		_isMouseAvailable: function(){
150			return window.matchMedia("(pointer: fine) and (hover: hover)").matches;
151		},
152
153		/**
154		 * Check if the screen size fits a medium viewport.
155		 *
156		 * @since  1.10.5
157		 * @return bool
158		 */
159		_isMedium: function(){
160			return this.currentBrowserWidth <= this.breakPoints.medium ? true : false;
161		},
162
163		/**
164		 * Check if the screen size fits a large viewport.
165		 *
166		 * @since  1.10.5
167		 * @return bool
168		 */
169		_isLarge: function(){
170			return this.currentBrowserWidth <= this.breakPoints.large ? true : false;
171		},
172
173		/**
174		 * Check if the menu should toggle for the current viewport base on the selected breakpoint.
175		 *
176		 * @see 	 this._isMobile()
177		 * @see 	 this._isMedium()
178		 * @since  1.10.5
179		 * @return bool
180		 */
181		_isMenuToggle: function(){
182			if ( ( 'always' == this.mobileBreakpoint
183				|| ( this._isMobile() && 'mobile' == this.mobileBreakpoint )
184				|| ( this._isMedium() && 'medium-mobile' == this.mobileBreakpoint )
185				|| ( this._isLarge() && 'large-mobile' == this.mobileBreakpoint )
186			) && ( $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).is(':visible') || 'expanded' == this.mobileToggle ) ) {
187				return true;
188			}
189
190			return false;
191		},
192
193		/**
194		 * Initialize the toggle logic for the menu.
195		 *
196		 * @see    this._isMenuToggle()
197		 * @see    this._menuOnCLick()
198		 * @see    this._clickOrHover()
199		 * @see    this._submenuOnRight()
200		 * @see    this._submenuRowZindexFix()
201		 * @see    this._toggleForMobile()
202		 * @since  1.6.1
203		 * @return void
204		 */
205		_initMenu: function( resized = false ){
206			this._setupSubmenu();
207			if ( ! resized ) {
208				this._menuOnFocus();
209				this._menuOnClick();
210				this._menuOnEscape();
211			}
212			if ( $( this.nodeClass ).length && this.type == 'horizontal' ) {
213				this._initMegaMenus();
214			}
215
216			if( this._isMenuToggle() || this.type == 'accordion' ){
217
218				$( this.wrapperClass ).off( 'mouseenter mouseleave' );
219				this._clickOrHover();
220
221			} else {
222				this._submenuOnRight();
223				this._submenuRowZindexFix();
224			}
225
226			if( this.mobileToggle != 'expanded' ){
227				this._toggleForMobile();
228			}
229
230			if( $( this.wrapperClass ).find( '.fl-menu-search-item' ).length ){
231				this._toggleMenuSearch();
232			}
233
234			if( $( this.wrapperClass ).find( '.fl-menu-cart-item').length ){
235				this._wooUpdateParams();
236			}
237		},
238
239		/**
240		 * Whether the toggle behavior for submenus is through hovering or not.
241		 *
242		 * @since  2.5
243		 * @return void
244		 */
245		_setupSubmenu: function() {
246			if ( ! this._isMouseAvailable() || this._isMenuToggle() || this.type === 'accordion' ) {
247				$( this.wrapperClass ).addClass( 'no-hover' );
248			}
249			else {
250				$( this.wrapperClass ).removeClass( 'no-hover' );
251			}
252		},
253
254		/**
255		 * Logic for menu items when focused.
256		 *
257		 * @since  1.9.0
258		 * @return void
259		 */
260		_menuOnFocus: function(){
261			$( this.wrapperClass ).on( 'focus', 'a:not(.fl-button), .fl-menu-toggle', $.proxy( function( event ) {
262				const focusedMenuItem = $( event.currentTarget ).closest( '.menu-item' );
263				const blurredMenuItem = $( event.relatedTarget ).closest( '.menu-item' );
264				// In case the blurred & focused items are siblings
265				if ( focusedMenuItem.closest( 'ul' ).is( blurredMenuItem.closest( 'ul' ) ) )	{
266					// Check if the focus event is not between the link & submenu icon of the same menu item
267					if ( ! focusedMenuItem.is( blurredMenuItem ) ) {
268						this._toggleSubmenu( blurredMenuItem, false );
269					}
270				}
271				// In case neither items are child & parent nor vice versa
272				else if ( focusedMenuItem.has( blurredMenuItem ).length === blurredMenuItem.has( focusedMenuItem ).length ) {
273					// Get the blurred item parent & is the sibling of the focused item
274					blurredMenuItem.parents( '.fl-has-submenu' ).each( ( _, parent ) => {
275						if ( focusedMenuItem.closest( 'ul' ).is( $( parent ).closest( 'ul' ) ) ) {
276							this._toggleSubmenu( $( parent ), false );
277							return false;
278						}
279					} );
280				}
281				// In case the blurred item is a child of the focused item
282				else if ( focusedMenuItem.has( blurredMenuItem ).length ) {
283					if ( this.type !== 'accordion' && this.submenuIcon === 'none' ) {
284						this._toggleSubmenu( blurredMenuItem, false );
285					}
286				}
287			}, this ) );
288		},
289
290		/**
291		 * Logic for menu items when Escape key is pressed.
292		 *
293		 * @since  2.7.1
294		 * @return void
295		 */
296		_menuOnEscape: function(){
297			$( this.wrapperClass ).on( 'keydown', $.proxy( function( event ){
298				if ( event.key !== 'Escape' ) return;
299				const menuItem = $( event.target ).closest( '.menu-item' );
300				const mobileToggle = $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' );
301				// In case there is a focused menu item
302				if ( menuItem.length || $( event.target ).hasClass( 'fl-menu-mobile-close' ) ) {
303					// Close the search form if it is open
304					if ( menuItem.hasClass( 'fl-menu-search-item' ) && $( this.wrapperClass ).find('.fl-search-form-input-wrap').is( ':visible' ) ) {
305						$( this.wrapperClass ).find('.fl-menu-search-item .fl-button:is(a, button:not([type="submit"]))').trigger( 'focus' );
306					}
307					// Close all the submenus of the focused menu item
308					else if ( menuItem.hasClass( 'fl-has-submenu' ) && menuItem.find( '.sub-menu' ).first().is( ':visible' ) ) {
309						this._toggleSubmenu( menuItem, false );
310					}
311					else {
312						// Shift focus to the parent while closing all its submenus
313						const parentMenuItem = menuItem.parents( '.fl-has-submenu' ).not( '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading' ).first();
314						// Close the mobile menu if there is no parent menu item and the mobile toggle is active
315						if ( parentMenuItem.length === 0 && this._isMenuToggle() && mobileToggle.hasClass( 'fl-active' ) ) {
316							// Blur to trigger the focus-out event for closing the menu
317							mobileToggle.trigger( 'blur' ).trigger( 'focus' );
318						}
319						// Close the parent submenu and shift focus to its link
320						else if ( parentMenuItem.length !== 0 ) {
321							this._toggleSubmenu( parentMenuItem, false );
322							parentMenuItem.find( 'a' ).first().trigger( 'focus' );
323						}
324					}
325				}
326				// Close the mobile menu if the mobile toggle is active
327				else if ( $( event.target ).hasClass( 'fl-menu-mobile-toggle' ) && mobileToggle.hasClass( 'fl-active' ) ) {
328					// Blur to trigger the focus-out event for closing the menu
329					mobileToggle.trigger( 'blur' ).trigger( 'focus' );
330				}
331			}, this ) );
332		},
333
334		/**
335		 * Logic for menu items when clicked.
336		 *
337		 * @since  1.6.1
338		 * @return void
339		 */
340		_menuOnClick: function(){
341			// Fallback for span elements and fake links to interact with the keyboard
342			$( this.wrapperClass ).on( 'keydown', 'a:not(.fl-button, [href]), span.fl-menu-toggle', $.proxy( function( event ) {
343				if ( event.key === 'Enter' || event.key === ' ' ) {
344					event.preventDefault();
345					$( event.currentTarget ).trigger( 'click' );
346				}
347			}, this ) );
348			$( this.wrapperClass ).on( 'click', 'a, .fl-menu-toggle', $.proxy( function( event ) {
349				// Only allow mouse clicks with accordion & mobile menus
350				if ( this._isMouseAvailable() && ! this._isMenuToggle() && event.detail && this.type !== 'accordion' ) return;
351				// Links only open & do not toggle submenus if there is either a submenu icon or an accordion layout
352				if ( $( event.currentTarget ).is( 'a' ) && ( this.submenuIcon !== 'none' || this.type === 'accordion' ) ) return;
353				const menuItem = $( event.currentTarget ).closest( '.menu-item, .fl-menu-logo' );
354				const menuLink = menuItem.find( 'a' ).first().attr( 'href' );
355				const submenuHidden = menuItem.find( '.sub-menu' ).first().is( ':hidden' );
356				if ( typeof menuLink === 'undefined' || menuLink === '#' || submenuHidden ) {
357					event.preventDefault();
358				}
359				if ( $( event.currentTarget ).hasClass( 'fl-menu-toggle' ) || submenuHidden ) {
360					this._toggleSubmenu( menuItem, submenuHidden );
361				}
362			}, this ) );
363		},
364
365		/**
366		 * Controls toggling the visibility of all submenu items for desktop & mobile.
367		 *
368		 * @since  2.10
369		 * @return void
370		 */
371		_toggleSubmenu: function ( menuItem, opened ) {
372			const togglingClass = this._isMenuToggle() || this.type === 'accordion' ? 'fl-active' : 'focus';
373			const toggleElement = this.submenuIcon === 'none' ? 'a' : '.fl-menu-toggle';
374			const hiddenMenu = '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading';
375			if ( opened && menuItem.hasClass( 'fl-has-submenu' ) && ! menuItem.is( hiddenMenu ) ) {
376				menuItem.addClass( togglingClass );
377				menuItem.find( toggleElement ).first().attr( 'aria-expanded', true );
378				if ( this._isMenuToggle() || this.type === 'accordion' ) {
379					menuItem.find( '.sub-menu' ).first().filter( ':hidden' ).slideDown();
380				}
381			}
382			else {
383				menuItem.parent().find( '.menu-item' ).removeClass( togglingClass );
384				menuItem.parent().find( '.fl-has-submenu' ).not( hiddenMenu ).find( toggleElement ).attr( 'aria-expanded', false );
385				if ( this._isMenuToggle() || this.type === 'accordion' ) {
386					menuItem.find( '.sub-menu' ).filter( ':visible' ).slideUp();
387				}
388			}
389		},
390
391		/**
392		 * Changes general styling and behavior of menus based on mobile / desktop viewport.
393		 *
394		 * @see    this._isMenuToggle()
395		 * @since  1.6.1
396		 * @return void
397		 */
398		_clickOrHover: function( clear = false ){
399			const selector = this._isMobileBelowRowEnabled() ? this.nodeClass + '-clone' : this.nodeClass;
400			this.$submenus = this.$submenus || $( selector ).find( '.sub-menu' );
401
402			const className = this._isMenuToggle() || this.type === 'accordion' ? 'fl-active' : 'focus';
403			const toggleElement = this.submenuIcon === 'none' ? 'a' : '.fl-menu-toggle';
404			const hiddenMenu = '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading';
405			$( selector ).find( '.fl-has-submenu' ).not( hiddenMenu ).each( function() {
406				if( clear || ! $ ( this ).hasClass( className ) ){
407					if ( clear ) $( this ).removeClass( className );
408					$( this ).find( toggleElement ).first().attr( 'aria-expanded', false );
409					if ( className === 'fl-active' ) {
410						$( this ).find( '.sub-menu' ).fadeOut();
411					} else if ( className === 'focus' ) {
412						$( this ).find( '.sub-menu' ).css( {
413							'display' : '',
414							'opacity' : ''
415						} );
416					}
417				}
418			} );
419		},
420
421		/**
422		 * Logic to prevent submenus to go outside viewport boundaries.
423		 *
424		 * @since  1.6.1
425		 * @return void
426		 */
427		_submenuOnRight: function(){
428
429			$( this.wrapperClass )
430				.on( 'mouseenter focus', '.fl-has-submenu', $.proxy( function( e ){
431
432					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
433						return;
434					}
435
436					var $link           = $( e.currentTarget ),
437						$parent         = $link.parent(),
438						$subMenu        = $link.find( '.sub-menu' ),
439						subMenuWidth    = $subMenu.width(),
440						subMenuPos      = 0,
441						bodyWidth       = $( 'body' ).width();
442
443					if( $link.closest( '.fl-menu-submenu-right' ).length !== 0) {
444
445						$link.addClass( 'fl-menu-submenu-right' );
446
447					} else if( $( 'body' ).hasClass( 'rtl' ) ) {
448
449						subMenuPos = $parent.is( '.sub-menu' ) ?
450									 $parent.offset().left - subMenuWidth:
451									 $link.offset().left - $link.width() - subMenuWidth;
452
453						if( subMenuPos <= 0 ) {
454							$link.addClass( 'fl-menu-submenu-right' );
455						}
456
457					} else {
458
459						subMenuPos = $parent.is( '.sub-menu' ) ?
460									 $parent.offset().left + $parent.width() + subMenuWidth :
461									 $link.offset().left + $link.width() + subMenuWidth;
462
463						if( subMenuPos > bodyWidth ) {
464							$link.addClass('fl-menu-submenu-right');
465						}
466					}
467				}, this ) )
468				.on( 'mouseleave', '.fl-has-submenu', $.proxy( function( e ){
469					$( e.currentTarget ).removeClass( 'fl-menu-submenu-right' );
470				}, this ) );
471
472		},
473
474		/**
475		 * Logic to prevent submenus to go behind the next overlay row.
476		 *
477		 * @since  1.10.9
478		 * @return void
479		 */
480		_submenuRowZindexFix: function(){
481
482			$( this.wrapperClass )
483				.on( 'mouseenter', 'ul.menu > .fl-has-submenu', $.proxy( function( e ){
484
485					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
486						return;
487					}
488
489					$( this.nodeClass )
490						.closest( '.fl-row' )
491						.find( '.fl-row-content' )
492						.css( 'z-index', '10' );
493
494				}, this ) )
495				.on( 'mouseleave', 'ul.menu > .fl-has-submenu', $.proxy( function(){
496
497					$( this.nodeClass )
498						.closest( '.fl-row' )
499						.find( '.fl-row-content' )
500						.css( 'z-index', '' );
501
502				}, this ) );
503		},
504
505		/**
506		 * Logic for the mobile menu button.
507		 *
508		 * @since  1.6.1
509		 * @return void
510		 */
511		_toggleForMobile: function(){
512
513			var $wrapper = null,
514				$menu    = null,
515				self     = this;
516
517			$( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).attr('aria-controls', $( this.wrapperClass ).find( 'ul.menu' ).attr('id'));
518
519			if( this._isMenuToggle() ){
520
521				if ( this._isMobileBelowRowEnabled() ) {
522					this._placeMobileMenuBelowRow();
523					$wrapper = $( this.wrapperClass );
524					$menu    = $( this.nodeClass + '-clone' );
525					$menu.find( 'ul.menu' ).show();
526				}
527				else {
528					$wrapper = $( this.wrapperClass );
529					$menu    = $wrapper.find( '.menu' );
530				}
531
532				if( !$wrapper.find( '.fl-menu-mobile-toggle' ).hasClass( 'fl-active' ) && ! self.mobileFlyout ){
533					$menu.css({ display: 'none' });
534				}
535
536				// Flayout Menu
537				if ( self.mobileFlyout ) {
538					this._initFlyoutMenu();
539				}
540
541				$wrapper.on( 'click', '.fl-menu-mobile-toggle', function( e ){
542					e.stopImmediatePropagation();
543
544					$( this ).toggleClass( 'fl-active' );
545
546					if ( self.mobileFlyout ) {
547						self._toggleFlyoutMenu();
548						const flyoutWrapper = $( '.fl-menu-mobile-flyout' );
549						if ( $( this ).hasClass( 'fl-active' ) ) {
550							flyoutWrapper.attr( 'aria-hidden', false );
551							flyoutWrapper.find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex="-1"]' ).attr( 'tabindex', 0 );
552						}
553						else {
554							flyoutWrapper.attr( 'aria-hidden', true );
555							flyoutWrapper.find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex]:not
555([tabindex="-1"])' ).attr( 'tabindex', -1 );
556						}
557					}
558					else {
559						var targetMenu = null;
560
561						if ( self.mobileBelowRow ) {
562							var $closestCol = $( this ).parents( '.fl-col, .fl-module-box' ),
563								$closestColGroup = $closestCol.length ? $closestCol.parent( '.fl-col-group' ) : null;
564								targetMenu  = $closestCol.length ? $closestCol.last().next( '.fl-menu-mobile-clone' ) : null;
565
566							if ( $closestColGroup.length ) {
567								if ( $closestColGroup.hasClass( 'fl-col-group-responsive-reversed' ) ) {
568									$closestColGroup.find( '.fl-menu-mobile-clone' ).css( 'order', -1 );
569								} else if ( $closestColGroup ) {
570									$closestColGroup.find( '.fl-menu-mobile-clone' ).css( 'order', 2 );
571								}
572							}
573						} else {
574							targetMenu = $( this ).closest( '.fl-menu' ).find( 'ul.menu' );
575						}
576						
577						if ( targetMenu.length ) {
578							$menu = $( targetMenu );
579						}
580
581						$menu.slideToggle();
582					}
583
584					e.stopPropagation();
585				} );
586
587				// Hide active menu when click on anchor link ID that exists on a page
588				$menu.off().on( 'click', '.menu-item > a[href*="#"]:not([href="#"])', function(){
589					var $href = $(this).attr('href'),
590						$targetID = $href.split('#')[1],
591						element = $('#' + $targetID);
592					if ( $('body').find(element).length > 0 ) {
593						$( this ).toggleClass( 'fl-active' );
594						FLBuilderLayout._scrollToElement( element );
595						if ( ! self._isMenuToggle() ) {
596							$menu.slideToggle();
597						}
598					}
599				});
600			}
601			else {
602
603				if ( this._isMobileBelowRowEnabled() ) {
604					this._removeMenuFromBelowRow();
605				}
606
607				$wrapper = $( this.wrapperClass ),
608				$menu    = $wrapper.find( 'ul.menu' );
609				$wrapper.find( '.fl-menu-mobile-toggle' ).removeClass( 'fl-active' );
610				$menu.css({ display: '' });
611
612				if ( ! this._isMobileBelowRowEnabled() ) {
613					$menu.off( 'click', '.menu-item > a[href*="#"]:not([href="#"])' );
614				}
615
616				if ( this.mobileFlyout && $wrapper.find( '.fl-menu-mobile-flyout' ).length > 0 ) {
617					$( 'body' ).css( 'margin', '' );
618					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
619					$menu.unwrap();
620					$wrapper.find( '.fl-menu-mobile-close' ).remove();
621					$wrapper.find( '.fl-menu-mobile-opacity' ).remove();
622				}
623			}
624		},
625
626		/**
627		 * Init any mega menus that exist.
628		 *
629		 * @see 	 this._isMenuToggle()
630		 * @since  1.10.4
631		 * @return void
632		 */
633		_initMegaMenus: function(){
634
635			var module     = $( this.nodeClass ),
636				rowContent = module.closest( '.fl-row-content' ),
637				rowWidth   = rowContent.width(),
638				megas      = module.find( '.mega-menu' ),
639				disabled   = module.find( '.mega-menu-disabled' ),
640				isToggle   = this._isMenuToggle();
641
642			if ( isToggle ) {
643				megas.removeClass( 'mega-menu' ).addClass( 'mega-menu-disabled' );
644				module.find( 'li.mega-menu-disabled > ul.sub-menu' ).css( 'width', '' );
645				rowContent.css( 'position', '' );
646			} else {
647				disabled.removeClass( 'mega-menu-disabled' ).addClass( 'mega-menu' );
648				module.find( 'li.mega-menu > ul.sub-menu' ).css( 'width', rowWidth + 'px' );
649				rowContent.css( 'position', 'relative' );
650			}
651		},
652
653		/**
654		 * Check to see if Below Row should be enabled.
655		 *
656		 * @since  1.11
657		 * @return boolean
658		 */
659		_isMobileBelowRowEnabled: function() {
660			return this.mobileBelowRow && ( $( this.nodeClass ).parents( '.fl-col, .fl-module-box' ).length );
661		},
662
663		/**
664		 * Logic for putting the mobile menu below the menu's
665		 * column so it spans the full width of the page.
666		 *
667		 * @since  1.10
668		 * @return void
669		 */
670		_placeMobileMenuBelowRow: function(){
671
672			if ( $( this.nodeClass + '-clone' ).length ) {
673				return;
674			}
675
676			var module = $( this.nodeClass ),
677				clone  = null,
678				col    = module.parents( '.fl-col, .fl-module-box' ).last();
679
680			if ( module.length < 1 ) {
681				return;
682			}
683
684			clone = ( module.length > 1 ) ? $( module[0] ).clone() : module.clone();
685			module.find( 'ul.menu' ).remove();
686			clone.addClass( ( this.nodeClass + '-clone' ).replace( '.', '' ) );
687			clone.addClass( 'fl-menu-mobile-clone' );
688			clone.find( '.fl-menu-mobile-toggle' ).remove();
689			col.after( clone );
690
691			// Removes animation when enabled
692			if ( module.hasClass( 'fl-animation' ) ) {
693				clone.removeClass( 'fl-animation' );
694			}
695
696			this._menuOnFocus();
697			this._menuOnClick();
698			this._menuOnEscape();
699		},
700
701		/**
702		 * Logic for removing the mobile menu from below the menu's
703		 * column and putting it back in the main wrapper.
704		 *
705		 * @since  1.10
706		 * @return void
707		 */
708		_removeMenuFromBelowRow: function(){
709
710			if ( ! $( this.nodeClass + '-clone' ).length ) {
711				return;
712			}
713
714			var module = $( this.nodeClass ),
715				clone  = $( this.nodeClass + '-clone' ),
716				menu   = clone.find( 'ul.menu' ),
717				nav    = module.find( 'nav' );
718
719			if ( nav.length ) {
720				nav.append( menu );
721			} else {
722				module.find( '.fl-menu-mobile-toggle' ).after( menu );
723			}
724			clone.remove();
725			menu.find( 'a' ).each( FLBuilderLayout._initAnchorLink );
726		},
727
728		/**
729		 * Logic for Flyout responsive menu.
730		 *
731		 * @since  2.2
732		 * @return void
733		 */
734		_initFlyoutMenu: function(){
735			var wrapper = $( this.wrapperClass ),
736				menu  	= wrapper.find( 'ul.menu' ),
737				button	= wrapper.find( '.fl-menu-mobile-toggle' );
738
739			if ( 0 === wrapper.find( '.fl-menu-mobile-flyout' ).length ) {
740				menu.wrap( '<div class="fl-menu-mobile-flyout" aria-hidden="true"></div>' );
741			}
742
743			if ( 0 === wrapper.find( '.fl-menu-mobile-close' ).length ) {
744				var close = window.fl_responsive_close || 'Close'
745				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>' );
746			}
747
748			// Push with opacity
749			if ( wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ) && 0 === wrapper.find( '.fl-menu-mobile-opacity' ).length ) {
750				wrapper.append( '<div class="fl-menu-mobile-opacity"></div>' );
751			}
752
753			wrapper.off( 'click', '.fl-menu-mobile-opacity, .fl-menu-mobile-close' ).on( 'click', '.fl-menu-mobile-opacity, .fl-menu-mobile-close', function(e){
754				button.trigger('focus').trigger( 'click' );
755				e.stopPropagation();
756			});
757
758			if ( 'undefined' !== typeof FLBuilder ) {
759				FLBuilder.addHook('restartEditingSession', function(){
760					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
761
762					// Toggle active menu
763					if ( button.hasClass( 'fl-active' ) ) {
764						button.trigger( 'click' );
765					}
766				});
767			}
768			$( '.fl-menu-mobile-flyout' ).find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex]:not([tabindex="-1"])' ).attr( 'tabindex', -1 );
769		},
770
771		/**
772		 * Logic to enable/disable the Flyout menu on button click.
773		 *
774		 * @since  2.2
775		 * @return void
776		 */
777		_toggleFlyoutMenu: function(){
778			var wrapper		= $( this.wrapperClass ),
779				button		= wrapper.find( '.fl-menu-mobile-toggle' ),
780				position 	= wrapper.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
781				pushMenu 	= wrapper.hasClass( 'fl-menu-responsive-flyout-push' ) || wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
782				opacity		= wrapper.find( '.fl-menu-mobile-opacity' ),
783				marginPos	= {},
784				fixedPos 	= {},
785				fixedHeader	= $('header, header > div');
786
787			this._resizeFlyoutMenuPanel();
788
789			// Fix the push menu when builder ui panel is pinned
790			if ( $( '.fl-builder-ui-pinned-content-transform' ).length > 0 && ! $( 'body' ).hasClass( 'fl-builder-edit' ) ) {
791				$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', 'none' );
792			}
793
794			if ( pushMenu ) {
795				marginPos[ 'margin-' + position ] = button.hasClass( 'fl-active' ) ? this.flyoutWidth + 'px' : '0px';
796				$( 'body' ).animate( marginPos, 200);
797
798				// Fixed header
799				if ( fixedHeader.length > 0 ) {
800					fixedPos[ position] = button.hasClass( 'fl-active' ) ? this.flyoutWidth + 'px' : '0px';
801					fixedHeader.each(function(){
802						if ( 'fixed' == $( this ).css( 'position' ) ) {
803							$( this ).css({ 'transition' : 'none' });
804							$( this ).animate( fixedPos, 200 );
805						}
806					});
807				}
808			}
809
810			if ( opacity.length > 0 && button.hasClass( 'fl-active' ) ) {
811				opacity.show();
812			}
813			else {
814				opacity.hide();
815			}
816		},
817
818		/**
819		 * Resize or reposition the Flyout Menu Panel.
820		 * 
821		 * @since  2.8.1
822		 * @return void
823		 */
824		_resizeFlyoutMenuPanel: function(){
825			const wrapper    = $( this.wrapperClass );
826			const wrapFlyout = wrapper.find( '.fl-menu-mobile-flyout' );
827				
828			if ( wrapFlyout.length > 0 ) {
829				wrapFlyout.css( this._getFlyoutMenuPanelPosition() );
830			}
831		},
832
833		/**
834		 * Compute the Flyout Menu Panel's position on the screen.
835		 * 
836		 * @since  2.8.1
837		 * @return object
838		 */
839		_getFlyoutMenuPanelPosition: function() {
840			var wrapper        = $( this.wrapperClass ),
841				button         = wrapper.find( '.fl-menu-mobile-toggle' ),
842				side           = wrapper.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
843				winHeight      = $(window).outerHeight(),
844				winTop         = $(window).scrollTop(),
845				adminBarHeight = $( '#wpadminbar' ).length ? $( '#wpadminbar' ).height() : 0,
846				flyoutPosition = {};
847
848			flyoutPosition[ side ]  = '-' + ( parseInt( this.flyoutWidth ) + 15 ) + 'px';
849			if ( ! button.hasClass( 'fl-active' ) ) {
850				return flyoutPosition;
851			}
852
853			flyoutPosition[ side ]  = '0px';
854			flyoutPosition[ 'height' ]  = winHeight + 'px';
855			flyoutPosition[ 'top' ] = '0px';
856			
857			if ( adminBarHeight > 0 ) {
858				const diff = adminBarHeight - winTop;
859				flyoutPosition[ 'top' ] = diff <= 0 ? '0px' : (diff) + 'px';
860			}
861
862			return flyoutPosition;
863		},
864
865		/**
866		 * Shows or hides the nav search form.
867		 *
868		 * @since  2.5
869		 * @method _toggleMenuSearch
870		 */
871		_toggleMenuSearch: function(){
872			const form   = $( this.wrapperClass ).find('.fl-menu-search-item .fl-search-form-input-wrap'); 
873			const button = $( this.wrapperClass ).find('.fl-menu-search-item .fl-button:is(a, button:not([type="submit"]))');
874			form.on('submit', () => form.stop().fadeToggle('fast'));
875			// Close the search form when focus is lost
876			form.on('focusout', (event) => {
877				if (form.is(':visible') && form.has($(event.relatedTarget)).length === 0) {
878					button.trigger('click');
879				}
880			});
881			button.attr('aria-expanded', false);
882			// Close other open submenus when focusing on the search button
883			button.on('focus', (event) => {
884				const parentMenus = $(event.relatedTarget).parents('.menu-item.fl-has-submenu');
885				if (event.relatedTarget && parentMenus.length) {
886					this._toggleSubmenu(parentMenus, false);
887				}
888			});
889			button.on('click', (event) => {
890				// Prevent toggling when clicking with mouse while the form is already open
891				if (event.detail && event.type === 'click' && form.is(':visible')) return;
892				form.stop().fadeToggle('fast', () => {
893					button.attr('aria-expanded', form.is(':visible'));
894					if(form.is(':visible')) {
895						form.find('.fl-search-text').focus();
896					}
897				});
898			});
899		},
900
901		/**
902		 * Adds menu node and post ID to WooCommerce ajax URL requests.
903		 *
904		 * @since  2.5
905		 * @return void
906		 */
907		_wooUpdateParams: function() {
908			if ( 'undefined' !== typeof wc_cart_fragments_params ) {
909				wc_cart_fragments_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
910			}
911			if ( 'undefined' !== typeof wc_add_to_cart_params ) {
912				wc_add_to_cart_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
913			}
914		},
915	};
916
917})(jQuery);
918
919(function($) {
920
921	$(function() {
922
923		new FLBuilderMenu({
924			id: '6166f42df0bd2',
925			type: 'vertical',
926			mobile: 'expanded',
927			mobileBelowRow: false,
928			mobileFlyout: false,
929			breakPoints: {
930				large: 1200,
931				medium: 992,
932				small: 768			},
933			mobileBreakpoint: 'mobile',
934			postId : '27335',
935			mobileStacked: true,
936			submenuIcon: 'none',
937			flyoutWidth: '250',
938		});
939
940	});
941
942})(jQuery);
943
944(function($) {
945
946	$(function() {
947
948		new FLBuilderMenu({
949			id: '6166f49fcad45',
950			type: 'vertical',
951			mobile: 'expanded',
952			mobileBelowRow: false,
953			mobileFlyout: false,
954			breakPoints: {
955				large: 1200,
956				medium: 992,
957				small: 768			},
958			mobileBreakpoint: 'mobile',
959			postId : '27335',
960			mobileStacked: true,
961			submenuIcon: 'none',
962			flyoutWidth: '250',
963		});
964
965	});
966
967})(jQuery);
968
969(function($) {
970
971	$(function() {
972
973		new FLBuilderMenu({
974			id: '6166f4b81fcaf',
975			type: 'vertical',
976			mobile: 'expanded',
977			mobileBelowRow: false,
978			mobileFlyout: false,
979			breakPoints: {
980				large: 1200,
981				medium: 992,
982				small: 768			},
983			mobileBreakpoint: 'mobile',
984			postId : '27335',
985			mobileStacked: true,
986			submenuIcon: 'none',
987			flyoutWidth: '250',
988		});
989
990	});
991
992})(jQuery);
993
994(function($) {
995
996	$(function() {
997
998		new FLBuilderMenu({
999			id: '6166f60bec55f',
1000			type: 'vertical',
1001			mobile: 'expanded',
1002			mobileBelowRow: false,
1003			mobileFlyout: false,
1004			breakPoints: {
1005				large: 1200,
1006				medium: 992,
1007				small: 768			},
1008			mobileBreakpoint: 'mobile',
1009			postId : '27335',
1010			mobileStacked: true,
1011			submenuIcon: 'none',
1012			flyoutWidth: '250',
1013		});
1014
1015	});
1016
1017})(jQuery);
1018
1019/* Start Layout Custom JS */
1020
1021/* End Layout Custom JS */
1022
1023
1024jQuery(function($) {
1025	
1026		$(function() {
1027		$( '.fl-node-izhljdrm4vo8 .fl-photo-img' )
1028			.on( 'mouseenter', function( e ) {
1029				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
1030			} )
1031			.on( 'mouseleave', function( e ){
1032				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
1033			} );
1034	});
1035		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
1036});
1037(function($){
1038	})(jQuery);
1039jQuery(function($) {
1040	
1041		$(function() {
1042		$( '.fl-node-6jio1mt2wnkz .fl-photo-img' )
1043			.on( 'mouseenter', function( e ) {
1044				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
1045			} )
1046			.on( 'mouseleave', function( e ){
1047				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
1048			} );
1049	});
1050		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
1051});
1052
1053(function($) {
1054
1055	$(function() {
1056
1057		new FLBuilderMenu({
1058			id: 'u8pveyc47g30',
1059			type: 'horizontal',
1060			mobile: 'expanded',
1061			mobileBelowRow: true,
1062			mobileFlyout: false,
1063			breakPoints: {
1064				large: 1200,
1065				medium: 992,
1066				small: 768			},
1067			mobileBreakpoint: 'mobile',
1068			postId : '230550',
1069			mobileStacked: true,
1070			submenuIcon: 'arrows',
1071			flyoutWidth: '250',
1072		});
1073
1074	});
1075
1076})(jQuery);
1077
1078/* Start Layout Custom JS */
1079
1080/* End Layout Custom JS */
1081
1082(function($){
1083
1084	/**
1085	 * Helper class for header layout logic.
1086	 *
1087	 * @since 1.0
1088	 * @class FLThemeBuilderHeaderLayout
1089	 */
1090	FLThemeBuilderHeaderLayout = {
1091
1092		/**
1093		 * A reference to the window object for this page.
1094		 *
1095		 * @since 1.0
1096		 * @property {Object} win
1097		 */
1098		win : null,
1099
1100		/**
1101		 * A reference to the body object for this page.
1102		 *
1103		 * @since 1.0
1104		 * @property {Object} body
1105		 */
1106		body : null,
1107
1108		/**
1109		 * A reference to the header object for this page.
1110		 *
1111		 * @since 1.0
1112		 * @property {Object} header
1113		 */
1114		header : null,
1115
1116		/**
1117		 * Whether this header overlays the content or not.
1118		 *
1119		 * @since 1.0
1120		 * @property {Boolean} overlay
1121		 */
1122		overlay : false,
1123
1124		/**
1125		 * Whether the page has the WP admin bar or not.
1126		 *
1127		 * @since 1.0
1128		 * @property {Boolean} hasAdminBar
1129		 */
1130		hasAdminBar : false,
1131
1132		/**
1133		 * Breakpoint for when the sticky header should apply.
1134		 *
1135		 * @since 1.4
1136		 * @property {String} stickyOn
1137		 */
1138		stickyOn: '',
1139
1140		/**
1141		 * A reference of the sticky and shrink header breakpoint.
1142		 *
1143		 * @since 1.2.5
1144		 * @property {Number} breakpointWidth
1145		 */
1146		breakpointWidth: 0,
1147
1148		/**
1149		 * Whether this header can be pinned from page load.
1150		 *
1151		 * @since 1.6.1
1152		 * @property {Boolean} pinnable
1153		 */
1154		pinnable : false,
1155
1156		/**
1157		 * Initializes header layout logic.
1158		 *
1159		 * @since 1.0
1160		 * @method init
1161		 */
1162		init: function()
1163		{
1164			var editing          = $( 'html.fl-builder-edit' ).length,
1165				header           = $( '.fl-builder-content[data-type=header]' ),
1166				menuModule       = header.find( '.fl-module-menu' ),
1167				breakpoint       = null,
1168				adminBarHeight   = 0;
1169
1170			if ( ! editing && header.length ) {
1171
1172				header.imagesLoaded( $.proxy( function() {
1173
1174					this.win         = $( window );
1175					this.body        = $( 'body' );
1176					this.header      = header.eq( 0 );
1177					this.overlay     = !! Number( header.attr( 'data-overlay' ) );
1178					this.hasAdminBar = !! $( 'body.admin-bar' ).length;
1179					this.stickyOn    = this.header.data( 'sticky-on' );
1180					breakpoint       = this.header.data( 'sticky-breakpoint' );
1181
1182					if ( '' == this.stickyOn ) {
1183						if ( typeof FLBuilderLayoutConfig.breakpoints[ breakpoint ] !== undefined ) {
1184							this.breakpointWidth = FLBuilderLayoutConfig.breakpoints[ breakpoint ];
1185						}
1186						else {
1187							this.breakpointWidth = FLBuilderLayoutConfig.breakpoints.medium;
1188						}
1189					}
1190
1191					if ( Number( header.attr( 'data-sticky' ) ) ) {
1192
1193						this.header.data( 'original-top', this.header.offset().top );
1194
1195						// The pin decision is made once here, while the header offset and the admin bar height are read from the same layout.
1196						adminBarHeight = $( '#wpadminbar' ).length ? $( '#wpadminbar' ).outerHeight() : 0;
1197						this.pinnable  = this.overlay && this.header.data( 'original-top' ) <= adminBarHeight;
1198
1199						this.win.on( 'resize', $.throttle( 500, $.proxy( this._initSticky, this ) ) );
1200						this._initSticky();
1201
1202					}
1203
1204				}, this ) );
1205			}
1206		},
1207
1208		/**
1209		 * Initializes sticky logic for a header.
1210		 *
1211		 * @since 1.0
1212		 * @access private
1213		 * @method _initSticky
1214		 */
1215		_initSticky: function( e )
1216		{
1217			var header     = $('.fl-builder-content[data-type=header]'),
1218				windowSize = this.win.width(),
1219				makeSticky = false;
1220
1221			makeSticky = this._makeWindowSticky( windowSize );
1222			if ( makeSticky || ( this.breakpointWidth > 0 && windowSize >= this.breakpointWidth ) ) {
1223				this.win.on( 'scroll.fl-theme-builder-header-sticky', $.proxy( this._doSticky, this ) );
1224				this._initPin();
1225
1226				// Apply the sticky state on initial load when the page is
1227				// already scrolled past the header — e.g. when the browser
1228				// restores the scroll position on refresh. Overlay headers are
1229				// out of scope here; this mirrors the shrink-on-load behavior
1230				// in _initShrink().
1231				if ( ! e && ! this.overlay && ! this.header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1232					var loadWinTop    = this.win.scrollTop(),
1233						loadHeaderTop = Math.floor( this.header.data( 'original-top' ) );
1234
1235					if ( this.hasAdminBar && windowSize > 600 ) {
1236						loadWinTop += Math.floor( $( '#wpadminbar' ).outerHeight() );
1237					}
1238
1239					if ( loadWinTop > loadHeaderTop ) {
1240						this.header.addClass( 'fl-theme-builder-header-sticky' );
1241						this.header.addClass( 'fl-theme-builder-header-scrolled' );
1242						this._adjustHeaderHeight();
1243						this._adjustStickyHeaderWidth();
1244					}
1245				}
1246
1247				//
1248				// Check if Event Type is 'resize' then invoke this._doSticky()
1249				// only if the 'fl-theme-builder-header-sticky' class is already present.
1250				//
1251				if ( e && 'resize' === e.type ) {
1252					if ( this.header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1253						this._doSticky( e );
1254					}
1255					this._adjustStickyHeaderWidth();
1256				}
1257
1258				if ( Number( header.attr( 'data-shrink' ) ) ) {
1259					this.header.data( 'original-height', this.header.outerHeight() );
1260					this.win.on( 'resize', $.throttle( 500, $.proxy( this._initShrink, this ) ) );
1261					this._initShrink();
1262				}
1263
1264				this._initFlyoutMenuFix( e );
1265			} else {
1266				this.win.off( 'scroll.fl-theme-builder-header-sticky' );
1267				this.win.off( 'resize.fl-theme-builder-header-sticky' );
1268
1269				this.header.removeClass( 'fl-theme-builder-header-sticky' );
1270				this.header.removeClass( 'fl-theme-builder-header-pinned' );
1271				this.header.removeAttr( 'style' );
1272				this.header.parent().css( 'padding-top', '0' );
1273			}
1274		},
1275
1276		/**
1277		 * Pins an overlay header with fixed positioning from page load, avoiding a position change that a scroll handler cannot apply before the compositor paints.
1278		 *
1279		 * @since 1.6.1
1280		 * @access private
1281		 * @method _initPin
1282		 */
1283		_initPin: function()
1284		{
1285			this.header.toggleClass( 'fl-theme-builder-header-pinned', this.pinnable );
1286
1287			if ( ! this.pinnable ) {
1288				return;
1289			}
1290
1291			// Fixed positioning resolves the width against the viewport, so boxed layouts require their maximum width immediately.
1292			this._adjustStickyHeaderWidth();
1293
1294			// The header is visible from the first paint, so the scrolled state must reflect any restored scroll position.
1295			if ( this.win.scrollTop() > Math.floor( this.header.data( 'original-top' ) ) ) {
1296				this.header.addClass( 'fl-theme-builder-header-scrolled' );
1297			}
1298		},
1299
1300		/**
1301		 * Check if Header should be sticky at a particular Window size.
1302		 *
1303		 * @since 1.4
1304		 * @access private
1305		 * @param  widowSize
1306		 * @method _makeWindowSticky
1307		 */
1308		_makeWindowSticky: function ( windowSize )
1309		{
1310			var makeSticky = false;
1311
1312			switch (this.stickyOn) {
1313				case 'xl':
1314					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['large'];
1315					break;
1316				case '': // Default
1317				case 'desktop':
1318					makeSticky = windowSize >= FLBuilderLayoutConfig.breakpoints['medium'];
1319					break;
1320				case 'desktop-medium':
1321					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'];
1322					break;
1323				case 'large':
1324					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['medium'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
1325					break;
1326				case 'large-medium':
1327					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
1328					break;
1329				case 'medium':
1330					makeSticky = ( windowSize <= FLBuilderLayoutConfig.breakpoints['medium'] && windowSize > FLBuilderLayoutConfig.breakpoints['small'] );
1331					break;
1332				case 'medium-mobile':
1333					makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['medium']);
1334					break;
1335				case 'mobile':
1336					makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['small']);
1337					break;
1338				case 'all':
1339					makeSticky = true;
1340					break;
1341			}
1342
1343			return makeSticky;
1344		},
1345
1346		/**
1347		 * Sticks the header when the page is scrolled.
1348		 *
1349		 * @since 1.0
1350		 * @access private
1351		 * @method _doSticky
1352		 */
1353		_doSticky: function( e )
1354		{
1355			var winTop    		  = Math.floor( this.win.scrollTop() ),
1356				headerTop 		  = Math.floor( this.header.data( 'original-top' ) ),
1357				hasStickyClass    = this.header.hasClass( 'fl-theme-builder-header-sticky' ),
1358				hasScrolledClass  = this.header.hasClass( 'fl-theme-builder-header-scrolled' ),
1359				beforeHeader      = this.header.prevAll( '.fl-builder-content' ),
1360				bodyTopPadding    = parseInt( jQuery('body').css('padding-top') ),
1361				winBarHeight      = $('#wpadminbar').length ? $('#wpadminbar').outerHeight() : 0,
1362				headerHeight      = 0;
1363
1364			if ( isNaN( bodyTopPadding ) ) {
1365				bodyTopPadding = 0;
1366			}
1367
1368			if ( this.hasAdminBar && this.win.width() > 600 ) {
1369				winTop += Math.floor( winBarHeight );
1370			}
1371
1372			if ( winTop > headerTop ) {
1373				if ( ! hasStickyClass ) {
1374					if ( e && ( 'scroll' === e.type || 'smartscroll' === e.type ) ) {
1375					 	this.header.addClass( 'fl-theme-builder-header-sticky' );
1376						if ( this.overlay && beforeHeader.length ) {
1377							this.header.css( 'top', winBarHeight);
1378						}
1379					}
1380
1381					if ( ! this.overlay ) {
1382						this._adjustHeaderHeight();
1383					}
1384				}
1385			}
1386			else if ( hasStickyClass ) {
1387				this.header.removeClass( 'fl-theme-builder-header-sticky' );
1388				this.header.removeAttr( 'style' );
1389				this.header.parent().css( 'padding-top', '0' );
1390			}
1391
1392			this._adjustStickyHeaderWidth();
1393
1394			if ( winTop > headerTop ) {
1395				if ( ! hasScrolledClass ) {
1396					this.header.addClass( 'fl-theme-builder-header-scrolled' );
1397				}
1398			} else if ( hasScrolledClass ) {
1399				this.header.removeClass( 'fl-theme-builder-header-scrolled' );
1400			}
1401
1402			this._flyoutMenuFix( e );
1403		},
1404
1405		/**
1406		 * Initializes flyout menu fixes on sticky header.
1407		 *
1408		 * @since 1.4.1
1409		 * @method _initFlyoutMenuFix
1410		 */
1411		_initFlyoutMenuFix: function( e ) {
1412			var header       = this.header,
1413				menuModule   = header.closest( '.fl-menu' ),
1414				flyoutMenu   = menuModule.find( '.fl-menu-mobile-flyout' ),
1415				isPushMenu   = menuModule.hasClass( 'fl-menu-responsive-flyout-push' ) || menuModule.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
1416				isOverlay    = menuModule.hasClass( 'fl-menu-responsive-flyout-overlay' ),
1417				flyoutPos    = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
1418				flyoutParent = header.parent().is( 'header' ) ? header.parent().parent() : header.parent();
1419				isFullWidth  = this.win.width() === header.width(),
1420				flyoutLayout = '',
1421				activePos    = 250,
1422				headerPos    = 0;
1423
1424			if ( ! flyoutMenu.length ) {
1425				return;
1426			}
1427
1428			if ( this.win.width() > header.parent().width() ) {
1429				headerPos = ( this.win.width() - header.width() ) / 2;
1430			}
1431
1432			if ( isOverlay ) {
1433				activePos = headerPos;
1434			}
1435			else if ( isPushMenu ) {
1436				activePos = activePos + headerPos;
1437			}
1438			flyoutMenu.data( 'activePos', activePos );
1439
1440			if ( isPushMenu ) {
1441				flyoutLayout = 'push-' + flyoutPos;
1442			}
1443			else if ( isOverlay ) {
1444				flyoutLayout = 'overlay-' + flyoutPos;
1445			}
1446
1447			if ( isPushMenu && ! $( 'html' ).hasClass( 'fl-theme-builder-has-flyout-menu' ) ) {
1448				$( 'html' ).addClass( 'fl-theme-builder-has-flyout-menu' );
1449			}
1450
1451			if ( ! flyoutParent.hasClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout ) ) {
1452				flyoutParent.addClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout );
1453			}
1454
1455			if ( ! header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && isOverlay ) {
1456				header.addClass( 'fl-theme-builder-flyout-menu-overlay' );
1457			}
1458
1459			if ( ! header.hasClass( 'fl-theme-builder-header-full-width' ) && isFullWidth ) {
1460			   header.addClass( 'fl-theme-builder-header-full-width' );
1461		    }
1462			else if ( ! isFullWidth ) {
1463				header.removeClass( 'fl-theme-builder-header-full-width' );
1464			}
1465
1466			menuModule.on( 'click', '.fl-menu-mobile-toggle', $.proxy( function( event ){
1467				if ( menuModule.find( '.fl-menu-mobile-toggle.fl-active' ).length ) {
1468					$( 'html' ).addClass( 'fl-theme-builder-flyout-menu-active' );
1469					event.stopImmediatePropagation();
1470				}
1471				else {
1472					$( 'html' ).removeClass( 'fl-theme-builder-flyout-menu-active' );
1473				}
1474
1475				this._flyoutMenuFix( event );
1476			}, this ) );
1477		},
1478
1479		/**
1480		 * Fix flyout menu inside the sticky header.
1481		 *
1482		 * @since 1.4.1
1483		 * @method _flyoutMenuFix
1484		 */
1485		_flyoutMenuFix: function( e ){
1486			var header      = this.header,
1487			    menuModule  = $( e.target ).closest( '.fl-menu' ),
1488				flyoutMenu  = menuModule.find( '.fl-menu-mobile-flyout' ),
1489				flyoutPos   = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
1490				menuOpacity = menuModule.find( '.fl-menu-mobile-opacity' ),
1491				isScroll    = 'undefined' !== typeof e && 'scroll' === e.handleObj.type,
1492				activePos   = 'undefined' !== typeof flyoutMenu.data( 'activePos' ) ? flyoutMenu.data( 'activePos' ) : 0,
1493				headerPos   = ( this.win.width() - header.width() ) / 2,
1494				inactivePos = headerPos > 0 ? activePos + 4 : 254;
1495
1496			if ( ! flyoutMenu.length ) {
1497				return;
1498			}
1499
1500			if ( this.overlay ) {
1501				return;
1502			}
1503
1504			if( $( '.fl-theme-builder-flyout-menu-active' ).length ) {
1505
1506				if ( isScroll && ! flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
1507					flyoutMenu.addClass( 'fl-menu-disable-transition' );
1508				}
1509
1510				if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1511					if ( ! isScroll ) {
1512						setTimeout( $.proxy( function(){
1513							flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
1514						}, this ), 1 );
1515					}
1516					else {
1517						flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
1518					}
1519				}
1520				else {
1521					flyoutMenu.css( flyoutPos, '0px' );
1522				}
1523			}
1524			else {
1525				if ( flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
1526					flyoutMenu.removeClass( 'fl-menu-disable-transition' );
1527				}
1528
1529				if ( header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && headerPos > 0 && headerPos < 250 ) {
1530					if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1531						inactivePos = headerPos + 254;
1532					}
1533					else {
1534						inactivePos = 254;
1535					}
1536				}
1537
1538				if ( e && e.type === 'resize' ) {
1539					inactivePos = headerPos + 254;
1540				}
1541
1542				flyoutMenu.css( flyoutPos, '-' + inactivePos + 'px' );
1543			}
1544
1545			if ( e && menuModule.is('.fl-menu-responsive-flyout-overlay') && $.infinitescroll ) {
1546				e.stopImmediatePropagation();
1547			}
1548
1549			if( menuOpacity.length ) {
1550				if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1551					if ( '0px' === menuOpacity.css( 'left' ) ) {
1552						menuOpacity.css( 'left', '-' + headerPos + 'px' );
1553					}
1554				}
1555				else {
1556					menuOpacity.css( 'left', '' );
1557				}
1558			}
1559		},
1560
1561		/**
1562		 * Adjust sticky header width if BB Theme Boxed Layout is used.
1563		 *
1564		 * @since 1.4
1565		 * @access private
1566		 * @method _adjustStickyHeaderWidth
1567		 */
1568		_adjustStickyHeaderWidth: function () {
1569			if ( $('body').hasClass( 'fl-fixed-width' ) ) {
1570				var parentWidth = this.header.parent().width();
1571
1572				// Better if this is set in the stylesheet file.
1573				if ( this.win.width() >= 992 ) {
1574					this.header.css({
1575						'margin': '0 auto',
1576						'max-width': parentWidth,
1577					});
1578				}
1579				else {
1580					this.header.css({
1581						'margin': '',
1582						'max-width': '',
1583					});
1584				}
1585			}
1586		},
1587
1588		/**
1589		 * Adjust Sticky Header Height
1590		 *
1591		 * @since 1.4
1592		 * @access private
1593		 * @method _adjustHeaderHeight
1594		 */
1595		_adjustHeaderHeight: function () {
1596			var beforeHeader = this.header.prevAll('.fl-builder-content'),
1597				beforeHeaderHeight = 0,
1598				beforeHeaderFix = 0,
1599				headerHeight = Math.floor( this.header.outerHeight() ),
1600				bodyTopPadding = parseInt( $( 'body' ).css( 'padding-top' ) ),
1601				wpAdminBarHeight = 0,
1602				totalHeaderHeight = 0;
1603
1604			if ( isNaN( bodyTopPadding ) ) {
1605				bodyTopPadding = 0;
1606			}
1607
1608			if ( beforeHeader.length ) {
1609				$.each( beforeHeader, function() {
1610					beforeHeaderHeight += Math.floor( $(this).outerHeight() );
1611				});
1612				// Subtract this value from the header parent's top padding.
1613				beforeHeaderFix = 2;
1614			}
1615
1616			if ( this.hasAdminBar && this.win.width() <= 600 ) {
1617				wpAdminBarHeight = Math.floor( $('#wpadminbar').outerHeight() );
1618			}
1619
1620			totalHeaderHeight = Math.floor( beforeHeaderHeight + headerHeight);
1621
1622			if ( headerHeight > 0 ) {
1623				var headerParent = this.header.parent(),
1624					headerParentTopPadding = 0;
1625
1626				// If the header's parent container is the BODY tag ignore its top padding.
1627				if ( $( headerParent ).is('body') ) {
1628					headerParentTopPadding = Math.floor( headerHeight - wpAdminBarHeight );
1629				} else {
1630					headerParentTopPadding = Math.floor( headerHeight - bodyTopPadding - wpAdminBarHeight );
1631				}
1632
1633				$( headerParent ).css( 'padding-top',  ( headerParentTopPadding - beforeHeaderFix ) + 'px' );
1634
1635				this.header.css({
1636					'-webkit-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
1637					'-ms-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
1638					'transform': 'translate(0px, -' + totalHeaderHeight + 'px)'
1639				});
1640
1641			}
1642
1643		},
1644
1645		/**
1646		 * Initializes shrink logic for a header.
1647		 *
1648		 * @since 1.0
1649		 * @access private
1650		 * @method _initShrink
1651		 */
1652		_initShrink: function( e )
1653		{
1654			if ( this.win.width() >= this.breakpointWidth ) {
1655				this.win.on( 'scroll.fl-theme-builder-header-shrink', $.proxy( this._doShrink, this ) );
1656				this._setImageMaxHeight();
1657
1658				if ( this.win.scrollTop() > 0 ){
1659					this._doShrink();
1660				}
1661
1662			} else {
1663				this.header.parent().css( 'padding-top', '0' );
1664				this.win.off( 'scroll.fl-theme-builder-header-shrink' );
1665				this._removeShrink();
1666				this._removeImageMaxHeight();
1667			}
1668		},
1669
1670		/**
1671		 * Shrinks the header when the page is scrolled.
1672		 *
1673		 * @since 1.0
1674		 * @access private
1675		 * @method _doShrink
1676		 */
1677		_doShrink: function( e )
1678		{
1679			var winTop 			  = this.win.scrollTop(),
1680				headerTop 		  = this.header.data('original-top'),
1681				headerHeight 	  = this.header.data('original-height'),
1682				shrinkImageHeight = this.header.data('shrink-image-height'),
1683				windowSize   	  = this.win.width(),
1684				makeSticky   	  = this._makeWindowSticky( windowSize ),
1685				hasClass     	  = this.header.hasClass( 'fl-theme-builder-header-shrink' );
1686
1687
1688			if ( this.hasAdminBar ) {
1689				winTop += 32;
1690			}
1691
1692			if ( makeSticky && ( winTop > headerTop + headerHeight ) ) {
1693				if ( ! hasClass ) {
1694
1695					this.header.addClass( 'fl-theme-builder-header-shrink' );
1696
1697					// Shrink images but don't include lightbox and menu images.
1698					this.header.find('img').each( function( i ) {
1699						var image           = $( this ),
1700							maxMegaMenu     = image.closest( '.max-mega-menu' ).length,
1701							imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
1702							imageInNavMenu  = image.closest( 'li.menu-item' ).length;
1703
1704						if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu ) ) {
1705							image.css( 'max-height', shrinkImageHeight );
1706						}
1707
1708					});
1709
1710					this.header.find( '.fl-row-content-wrap' ).each( function() {
1711
1712						var row = $( this );
1713
1714						if ( parseInt( row.css( 'padding-bottom' ) ) > 5 ) {
1715							row.addClass( 'fl-theme-builder-header-shrink-row-bottom' );
1716						}
1717
1718						if ( parseInt( row.css( 'padding-top' ) ) > 5 ) {
1719							row.addClass( 'fl-theme-builder-header-shrink-row-top' );
1720						}
1721					} );
1722
1723					this.header.find( '.fl-module' ).each( function() {
1724
1725						var module = $( this ).find( '.fl-module-content' ).length ? $( this ).find( '.fl-module-content' ) : $( this );
1726
1727						if ( parseInt( module.css( 'margin-bottom' ) ) > 5 ) {
1728							module.addClass( 'fl-theme-builder-header-shrink-module-bottom' );
1729						}
1730
1731						if ( parseInt( module.css( 'margin-top' ) ) > 5 ) {
1732							module.addClass( 'fl-theme-builder-header-shrink-module-top' );
1733						}
1734					} );
1735				}
1736			} else if (hasClass) {
1737				this.header.find( 'img' ).css( 'max-height', '' );
1738				this._removeShrink();
1739			}
1740
1741			// Fixes Shrink header issue with BB Theme when window is scrolled then resized and back.
1742			if ( 'undefined' === typeof( e ) && $('body').hasClass( 'fl-fixed-width' ) ) {
1743				if ( ! this.overlay ) {
1744					this._adjustHeaderHeight();
1745				}
1746			}
1747
1748		},
1749
1750		/**
1751		 * Removes the header shrink effect.
1752		 *
1753		 * @since 1.0
1754		 * @access private
1755		 * @method _removeShrink
1756		 */
1757		_removeShrink: function()
1758		{
1759			var rows    = this.header.find( '.fl-row-content-wrap' ),
1760				modules = this.header.find('.fl-module, .fl-module-content');
1761
1762			rows.removeClass( 'fl-theme-builder-header-shrink-row-bottom' );
1763			rows.removeClass( 'fl-theme-builder-header-shrink-row-top' );
1764			modules.removeClass( 'fl-theme-builder-header-shrink-module-bottom' );
1765			modules.removeClass( 'fl-theme-builder-header-shrink-module-top' );
1766			this.header.removeClass( 'fl-theme-builder-header-shrink' );
1767		},
1768
1769		/**
1770		 * Adds max height to images in modules for smooth scrolling.
1771		 *
1772		 * @since 1.1.1
1773		 * @access private
1774		 * @method _setImageMaxHeight
1775		 */
1776		_setImageMaxHeight: function()
1777		{
1778			var head = $( 'head' ),
1779				stylesId = 'fl-header-styles-' + this.header.data( 'post-id' ),
1780				styles = '',
1781				images = this.header.find( '.fl-module img' );
1782
1783			if ( $( '#' + stylesId ).length ) {
1784				return;
1785			}
1786
1787			images.each( function( i ) {
1788				var image           = $( this ),
1789					height          = image.height(),
1790					node            = image.closest( '.fl-module' ).data( 'node' ),
1791					className       = 'fl-node-' + node + '-img-' + i,
1792					maxMegaMenu     = image.closest( '.max-mega-menu' ).length,
1793					imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
1794					imageInNavMenu  = image.closest( 'li.menu-item' ).length;
1795
1796				if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu  ) ) {
1797					image.addClass( className );
1798					styles += '.' + className + ' { max-height: ' + ( height ? height : image[0].height )  + 'px }';
1799				}
1800
1801			} );
1802
1803			if ( '' !== styles ) {
1804				head.append( '<style id="' + stylesId + '">' + styles + '</style>' );
1805			}
1806		},
1807
1808		/**
1809		 * Removes max height on images in modules for smooth scrolling.
1810		 *
1811		 * @since 1.1.1
1812		 * @access private
1813		 * @method _removeImageMaxHeight
1814		 */
1815		_removeImageMaxHeight: function()
1816		{
1817			$( '#fl-header-styles-' + this.header.data( 'post-id' ) ).remove();
1818		},
1819	};
1820
1821	$( function() { FLThemeBuilderHeaderLayout.init(); } );
1822
1823})(jQuery);
1824

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.