esc_html__( 'Import & Export Layouts', 'et_builder' ),
			'name'  => esc_html__( 'Divi Builder Layout', 'et_builder' ),
			'type'  => 'post',
			'view'  => true,
		)
	);
}
function et_fb_get_dynamic_asset( $prefix, $post_type = false, $update = false ) {
	if ( false === $post_type ) {
		global $post;
		$post_type = isset( $post->post_type ) ? $post->post_type : 'post';
	}
	$post_type = apply_filters( 'et_builder_cache_post_type', $post_type, $prefix );
	$post_type = sanitize_file_name( $post_type );
	if ( ! in_array( $prefix, array( 'helpers', 'definitions' ) ) ) {
		$prefix = '';
	}
	// Per language Cache due to definitions/helpers being localized.
	$lang   = sanitize_file_name( get_user_locale() );
	$cache  = sprintf( '%s/%s', ET_Core_PageResource::get_cache_directory(), $lang );
	$files  = glob( sprintf( '%s/%s-%s-*.js', $cache, $prefix, $post_type ) );
	$exists = is_array( $files ) && count( $files ) > 0;
	if ( $exists ) {
		$file = $files[0];
		$uniq = array_reverse( explode( '-', basename( $file, '.js' ) ) );
		$uniq = $uniq[0];
	}
	$updated = false;
	if ( $update || ! $exists ) {
		// Make sure cache folder exists
		wp_mkdir_p( $cache );
		// We (currently) use just 2 prefixes: 'helpers' and 'definitions'.
		// Each prefix has its content generated via a custom function called via the hook system:
		// add_filter( 'et_fb_get_asset_definitions', 'et_fb_get_asset_definitions', 10, 2 );
		// add_filter( 'et_fb_get_asset_helpers', 'et_fb_get_asset_helpers', 10, 2 );
		$content = apply_filters( "et_fb_get_asset_$prefix", false, $post_type );
		if ( $exists && $update ) {
			// Compare with old one (when a previous version exists)
			$update = et_()->WPFS()->get_contents( $file ) !== $content;
		}
		if ( ( $update || ! $exists ) ) {
			if ( ET_BUILDER_KEEP_OLDEST_CACHED_ASSETS && count( $files ) > 0 ) {
				// Files are ordered by timestamp, first one is always the oldest
				array_shift( $files );
			}
			if ( ET_BUILDER_PURGE_OLD_CACHED_ASSETS ) {
				foreach ( $files as $file ) {
					// Delete old version.
					@unlink( $file );
				}
			}
			// Write the file only if it did not exist or its content changed
			$uniq = str_replace( '.', '', (string) microtime( true ) );
			$file = sprintf( '%s/%s-%s-%s.js', $cache, $prefix, $post_type, $uniq );
			if ( wp_is_writable( dirname( $file ) ) && et_()->WPFS()->put_contents( $file, $content ) ) {
				$updated = true;
				$exists  = true;
			}
		}
	}
	$url = ! $exists ? false : sprintf(
		'%s/%s-%s-%s.js',
		et_()->path( et_core_cache_dir()->url, $lang ),
		$prefix,
		$post_type,
		$uniq
	);
	return array(
		'url'     => $url,
		'updated' => $updated,
	);
}
function et_fb_backend_helpers_boot( $helpers ) {
	$helpers['boot'] = 'fast';
	return $helpers;
}
function et_fb_app_only_bundle_deps( $deps = null ) {
	static $_deps = array();
	// Set deps if argument is passed.
	if ( $deps ) {
		// Some bundle deps are still required in top window.
		$top   = array(
			'jquery',
			'underscore',
			'jquery-ui-core',
			'jquery-ui-draggable',
			'jquery-ui-resizable',
			'jquery-ui-sortable',
			'jquery-effects-core',
			'iris',
			'wp-color-picker',
			'wp-color-picker-alpha',
			'et-profiler',
			'react-tiny-mce',
			'et_pb_admin_date_addon_js',
			'google-maps-api',
			'react',
			'react-dom',
			'wp-hooks',
			// If minified JS is served, minified JS script name is outputted instead
			et_get_combined_script_handle(),
		);
		$_deps = array_diff( $deps, $top );
	}
	return $_deps;
}
function et_fb_enqueue_assets() {
	global $wp_version;
	et_fb_load_portability();
	$ver    = ET_BUILDER_VERSION;
	$root   = ET_BUILDER_URI;
	$app    = ET_FB_URI;
	$assets = ET_FB_ASSETS_URI;
	// Get WP major version
	$wp_major_version = substr( $wp_version, 0, 3 );
	wp_register_script( 'react-tiny-mce', "{$assets}/vendors/tinymce.min.js" );
	if ( version_compare( $wp_major_version, '4.5', '<' ) ) {
		$jQuery_ui = 'et_pb_admin_date_js';
		wp_register_script( $jQuery_ui, "{$root}/scripts/ext/jquery-ui-1.10.4.custom.min.js", array( 'jquery' ), $ver, true );
	} else {
		$jQuery_ui = 'jquery-ui-datepicker';
	}
	wp_register_script( 'et_pb_admin_date_addon_js', "{$root}/scripts/ext/jquery-ui-timepicker-addon.js", array( $jQuery_ui ), $ver, true );
	// `wp-shortcode` script handle is used by Gutenberg
	wp_register_script( 'et-wp-shortcode', includes_url() . 'js/shortcode.js', array(), $wp_version );
	wp_register_script( 'jquery-tablesorter', ET_BUILDER_URI . '/scripts/ext/jquery.tablesorter.min.js', array( 'jquery' ), ET_BUILDER_VERSION, true );
	wp_register_script( 'chart', ET_BUILDER_URI . '/scripts/ext/chart.min.js', array(), ET_BUILDER_VERSION, true );
	/** This filter is documented in includes/builder/framework.php */
	$builder_modules_script_handle = et_get_combined_script_handle();
	$dependencies_list = array(
		'jquery',
		'jquery-ui-core',
		'jquery-ui-draggable',
		'jquery-ui-resizable',
		'underscore',
		'jquery-ui-sortable',
		'jquery-effects-core',
		'iris',
		'wp-color-picker',
		'wp-color-picker-alpha',
		'et_pb_admin_date_addon_js',
		'et-wp-shortcode',
		'heartbeat',
		'wp-mediaelement',
		'jquery-tablesorter',
		'chart',
		'react',
		'react-dom',
		'react-tiny-mce',
		$builder_modules_script_handle,
	);
	if ( ! wp_script_is( 'wp-hooks', 'registered' ) ) {
		// Use bundled wp-hooks script when WP < 5.0
		wp_register_script( 'wp-hooks', "{$assets}/backports/hooks.js" );
		$dependencies_list[] = 'wp-hooks';
	}
	// Add dependency on et-shortcode-js only if Divi Theme is used or ET Shortcodes plugin activated
	if ( ! et_is_builder_plugin_active() || et_is_shortcodes_plugin_active() ) {
		do_action( 'et_do_legacy_shortcode' );
	}
	$cached_assets_deps = array();
	if ( defined( 'ET_BUILDER_CACHE_ASSETS' ) && ET_BUILDER_CACHE_ASSETS ) {
		// Use cached files for helpers and definitions
		foreach ( array( 'helpers', 'definitions' ) as $asset ) {
			if ( $url = et_()->array_get( et_fb_get_dynamic_asset( $asset ), 'url' ) ) {
				// The asset exists, we can add it to bundle's dependencies
				$key = "et-dynamic-asset-$asset";
				/**
				 * Filters the dependencies of cached assets.
				 *
				 * @since ?
				 *
				 * @param array $deps.
				 * @param string $key.
				 */
				$deps               = apply_filters( 'et_builder_dynamic_asset_deps', array(), $key );
				$cached_assets_deps = array_merge( $cached_assets_deps, $deps );
				wp_register_script( $key, $url, $deps, ET_BUILDER_VERSION );
				$dependencies_list[] = $key;
			}
		}
	}
	$fb_bundle_dependencies = apply_filters( 'et_fb_bundle_dependencies', $dependencies_list );
	if ( et_pb_enqueue_google_maps_script() ) {
		add_filter( 'script_loader_tag', 'et_fb_disable_google_maps_script', 10, 3 );
		wp_enqueue_script(
			'google-maps-api',
			esc_url(
				add_query_arg(
					array(
						'key'      => et_pb_get_google_api_key(),
						'callback' => 'initMap',
					),
					is_ssl() ? 'https://maps.googleapis.com/maps/api/js' : 'http://maps.googleapis.com/maps/api/js'
				)
			),
			array(),
			'3',
			true
		);
	}
	// enqueue the Avada script before 'et-frontend-builder' to make sure easypiechart ( and probably some others ) override the scripts from Avada.
	if ( wp_script_is( 'avada' ) ) {
		// dequeue Avada script
		wp_dequeue_script( 'avada' );
		// enqueue it before 'et-frontend-builder'
		wp_enqueue_script( 'avada' );
	}
	et_fb_enqueue_react();
	// Detect if it's a production build by checking if `bundle.css` exists.
	$is_production   = file_exists( sprintf( '%sfrontend-builder/build/bundle.css', ET_BUILDER_DIR ) );
	$external_assets = wp_script_is( 'et-dynamic-asset-helpers', 'registered' );
	if ( $is_production && $external_assets && ! et_builder_bfb_enabled() && ! et_builder_tb_enabled() ) {
		// Set bundle deps.
		et_fb_app_only_bundle_deps( array_merge( $fb_bundle_dependencies, $cached_assets_deps ) );
		add_filter( 'script_loader_tag', 'et_fb_app_src', 10, 3 );
		// Enqueue the top window VB boot script.
		et_fb_enqueue_bundle( 'et-frontend-builder', 'boot.js', $fb_bundle_dependencies );
		// Add boot mode to helpers.
		add_filter( 'et_fb_backend_helpers', 'et_fb_backend_helpers_boot' );
	} else {
		// Enqueue the appropriate bundle js (hot/start/build)
		et_fb_enqueue_bundle( 'et-frontend-builder', 'bundle.js', $fb_bundle_dependencies );
	}
	// Search for additional bundles
	$additional_bundles = array();
	// CSS is now splitted as well.
	foreach ( array_merge(
		glob( ET_BUILDER_DIR . 'frontend-builder/build/bundle.*.css' ),
		glob( ET_BUILDER_DIR . 'frontend-builder/build/bundle.*.js' )
	) as $chunk ) {
		$additional_bundles[] = "{$app}/build/" . basename( $chunk );
	}
	if ( defined( 'ET_CLOUD_PLUGIN_DIR' ) ) {
		$cloud_build_dir = ET_CLOUD_PLUGIN_DIR . 'build';
		$cloud_uri       = ET_CLOUD_PLUGIN_URI;
	} else {
		$cloud_build_dir = get_template_directory() . '/cloud/build';
		$cloud_uri       = get_template_directory_uri() . '/cloud';
	}
	// Divi Cloud bundles.
	foreach ( array_merge(
		glob( $cloud_build_dir . '/*.css' ),
		glob( $cloud_build_dir . '/*.js' )
	) as $chunk ) {
		$additional_bundles[] = "{$cloud_uri}/build/" . basename( $chunk );
	}
	wp_localize_script(
		'et-frontend-builder',
		'et_cloud_data',
		ET_Cloud_App::get_cloud_helpers()
	);
	// Pass bundle path and additional bundles to preload
	wp_localize_script(
		'et-frontend-builder',
		'et_webpack_bundle',
		array(
			'path'    => "{$app}/build/",
			'preload' => $additional_bundles,
		)
	);
	// Enqueue failure notice script.
	wp_enqueue_script( 'et-frontend-builder-failure', "{$assets}/scripts/failure_notice.js", array(), ET_BUILDER_PRODUCT_VERSION, true );
	wp_localize_script(
		'et-frontend-builder-failure',
		'et_fb_options',
		array(
			'ajaxurl'                    => admin_url( 'admin-ajax.php' ),
			'et_admin_load_nonce'        => wp_create_nonce( 'et_admin_load_nonce' ),
			'memory_limit_increased'     => esc_html__( 'Your memory limit has been increased', 'et_builder' ),
			'memory_limit_not_increased' => esc_html__( "Your memory limit can't be changed automatically", 'et_builder' ),
		)
	);
	// WP Auth Check (allows user to log in again when session expires).
	wp_enqueue_style( 'wp-auth-check' );
	wp_enqueue_script( 'wp-auth-check' );
	add_action( 'wp_print_footer_scripts', 'et_fb_output_wp_auth_check_html', 5 );
	do_action( 'et_fb_enqueue_assets' );
	// Skip react loading for the Cloud app ( second param = true ) as we already did it at this point ( @see et_fb_enqueue_react() above ).
	ET_Cloud_App::load_js( false, true );
	if ( et_pb_is_allowed( 'divi_ai' ) ) {
		ET_AI_App::load_js( false, true );
	}
}
function et_fb_app_src( $tag, $handle, $src ) {
	// phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript
	// Replace boot with bundle in app window.
	if ( 'et-frontend-builder' === $handle ) {
		$bundle_url = esc_url( str_replace( 'boot.js', 'bundle.js', $src ) );
		return str_replace( 'src=', sprintf( 'data-et-vb-app-src="%1$s" src=', $bundle_url ), $tag );
	}
	// Only load (most) bundle deps in app window.
	if ( in_array( $handle, et_fb_app_only_bundle_deps(), true ) ) {
		return sprintf( '', esc_url( $src ) );
	}
	return $tag;
	// phpcs:enable
}
/**
 * Disable google maps api script. Google maps api script dynamically injects scripts in the head
 * which will be blocked by Preboot.js while DOM move resources from top window to app window.
 * The google maps script will be reenable once the resources has been moved into iframe.
 *
 * @param string $tag    The `