403Webshell
Server IP : 65.109.86.83  /  Your IP : 37.27.51.148
Web Server : nginx/1.14.1
System : Linux libra 4.18.0-553.51.1.el8_10.x86_64 #1 SMP Wed Apr 30 20:24:04 UTC 2025 x86_64
User : root ( 0)
PHP Version : 8.3.31
Disable Function : exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/html/wp-content/plugins/thrive-leads/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/wp-content/plugins/thrive-leads/js/frontend.js
/**
 * Frontend javascript functionalities handling the display of forms
 */
window.TL_Front = window.TL_Front || {};

/* minor hackery to ensure we have this available */
window.ThriveGlobal = window.ThriveGlobal || {$j: jQuery.noConflict()};

const videoIframeSelector = '.thrv_responsive_video iframe, .thrv_custom_html_shortcode iframe';
const videoSourceSelector = '.thrv_responsive_video video source';
let modulesFinishedLoading = false;

/**
 * Form types that are trigger-based and should have their impressions tracked
 * only when the form becomes visible, not on page load.
 *
 * This constant is populated from PHP via localized script data to ensure
 * it stays synchronized with the server-side definition.
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
 * @see tve_leads_get_trigger_based_form_types() PHP function that defines these types
 * @see tve_leads_prepare_script_config() Where this is localized to JavaScript
 *
 * @todo Future enhancement: Check the actual trigger type (page_load vs time/scroll/exit/click)
 *       and only defer impressions for non-page_load triggers. All these form types support
 *       page_load as a trigger option.
 */
const TRIGGER_BASED_FORM_TYPES = ( typeof TL_Const !== 'undefined' && TL_Const.trigger_based_form_types ) 
	? TL_Const.trigger_based_form_types 
	: [ 'lightbox', 'screen_filler', 'slide_in', 'ribbon' ]; // Fallback for edge cases

/**
 * Form type prefixes that use Intersection Observer for viewport-based impression tracking.
 * These forms are embedded inline and may be below the fold, so we track impressions
 * only when they become visible in the viewport.
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
 */
const VIEWPORT_BASED_FORM_PREFIXES = [ 'shortcode_' ];

TL_Front.add_page_css = function ( stylesheets ) {
	ThriveGlobal.$j.each( stylesheets, function ( _id, href ) {
		_id += '-css';

		href = href.replace( /^http(s)?:\/\//, '//' );

		if ( href.indexOf( 'thrive_flat' ) !== - 1 ) {
			var testElement = document.createElement( 'div' );
			testElement.classList.add( 'tve-cb' );
			document.body.append( testElement );
			/* tcb/editor/css/sass/elements/_contentbox.scss line 59 - we're checking if a specific css exists then the file has been loaded
			 * one of the cases where the previous implementation was not working was when a caching plugin was merging the js files */
			if ( getComputedStyle( testElement )[ 'clear' ] === 'both' ) {
				testElement.remove();
				return;
			}

			testElement.remove();
		}

		/* make sure a css is not loaded twice */
		if ( ! ThriveGlobal.$j( '#' + _id ).length && ! ThriveGlobal.$j( 'link[href="http:' + href + '"]' ).length && ! ThriveGlobal.$j( 'link[href="https:' + href + '"]' ).length ) {
			ThriveGlobal.$j( '<link rel="stylesheet" id="' + _id + '" type="text/css" href="' + href + '"/>' ).prependTo( 'head' );
		}
	} );
};

/**
 * Load optimized styles and js modules
 * @param assets
 */
TL_Front.lightspeed_assets = function ( assets ) {
	var hasFlat = function () {
		return ThriveGlobal.$j( 'link[href*="thrive_flat.css"]' ).length > 0
	}, modulesToLoad = [];

	if ( assets.css ) {
		if ( assets.css.files ) {
			for ( var file in assets.css.files ) {
				var isFlat = file === 'flat';
				if ( ( ! hasFlat() && isFlat ) || ! isFlat ) {
					ThriveGlobal.$j( '<link rel="stylesheet" href="' + assets.css.files[ file ] + '"/>' ).prependTo( 'head' );
				}
			}
		}

		if ( assets.css.inline && assets.css.inline.length ) {
			assets.css.inline.forEach( function ( style ) {
				if ( ! hasFlat() ) {
					ThriveGlobal.$j( style ).prependTo( 'head' );
				}
			} )
		}
	}

	if ( assets.js ) {
		for ( var module in assets.js ) {
			if ( TCB_Front && ! TCB_Front.isModuleLoaded( module ) ) {
				modulesToLoad.push( module )
			}
		}
	}

	function loadModule() {
		if ( modulesToLoad.length ) {
			var currentModule = modulesToLoad.shift()
			/* load next module only after the current one is loaded */
			TL_Front.add_head_script( assets.js[ currentModule ], 'tl-lightspeed-' + currentModule, loadModule );
		} else {
			modulesFinishedLoading = true
		}
	}

	loadModule()
}
/**
 * Add the conditions from TL in the localized conditions preview object
 *
 * @param allData - request data
 */
TL_Front.conditional_display = function ( allData ) {
	/* if we have conditional displays on the request, we append them to the localized variable */
	if ( typeof allData !== 'undefined' && allData.lazy_load_conditional_preview && tcb_condition_sets ) {
		allData.lazy_load_conditional_preview.forEach( function ( display ) {
			var index = tcb_condition_sets.findIndex( function ( item ) {
				return item.key === display.key
			} );
			if ( index === - 1 ) {
				tcb_condition_sets.push( display );
			}
		} )
	}
}

TL_Front.$document = ThriveGlobal.$j( document );

/**
 * Extend the TL_Const object being careful not to overwrite some of its fields.
 *
 * @param {*} configuration
 */
TL_Front.extendConst = function ( configuration ) {
	if ( TL_Const.current_screen ) { // this makes sure the original screen data is not changed
		delete configuration.current_screen;
	}
	ThriveGlobal.$j.extend( true, TL_Const, configuration );
}

/**
 * Emulates the default document.write function - but appending elements with jquery - thus not breaking the body on document.write after domready
 * @param str
 */
TL_Front.document_write = function ( str ) {
	ThriveGlobal.$j( 'body' ).append( str );
};

/**
 * we need to add the scripts using this method, to make sure the onload callback is fired properly
 * @param src
 * @param onload
 */
TL_Front.add_head_script = function ( src, id, onload ) {
	var script = document.createElement( 'script' ),
		head = ThriveGlobal.$j( 'head' )[ 0 ];

	script.async = true;
	if ( typeof onload === 'function' ) {
		script.onload = script.onreadystatechange = onload;
	}
	if ( typeof id !== 'undefined' ) {
		script.id = id;
	}

	script.src = src;

	head.insertBefore( script, head.firstChild );
};

TL_Front.add_page_js = function ( links, onLoad ) {
	if ( typeof onLoad !== 'function' ) {
		onLoad = function () {
		};
	}
	var to_load = 0;
	ThriveGlobal.$j.each( links, function ( _id, href ) {
		if ( _id === 'tve_frontend' && typeof TCB_Front !== 'undefined' ) {
			return true;
		}
		_id += '-js';
		/* make sure a script is not loaded twice */
		if ( href && ! ThriveGlobal.$j( '#' + _id ).length && ! ThriveGlobal.$j( 'script[src="' + href + '"]' ).length ) {
			to_load ++;
			/* facebook needs to be inserted with a custom fragment appended - jQuery.getScript does not allow that */
			if ( href.indexOf( 'connect.facebook.net' ) !== - 1 ) {
				TL_Front.add_head_script( href, _id, function () {
					to_load --;
				} );
				return true;
			}
			ThriveGlobal.$j.getScript( href, function () {
				to_load --;
			} );
		}
	} );

	function check_loaded() {
		if ( to_load === 0 ) {
			onLoad();
			return;
		}
		setTimeout( check_loaded, 50 );
	}

	check_loaded();
};

/**
 * Send impression data to the server.
 *
 * @param {Object} impressionData - The impression data to send
 * @param {Object} options - Optional settings
 * @param {boolean} options.useBatching - Whether to use TVE_Dash batching (default: false)
 */
TL_Front.send_impression = function ( impressionData, options ) {
	if ( ! impressionData ) {
		return;
	}

	options = options || {};

	var ajax_data = {
		security: TL_Const.security,
		action: TL_Const.action_impression,
		tl_data: impressionData,
		current_screen: TL_Const.current_screen
	};

	ThriveGlobal.$j.each( TL_Const.custom_post_data, function ( k, v ) {
		ajax_data[ k ] = v;
	} );

	if ( options.useBatching && window.TVE_Dash && ! TVE_Dash.ajax_sent ) {
		TVE_Dash.add_load_item( 'tl_impression', ajax_data );
	} else {
		ThriveGlobal.$j.post( TL_Const.ajax_url, ajax_data );
	}
};

/**
 * Check if a form type is viewport-based (needs Intersection Observer).
 *
 * @param {string} formType - The form type key (e.g., 'shortcode_123')
 * @returns {boolean}
 */
TL_Front.isViewportBasedForm = function ( formType ) {
	return VIEWPORT_BASED_FORM_PREFIXES.some( function ( prefix ) {
		return formType.indexOf( prefix ) === 0;
	} );
};

/**
 * Process and setup viewport-based impressions for tracking.
 * Separates viewport-based forms from other form types and stores them for observation.
 * Observers are initialized separately via event system.
 *
 * @param {Object} impressionsData - Object containing impression data keyed by formType
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
 */
TL_Front.setupViewportImpressions = function ( impressionsData ) {
	if ( ! impressionsData || Object.keys( impressionsData ).length === 0 ) {
		return;
	}

	// Initialize storage objects
	TL_Front.deferred_impressions = TL_Front.deferred_impressions || {};
	TL_Front.viewport_impressions = TL_Front.viewport_impressions || {};

	// Separate viewport-based forms from trigger-based forms
	Object.keys( impressionsData ).forEach( function ( formType ) {
		if ( TL_Front.isViewportBasedForm( formType ) ) {
			// Viewport-based form (shortcode) - use Intersection Observer
			TL_Front.viewport_impressions[ formType ] = impressionsData[ formType ];
		} else if ( TRIGGER_BASED_FORM_TYPES.indexOf( formType ) !== -1 ) {
			// Trigger-based form - use event-based tracking
			TL_Front.deferred_impressions[ formType ] = impressionsData[ formType ];
		}
	} );
};

/**
 * Track impressions for forms on page load.
 * Uses batching when TVE_Dash is available.
 *
 * Note: Trigger-based forms (lightbox, screen_filler, slide_in, ribbon) are excluded from
 * page-load impression tracking. Their impressions are tracked when they become visible.
 *
 * Note: Viewport-based forms (shortcodes) are also excluded. Their impressions are tracked
 * using Intersection Observer when they enter the viewport.
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
 */
TL_Front.do_impression = function () {
	if ( ! TL_Front.impressions_data ) {
		return;
	}

	var pageLoadImpressions = {},
		deferredData = {};

	// Separate page-load impressions from deferred impressions in a single pass
	Object.keys( TL_Front.impressions_data ).forEach( function ( formType ) {
		if ( TRIGGER_BASED_FORM_TYPES.indexOf( formType ) !== -1 || TL_Front.isViewportBasedForm( formType ) ) {
			// Trigger-based or viewport-based form - defer impression tracking
			deferredData[ formType ] = TL_Front.impressions_data[ formType ];
		} else {
			// Standard form - track on page load
			pageLoadImpressions[ formType ] = TL_Front.impressions_data[ formType ];
		}
	} );

	// Setup deferred and viewport-based impressions
	if ( Object.keys( deferredData ).length > 0 ) {
		TL_Front.setupViewportImpressions( deferredData );
		// Initialize observers immediately - DOM is already ready at this point
		TL_Front.initViewportObservers();
	}

	// Send only page-load impressions (non-deferred forms)
	if ( Object.keys( pageLoadImpressions ).length > 0 ) {
		TL_Front.send_impression( pageLoadImpressions, { useBatching: true } );
	}
};

/**
 * Initialize Intersection Observers for viewport-based forms (shortcodes).
 * Tracks impression when the form enters the viewport.
 *
 * Strategy:
 * - IntersectionObserver fires immediately when first attached with current state
 * - We skip this initial callback and only track on actual viewport entry
 * - This ensures impressions are only tracked when forms scroll into view
 * - Prevents creating multiple observers for the same elements
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
 */
TL_Front.initViewportObservers = function () {
	if ( ! TL_Front.viewport_impressions || Object.keys( TL_Front.viewport_impressions ).length === 0 ) {
		return;
	}

	// Check for Intersection Observer support
	if ( ! ( 'IntersectionObserver' in window ) ) {
		// Fallback: track all viewport impressions immediately if IO not supported
		Object.keys( TL_Front.viewport_impressions ).forEach( function ( formType ) {
			TL_Front.trackViewportImpression( formType );
		} );
		return;
	}

	// If observer already exists, reuse it instead of creating a new one
	if ( ! TL_Front.viewportObserver ) {
		// Track whether we've seen the initial callback for each element
		// This prevents tracking impressions on the initial IO callback
		TL_Front.viewportObserverInitialCallbacks = TL_Front.viewportObserverInitialCallbacks || new WeakMap();
		
		// Track which elements are already being observed to prevent duplicates
		TL_Front.viewportObservedElements = TL_Front.viewportObservedElements || new WeakSet();

		// Create observer with threshold of 0.5 (50% visible)
		TL_Front.viewportObserver = new IntersectionObserver( function ( entries ) {
			entries.forEach( function ( entry ) {
				var element = entry.target;
				
				// Check if this is the initial callback (fired when observer is first attached)
				if ( ! TL_Front.viewportObserverInitialCallbacks.has( element ) ) {
					// Mark that we've seen the initial callback for this element
					TL_Front.viewportObserverInitialCallbacks.set( element, true );
					// Don't track impression on initial callback - only track when element
					// transitions from not-intersecting to intersecting (i.e., scrolls into view)
					return;
				}
				
				// This is a real intersection change (element scrolled into view)
				if ( entry.isIntersecting ) {
					var $element = ThriveGlobal.$j( element ),
						formType = $element.attr( 'data-tl-type' ) || $element.closest( '.tve-leads-conversion-object' ).attr( 'data-tl-type' );

					if ( formType && TL_Front.viewport_impressions[ formType ] ) {
						TL_Front.trackViewportImpression( formType );
						// Stop observing this element and remove from tracked set
						TL_Front.viewportObserver.unobserve( element );
						TL_Front.viewportObservedElements.delete( element );
					}
				}
			} );
		}, {
			threshold: 0.5 // Trigger when 50% of the element is visible
		} );
	}

	// Observe all shortcode elements that aren't already being observed
	Object.keys( TL_Front.viewport_impressions ).forEach( function ( formType ) {
		// Skip if already tracked
		if ( TL_Front.viewport_impressions[ formType ]._tracked ) {
			return;
		}
		
		// Find element by data-tl-type attribute
		var $element = ThriveGlobal.$j( '.tve-leads-conversion-object[data-tl-type="' + formType + '"]' );
		
		if ( ! $element.length ) {
			return;
		}
		
		var element = $element[ 0 ];
		
		// Check if we're already observing this element
		if ( TL_Front.viewportObservedElements.has( element ) ) {
			return;
		}
		
		TL_Front.viewportObservedElements.add( element );
		TL_Front.viewportObserver.observe( element );
	} );
};

/**
 * Track impression for a viewport-based form when it becomes visible.
 *
 * @param {string} formType - The form type (e.g., 'shortcode_123')
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
 */
TL_Front.trackViewportImpression = function ( formType ) {
	if ( ! formType || ! TL_Front.viewport_impressions || ! TL_Front.viewport_impressions[ formType ] ) {
		return;
	}

	// Check if impression was already tracked
	if ( TL_Front.viewport_impressions[ formType ]._tracked ) {
		return;
	}

	// Mark as tracked to prevent duplicate impressions
	TL_Front.viewport_impressions[ formType ]._tracked = true;

	var impressionData = {};
	impressionData[ formType ] = TL_Front.viewport_impressions[ formType ];

	TL_Front.send_impression( impressionData );
};

/**
 * Track impression for a trigger-based form when it becomes visible.
 * Called from the showform.thriveleads event handler.
 *
 * @param {string} formType - The form type (e.g., 'lightbox', 'screen_filler', 'slide_in')
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
 */
TL_Front.do_trigger_based_impression = function ( formType ) {
	if ( ! formType ) {
		return;
	}

	// Check if we have deferred impression data for this form type
	if ( ! TL_Front.deferred_impressions || ! TL_Front.deferred_impressions[ formType ] ) {
		return;
	}

	// Check if impression was already tracked for this form type
	if ( TL_Front.deferred_impressions[ formType ]._tracked ) {
		return;
	}

	// Mark as tracked to prevent duplicate impressions
	TL_Front.deferred_impressions[ formType ]._tracked = true;

	var impressionData = {};
	impressionData[ formType ] = TL_Front.deferred_impressions[ formType ];

	TL_Front.send_impression( impressionData );
};

/**
 * Track impression for a single two-step (ThriveBox) form when it's actually opened.
 * This is called when the user clicks the trigger to open the ThriveBox.
 *
 * @see https://github.com/awesomemotive/thrive-themes/issues/2504
 *
 * @param {string} formKey - The form key (e.g., 'two_step_123')
 */
TL_Front.do_two_step_impression = function ( formKey ) {
	if ( ! TL_Const || ! TL_Const.forms || ! TL_Const.forms[ formKey ] ) {
		return;
	}

	var formConfig = TL_Const.forms[ formKey ],
		impressionData = {};

	impressionData[ formKey ] = {
		group_id: formConfig.main_group_id,
		form_type_id: formConfig.form_type_id,
		variation_key: formConfig._key,
		active_test_id: formConfig.active_test_id || null
	};

	TL_Front.send_impression( impressionData );
};

/**
 * Attempt to track impression for two-step (ThriveBox) forms when they're opened.
 * Only tracks if the form_id indicates a two-step form.
 *
 * @param {string} formId - The form ID from event data (format: 'tve-leads-track-2step-<variation_key>')
 */
TL_Front.maybe_track_two_step_impression = function ( formId ) {
	if ( ! formId || formId.indexOf( '2step-' ) === -1 ) {
		return;
	}

	if ( ! TL_Const || ! TL_Const.forms ) {
		return;
	}

	var variationKey = formId.replace( 'tve-leads-track-2step-', '' );

	var formKey = Object.keys( TL_Const.forms ).find( function ( key ) {
		return key.indexOf( 'two_step_' ) === 0 && TL_Const.forms[ key ]._key === variationKey;
	} );

	if ( ! formKey ) {
		return;
	}

	TL_Front.do_two_step_impression( formKey );
};

ThriveGlobal.$j( function () {

	function _ieVersion() {
		/*global navigator */
		var rv = - 1;
		var ua;
		var re;

		if ( navigator.appName == 'Microsoft Internet Explorer' ) {
			ua = navigator.userAgent;
			re = new RegExp( 'MSIE ([0-9]{1,}[\\.0-9]{0,})' );

			if ( re.exec( ua ) !== null ) {
				rv = parseFloat( RegExp.$1 );
			}
		} else if ( navigator.appName == 'Netscape' ) {
			ua = navigator.userAgent;
			re = new RegExp( 'Trident/.*rv:([0-9]{1,}[\\.0-9]{0,})' );

			if ( re.exec( ua ) !== null ) {
				rv = parseFloat( RegExp.$1 );
			}
		}

		return rv;
	}

	/**
	 * SUPP-1217 Divi + Yoast + TL conflict
	 */
	if ( typeof TL_Const === 'undefined' ) {
		return;
	}

	ThriveGlobal.$j( '.tve-leads-screen-filler iframe, .tve-leads-ribbon iframe' ).not( '.thrv_social_default iframe' ).not( '.tcb-dr-done' ).each( function () {
		var $frame = ThriveGlobal.$j( this ).addClass( 'tcb-dr-done' );
		if ( $frame.attr( 'src' ) ) {
			$frame.attr( 'data-src', $frame.attr( 'src' ) );
		}
		$frame.attr( 'src', '' );
	} );

	if ( typeof TCB_Front !== 'undefined' ) {
		ThriveGlobal.$j( TCB_Front ).on( 'content_loaded.thrive', function ( event, $element ) {
			$element.find( '.tve-tl-anim' ).each( function () {
				var $this = ThriveGlobal.$j( this );
				ThriveGlobal.$j( TL_Front ).trigger( 'showform.thriveleads', {$target: $this} );
			} );
		} );
	}

	ThriveGlobal.$j( window ).on( 'tcb_after_dom_ready', function () {
		if ( ! tve_frontend_options.is_editor_page ) {
			var postType = TCB_Front.queryString.get( 'post_type' );
			if ( postType && postType === 'tve_lead_2s_lightbox' ) {
				//do it with timeout just in case they were hidden from other places
				setTimeout( function () {
					TCB_Front.handleIframes( ThriveGlobal.$j( '.tve_p_lb_content' ) );
				}, 100 );
			}
		}
	} );

	ThriveGlobal.$j( TL_Front ).on( 'showform.thriveleads', function ( event, data ) {
		var $target = data.$target ? data.$target : ThriveGlobal.$j( '.' + data.form_id ),
			$anim_target;
		if ( ! $target.length ) {
			return;
		}

		if ( data.TargetEvent && data.TargetEvent.tve_trigger === 'exit' && $target.data( 'shown-on-exit' ) ) {
			/* do not show form again on exit intent it if was shown once */
			return;
		}

		if ( data.first ) {
			$target = $target.first();
		}

		if ( $target.attr( 'data-s-state' ) ) {
			/**
			 * find the already subscribed state and show it
			 */
			$target = $target.closest( '.tl-states-root' ).find( '[data-state="' + $target.attr( 'data-s-state' ) + '"] .tl-lb-target' );
		}

		/**
		 * to know where we came from
		 */
		if ( data && data.$parentStateEl ) {
			$target.closest( '.tl-style' ).first().data( 'parentStateEl', data.$parentStateEl )
		}

		$anim_target = $target.hasClass( 'tve-tl-anim' ) ? $target : $target.find( '.tve-tl-anim' );
		$target.css( 'display', '' );
		setTimeout( function () {
			$anim_target.addClass( 'tve-leads-triggered' );
			TL_Front.handle_typefocus( $anim_target, 'start' );
			if ( ThriveGlobal.$j( '.tve_post_grid_masonry' ).length ) {
				TCB_Front.postGridLayout();
			}
		}, 0 );

		/**
		 * Track impression for two-step (ThriveBox) forms when they're actually opened
		 * The form_id for two-step forms contains '2step-'
		 *
		 * @see https://github.com/awesomemotive/thrive-themes/issues/2504
		 */
		TL_Front.maybe_track_two_step_impression( data.form_id );

		/**
		 * Track impression for trigger-based forms when they become visible, not on page load.
		 *
		 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
		 */
		if ( data.form_type && TRIGGER_BASED_FORM_TYPES.indexOf( data.form_type ) !== -1 ) {
			TL_Front.do_trigger_based_impression( data.form_type );
		}

		if ( typeof TL_Front[ 'open_' + data.form_type ] === 'function' ) {
			TL_Front[ 'open_' + data.form_type ]( $target, data.TargetEvent );
		} else {
			$target.show();
		}
		TCB_Front.resizePageSection();

		$target.on( 'switchstate', function ( event, container ) {
			if ( container.offset().top - ThriveGlobal.$j( window ).scrollTop() + container.outerHeight() < 0 ) {
				ThriveGlobal.$j( 'html, body' ).animate( {scrollTop: container.offset().top + 'px'}, 50 );
			}
			TCB_Front.resizePageSection();
		} );
		setTimeout( function () {
			$target.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
				var $this = ThriveGlobal.$j( this );
				if ( $this.attr( 'data-src' ) ) {
					$this.attr( 'src', $this.attr( 'data-src' ) );
				}
			} );
		}, 200 );
	} );

	/* SUPP-3000 Close ribbon - moved here due to some weird cases involving ScrollMat on mobile devices*/
	ThriveGlobal.$j( 'body' ).on( 'click', '.tve-ribbon-close', function () {
		var $target = ThriveGlobal.$j( this ).closest( '.tve-leads-ribbon' ),
			position = $target.data( 'position' );
		$target.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
			var $this = ThriveGlobal.$j( this );
			$this.attr( 'data-src', $this.attr( 'src' ) );
			$this.attr( 'src', '' );
		} );
		$target.removeClass( 'tve-leads-triggered' );
		if ( position === 'top' ) {
			ThriveGlobal.$j( 'body' ).animate( {marginTop: 0}, 200, function () {
				document.body.style.removeProperty( 'margin-top' );
				if ( TCB_Front && TCB_Front.$window ) {
					TCB_Front.$window.trigger( 'scroll' );
				}
			} );
		} else if ( position === 'bottom' ) {
			ThriveGlobal.$j( 'body' ).animate( {marginBottom: 0 + 'px'}, 200, function () {
				document.body.style.removeProperty( 'margin-bottom' );
			} );
		}
		TL_Front.handle_typefocus( $target, 'pause' );

		setTimeout( function () {
			$target.css( position, '' );
		}, 400 );
		/**
		 * close any error messages that might have been displayed on forms inside the lightbox
		 */
		ThriveGlobal.$j( '#tve-lg-error-container' ).hide();
	} );

	/**
	 * Replace shortcodes from conditional displays
	 */
	ThriveGlobal.$j( window ).on( 'conditional_display_loaded', () => {
		const shortcodeKeys = Object.keys( TL_Front.contentHtml || {} );
		if ( shortcodeKeys.length ) {
			shortcodeKeys.forEach( key => {
				const $placeholder = ThriveGlobal.$j( `.tl-placeholder-f-type-${key}` );
				if ( $placeholder.length ) {
					const $content = ThriveGlobal.$j( TL_Front.contentHtml[ key ] );
					$placeholder.replaceWith( $content );
					setTimeout( () => {
						ThriveGlobal.$j( TL_Front ).trigger( 'showform.thriveleads', {$target: $content} );
					} );
				}
			} );
		}
	} );

	/**
	 * Initialize viewport observers when AJAX-loaded forms are ready
	 * This event is triggered after AJAX forms are loaded and DOM is ready
	 *
	 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
	 */
	ThriveGlobal.$j( TCB_Front ).on( 'tl-ajax-loaded', function() {
		// Initialize viewport observers for AJAX-loaded forms
		if ( TL_Front.viewport_impressions && Object.keys( TL_Front.viewport_impressions ).length > 0 ) {
			// Use requestAnimationFrame to ensure DOM is painted
			if ( window.requestAnimationFrame ) {
				requestAnimationFrame( function() {
					TL_Front.initViewportObservers();
				} );
			} else {
				TL_Front.initViewportObservers();
			}
		}
	} );

	if ( ! TL_Const.ajax_load ) {
		TL_Front.do_impression();
	}

	TL_Front.ajax_load_callback = function ( response, allData ) {
		if ( allData ) {
			TL_Front.conditional_display( allData );
		}

		if ( ! response || ! response.res || ! response.js || ! response.html ) {
			return;
		}

		TL_Front.lightspeed_assets( response.lightspeed || {} );
		TL_Front.add_page_css( response.res.css );
		TL_Front.add_page_css( response.res.fonts );

		if ( response.html ) {
			if ( ! response.html.widget ) {
				ThriveGlobal.$j( '.tl-widget-container' ).remove();
			}

			function show_trigger( twoStepKey ) {
				ThriveGlobal.$j( `.tl-2step-trigger-${twoStepKey.replace( 'two_step_', '' )}` ).show();
			}

			ThriveGlobal.$j.each( response.html, function ( elementType, html ) {
				if ( ! html ) {
					return true;
				}
				TL_Front.contentHtml = TL_Front.contentHtml || {};
				TL_Front.contentHtml[ elementType ] = html;
				if ( elementType === 'in_content' ) {
					// move the placeholder after the nth paragraph
					let position = parseInt( response.in_content_pos ),
						fn = 'after',
						post = ThriveGlobal.$j( '.tve-tl-cnt-wrap' );

					if ( ! post.length ) {
						post = ThriveGlobal.$j( '#tve_editor.tar-main-content' );
					}
					if ( ! post.length ) {
						post = ThriveGlobal.$j( '#post_content' );
					}
					const p = post.find( 'p' ).filter( ':visible' ).not( '.thrv_table p, form p, .tcb-post-list p, .thrv_text_element div p, p.wp-caption-text, .thrv_responsive_video p, .thrv_header p' );

					if ( p.length === 0 && position === 0 ) {
						post.prepend( html );
					} else {
						if ( position === 0 ) {
							position = 1;
							fn = 'before';
						}

						p.eq( position - 1 )[ fn ]( html );
					}
				} else {
					const $placeholder = ThriveGlobal.$j( '.tl-placeholder-f-type-' + elementType );
					if ( response.js[ elementType ] && response.js[ elementType ].content_locking ) {
						/**
						 * content locking shortcode - add the blur class if this is the case
						 * or show the locked content if the user has a conversion registered
						 */
						const $parent = $placeholder.parents( '.tve_content_lock' ).first();

						if ( response.js[ elementType ].has_conversion ) {
							/* remove the placeholder because we're going to display the content. */
							$placeholder.remove();
							$parent.removeClass( 'tve_lock_hide' );
							return true;
						}

						if ( response.js[ elementType ].lock === 'tve_lock_blur' ) {
							$parent.removeClass( 'tve_lock_hide' ).addClass( response.js[ elementType ].lock );
						}
					}

					if ( elementType === 'widget' ) {
						if ( $placeholder.hasClass( 'tl-preload-form' ) ) {
							$placeholder.first().replaceWith( ThriveGlobal.$j( html ).addClass( 'tve-leads-triggered' ) )
						} else {
							$placeholder.replaceWith( html );
							ThriveGlobal.$j( '.tl-widget-container' ).children().unwrap();
						}
					} else {
						$placeholder.replaceWith( html );
					}

					/* for the forms that we going to be added in the page, we're displaying the trigger */
					if ( elementType.indexOf( 'two_step' ) === 0 ) {
						show_trigger( elementType );
					}
				}
			} );
			if ( _ieVersion() > 0 ) {
				/* weird behaviour in IE11 in some cases - style node does not get interpreted after being inserted via AJAX */
				setTimeout( function () {
					var c = '';
					ThriveGlobal.$j( 'body style.tve_custom_style' ).each( function () {
						c = this.innerText;
						this.innerText = c;
					} );
				} );
			}
		}
		if ( response.body_end ) {
			/**
			 * filter the end-of-body contents to remove any (possible) existing wistia embed divs
			 */
			var $body_end = ThriveGlobal.$j( response.body_end );
			$body_end.find( '.tve_wistia_popover' ).each( function () {
				if ( ThriveGlobal.$j( '#' + this.id ).length ) {
					this.parentNode.removeChild( this );
				}
			} );
			/* make sure there are no CSS resources loaded twice */
			$body_end.filter( 'link[href]' ).each( function () {
				if ( ThriveGlobal.$j( 'link[href="' + this.getAttribute( 'href' ) + '"]' ).length ) {
					$body_end = $body_end.not( this );
				}
			} );
			/* make sure there are no JS resources loaded twice */
			$body_end.filter( 'script[src]' ).each( function () {
				if ( ThriveGlobal.$j( 'script[src="' + this.getAttribute( 'src' ) + '"]' ).length ) {
					$body_end = $body_end.not( this );
				}
			} );
			try {
				/**
				 * SUPP-3252, for some reason when the $body_end is appended X-Theme
				 * throws a js error for unknown ajaxurl variable, this try and catch fixes the issue.
				 */
				ThriveGlobal.$j( 'body' ).append( $body_end );
			} catch ( error ) {
				console.log( 'Body append: ' + error );
			}

		}

		if ( typeof response.js.TVO_Form !== 'undefined' ) {
			TVO_Form = response.js.TVO_Form;
		}

		TL_Front.add_page_js( response.res.js, function () {
			resources_loaded = true;
		} );

		/**
		 * rebind the TCB event listeners
		 */
		function dom_ready() {
			if ( ! resources_loaded || ! modulesFinishedLoading ) {
				setTimeout( dom_ready, 50 );
				return;
			}

			TCB_Front.event_triggers( ThriveGlobal.$j( 'body' ) );
			TCB_Front.onDOMReady();
			init();
			ThriveGlobal.$j( TCB_Front ).trigger( 'tl-ajax-loaded' );

			/**
			 * Ribbon compatibility with sticky header from other plugins
			 */
			TCB_Front.add_scroll_callback( function () {
				var $ribbon = ThriveGlobal.$j( '.tve-leads-ribbon[data-position="top"]' ),
					$editor = $ribbon.find( '.tve_shortcode_editor' ),
					visible = $ribbon.is( ':visible' ) && Number( $ribbon.css( 'opacity' ) ),
					height = visible ? Math.max( $ribbon.outerHeight(), $editor.outerHeight() ) : 0,
					$elementorHeader = ThriveGlobal.$j( '[data-elementor-type="header"] .elementor-top-section.elementor-sticky.elementor-sticky--active' );

				/**
				 * fallback in case Stickyheader plugin
				 */
				if ( ! $elementorHeader.length ) {
					$elementorHeader = ThriveGlobal.$j( '.she-header' );
				}

				if ( $elementorHeader.length ) {
					$elementorHeader[ 0 ].style.setProperty( 'margin-top', height + 'px', 'important' );
				}

			} );
		}

		setTimeout( dom_ready, 50 );
		TL_Const.forms = response.js;

		/**
		 * Store deferred impressions for trigger-based forms (lightbox, screen_filler, slide_in, ribbon)
		 * and viewport-based forms (shortcodes). These impressions will be tracked when the form
		 * is actually shown to the user.
		 *
		 * @see https://github.com/awesomemotive/thrive-themes/issues/2956
		 */
		if ( response.deferred_impressions ) {
			// Setup viewport impressions (separates viewport-based from trigger-based)
			TL_Front.setupViewportImpressions( response.deferred_impressions );
		}

		/* After the wait we should search for the placeholders and remove them
		because for hidden displays we get no response and we don't have any way of replacing them with content */
		setTimeout( () => {
			ThriveGlobal.$j( '.tl-preload-form' ).remove();
		}, 1000 );
	};

	function init() {
		if ( ! TL_Const.forms ) {
			return false;
		}

		/**
		 * try to detect the email field from a form and get its value
		 *
		 * @param $form
		 */
		function try_getting_email( $form ) {
			/* if there is a field which requires email validation, use that */
			if ( $form.find( '[data-validation="email"]' ).length ) {
				return $form.find( '[data-validation="email"]' ).val();
			}
			var maybe_email = '';
			/* try search for 'email' in the input name */
			$form.find( 'input' ).each( function () {
				if ( this.name && this.name.match( /email/i ) ) {
					maybe_email = this.value;
					return false;
				}
			} );

			return maybe_email;
		}

		/**
		 * For the fluent form prevent our handling to dont mess up with user's setup
		 * @param $form
		 * @returns {boolean}
		 */
		function isFluentForm( $form ) {
			var id = $form.attr( 'id' ),
				fluentVars = window.fluentFormVars,
				isFluent = false;

			if ( fluentVars && fluentVars.forms ) {
				isFluent = fluentVars.forms.some( function ( formData ) {
					return formData.form_id_selector === id;
				} )
			}
			return isFluent;
		}

		function isHappyForm( $form ) {
			var formID = $form.attr( 'id' );
			return formID && formID.includes( 'happyforms' ) && window.HappyForms;
		}

		/**
		 * listen for the forms submission, and send tracking data requests
		 * the submit listener is delegated just to be sure we can track everything
		 */
		ThriveGlobal.$j( 'body' ).on( 'submit', '.tve-leads-conversion-object form', function ( event ) {
			var $form = ThriveGlobal.$j( this ),
				type = $form.parents( '.tve-leads-conversion-object' ).first().attr( 'data-tl-type' ),
				custom_fields = {};

			if ( $form.data( 'tve-force-submit' ) || $form.closest( '.thrv_custom_html_shortcode' ).length || $form.data( 'tl-do-submit' ) || ! type || ! TL_Const.forms[ type ] || isFluentForm( $form ) || isHappyForm( $form ) ) {
				return true;
			}
			$form.tve_form_loading();

			$form.find( 'input' ).each( function () {
				var $input = ThriveGlobal.$j( this ),
					field = $input.attr( 'name' );
				if ( typeof field !== 'undefined' && TL_Const.ignored_fields.indexOf( field ) === - 1 ) {
					custom_fields[ $input.attr( 'name' ) ] = $input.val();
				}
			} );

			var ajax_data = {
				security: TL_Const.security,
				action: TL_Const.action_conversion,
				type: type,
				tl_data: TL_Const.forms[ type ],
				custom_fields: custom_fields,
				email: try_getting_email( $form ),
				current_screen: TL_Const.current_screen
			};

			ThriveGlobal.$j.each( TL_Const.custom_post_data, function ( k, v ) {
				ajax_data[ k ] = v;
			} );

			/**
			 * XHR synchronous requests on the main threads are deprecated. We need to make it async, and after that trigger the form submission
			 */
			ThriveGlobal.$j.ajax( {
				url: TL_Const.ajax_url,
				data: ajax_data,
				type: 'post',
				xhrFields: {
					withCredentials: true
				}
			} ).always( function () {
				/* When there is no action for the form we reload the page manually so we won't mess up the redirects from WP */
				if ( typeof $form.attr( 'action' ) === 'undefined' ) {
					location.reload();
				} else {
					$form.data( 'tve-force-submit', true ).submit();
				}
			} );

			return false;
		} );

		/**
		 * event listener that allows setting custom post data in forms created with TCB and connected to an API
		 */
		ThriveGlobal.$j( 'body' ).on( 'form_conversion.tcb', '.tve-leads-conversion-object form', function ( event ) {
			var $form = ThriveGlobal.$j( this ),
				type = $form.parents( '.tve-leads-conversion-object' ).first().attr( 'data-tl-type' );

			if ( ! type || ! TL_Const.hasOwnProperty( 'forms' ) || ! TL_Const.forms[ type ] ) {
				return true;
			}

			var ajax_data = {
				type: type,
				tl_data: TL_Const.forms[ type ],
				current_screen: TL_Const.current_screen
			};

			ThriveGlobal.$j.each( TL_Const.custom_post_data, function ( k, v ) {
				ajax_data[ k ] = v;
			} );

			event.post_data = event.post_data || {};
			event.post_data.thrive_leads = ajax_data;
		} ).on( 'lead_conversion_success.tcb', '.tve_lead_lock_shortcode form, .tve_post_lightbox form', function ( event ) {
			var $form = ThriveGlobal.$j( this ),
				$container = $form.parents( '.tve_content_lock' );

			if ( $form.closest( '.tve_post_lightbox' ).length ) {
				/* case: lightbox state of a content-lock shortcode */
				var formType = $form.closest( '.tve-leads-conversion-object' ).attr( 'data-tl-type' );

				/* find out if the lightbox is connected to the shortcode */
				if ( TL_Front.parent_state && TL_Front.parent_state.parent().hasClass( 'tve-leads-track-' + formType ) ) {
					$container = TL_Front.parent_state.closest( '.tve_content_lock' );
				}
			}

			if ( $container.length && $container.hasClass( 'tve_content_lock' ) ) {
				$container.removeClass( 'tve_lead_lock' ).find( '.tve_lead_lock_shortcode' ).remove();
				$container.find( '.tve_lead_locked_overlay' ).remove();

				event.content_unlocked = true;
			}
		} ).on( 'leads_states.tcb', '.tve-leads-conversion-object form', function ( event, content ) {
			var $form = ThriveGlobal.$j( this ),
				_form_type = $form.find( '#_form_type' ).val();

			switch ( _form_type ) {
				case 'ribbon':
					var ribbon = $form.parents( '.tve-leads-ribbon' );
					$form.parents( '.tve_shortcode_editor' ).empty().html( content );
					TL_Front.open_ribbon( ribbon );
					break;
				case 'lightbox':
				case 'tve_lead_2s_lightbox':
					$form.parents( '.tve_p_lb_control' ).empty().html( content );
					break;
				case 'widget':
				case 'in-content':
				case 'post-footer':
				case 'php-insert':
					$form.parents( '.tve_shortcode_editor' ).empty().html( content );
					break;
				case 'slide-in':
					var slide_in = $form.parents( '.tve-leads-slide-in' );
					$form.parents( '.tve_shortcode_editor' ).empty().html( content );
					TL_Front.open_slide_in( slide_in );
					break;
				case 'screen-filler-lightbox':
					var screen_filler = $form.parents( '.tve-leads-screen-filler' );
					$form.parents( '.tve_shortcode_editor' ).empty().html( content );
					TL_Front.open_screen_filler( screen_filler );
					break;
				case 'scroll-mat':
					var ribbon = $form.parents( '.tve-leads-greedy_ribbon' );
					$form.parents( '.tve_shortcode_editor' ).empty().html( content );
					TL_Front.open_ribbon( ribbon );
					break;
				case 'tve_lead_shortcode':
					$form.parents( '.tve-leads-shortcode' ).empty().html( content );
					break;
				case 'lead_generation':
				default:
					event.change_states = false;
					break;
			}

			event.change_states = true;

		} ).on( 'leads_messages.tcb', '.tve-leads-conversion-object form', function ( event ) {
			var $form = ThriveGlobal.$j( this ),
				_form_type = $form.find( '#_form_type' ).val();

			switch ( _form_type ) {
				case 'tve_lead_shortcode':
					if ( event.lightbox_state ) {
						$form.parents( '.tve-leads-shortcode' ).hide();
					}
					break;
				case 'ribbon':
					$form.parents( '.thrv-ribbon' ).find( '.tve-ribbon-close' ).click();
					break;
				case 'lightbox':
				case 'tve_lead_2s_lightbox':
					$form.parents( '.tve_p_lb_content' ).find( '.tve_p_lb_close' ).click();
					$form.parents( '.tve-leads-screen-filler' ).find( '.tve-screen-filler-close' ).click();
					break;
				case 'slide-in':
					$form.parents( '.thrv-leads-slide-in' ).find( '.tve-leads-close' ).click();
					break;
				case 'screen-filler-lightbox':
					$form.parents( '.tve-leads-screen-filler' ).find( '.tve-screen-filler-close' ).click();
					break;
				case 'scroll-mat':
					$form.parents( '.thrv-greedy-ribbon' ).find( '.tve_et_click' ).click();
					break;
				case 'widget':
				case 'in-content':
				case 'post-footer':
				case 'php-insert':
				default:
					$form.find( 'input:not(:hidden):not([type="checkbox"]):not([type="radio"])' ).val( '' );
					break;
			}

			$form.parents( '.tve-leads-conversion-object' ).find( '.tve_ea_thrive_leads_form_close' ).click();

			/* SUPP-2803 - Also close the parent state (e.g. ribbon that triggered a lightbox */
			if ( TL_Front.parent_state ) {
				TL_Front.close_form( TL_Front.parent_state );
			}
		} );
		/**
		 * This code will replace <script type="text/template"> nodes with their content
		 * Used, for example, to execute javascript only when a state is displayed, and not on page load
		 */
		TL_Front.$document.on( 'switchstate', function ( event, container ) {
			container.find( 'script.tcb-lazyload-template' ).each( function () {
				ThriveGlobal.$j( this ).replaceWith( this.innerHTML );
			} );
		} );
	}

	if ( TL_Const.ajax_load ) {

		var resources_loaded = false;

		/* We hide all the triggers for the two step lightbox and display them only if the lightbox is visible */
		var two_step_triggers = ThriveGlobal.$j( '.tve-leads-two-step-trigger' ).hide();

		/**
		 * ajax load all the forms that are to be displayed on this page
		 */
		var ajax_data = {
			tcb_js: typeof TCB_Front !== 'undefined' ? 1 : 0, // do not Load TCB frontend twice
			main_group_id: TL_Const.main_group_id,
			shortcode_ids: TL_Const.shortcode_ids,
			two_step_ids: TL_Const.two_step_ids,
			action: 'tve_leads_ajax_load_forms',
			security: TL_Const.security,
			display_options: TL_Const.display_options,
			current_screen: TL_Const.current_screen
		};
		ThriveGlobal.$j.each( TL_Const.custom_post_data, function ( k, v ) {
			ajax_data[ k ] = v;
		} );

		if ( window.TVE_Dash && ! TVE_Dash.ajax_sent ) {
			ThriveGlobal.$j( document ).on( 'tve-dash.load', function ( event ) {
				TVE_Dash.add_load_item( 'tl_lazy_load', ajax_data, TL_Front.ajax_load_callback );
			} );
		} else {
			ThriveGlobal.$j.ajax( {
				url: TL_Const.ajax_url,
				type: 'post',
				dataType: 'json',
				data: ajax_data,
				xhrFields: {
					withCredentials: true
				}
			} ).done( TL_Front.ajax_load_callback );
		}
		return;
	}
	/**
	 * if there is no ajax_load setting, init stuff as usual
	 */
	init();
} );

TL_Front.switch_lightbox_state = function ( $state_target, $current_state ) {
	$state_target.find( '.tve_p_lb_overlay' ).css( 'opacity', '0.8' );
	$state_target.find( '.tve_p_lb_content' ).css( 'top', $current_state.find( '.tve_p_lb_content' ).css( 'top' ) ).addClass( 'tve-leads-triggered' );
	window.tve_lb_switch_state = true;
	return TL_Front.open_lightbox( $state_target.find( '.tl-lb-target' ) );
};

TL_Front.close_lightbox = function () {
	/**
	 * Clear the parent state in case we have other forms working with lightboxes
	 */
	var $body = ThriveGlobal.$j( 'body' ),
		$html = ThriveGlobal.$j( 'html' ),
		overflow_hidden = 'tve-o-hidden tve-l-open tve-hide-overflow',
		$lightbox = arguments[ 0 ] || $body.data( 'tl-open-lightbox' );
	if ( ! $lightbox || ! $lightbox.length ) {
		return;
	}
	$lightbox.find( '.tve-tl-anim' ).removeClass( 'tve-leads-triggered' );
	if ( ! window.tve_lb_switch_state ) {
		if ( ThriveGlobal.$j( '.tve_lb_open' ).length === 1 ) {
			$body.removeClass( overflow_hidden ).css( 'padding-right', '' );
			$html.removeClass( overflow_hidden );
			if ( $lightbox.data( 'doc-scroll-top' ) ) {
				document.documentElement.scrollTop = $lightbox.data( 'doc-scroll-top' );
				$lightbox.data( 'doc-scroll-top', '' );
			} else if ( $lightbox.data( 'bdy-scroll-top' ) ) {
				document.body.scrollTop = $lightbox.data( 'bdy-scroll-top' );
				$lightbox.data( 'bdy-scroll-top', '' );
			}
		}
		$html.removeClass( $html.data( 'tl-anim-class' ) );
	}
	window.tve_lb_switch_state = false;
	setTimeout( function () {
		$lightbox.addClass( 'tve_lb_closing' );
		$lightbox.removeClass( 'tve_lb_open tve_lb_opening tve_lb_closing tve_p_lb_background' ).css( 'display', 'none' ).find( 'tve_p_lb_content' ).trigger( 'tve.lightbox-close' );
	}, 200 );

	$lightbox.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
		var $this = ThriveGlobal.$j( this );

		if ( 'SOURCE' === this.tagName ) {
			$this.parent( 'video' ).trigger( 'pause' );
		}

		$this.attr( 'data-src', $this.attr( 'src' ) );
		$this.attr( 'src', '' );
	} );

	TL_Front.handle_typefocus( $lightbox, 'pause' );

	/**
	 * close any error messages that might have been displayed on forms inside the lightbox
	 */
	ThriveGlobal.$j( '#tve-lg-error-container' ).hide();
};

TL_Front.open_lightbox = function ( $target, TargetEvent ) {
	if ( $target.hasClass( 'tve_lb_open' ) || $target.hasClass( 'tve_lb_opening' ) ) {
		return;
	}

	function getBrowserScrollSize() {
		var $ = ThriveGlobal.$j;
		var css = {
			"border": "none",
			"height": "200px",
			"margin": "0",
			"padding": "0",
			"width": "200px"
		};

		var inner = $( "<div>" ).css( $.extend( {}, css ) );
		var outer = $( "<div>" ).css( $.extend( {
			"left": "-1000px",
			"overflow": "scroll",
			"position": "absolute",
			"top": "-1000px"
		}, css ) ).append( inner ).appendTo( "body" ).scrollLeft( 1000 ).scrollTop( 1000 );

		var scrollSize = {
			"height": (
				          outer.offset().top - inner.offset().top
			          ) || 0,
			"width": (
				         outer.offset().left - inner.offset().left
			         ) || 0
		};

		outer.remove();
		return scrollSize;
	}

	var is_switch_state = window.tve_lb_switch_state;

	ThriveGlobal.$j.fn.thrive_iphone_placeholder && $target.find( 'input[placeholder]' ).thrive_iphone_placeholder();

	/* close any other opened lightboxes */
	TL_Front.close_lightbox( ThriveGlobal.$j( '.tve_p_lb_background.tve_lb_open' ) );

	//$target.css('display', '').parents('.tl-style').css('display', '');
	$target.css( {
		'visibility': '',
		'position': '',
		'left': '',
		'display': ''
	} ).parents( '.tl-style' ).css( {
		'visibility': '',
		'position': '',
		'left': '',
		'display': ''
	} );

	var $body = ThriveGlobal.$j( 'body' ),
		$html = ThriveGlobal.$j( 'html' ),
		overflow_hidden = 'tve-o-hidden tve-l-open tve-hide-overflow',
		scroll_width = getBrowserScrollSize().width,
		oPadding = parseInt( $body.css( 'paddingRight' ) ),
		has_lb_open = ThriveGlobal.$j( '.tve_p_lb_background.tve_lb_open' ).length;

	if ( isNaN( oPadding ) ) {
		oPadding = 0;
	}

	$target.find( '.tve_p_lb_close' ).off().on( "click", function () {
		TL_Front.close_lightbox();
		return false;
	} );

	$body.off( 'keyup.tve_lb_close' ).on( 'keyup.tve_lb_close', function ( e ) {
		if ( e.which == 27 ) {
			TL_Front.close_lightbox();
			return false;
		}
	} );

	$target.find( '.tve_p_lb_overlay' ).off( 'click.tve_lb_close' ).on( 'click.tve_lb_close', function () {
		TL_Front.close_lightbox();
		return false;
	} );

	$body.data( 'tl-open-lightbox', $target );

	$target.addClass( 'tve_p_lb_background' );
	$target.data( 'doc-scroll-top', document.documentElement.scrollTop );
	$target.data( 'bdy-scroll-top', document.body.scrollTop );

	$body.addClass( overflow_hidden );
	$html.addClass( overflow_hidden );

	var wHeight = window.innerHeight, // Use window.innerHeight instead of jQuery which can return document height
		page_has_scroll = wHeight < ThriveGlobal.$j( document ).height();

	if ( ! is_switch_state && page_has_scroll ) {
		$body.css( 'padding-right', (
		                            oPadding + scroll_width
		                            ) + 'px' );
	}

	//load the responsive video iframes
	$target.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
		var $this = jQuery( this );
		if ( $this.attr( 'data-src' ) ) {
			$this.attr( 'src', $this.attr( 'data-src' ) );
		}
	} );

	$target.find( '.thrv_responsive_video' ).each( function () {
		var $this = ThriveGlobal.$j( this );

		TCB_Front.makeAutoplayVideo( $this );
	} );

	var cls = '';
	/* append the animation class to the html element */
	ThriveGlobal.$j.each( $target.parents( '.tl-states-root' ).attr( 'class' ).split( ' ' ), function ( i, c ) {
		if ( c.indexOf( 'tl-anim' ) === 0 ) {
			cls = c;
			return false;
		}
	} );
	$html.addClass( cls ).data( 'tl-anim-class', cls );

	setTimeout( function () {

		setTimeout( function () {
			$target.addClass( 'tve_lb_opening' );
		}, 0 );

		/* reload any iframe that might be in there, this was causing issues with google maps embeds in hidden tabs */
		$target.find( 'iframe' ).not( '.thrv_social_default iframe' ).each( function () {
			var $this = ThriveGlobal.$j( this );
			if ( $this.data( 'tve_ifr_loaded' ) || ! $this.attr( 'data-src' ) ) {
				return;
			}
			$this.data( 'tve_ifr_loaded', 1 ).attr( 'src', $this.attr( 'data-src' ) );
		} );

		function position_it() {
			var cHeight = $target.find( '.tve_p_lb_content' ).outerHeight( true ) + (
					2 * parseInt( $target.css( 'padding-top' ) )
				),
				$lContent = $target.find( '.tve_p_lb_content' ),
				wHeight = window.innerHeight, // Use window.innerHeight instead of jQuery which can return document height

				top = (
					      wHeight - cHeight
				      ) / 2;

			$target.find( '.tve_p_lb_overlay' ).css( {
				height: (
				        cHeight + 80
				        ) + 'px',
				'min-height': wHeight + 'px'
			} );
			if ( has_lb_open ) {
				$lContent.animate( {
					top: (
						top < 40 ? 40 : top
					)
				}, 100 );
			} else {
				$lContent.css( 'top', (
					                      top < 40 ? 40 : top
				                      ) + 'px' );
			}
			if ( cHeight + 40 > wHeight ) {
				$target.addClass( 'tve-scroll' );
			}
		}

		TCB_Front.resizePageSection();
		position_it();
		ThriveGlobal.$j( window ).on( 'resize', position_it );

	}, 20 );

	setTimeout( function () {
		$target.removeClass( 'tve_lb_opening' ).addClass( 'tve_lb_open' ).find( '.tve_p_lb_content' ).trigger( 'tve.lightbox-open' );
		
		/**
		 * Fix for browser validation: Ensure form fields are focusable for browser validation
		 * When a form is submitted with invalid required fields, the browser tries to focus
		 * the first invalid field. If fields are not focusable (e.g., inside display:none container),
		 * browser validation fails with "An invalid form control is not focusable" error.
		 */
		const $forms = $target.find( 'form' );
		$forms.each( function() {
			const $form = ThriveGlobal.$j( this );
			// Find all required fields and ensure they're focusable
			// Support both required attribute and data-required for compatibility
			$form.find( 'input[required], textarea[required], select[required], input[data-required="true"], textarea[data-required="true"], select[data-required="true"]' ).each( function() {
				const $field = ThriveGlobal.$j( this );
				// Ensure field is visible (not display:none or visibility:hidden)
				if ( $field.css( 'display' ) === 'none' ) {
					$field.show();
				}
				if ( $field.css( 'visibility' ) === 'hidden' ) {
					$field.css( 'visibility', 'visible' );
				}
				// Ensure parent containers are also visible
				const $parent = $field.parentsUntil( '.tve_p_lb_content' ).filter( function() {
					return ThriveGlobal.$j( this ).css( 'display' ) === 'none' || ThriveGlobal.$j( this ).css( 'visibility' ) === 'hidden';
				} );
				$parent.show().css( 'visibility', 'visible' );
				// Remove negative tabindex that prevents focusing
				const tabindex = $field.attr( 'tabindex' );
				if ( tabindex && parseInt( tabindex ) < 0 ) {
					$field.removeAttr( 'tabindex' );
				}
			} );
		} );
		
		ThriveGlobal.$j( window ).trigger( 'scroll' );
	}, 300 );

	// called to stop other events that might interact in the bad way with the lightbox, like a button that redirects the page.
	if ( TargetEvent && TargetEvent.preventDefault ) {
		TargetEvent.preventDefault();
		TargetEvent.stopPropagation();
	}
	$target.parents( '.tl-states-root' ).off( 'switchstate' ).on( 'switchstate', function ( e, $state ) {
		var args = Array.prototype.slice.call( arguments, 1 );
		TL_Front.switch_lightbox_state.apply( TL_Front, args );
	} );

	/**
	 * If exit intent, do not open this again at exit intent
	 */
	if ( TargetEvent && TargetEvent.tve_trigger === 'exit' ) {
		$target.data( 'shown-on-exit', true );
	}

	/* trigger a custom event after we opened the lightbox */
	TCB_Front.$window.trigger( 'tl_after_lightbox_open', $target );

	/* make sure that its trigger after the animation is done too */
	setTimeout( () => {
		TCB_Front.$window.trigger( 'tve_after_content_toggle', [ $target ] );
	}, 500 );
};

TL_Front.open_two_step_lightbox = TL_Front.open_lightbox;

TL_Front.open_ribbon = function ( $target ) {

	/**
	 * used when there is also a Scroll mat on the page, this will make sure the ribbon is opened after the greedy ribbon
	 */
	function open_it() {
		$target.addClass( 'tve-leads-triggered' );
		const $editor = $target.find( '.tve_shortcode_editor' ),
			editorHeight = $editor.length ? $editor.outerHeight() : 0,
			position = $target.attr( 'data-position' ) || 'top';

		switch ( position ) {
			case 'above':
				$target.css( 'bottom', 'auto' );
			case 'top':
				$target.css( 'top', ThriveGlobal.$j( '#wpadminbar' ).length ? '32px' : '0px' );
				break;

			case 'bottom':
				$target.css( 'bottom', '0px' );
				$target.css( 'top', 'auto' );
				break;
			default:
				break;
		}

		/**
		 * Mozilla is really slow at applying the loaded css. we need this workaround to have it work in mozilla.
		 */
		let iterations = 0,
			initialHeight = Math.max( $target.outerHeight(), editorHeight ),
			ii = setInterval( function () {
				iterations ++;
				const _h = Math.max( $target.outerHeight(), editorHeight );
				if ( _h != initialHeight || iterations == 10 ) {
					clearInterval( ii );
				}
				if ( position === 'top' ) {
					ThriveGlobal.$j( 'body' ).animate( {'margin-top': _h + 'px'}, 200, function () {
						document.body.style.setProperty( 'margin-top', _h + 'px', 'important' );
					} );

					if ( TCB_Front && TCB_Front.$window ) {
						TCB_Front.$window.trigger( 'scroll' );
					}
				} else if ( position === 'bottom' ) {
					ThriveGlobal.$j( 'body' ).animate( {'margin-bottom': _h + 'px'}, 200 );
				}
			}, 100 );

		const $header = ThriveGlobal.$j( 'body' ).find( '.thrv_header.tve-scroll-sticky' );

		if ( $header.length && position === 'top' ) {
			const extraOffset = parseFloat( TCB_Front.inlineCssVariable( $header, '--tcb-header-extra-offset' ) ) || 0;

			TCB_Front.inlineCssVariable( $header, '--tcb-header-extra-offset', extraOffset + initialHeight + 'px' );
		}

		$target.off( 'switchstate' ).on( 'switchstate', function ( e, $target ) {
			const args = Array.prototype.slice.call( arguments, 1 );
			TL_Front.switch_ribbon_state.apply( TL_Front, args );
		} );
	}

	if ( TL_Const.forms.greedy_ribbon ) {
		TL_Const.close_callbacks = TL_Const.close_callbacks || {};
		TL_Const.close_callbacks.greedy_ribbon = [ open_it ];
	} else {
		open_it();
	}
};

TL_Front.switch_ribbon_state = function ( $target ) {
	var h = $target.outerHeight( true ),
		prop = $target.parent().attr( 'data-position' ) === 'top' ? 'margin-top' : 'margin-bottom',
		animation = {};
	animation[ prop ] = h + 'px';
	$target.find( '.tve-tl-anim' ).removeClass( function ( index, className ) {
		return ( className.match( /(^|\s)tl-anim-\S+/g ) || [] ).join( ' ' );
	} ).removeClass( 'tve-tl-anim' );
	ThriveGlobal.$j( 'body' ).animate( animation, 200 );

};

TL_Front.open_greedy_ribbon = function ( $target ) {
	const $body = ThriveGlobal.$j( 'body' ),
		$window = ThriveGlobal.$j( window ),
		initial_position = $body.css( 'position' );

	$window.scrollTop( 0 );
	//for situations where the user's theme adds a position css on body
	$body.css( 'position', 'static' );
	$body.addClass( 'tve-tl-gr-anim' );

	TCB_Front.$window.trigger( 'scroll' );
	$target.css( 'top', ThriveGlobal.$j( '#wpadminbar' ).length ? '32px' : '0px' );
	const wHeight = $target.outerHeight();
	$body[ 0 ].style.setProperty( 'margin-top', wHeight + 'px', 'important' );
	let greedyCondition = 1;
	setTimeout( function () {
		ThriveGlobal.$j( '.tve-leads-ribbon[data-position="top"]' ).removeClass( 'tve-leads-triggered' );
	}, 50 );

	$window.scroll( function () {
		const isFormOpen = $body.hasClass( 'tve-tl-gr-anim' );
		if ( greedyCondition && isFormOpen ) {
			const browserScroll = $window.scrollTop();
			if ( browserScroll > wHeight ) {
				const hasWistiaPopover = $target.find( '.tve_ea_thrive_wistia' ).length || $target.find( '.tve_with_wistia_popover' );
				if ( hasWistiaPopover ) {
					ThriveGlobal.$j( '.wistia_placebo_close_button' ).trigger( 'click' );
				}
				$body.removeClass( 'tve-tl-gr-anim' );
				$target.addClass( 'tve-no-animation' );
				const greedyScroll = browserScroll - wHeight;
				$target.removeClass( 'tve-leads-triggered' );
				$target.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
					const $this = ThriveGlobal.$j( this );
					$this.attr( 'data-src', $this.attr( 'src' ) );
					$this.attr( 'src', '' );
				} );
				$body.css( 'margin-top', '' );
				$body.css( 'position', initial_position );
				$window.scrollTop( greedyScroll );
				$target.removeClass( 'tve-no-animation' );
				greedyCondition = 0;
				TL_Front.form_closed( 'greedy_ribbon' );
				TL_Const.forms.greedy_ribbon.allow_callbacks = false;
			}
		}
	} );
	$target.off( 'switchstate' ).on( 'switchstate', function ( e, $target ) {

	} );
};

TL_Front.open_screen_filler = function ( $target, TargetEvent ) {
	var overflow_hidden = 'tve-so-hidden tve-sl-open tve-s-hide-overflow',
		html_body = ThriveGlobal.$j( 'html,body' ),
		$html = ThriveGlobal.$j( 'html' );

	ThriveGlobal.$j.fn.thrive_iphone_placeholder && $target.find( 'input[placeholder]' ).thrive_iphone_placeholder();

	$target.css( 'top', ThriveGlobal.$j( '#wpadminbar' ).length ? '32px' : '0px' ).css( 'visibility', '' );
	if ( $target.hasClass( 'stl-anim-slip_from_top' ) === true ) {
		var browserScroll = ThriveGlobal.$j( window ).scrollTop();
		$target.css( 'top', browserScroll ).css( 'visibility', '' );
	}

	$target.find( '.tve-screen-filler-close' ).on( 'click', function () {
		close_it( $target );
	} );

	$target.data( 'doc-scroll-top', document.documentElement.scrollTop );
	$target.data( 'bdy-scroll-top', document.body.scrollTop );

	/**
	 * Prevent screen filler to hide page overflow for displays where its content is hidden
	 */
	var $innerContent = $target.find( '.thrv-leads-screen-filler.thrv_wrapper ' );
	if ( $innerContent.css( 'display' ) !== 'none' ) {
		html_body.addClass( overflow_hidden );
	}

	var cls = '';
	/* append the animation class to the html element */
	ThriveGlobal.$j.each( $target.attr( 'class' ).split( ' ' ), function ( i, c ) {
		if ( c.indexOf( 'stl-anim' ) === 0 ) {
			cls = c;
			return false;
		}
	} );
	$html.addClass( cls ).data( 'tl-s-anim-class', cls );

	function close_it( $screen_filler ) {

		$screen_filler.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
			var $this = ThriveGlobal.$j( this );
			$this.attr( 'data-src', $this.attr( 'src' ) );
			$this.attr( 'src', '' );
		} );

		$screen_filler.removeClass( 'tve-leads-triggered' );
		TL_Front.handle_typefocus( $screen_filler, 'pause' );
		ThriveGlobal.$j( document ).off( 'keyup.close-screenfiller' );
		if ( ThriveGlobal.$j.find( '.tve-leads-ribbon' ).length == 0 ) {
			ThriveGlobal.$j( 'body' ).animate( {'margin-top': 0 + 'px'}, 200 );
		}
		html_body.removeClass( overflow_hidden );
		$html.removeClass( $html.data( 'tl-s-anim-class' ) );
		setTimeout( function () {
			$screen_filler.css( 'top', '' ).hide();
			if ( $screen_filler.css( 'display' ) === 'none' ) {
				html_body.removeClass( overflow_hidden );
				$screen_filler.removeClass( 'tve-leads-triggered' );
			}
		}, 400 );
		if ( $screen_filler.data( 'doc-scroll-top' ) ) {
			document.documentElement.scrollTop = $screen_filler.data( 'doc-scroll-top' )
			$screen_filler.data( 'doc-scroll-top', '' );
		} else if ( $screen_filler.data( 'bdy-scroll-top' ) ) {
			document.body.scrollTop = $screen_filler.data( 'bdy-scroll-top' );
			$screen_filler.data( 'bdy-scroll-top', '' )
		}

		/**
		 * close any error messages that might have been displayed on forms inside the lightbox
		 */
		ThriveGlobal.$j( '#tve-lg-error-container' ).hide();
	}

	//each time a screen filler is opened then it should open with the default(1st state) or already subscribed state SUPP-6469
	var $states = $target.find( '> .tl-style' ).hide(),
		$already_subscribed = $target.find( '> .tl-style[data-form-state="already_subscribed"]' );
	if ( $already_subscribed.length ) {
		$already_subscribed.show();
	} else {
		$states.first().show();
	}

	TL_Front.close_screen_filler = close_it;

	// called to stop other events that might interact in the bad way with the lightbox, like a button that redirects the page.
	if ( TargetEvent && TargetEvent.preventDefault ) {
		TargetEvent.preventDefault();
		TargetEvent.stopPropagation();
	}

	ThriveGlobal.$j( document ).off( 'keyup.close-screenfiller' ).on( 'keyup.close-screenfiller', function ( e ) {
		if ( e.which == 27 ) {
			close_it( $target );
		}
	} );

	//load the responsive video iframes
	$target.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
		var $this = jQuery( this );
		if ( $this.attr( 'data-src' ) ) {
			$this.attr( 'src', $this.attr( 'data-src' ) );
		}
	} );
	setTimeout( () => {
		TCB_Front.resizePageSection();
	}, 500 )
};

TL_Front.switch_slide_in_state = function ( $state ) {
	$state.find( '.tve-tl-anim' ).removeClass( function ( index, className ) {
		return ( className.match( /(^|\s)tl-anim-\S+/g ) || [] ).join( ' ' );
	} ).removeClass( 'tve-tl-anim' );
	TL_Front.slide_in_position( $state.find( '.thrv-leads-slide-in' ) );
};
TL_Front.slide_in_position = function ( $lContent ) {
	var $window = ThriveGlobal.$j( window ),
		elHeight = $lContent.outerHeight();
	if ( $window.width() <= 782 || $window.height() < elHeight ) {
		$lContent.parents( '.tve-leads-slide-in' ).addClass( 'tve-lb' ); // display it as a lightbox
		var wHeight = $window.height();

		setTimeout( function () {
			let top;

			//set the top value according to the position set for the element
			if ( $lContent.parents( '.tve-leads-slide-in' ).is( '[class*="bot"]' ) ) {
				top = wHeight - elHeight; //bottom
			} else {
				top = 0; //top
			}

			$lContent.closest( '.tve-leads-slide-in' )
			         .data( 'doc-scroll-top', document.documentElement.scrollTop )
			         .data( 'bdy-scroll-top', document.body.scrollTop );

			$lContent.parents( '.tve-leads-conversion-object' ).first().css( {
				height: ( elHeight + 80 ) + 'px',
				'min-height': wHeight + 'px'
			} );

			$lContent.css( 'top', ( top < 40 ? 40 : top ) + 'px' );
			if ( elHeight + 40 > wHeight ) {
				$lContent.parents( '.tve-leads-slide-in' ).css( 'overflow-y', 'scroll' );
			}
		}, 0 );
	}
};
TL_Front.open_slide_in = function ( $target, TargetEvent ) {
	var overflow_hidden = 'tve-o-hidden tve-l-open tve-hide-overflow',
		$body = ThriveGlobal.$j( 'body' ),
		$html = ThriveGlobal.$j( 'html' );

	ThriveGlobal.$j.fn.thrive_iphone_placeholder && $target.find( 'input[placeholder]' ).thrive_iphone_placeholder();

	TL_Front.slide_in_position( $target.find( '.thrv-leads-slide-in' ).filter( ':visible' ) );

	function close_it( $slidein ) {
		$slidein.removeClass( 'tve-leads-triggered' );
		TL_Front.handle_typefocus( $slidein, 'pause' );
		ThriveGlobal.$j( document ).off( 'keyup.close-slidein' );
		/* If we still have a lightbox open on the page we don't need to remove the overflow hidden classes */
		if ( ! ThriveGlobal.$j( '.tve_lb_open' ).length ) {
			$body.removeClass( overflow_hidden );
			$html.removeClass( overflow_hidden );
		}
		$slidein.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
			var $this = ThriveGlobal.$j( this );
			$this.attr( 'data-src', $this.attr( 'src' ) );
			$this.attr( 'src', '' );
		} );
		/**
		 * close any error messages that might have been displayed on forms inside the lightbox
		 */
		ThriveGlobal.$j( '#tve-lg-error-container' ).hide();
		if ( $target.data( 'doc-scroll-top' ) ) {
			document.documentElement.scrollTop = $target.data( 'doc-scroll-top' );
			$target.data( 'doc-scroll-top', '' );
		} else if ( $target.data( 'bdy-scroll-top' ) ) {
			document.body.scrollTop = $target.data( 'bdy-scroll-top' );
			$target.data( 'bdy-scroll-top', '' );
		}
	}

	$target.off().on( 'click', '.tve-leads-close', function () {
		close_it( $target );
	} );
	$target.find( '.tve_ea_thrive_leads_form_close' ).on( 'click', function () {
		close_it( $target );
	} );
	$target.on( 'switchstate', function ( e, $state ) {
		var args = Array.prototype.slice.call( arguments, 1 );
		TL_Front.switch_slide_in_state.apply( TL_Front, args );
	} );
	ThriveGlobal.$j( document ).off( 'keyup.close-slidein' ).on( 'keyup.close-slidein', function ( e ) {
		if ( e.which == 27 ) {
			close_it( $target );
		}
	} );

	if ( TargetEvent && TargetEvent.preventDefault ) {
		TargetEvent.preventDefault();
		TargetEvent.stopPropagation();
	}
};

TL_Front.close_form = function ( element, trigger, action, config ) {
	var $element = ThriveGlobal.$j( element ),
		$parent = $element.parents( '.tve-leads-triggered' ), //every form has this class on its wrapper
		type = $parent.attr( 'data-tl-type' ); //some of them have its type in data-tl-type

	//if no type then identify it from class
	if ( type === undefined && $parent.hasClass( 'tve-leads-widget' ) ) {
		type = 'widget';
	} else if ( type === undefined && $parent.hasClass( 'tve-leads-post-footer' ) ) {
		type = 'post-footer';
	} else if ( type === undefined && $parent.hasClass( 'tve-leads-slide-in' ) ) {
		type = 'slide-in';
	} else if ( type === undefined && $parent.hasClass( 'tve-leads-in-content' ) ) {
		type = 'in-content';
	} else if ( type === undefined && $parent.hasClass( 'tve-leads-shortcode' ) ) {
		type = 'shortcode';
	} else if ( type === undefined && $parent.hasClass( 'tve-leads-greedy_ribbon' ) ) {
		type = 'greedy_ribbon';
	} else if ( type === undefined && $parent.hasClass( 'tve_p_lb_content' ) ) {
		TL_Front.close_lightbox();
		return false;
	} else if ( type === undefined && $parent.hasClass( 'tve-leads-screen-filler' ) ) {
		TL_Front.close_screen_filler( $parent );
		return false;
	}

	//remove this class just because it is added dynamically and maybe we want to trigger it again
	$parent.removeClass( 'tve-leads-triggered' );
	TL_Front.handle_typefocus( $parent, 'pause' );
	switch ( type ) {
		case 'ribbon':
			let $close = $parent.find( '.tve-ribbon-close' );
			if ( ! $close.length ) {
				$close = jQuery( '<span class="tve-ribbon-close" style="display: none"></span>' ).appendTo( $parent );
			}
			$close.trigger( 'click' );//there already exists a bind for close

			const $header = ThriveGlobal.$j( 'body' ).find( '.thrv_header.tve-scroll-sticky' );

			if ( $header.length && $parent.attr( 'data-position' ) === 'top' ) {
				const extraOffset = ( parseFloat( TCB_Front.inlineCssVariable( $header, '--tcb-header-extra-offset' ) ) - $parent.outerHeight( true ) ) + 'px'

				TCB_Front.inlineCssVariable( $header, '--tcb-header-extra-offset', extraOffset );
			}
			break;
		case 'slide-in':
			$parent.find( '.tve_ea_thrive_leads_form_close' ).trigger( 'click' );//there already exists a bind for close
			$parent.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
				var $this = ThriveGlobal.$j( this );
				$this.attr( 'data-src', $this.attr( 'src' ) );
				$this.attr( 'src', '' );
			} );
			break;
		case 'post-footer'://case able for PHP Insert form too
		case 'in-content':
		case 'shortcode':
			$parent.fadeOut( 200, function () {
				TL_Front.form_closed( type );
			} );
			break;
		case 'widget':
			$parent.parent().slideUp( 200 );//its parent is a section tag; see the function thrive_dynamic_sidebar_params()
			break;
		case 'greedy_ribbon':
			var $body = ThriveGlobal.$j( 'body' ),
				$window = ThriveGlobal.$j( window ),
				_tempMargin = $body.css( 'margin-top' );
			$body[ 0 ].style.removeProperty( 'margin-top' );
			$parent.find( videoIframeSelector + ', ' + videoSourceSelector ).each( function () {
				var $this = ThriveGlobal.$j( this );
				$this.attr( 'data-src', $this.attr( 'src' ) );
				$this.attr( 'src', '' );
			} );
			$body.css( 'margin-top', _tempMargin );
			$window.scrollTop( 0 );
			$body.animate( {'margin-top': 0 + 'px'}, 300, 'linear', function () {
				TL_Front.form_closed( type );
			} ).removeClass( 'tve-tl-gr-anim' );

			break;
	}
};

TL_Front.form_closed = function ( type ) {
	if ( TL_Const.close_callbacks && TL_Const.close_callbacks[ type ] ) {
		ThriveGlobal.$j.each( TL_Const.close_callbacks[ type ], function ( i, f ) {
			if ( ThriveGlobal.$j.isFunction( f ) ) {
				f();
			}
		} );
	}
};

TL_Front.handle_typefocus = function ( element, action ) {
	element.find( '.tve_typefocus' ).each( function () {
		var $this = jQuery( this );
		$this.attr( 'data-typefocus', action );
	} );
};

Youez - 2016 - github.com/yon3zu
LinuXploit