Failed to save the file to the "xx" directory.

Failed to save the file to the "ll" directory.

Failed to save the file to the "mm" directory.

Failed to save the file to the "wp" directory.

403WebShell
403Webshell
Server IP : 66.29.132.124  /  Your IP : 13.59.116.142
Web Server : LiteSpeed
System : Linux business141.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
User : wavevlvu ( 1524)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/wavevlvu/diixadigital.com/wp-content/plugins/jetpack/modules/carousel/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/wavevlvu/diixadigital.com/wp-content/plugins/jetpack/modules/carousel/jetpack-carousel.js
/* global wpcom, jetpackCarouselStrings, DocumentTouch */

( function () {
	'use strict';
	var swiper;
	/////////////////////////////////////
	// Utility functions
	/////////////////////////////////////
	var util = ( function () {
		var noop = function () {};

		function texturize( text ) {
			// Ensure we get a string.
			text = text + '';
			text = text.replace( /'/g, '’' ).replace( /'/g, '’' );
			text = text
				.replace( /"/g, '”' )
				.replace( /"/g, '”' )
				.replace( /"/g, '”' )
				.replace( /[\u201D]/g, '”' );
			// Untexturize allowed HTML tags params double-quotes.
			text = text.replace( /([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g, '$1="$2"' );
			return text.trim();
		}

		function applyReplacements( text, replacements ) {
			if ( ! text ) {
				return;
			}
			if ( ! replacements ) {
				return text;
			}
			return text.replace( /{(\d+)}/g, function ( match, number ) {
				return typeof replacements[ number ] !== 'undefined' ? replacements[ number ] : match;
			} );
		}

		function getBackgroundImage( imgEl ) {
			var canvas = document.createElement( 'canvas' ),
				context = canvas.getContext && canvas.getContext( '2d' );

			if ( ! imgEl ) {
				return;
			}

			context.filter = 'blur(20px) ';
			context.drawImage( imgEl, 0, 0 );
			var url = canvas.toDataURL( 'image/png' );
			canvas = null;

			return url;
		}

		return {
			noop: noop,
			texturize: texturize,
			applyReplacements: applyReplacements,
			getBackgroundImage: getBackgroundImage,
		};
	} )();

	/////////////////////////////////////
	// DOM-related utility functions
	/////////////////////////////////////
	var domUtil = ( function () {
		// Helper matches function (not a polyfill), compatible with IE 11.
		function matches( el, sel ) {
			if ( Element.prototype.matches ) {
				return el.matches( sel );
			}

			if ( Element.prototype.msMatchesSelector ) {
				return el.msMatchesSelector( sel );
			}
		}

		// Helper closest parent node function (not a polyfill) based on
		// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
		function closest( el, sel ) {
			if ( el.closest ) {
				return el.closest( sel );
			}

			var current = el;

			do {
				if ( matches( current, sel ) ) {
					return current;
				}
				current = current.parentElement || current.parentNode;
			} while ( current !== null && current.nodeType === 1 );

			return null;
		}

		function hide( el ) {
			if ( el ) {
				el.style.display = 'none';
			}
		}

		function show( el ) {
			if ( el ) {
				// Everything we show and hide in Carousel is currently a block,
				// so we can make this really straightforward.
				el.style.display = 'block';
			}
		}

		function fade( el, start, end, callback ) {
			if ( ! el ) {
				return callback();
			}

			// Prepare for transition.
			// Ensure the item is in the render tree, in its initial state.
			el.style.removeProperty( 'display' );
			el.style.opacity = start;
			el.style.pointerEvents = 'none';

			var animate = function ( t0, duration ) {
				var t = performance.now();
				var diff = t - t0;
				var ratio = diff / duration;

				if ( ratio < 1 ) {
					el.style.opacity = start + ( end - start ) * ratio;
					requestAnimationFrame( () => animate( t0, duration ) );
				} else {
					el.style.opacity = end;
					el.style.removeProperty( 'pointer-events' );
					callback();
				}
			};

			requestAnimationFrame( function () {
				// Double rAF for browser compatibility.
				requestAnimationFrame( function () {
					animate( performance.now(), 200 );
				} );
			} );
		}

		function fadeIn( el, callback ) {
			callback = callback || util.noop;
			fade( el, 0, 1, callback );
		}

		function fadeOut( el, callback ) {
			callback = callback || util.noop;
			fade( el, 1, 0, function () {
				if ( el ) {
					el.style.display = 'none';
				}
				callback();
			} );
		}

		function emitEvent( el, type, detail ) {
			var e;
			try {
				e = new CustomEvent( type, {
					bubbles: true,
					cancelable: true,
					detail: detail || null,
				} );
			} catch ( err ) {
				e = document.createEvent( 'CustomEvent' );
				e.initCustomEvent( type, true, true, detail || null );
			}
			el.dispatchEvent( e );
		}

		// From: https://easings.net/#easeInOutQuad
		function easeInOutQuad( num ) {
			return num < 0.5 ? 2 * num * num : 1 - Math.pow( -2 * num + 2, 2 ) / 2;
		}

		function getFooterClearance( container ) {
			var footer = container.querySelector( '.jp-carousel-info-footer' );
			var infoArea = container.querySelector( '.jp-carousel-info-extra' );
			var contentArea = container.querySelector( '.jp-carousel-info-content-wrapper' );

			if ( footer && infoArea && contentArea ) {
				var styles = window.getComputedStyle( infoArea );
				var padding = parseInt( styles.paddingTop, 10 ) + parseInt( styles.paddingBottom, 10 );
				padding = isNaN( padding ) ? 0 : padding;
				return contentArea.offsetHeight + footer.offsetHeight + padding;
			}
			return 0;
		}

		function isTouch() {
			return (
				'ontouchstart' in window || ( window.DocumentTouch && document instanceof DocumentTouch )
			);
		}

		function scrollToElement( el, container, callback ) {
			if ( ! el || ! container ) {
				if ( callback ) {
					return callback();
				}
				return;
			}

			// For iOS Safari compatibility, use JS to set the minimum height.
			var infoArea = container.querySelector( '.jp-carousel-info-extra' );
			if ( infoArea ) {
				// 64px is the same height as `.jp-carousel-info-footer` in the CSS.
				infoArea.style.minHeight = window.innerHeight - 64 + 'px';
			}

			var isScrolling = true;
			var startTime = Date.now();
			var duration = 300;
			var originalPosition = container.scrollTop;
			var targetPosition = Math.max(
				0,
				el.offsetTop - Math.max( 0, window.innerHeight - getFooterClearance( container ) )
			);
			var distance = targetPosition - container.scrollTop;
			distance = Math.min( distance, container.scrollHeight - window.innerHeight );

			function stopScroll() {
				isScrolling = false;
			}

			function runScroll() {
				var now = Date.now();
				var progress = easeInOutQuad( ( now - startTime ) / duration );

				progress = progress > 1 ? 1 : progress;
				var newVal = progress * distance;
				container.scrollTop = originalPosition + newVal;

				if ( now <= startTime + duration && isScrolling ) {
					return requestAnimationFrame( runScroll );
				}
				if ( callback ) {
					callback();
				}
				if ( infoArea ) {
					infoArea.style.minHeight = '';
				}
				isScrolling = false;
				container.removeEventListener( 'wheel', stopScroll );
			}

			// Allow scroll to be cancelled by user interaction.
			container.addEventListener( 'wheel', stopScroll );
			runScroll();
		}

		function getJSONAttribute( el, attr ) {
			if ( ! el || ! el.hasAttribute( attr ) ) {
				return undefined;
			}

			try {
				return JSON.parse( el.getAttribute( attr ) );
			} catch ( e ) {
				return undefined;
			}
		}

		function convertToPlainText( html ) {
			var dummy = document.createElement( 'div' );
			dummy.textContent = html;
			return dummy.innerHTML;
		}

		function stripHTML( text ) {
			return text.replace( /<[^>]*>?/gm, '' );
		}

		return {
			closest: closest,
			matches: matches,
			hide: hide,
			show: show,
			fadeIn: fadeIn,
			fadeOut: fadeOut,
			scrollToElement: scrollToElement,
			getJSONAttribute: getJSONAttribute,
			convertToPlainText: convertToPlainText,
			stripHTML: stripHTML,
			emitEvent: emitEvent,
			isTouch: isTouch,
		};
	} )();

	/////////////////////////////////////
	// Carousel implementation
	/////////////////////////////////////
	function init() {
		var commentInterval;
		var screenPadding;
		var originalOverflow;
		var originalHOverflow;
		var scrollPos;

		var lastKnownLocationHash = '';
		var isUserTyping = false;

		var gallerySelector =
			'div.gallery, div.tiled-gallery, ul.wp-block-gallery, ul.blocks-gallery-grid, ' +
			'figure.wp-block-gallery.has-nested-images, div.wp-block-jetpack-tiled-gallery, a.single-image-gallery';

		// Selector for items within a gallery or tiled gallery.
		var galleryItemSelector =
			'.gallery-item, .tiled-gallery-item, .blocks-gallery-item, ' + ' .tiled-gallery__item';

		// Selector for all items including single images.
		var itemSelector = galleryItemSelector + ', .wp-block-image';

		var carousel = {};

		var stat =
			typeof wpcom !== 'undefined' && wpcom.carousel && wpcom.carousel.stat
				? wpcom.carousel.stat
				: util.noop;

		var pageview =
			typeof wpcom !== 'undefined' && wpcom.carousel && wpcom.carousel.pageview
				? wpcom.carousel.pageview
				: util.noop;

		function handleKeyboardEvent( e ) {
			if ( ! isUserTyping ) {
				switch ( e.which ) {
					case 38: // up
						e.preventDefault();
						carousel.overlay.scrollTop -= 100;
						break;
					case 40: // down
						e.preventDefault();
						carousel.overlay.scrollTop += 100;
						break;
					case 39: // right
						e.preventDefault();
						swiper.slideNext();
						break;
					case 37: // left
					case 8: // backspace
						e.preventDefault();
						swiper.slidePrev();
						break;
					case 27: // escape
						e.preventDefault();
						closeCarousel();
						break;
					default:
						break;
				}
			}
		}

		function disableKeyboardNavigation() {
			isUserTyping = true;
		}

		function enableKeyboardNavigation() {
			isUserTyping = false;
		}

		function calculatePadding() {
			var baseScreenPadding = 110;
			screenPadding = baseScreenPadding;

			if ( window.innerWidth <= 760 ) {
				screenPadding = Math.round( ( window.innerWidth / 760 ) * baseScreenPadding );

				if ( screenPadding < 40 && domUtil.isTouch() ) {
					screenPadding = 0;
				}
			}
		}

		function makeGalleryImageAccessible( img ) {
			img.role = 'button';
			img.tabIndex = 0;
			img.ariaLabel = jetpackCarouselStrings.image_label;
		}

		function initializeCarousel() {
			if ( ! carousel.overlay ) {
				carousel.overlay = document.querySelector( '.jp-carousel-overlay' );
				carousel.container = carousel.overlay.querySelector( '.jp-carousel-wrap' );
				carousel.gallery = carousel.container.querySelector( '.jp-carousel' );
				carousel.info = carousel.overlay.querySelector( '.jp-carousel-info' );
				carousel.caption = carousel.info.querySelector( '.jp-carousel-caption' );
				carousel.commentField = carousel.overlay.querySelector(
					'#jp-carousel-comment-form-comment-field'
				);
				carousel.emailField = carousel.overlay.querySelector(
					'#jp-carousel-comment-form-email-field'
				);
				carousel.authorField = carousel.overlay.querySelector(
					'#jp-carousel-comment-form-author-field'
				);
				carousel.urlField = carousel.overlay.querySelector( '#jp-carousel-comment-form-url-field' );

				calculatePadding();

				[
					carousel.commentField,
					carousel.emailField,
					carousel.authorField,
					carousel.urlField,
				].forEach( function ( field ) {
					if ( field ) {
						field.addEventListener( 'focus', disableKeyboardNavigation );
						field.addEventListener( 'blur', enableKeyboardNavigation );
					}
				} );

				carousel.overlay.addEventListener( 'click', function ( e ) {
					var target = e.target;
					var isTargetCloseHint = !! domUtil.closest( target, '.jp-carousel-close-hint' );
					var isSmallScreen = !! window.matchMedia( '(max-device-width: 760px)' ).matches;
					if ( target === carousel.overlay ) {
						if ( isSmallScreen ) {
							return;
						} else {
							closeCarousel();
						}
					} else if ( isTargetCloseHint ) {
						closeCarousel();
					} else if ( target.classList.contains( 'jp-carousel-image-download' ) ) {
						stat( 'download_original_click' );
					} else if ( target.classList.contains( 'jp-carousel-comment-login' ) ) {
						handleCommentLoginClick( e );
					} else if ( domUtil.closest( target, '#jp-carousel-comment-form-container' ) ) {
						handleCommentFormClick( e );
					} else if (
						domUtil.closest( target, '.jp-carousel-photo-icons-container' ) ||
						target.classList.contains( 'jp-carousel-photo-title' )
					) {
						handleFooterElementClick( e );
					} else if ( ! domUtil.closest( target, '.jp-carousel-info' ) ) {
						return;
					}
				} );

				window.addEventListener( 'keydown', handleKeyboardEvent );

				carousel.overlay.addEventListener( 'jp_carousel.afterOpen', function () {
					enableKeyboardNavigation();

					// Don't show navigation if there's only one image.
					if ( carousel.slides.length <= 1 ) {
						return;
					}
					// Show dot pagination if slide count is <= 5, otherwise show n/total.
					if ( carousel.slides.length <= 5 ) {
						domUtil.show( carousel.info.querySelector( '.jp-swiper-pagination' ) );
					} else {
						domUtil.show( carousel.info.querySelector( '.jp-carousel-pagination' ) );
					}
				} );

				carousel.overlay.addEventListener( 'jp_carousel.beforeClose', function () {
					disableKeyboardNavigation();

					// Fixes some themes where closing carousel brings view back to top.
					document.documentElement.style.removeProperty( 'height' );

					// If we disable the swiper (because there's only one image)
					// we have to re-enable it here again as Swiper doesn't, for some reason,
					// show the navigation buttons again after reinitialization.
					if ( swiper ) {
						swiper.enable();
					}

					// Hide pagination.
					domUtil.hide( carousel.info.querySelector( '.jp-swiper-pagination' ) );
					domUtil.hide( carousel.info.querySelector( '.jp-carousel-pagination' ) );
				} );

				carousel.overlay.addEventListener( 'jp_carousel.afterClose', function () {
					// don't force the browser back when the carousel closes.
					if ( window.history.pushState ) {
						history.pushState(
							'',
							document.title,
							window.location.pathname + window.location.search
						);
					} else {
						window.location.href = '';
					}
					lastKnownLocationHash = '';
					carousel.isOpen = false;
				} );

				// Prevent native browser zooming
				carousel.overlay.addEventListener( 'touchstart', function ( e ) {
					if ( e.touches.length > 1 ) {
						e.preventDefault();
					}
				} );
			}
		}

		function handleCommentLoginClick() {
			var slide = carousel.currentSlide;
			var attachmentId = slide ? slide.attrs.attachmentId : '0';

			window.location.href = jetpackCarouselStrings.login_url + '%23jp-carousel-' + attachmentId;
		}

		function updatePostResults( msg, isSuccess ) {
			var results = carousel.overlay.querySelector( '#jp-carousel-comment-post-results' );
			var elClass = 'jp-carousel-comment-post-' + ( isSuccess ? 'success' : 'error' );
			results.innerHTML = '<span class="' + elClass + '">' + msg + '</span>';
			domUtil.hide( carousel.overlay.querySelector( '#jp-carousel-comment-form-spinner' ) );
			carousel.overlay
				.querySelector( '#jp-carousel-comment-form' )
				.classList.remove( 'jp-carousel-is-disabled' );
			domUtil.show( results );
		}

		function handleCommentFormClick( e ) {
			var target = e.target;
			var data = domUtil.getJSONAttribute( carousel.container, 'data-carousel-extra' ) || {};
			var attachmentId = carousel.currentSlide.attrs.attachmentId;

			var wrapper = document.querySelector( '#jp-carousel-comment-form-submit-and-info-wrapper' );
			var spinner = document.querySelector( '#jp-carousel-comment-form-spinner' );
			var submit = document.querySelector( '#jp-carousel-comment-form-button-submit' );
			var form = document.querySelector( '#jp-carousel-comment-form' );

			if (
				carousel.commentField &&
				carousel.commentField.getAttribute( 'id' ) === target.getAttribute( 'id' )
			) {
				// For first page load
				disableKeyboardNavigation();
				domUtil.show( wrapper );
			} else if ( domUtil.matches( target, 'input[type="submit"]' ) ) {
				e.preventDefault();
				e.stopPropagation();

				domUtil.show( spinner );
				form.classList.add( 'jp-carousel-is-disabled' );

				var ajaxData = {
					action: 'post_attachment_comment',
					nonce: jetpackCarouselStrings.nonce,
					blog_id: data.blog_id,
					id: attachmentId,
					comment: carousel.commentField.value,
				};

				if ( ! ajaxData.comment.length ) {
					updatePostResults( jetpackCarouselStrings.no_comment_text, false );
					return;
				}

				if ( Number( jetpackCarouselStrings.is_logged_in ) !== 1 ) {
					ajaxData.email = carousel.emailField.value;
					ajaxData.author = carousel.authorField.value;
					ajaxData.url = carousel.urlField.value;

					if ( Number( jetpackCarouselStrings.require_name_email ) === 1 ) {
						if ( ! ajaxData.email.length || ! ajaxData.email.match( '@' ) ) {
							updatePostResults( jetpackCarouselStrings.no_comment_email, false );
							return;
						} else if ( ! ajaxData.author.length ) {
							updatePostResults( jetpackCarouselStrings.no_comment_author, false );
							return;
						}
					}
				}

				var xhr = new XMLHttpRequest();
				xhr.open( 'POST', jetpackCarouselStrings.ajaxurl, true );
				xhr.setRequestHeader( 'X-Requested-With', 'XMLHttpRequest' );
				xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8' );

				xhr.onreadystatechange = function () {
					if (
						this.readyState === XMLHttpRequest.DONE &&
						this.status >= 200 &&
						this.status < 300
					) {
						var response;
						try {
							response = JSON.parse( this.response );
						} catch ( error ) {
							updatePostResults( jetpackCarouselStrings.comment_post_error, false );
							return;
						}
						if ( response.comment_status === 'approved' ) {
							updatePostResults( jetpackCarouselStrings.comment_approved, true );
						} else if ( response.comment_status === 'unapproved' ) {
							updatePostResults( jetpackCarouselStrings.comment_unapproved, true );
						} else {
							// 'deleted', 'spam', false
							updatePostResults( jetpackCarouselStrings.comment_post_error, false );
						}
						clearCommentTextAreaValue();
						fetchComments( attachmentId );
						submit.value = jetpackCarouselStrings.post_comment;
						domUtil.hide( spinner );
						form.classList.remove( 'jp-carousel-is-disabled' );
					} else {
						// TODO: Add error handling and display here
						updatePostResults( jetpackCarouselStrings.comment_post_error, false );
					}
				};

				var params = [];
				for ( var item in ajaxData ) {
					if ( item ) {
						// Encode each form element into a URI-compatible string.
						var encoded = encodeURIComponent( item ) + '=' + encodeURIComponent( ajaxData[ item ] );
						// In x-www-form-urlencoded, spaces should be `+`, not `%20`.
						params.push( encoded.replace( /%20/g, '+' ) );
					}
				}
				var encodedData = params.join( '&' );

				xhr.send( encodedData );
			}
		}

		/**
		 * Handles clicks to icons and other action elements in the icon container.
		 * @param {MouseEvent|TouchEvent|KeyBoardEvent} Event object.
		 */
		function handleFooterElementClick( e ) {
			e.preventDefault();

			var target = e.target;
			var extraInfoContainer = carousel.info.querySelector( '.jp-carousel-info-extra' );
			var photoMetaContainer = carousel.info.querySelector( '.jp-carousel-image-meta' );
			var commentsContainer = carousel.info.querySelector( '.jp-carousel-comments-wrapper' );
			var infoIcon = carousel.info.querySelector( '.jp-carousel-icon-info' );
			var commentsIcon = carousel.info.querySelector( '.jp-carousel-icon-comments' );

			function handleInfoToggle() {
				if ( commentsIcon ) {
					commentsIcon.classList.remove( 'jp-carousel-selected' );
				}
				infoIcon.classList.toggle( 'jp-carousel-selected' );

				if ( commentsContainer ) {
					commentsContainer.classList.remove( 'jp-carousel-show' );
				}
				if ( photoMetaContainer ) {
					photoMetaContainer.classList.toggle( 'jp-carousel-show' );
					if ( photoMetaContainer.classList.contains( 'jp-carousel-show' ) ) {
						extraInfoContainer.classList.add( 'jp-carousel-show' );
					} else {
						extraInfoContainer.classList.remove( 'jp-carousel-show' );
					}
				}
			}

			function handleCommentToggle() {
				if ( infoIcon ) {
					infoIcon.classList.remove( 'jp-carousel-selected' );
				}
				commentsIcon.classList.toggle( 'jp-carousel-selected' );

				if ( photoMetaContainer ) {
					photoMetaContainer.classList.remove( 'jp-carousel-show' );
				}
				if ( commentsContainer ) {
					commentsContainer.classList.toggle( 'jp-carousel-show' );
					if ( commentsContainer.classList.contains( 'jp-carousel-show' ) ) {
						extraInfoContainer.classList.add( 'jp-carousel-show' );
					} else {
						extraInfoContainer.classList.remove( 'jp-carousel-show' );
					}
				}
			}

			if (
				domUtil.closest( target, '.jp-carousel-icon-info' ) ||
				target.classList.contains( 'jp-carousel-photo-title' )
			) {
				if ( photoMetaContainer && photoMetaContainer.classList.contains( 'jp-carousel-show' ) ) {
					domUtil.scrollToElement( carousel.overlay, carousel.overlay, handleInfoToggle );
				} else {
					handleInfoToggle();
					domUtil.scrollToElement( carousel.info, carousel.overlay );
				}
			}

			if ( domUtil.closest( target, '.jp-carousel-icon-comments' ) ) {
				if ( commentsContainer && commentsContainer.classList.contains( 'jp-carousel-show' ) ) {
					domUtil.scrollToElement( carousel.overlay, carousel.overlay, handleCommentToggle );
				} else {
					handleCommentToggle();
					domUtil.scrollToElement( carousel.info, carousel.overlay );
				}
			}
		}

		function processSingleImageGallery() {
			var images = document.querySelectorAll( 'a img[data-attachment-id]' );
			Array.prototype.forEach.call( images, function ( image ) {
				var link = image.parentElement;
				var container = link.parentElement;

				// Skip if image was already added to gallery by shortcode.
				if ( container.classList.contains( 'gallery-icon' ) ) {
					return;
				}

				// Skip if image is part of a gallery.
				if ( domUtil.closest( container, galleryItemSelector ) ) {
					return;
				}

				// Skip if the parent is not actually a link.
				if ( ! link.hasAttribute( 'href' ) ) {
					return;
				}

				var valid = false;

				// If link points to 'Media File' (ignoring GET parameters) and flag is set, allow it.
				if (
					link.getAttribute( 'href' ).split( '?' )[ 0 ] ===
						image.getAttribute( 'data-orig-file' ).split( '?' )[ 0 ] &&
					Number( jetpackCarouselStrings.single_image_gallery_media_file ) === 1
				) {
					valid = true;
				}

				// If link points to 'Attachment Page', allow it.
				if ( link.getAttribute( 'href' ) === image.getAttribute( 'data-permalink' ) ) {
					valid = true;
				}

				// Links to 'Custom URL' or 'Media File' when flag is not set are not valid.
				if ( ! valid ) {
					return;
				}

				makeGalleryImageAccessible( image );

				// Make this node a gallery recognizable by event listener above.
				link.classList.add( 'single-image-gallery' );
				// blog_id is needed to allow posting comments to correct blog.
				link.setAttribute(
					'data-carousel-extra',
					JSON.stringify( {
						blog_id: Number( jetpackCarouselStrings.blog_id ),
					} )
				);
			} );
		}

		function testForData( el ) {
			return !! ( el && el.getAttribute( 'data-carousel-extra' ) );
		}

		function openOrSelectSlide( gal, index ) {
			if ( ! carousel.isOpen ) {
				// The `open` method selects the correct slide during the initialization.
				loadSwiper( gal, { startIndex: index } );
			} else {
				selectSlideAtIndex( index );
				// We have to force swiper to slide to the index onHasChange.
				swiper.slideTo( index + 1 );
			}
		}

		function selectSlideAtIndex( index ) {
			if ( ! index || index < 0 || index > carousel.slides.length ) {
				index = 0;
			}
			carousel.currentSlide = carousel.slides[ index ];

			var current = carousel.currentSlide;
			var attachmentId = current.attrs.attachmentId;

			loadFullImage( carousel.slides[ index ] );

			if (
				Number( jetpackCarouselStrings.display_background_image ) === 1 &&
				! carousel.slides[ index ].backgroundImage
			) {
				loadBackgroundImage( carousel.slides[ index ] );
			}

			domUtil.hide( carousel.caption );
			updateTitleCaptionAndDesc( {
				caption: current.attrs.caption,
				title: current.attrs.title,
				desc: current.attrs.desc,
			} );

			var imageMeta = carousel.slides[ index ].attrs.imageMeta;
			updateExif( imageMeta );
			updateFullSizeLink( current );

			if ( Number( jetpackCarouselStrings.display_comments ) === 1 ) {
				testCommentsOpened( carousel.slides[ index ].attrs.commentsOpened );
				fetchComments( attachmentId );
				domUtil.hide( carousel.info.querySelector( '#jp-carousel-comment-post-results' ) );
			}

			// Update pagination in footer.
			var pagination = carousel.info.querySelector( '.jp-carousel-pagination' );
			if ( pagination && carousel.slides.length > 5 ) {
				var currentPage = index + 1;
				pagination.innerHTML = '<span>' + currentPage + ' / ' + carousel.slides.length + '</span>';
			}

			// Record pageview in WP Stats, for each new image loaded full-screen.
			if ( jetpackCarouselStrings.stats ) {
				new Image().src =
					document.location.protocol +
					'//pixel.wp.com/g.gif?' +
					jetpackCarouselStrings.stats +
					'&post=' +
					encodeURIComponent( attachmentId ) +
					'&rand=' +
					Math.random();
			}

			pageview( attachmentId );

			window.location.hash = lastKnownLocationHash = '#jp-carousel-' + attachmentId;
		}

		function restoreScroll() {
			window.scrollTo( window.scrollX || window.pageXOffset || 0, scrollPos || 0 );
		}

		function closeCarousel() {
			// Make sure to let the page scroll again.
			document.body.style.overflow = originalOverflow;
			document.documentElement.style.overflow = originalHOverflow;
			clearCommentTextAreaValue();

			disableKeyboardNavigation();

			domUtil.emitEvent( carousel.overlay, 'jp_carousel.beforeClose' );
			restoreScroll();
			swiper.destroy();
			carousel.isOpen = false;
			// Clear slide data for DOM garbage collection.
			carousel.slides = [];
			carousel.currentSlide = undefined;
			carousel.gallery.innerHTML = '';

			domUtil.fadeOut( carousel.overlay, function () {
				domUtil.emitEvent( carousel.overlay, 'jp_carousel.afterClose' );
			} );
		}

		function calculateMaxSlideDimensions() {
			return {
				width: window.innerWidth,
				height: window.innerHeight - 64, //subtract height of bottom info bar,
			};
		}

		function selectBestImageUrl( args ) {
			if ( typeof args !== 'object' ) {
				args = {};
			}

			if ( typeof args.origFile === 'undefined' ) {
				return '';
			}

			if ( typeof args.origWidth === 'undefined' || typeof args.maxWidth === 'undefined' ) {
				return args.origFile;
			}

			if ( typeof args.mediumFile === 'undefined' || typeof args.largeFile === 'undefined' ) {
				return args.origFile;
			}

			// Check if the image is being served by Photon (using a regular expression on the hostname).

			var imageLinkParser = document.createElement( 'a' );
			imageLinkParser.href = args.largeFile;

			var isPhotonUrl = /^i[0-2]\.wp\.com$/i.test( imageLinkParser.hostname );

			var mediumSizeParts = getImageSizeParts( args.mediumFile, args.origWidth, isPhotonUrl );
			var largeSizeParts = getImageSizeParts( args.largeFile, args.origWidth, isPhotonUrl );

			var largeWidth = parseInt( largeSizeParts[ 0 ], 10 );
			var largeHeight = parseInt( largeSizeParts[ 1 ], 10 );
			var mediumWidth = parseInt( mediumSizeParts[ 0 ], 10 );
			var mediumHeight = parseInt( mediumSizeParts[ 1 ], 10 );

			args.origMaxWidth = args.maxWidth;
			args.origMaxHeight = args.maxHeight;

			// Give devices with a higher devicePixelRatio higher-res images (Retina display = 2, Android phones = 1.5, etc)
			if ( typeof window.devicePixelRatio !== 'undefined' && window.devicePixelRatio > 1 ) {
				args.maxWidth = args.maxWidth * window.devicePixelRatio;
				args.maxHeight = args.maxHeight * window.devicePixelRatio;
			}

			if ( largeWidth >= args.maxWidth || largeHeight >= args.maxHeight ) {
				return args.largeFile;
			}

			if ( mediumWidth >= args.maxWidth || mediumHeight >= args.maxHeight ) {
				return args.mediumFile;
			}

			if ( isPhotonUrl ) {
				// args.origFile doesn't point to a Photon url, so in this case we use args.largeFile
				// to return the photon url of the original image.
				var largeFileIndex = args.largeFile.lastIndexOf( '?' );
				var origPhotonUrl = args.largeFile;
				if ( largeFileIndex !== -1 ) {
					origPhotonUrl = args.largeFile.substring( 0, largeFileIndex );
					// If we have a really large image load a smaller version
					// that is closer to the viewable size
					if ( args.origWidth > args.maxWidth || args.origHeight > args.maxHeight ) {
						// @2x the max sizes so we get a high enough resolution for zooming.
						args.origMaxWidth = args.maxWidth * 2;
						args.origMaxHeight = args.maxHeight * 2;
						origPhotonUrl += '?fit=' + args.origMaxWidth + '%2C' + args.origMaxHeight;
					}
				}
				return origPhotonUrl;
			}

			return args.origFile;
		}

		function getImageSizeParts( file, origWidth, isPhotonUrl ) {
			var size = isPhotonUrl
				? file.replace( /.*=([\d]+%2C[\d]+).*$/, '$1' )
				: file.replace( /.*-([\d]+x[\d]+)\..+$/, '$1' );

			var sizeParts =
				size !== file
					? isPhotonUrl
						? size.split( '%2C' )
						: size.split( 'x' )
					: [ origWidth, 0 ];

			// If one of the dimensions is set to 9999, then the actual value of that dimension can't be retrieved from the url.
			// In that case, we set the value to 0.
			if ( sizeParts[ 0 ] === '9999' ) {
				sizeParts[ 0 ] = '0';
			}

			if ( sizeParts[ 1 ] === '9999' ) {
				sizeParts[ 1 ] = '0';
			}

			return sizeParts;
		}

		/**
		 * Returns a number in a fraction format that represents the shutter speed.
		 * @param Number speed
		 * @return String
		 */
		function formatShutterSpeed( speed ) {
			var denominator;

			// round to one decimal if value > 1s by multiplying it by 10, rounding, then dividing by 10 again
			if ( speed >= 1 ) {
				return Math.round( speed * 10 ) / 10 + 's';
			}

			// If the speed is less than one, we find the denominator by inverting
			// the number. Since cameras usually use rational numbers as shutter
			// speeds, we should get a nice round number. Or close to one in cases
			// like 1/30. So we round it.
			denominator = Math.round( 1 / speed );

			return '1/' + denominator + 's';
		}

		function parseTitleOrDesc( value ) {
			if ( ! value.match( ' ' ) && value.match( '_' ) ) {
				return '';
			}

			return value;
		}

		function updateTitleCaptionAndDesc( data ) {
			var caption = '';
			var title = '';
			var desc = '';
			var captionMainElement;
			var captionInfoExtraElement;
			var titleElement;
			var descriptionElement;

			captionMainElement = carousel.overlay.querySelector( '.jp-carousel-photo-caption' );
			captionInfoExtraElement = carousel.overlay.querySelector( '.jp-carousel-caption' );

			titleElement = carousel.overlay.querySelector( '.jp-carousel-photo-title' );
			descriptionElement = carousel.overlay.querySelector( '.jp-carousel-photo-description' );

			domUtil.hide( captionMainElement );
			domUtil.hide( captionInfoExtraElement );
			domUtil.hide( titleElement );
			domUtil.hide( descriptionElement );

			caption = parseTitleOrDesc( data.caption ) || '';
			title = parseTitleOrDesc( data.title ) || '';
			desc = parseTitleOrDesc( data.desc ) || '';

			if ( caption || title || desc ) {
				if ( caption ) {
					captionMainElement.innerHTML = caption;
					captionInfoExtraElement.innerHTML = caption;

					domUtil.show( captionMainElement );
					domUtil.show( captionInfoExtraElement );
				}

				if ( domUtil.stripHTML( caption ) === domUtil.stripHTML( title ) ) {
					title = '';
				}

				if ( domUtil.stripHTML( caption ) === domUtil.stripHTML( desc ) ) {
					desc = '';
				}

				if ( domUtil.stripHTML( title ) === domUtil.stripHTML( desc ) ) {
					desc = '';
				}

				if ( desc ) {
					descriptionElement.innerHTML = desc;
					domUtil.show( descriptionElement );

					if ( ! title && ! caption ) {
						captionMainElement.innerHTML = domUtil.stripHTML( desc );
						domUtil.show( captionMainElement );
					}
				}

				if ( title ) {
					var plainTitle = domUtil.stripHTML( title );
					titleElement.innerHTML = plainTitle;

					if ( ! caption ) {
						captionMainElement.innerHTML = plainTitle;
						captionInfoExtraElement.innerHTML = plainTitle;

						domUtil.show( captionMainElement );
					}

					domUtil.show( titleElement );
				}
			}
		}

		// updateExif updates the contents of the exif UL (.jp-carousel-image-exif)
		function updateExif( meta ) {
			if ( ! meta || Number( jetpackCarouselStrings.display_exif ) !== 1 ) {
				return false;
			}

			var ul = carousel.info.querySelector( '.jp-carousel-image-meta ul.jp-carousel-image-exif' );
			var html = '';

			for ( var key in meta ) {
				var val = meta[ key ];
				var metaKeys = jetpackCarouselStrings.meta_data || [];

				if ( parseFloat( val ) === 0 || ! val.length || metaKeys.indexOf( key ) === -1 ) {
					continue;
				}

				switch ( key ) {
					case 'focal_length':
						val = val + 'mm';
						break;
					case 'shutter_speed':
						val = formatShutterSpeed( val );
						break;
					case 'aperture':
						val = 'f/' + val;
						break;
				}

				html += '<li><h5>' + jetpackCarouselStrings[ key ] + '</h5>' + val + '</li>';
			}

			ul.innerHTML = html;
			ul.style.removeProperty( 'display' );
		}

		// Update the contents of the jp-carousel-image-download link
		function updateFullSizeLink( currentSlide ) {
			if ( ! currentSlide ) {
				return false;
			}
			var original;
			var origSize = [ currentSlide.attrs.origWidth, currentSlide.attrs.origHeight ];
			var imageLinkParser = document.createElement( 'a' );

			imageLinkParser.href = currentSlide.attrs.src.replace( /\?.+$/, '' );

			// Is this a Photon URL?
			if ( imageLinkParser.hostname.match( /^i[\d]{1}\.wp\.com$/i ) !== null ) {
				original = imageLinkParser.href;
			} else {
				original = currentSlide.attrs.origFile.replace( /\?.+$/, '' );
			}

			var downloadText = carousel.info.querySelector( '.jp-carousel-download-text' );
			var permalink = carousel.info.querySelector( '.jp-carousel-image-download' );

			downloadText.innerHTML = util.applyReplacements(
				jetpackCarouselStrings.download_original,
				origSize
			);
			permalink.setAttribute( 'href', original );
			permalink.style.removeProperty( 'display' );
		}

		function testCommentsOpened( opened ) {
			var commentForm = carousel.container.querySelector( '.jp-carousel-comment-form-container' );
			var isOpened = parseInt( opened, 10 ) === 1;

			if ( isOpened ) {
				domUtil.fadeIn( commentForm );
			} else {
				domUtil.fadeOut( commentForm );
			}
		}

		function fetchComments( attachmentId, offset ) {
			var shouldClear = offset === undefined;
			var commentsIndicator = carousel.info.querySelector(
				'.jp-carousel-icon-comments .jp-carousel-has-comments-indicator'
			);

			commentsIndicator.classList.remove( 'jp-carousel-show' );

			clearInterval( commentInterval );

			if ( ! attachmentId ) {
				return;
			}

			if ( ! offset || offset < 1 ) {
				offset = 0;
			}

			var comments = carousel.info.querySelector( '.jp-carousel-comments' );
			var commentsLoading = carousel.info.querySelector( '#jp-carousel-comments-loading' );
			domUtil.show( commentsLoading );

			if ( shouldClear ) {
				domUtil.hide( comments );
				comments.innerHTML = '';
			}

			var xhr = new XMLHttpRequest();
			var url =
				jetpackCarouselStrings.ajaxurl +
				'?action=get_attachment_comments' +
				'&nonce=' +
				jetpackCarouselStrings.nonce +
				'&id=' +
				attachmentId +
				'&offset=' +
				offset;
			xhr.open( 'GET', url );
			xhr.setRequestHeader( 'X-Requested-With', 'XMLHttpRequest' );

			var onError = function () {
				domUtil.fadeIn( comments );
				domUtil.fadeOut( commentsLoading );
			};

			xhr.onload = function () {
				// Ignore the results if they arrive late and we're now on a different slide.
				if (
					! carousel.currentSlide ||
					carousel.currentSlide.attrs.attachmentId !== attachmentId
				) {
					return;
				}

				var isSuccess = xhr.status >= 200 && xhr.status < 300;
				var data;
				try {
					data = JSON.parse( xhr.responseText );
				} catch ( e ) {
					// Do nothing.
				}

				if ( ! isSuccess || ! data || ! Array.isArray( data ) ) {
					return onError();
				}

				if ( shouldClear ) {
					comments.innerHTML = '';
				}

				for ( var i = 0; i < data.length; i++ ) {
					var entry = data[ i ];
					var comment = document.createElement( 'div' );
					comment.classList.add( 'jp-carousel-comment' );
					comment.setAttribute( 'id', 'jp-carousel-comment-' + entry.id );
					comment.innerHTML =
						'<div class="comment-gravatar">' +
						entry.gravatar_markup +
						'</div>' +
						'<div class="comment-content">' +
						'<div class="comment-author">' +
						entry.author_markup +
						'</div>' +
						'<div class="comment-date">' +
						entry.date_gmt +
						'</div>' +
						entry.content +
						'</div>';
					comments.appendChild( comment );

					// Set the interval to check for a new page of comments.
					clearInterval( commentInterval );
					commentInterval = setInterval( function () {
						if ( carousel.container.scrollTop + 150 > window.innerHeight ) {
							fetchComments( attachmentId, offset + 10 );
							clearInterval( commentInterval );
						}
					}, 300 );
				}

				if ( data.length > 0 ) {
					domUtil.show( comments );
					commentsIndicator.innerText = data.length;
					commentsIndicator.classList.add( 'jp-carousel-show' );
				}

				domUtil.hide( commentsLoading );
			};

			xhr.onerror = onError;

			xhr.send();
		}

		function loadFullImage( slide ) {
			var el = slide.el;
			var attrs = slide.attrs;
			var image = el.querySelector( 'img' );

			if ( ! image.hasAttribute( 'data-loaded' ) ) {
				var hasPreview = !! attrs.previewImage;
				var thumbSize = attrs.thumbSize;

				if ( ! hasPreview || ( thumbSize && el.offsetWidth > thumbSize.width ) ) {
					image.src = attrs.src;
				} else {
					image.src = attrs.previewImage;
				}

				image.setAttribute( 'itemprop', 'image' );
				image.setAttribute( 'data-loaded', 1 );
			}
		}

		function loadBackgroundImage( slide ) {
			var currentSlide = slide.el;

			if ( swiper && swiper.slides ) {
				currentSlide = swiper.slides[ swiper.activeIndex ];
			}

			var image = slide.attrs.originalElement;
			var isLoaded = image.complete && image.naturalHeight !== 0;

			if ( isLoaded ) {
				applyBackgroundImage( slide, currentSlide, image );
				return;
			}

			image.onload = function () {
				applyBackgroundImage( slide, currentSlide, image );
			};
		}

		function applyBackgroundImage( slide, currentSlide, image ) {
			var url = util.getBackgroundImage( image );
			slide.backgroundImage = url;
			currentSlide.style.backgroundImage = 'url(' + url + ')';
			currentSlide.style.backgroundSize = 'cover';
		}

		function clearCommentTextAreaValue() {
			if ( carousel.commentField ) {
				carousel.commentField.value = '';
			}
		}

		function getOriginalDimensions( el ) {
			var size = el.getAttribute( 'data-orig-size' ) || '';

			if ( size ) {
				var parts = size.split( ',' );
				return { width: parseInt( parts[ 0 ], 10 ), height: parseInt( parts[ 1 ], 10 ) };
			} else {
				return {
					width:
						el.getAttribute( 'data-original-width' ) || el.getAttribute( 'width' ) || undefined,
					height:
						el.getAttribute( 'data-original-height' ) || el.getAttribute( 'height' ) || undefined,
				};
			}
		}

		function initCarouselSlides( items, startIndex ) {
			carousel.slides = [];

			var max = calculateMaxSlideDimensions();

			// If the startIndex is not 0 then preload the clicked image first.
			if ( startIndex !== 0 ) {
				var img = new Image();
				img.src = items[ startIndex ].getAttribute( 'data-gallery-src' );
			}

			var useInPageThumbnails = !! domUtil.closest( items[ 0 ], '.tiled-gallery.type-rectangular' );

			// create the 'slide'
			Array.prototype.forEach.call( items, function ( item, i ) {
				var permalinkEl = domUtil.closest( item, 'a' );
				var origFile = item.getAttribute( 'data-orig-file' ) || item.getAttribute( 'src-orig' );
				var attrID =
					item.getAttribute( 'data-attachment-id' ) || item.getAttribute( 'data-id' ) || '0';
				var caption = document.querySelector(
					'img[data-attachment-id="' + attrID + '"] + figcaption'
				);

				if ( caption ) {
					caption = caption.innerHTML;
				} else {
					caption = item.getAttribute( 'data-image-caption' );
				}

				var attrs = {
					originalElement: item,
					attachmentId: attrID,
					commentsOpened: item.getAttribute( 'data-comments-opened' ) || '0',
					imageMeta: domUtil.getJSONAttribute( item, 'data-image-meta' ) || {},
					title: item.getAttribute( 'data-image-title' ) || '',
					desc: item.getAttribute( 'data-image-description' ) || '',
					mediumFile: item.getAttribute( 'data-medium-file' ) || '',
					largeFile: item.getAttribute( 'data-large-file' ) || '',
					origFile: origFile || '',
					thumbSize: { width: item.naturalWidth, height: item.naturalHeight },
					caption: caption || '',
					permalink: permalinkEl && permalinkEl.getAttribute( 'href' ),
					src: origFile || item.getAttribute( 'src' ) || '',
				};

				var tiledGalleryItem = domUtil.closest( item, '.tiled-gallery-item' );
				var tiledCaptionEl =
					tiledGalleryItem && tiledGalleryItem.querySelector( '.tiled-gallery-caption' );
				var tiledCaption = tiledCaptionEl && tiledCaptionEl.innerHTML;
				if ( tiledCaption ) {
					attrs.caption = tiledCaption;
				}

				var origDimensions = getOriginalDimensions( item );

				attrs.origWidth = origDimensions.width || attrs.thumbSize.width;
				attrs.origHeight = origDimensions.height || attrs.thumbSize.height;

				if ( typeof wpcom !== 'undefined' && wpcom.carousel && wpcom.carousel.generateImgSrc ) {
					attrs.src = wpcom.carousel.generateImgSrc( item, max );
				} else {
					attrs.src = selectBestImageUrl( {
						origFile: attrs.src,
						origWidth: attrs.origWidth,
						origHeight: attrs.origHeight,
						maxWidth: max.width,
						maxHeight: max.height,
						mediumFile: attrs.mediumFile,
						largeFile: attrs.largeFile,
					} );
				}

				// Set the final src.
				item.setAttribute( 'data-gallery-src', attrs.src );

				if ( attrs.attachmentId !== '0' ) {
					attrs.title = util.texturize( attrs.title );
					attrs.desc = util.texturize( attrs.desc );
					attrs.caption = util.texturize( attrs.caption );

					// Initially, the image is a 1x1 transparent gif.
					// The preview is shown as a background image on the slide itself.
					var image = new Image();
					image.src = attrs.src;

					var slideEl = document.createElement( 'div' );
					slideEl.classList.add( 'swiper-slide' );
					slideEl.setAttribute( 'itemprop', 'associatedMedia' );
					slideEl.setAttribute( 'itemscope', '' );
					slideEl.setAttribute( 'itemtype', 'https://schema.org/ImageObject' );
					var zoomEl = document.createElement( 'div' );
					zoomEl.classList.add( 'swiper-zoom-container' );

					carousel.gallery.appendChild( slideEl );

					slideEl.appendChild( zoomEl );
					zoomEl.appendChild( image );
					slideEl.setAttribute( 'data-attachment-id', attrs.attachmentId );
					slideEl.setAttribute( 'data-permalink', attrs.permalink );
					slideEl.setAttribute( 'data-orig-file', attrs.origFile );

					if ( useInPageThumbnails ) {
						// Use the image already loaded in the gallery as a preview.
						attrs.previewImage = attrs.src;
					}

					var slide = { el: slideEl, attrs: attrs, index: i };
					carousel.slides.push( slide );
				}
			} );
		}

		function loadSwiper( gallery, options ) {
			if ( ! window.Swiper670 ) {
				var loader = document.querySelector( '#jp-carousel-loading-overlay' );
				domUtil.show( loader );
				var jsScript = document.createElement( 'script' );
				jsScript.id = 'jetpack-carousel-swiper-js';
				jsScript.src = window.jetpackSwiperLibraryPath.url;
				jsScript.async = true;
				jsScript.onload = function () {
					domUtil.hide( loader );
					openCarousel( gallery, options );
				};
				jsScript.onerror = function () {
					domUtil.hide( loader );
				};
				document.head.appendChild( jsScript );
				return;
			}
			openCarousel( gallery, options );
		}

		function openCarousel( gallery, options ) {
			var settings = {
				imgSelector:
					'.gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id], img[data-attachment-id], img[data-id]',
				startIndex: 0,
			};

			var data = domUtil.getJSONAttribute( gallery, 'data-carousel-extra' );
			var tapTimeout;

			if ( ! data ) {
				return; // don't run if the default gallery functions weren't used
			}

			const images = gallery.querySelectorAll( settings.imgSelector );
			if ( ! images.length ) {
				return; // don't run if we found no images in the gallery (somehow it has images that aren't in the media library?)
			}

			initializeCarousel();

			if ( carousel.isOpen ) {
				return; // don't open if already opened
			}
			carousel.isOpen = true;

			// make sure to stop the page from scrolling behind the carousel overlay, so we don't trigger
			// infiniscroll for it when enabled (Reader, theme infiniscroll, etc).
			originalOverflow = getComputedStyle( document.body ).overflow;
			document.body.style.overflow = 'hidden';
			// prevent html from overflowing on some of the new themes.
			originalHOverflow = getComputedStyle( document.documentElement ).overflow;
			document.documentElement.style.overflow = 'hidden';
			scrollPos = window.scrollY || window.pageYOffset || 0;

			carousel.container.setAttribute( 'data-carousel-extra', JSON.stringify( data ) );
			stat( [ 'open', 'view_image' ] );

			// If options exist, lets merge them
			// with our default settings
			for ( var option in options || {} ) {
				settings[ option ] = options[ option ];
			}

			if ( settings.startIndex === -1 ) {
				settings.startIndex = 0; // -1 returned if can't find index, so start from beginning
			}

			domUtil.emitEvent( carousel.overlay, 'jp_carousel.beforeOpen' );
			carousel.gallery.innerHTML = '';

			// Need to set the overlay manually to block or swiper does't initialise properly.
			carousel.overlay.style.opacity = 1;
			carousel.overlay.style.display = 'block';

			initCarouselSlides( images, settings.startIndex );

			swiper = new window.Swiper670( '.jp-carousel-swiper-container', {
				centeredSlides: true,
				zoom: true,
				loop: carousel.slides.length > 1,
				// Turn off interactions and hide navigation arrows if there is only one slide.
				enabled: carousel.slides.length > 1,
				pagination: {
					el: '.jp-swiper-pagination',
					clickable: true,
				},
				navigation: {
					nextEl: '.jp-swiper-button-next',
					prevEl: '.jp-swiper-button-prev',
				},
				initialSlide: settings.startIndex,
				on: {
					init: function () {
						selectSlideAtIndex( settings.startIndex );
					},
				},
				preventClicks: false,
				preventClicksPropagation: false,
				preventInteractionOnTransition: ! domUtil.isTouch(),
				threshold: 5,
			} );

			swiper.on( 'slideChange', function ( swiper ) {
				var index;
				// Swiper indexes slides from 1, plus when looping to left last slide ends up
				// as 0 and looping to right first slide as total slides + 1. These are adjusted
				// here to match index of carousel.slides.
				if ( swiper.activeIndex === 0 ) {
					index = carousel.slides.length - 1;
				} else if ( swiper.activeIndex === carousel.slides.length + 1 ) {
					index = 0;
				} else {
					index = swiper.activeIndex - 1;
				}
				selectSlideAtIndex( index );

				carousel.overlay.classList.remove( 'jp-carousel-hide-controls' );
			} );

			swiper.on( 'zoomChange', function ( swiper, scale ) {
				if ( scale > 1 ) {
					carousel.overlay.classList.add( 'jp-carousel-hide-controls' );
				}

				if ( scale === 1 ) {
					carousel.overlay.classList.remove( 'jp-carousel-hide-controls' );
				}
			} );

			swiper.on( 'doubleTap', function ( swiper ) {
				clearTimeout( tapTimeout );
				if ( swiper.zoom.scale === 1 ) {
					var zoomTimeout = setTimeout( function () {
						carousel.overlay.classList.remove( 'jp-carousel-hide-controls' );
						clearTimeout( zoomTimeout );
					}, 150 );
				}
			} );

			swiper.on( 'tap', function () {
				if ( swiper.zoom.scale > 1 ) {
					tapTimeout = setTimeout( function () {
						carousel.overlay.classList.toggle( 'jp-carousel-hide-controls' );
					}, 150 );
				}
			} );

			domUtil.fadeIn( carousel.overlay, function () {
				domUtil.emitEvent( carousel.overlay, 'jp_carousel.afterOpen' );
			} );
		}

		// Register the event listeners for starting the gallery
		document.body.addEventListener( 'click', handleInteraction );
		document.body.addEventListener( 'keydown', handleInteraction );
		document.querySelectorAll( galleryItemSelector + 'img' ).forEach( function ( galleryImage ) {
			if ( shouldOpenModal( galleryImage ) ) {
				makeGalleryImageAccessible( galleryImage );
			}
		} );

		function handleInteraction( e ) {
			if ( e.type === 'click' ) {
				handleClick( e );
				return;
			}

			if ( e.type === 'keydown' ) {
				const parentElement = document.activeElement.parentElement;
				const isParentCarouselContainer =
					parentElement && parentElement.classList.contains( 'tiled-gallery__item' );

				if ( ( e.key === ' ' || e.key === 'Enter' ) && isParentCarouselContainer ) {
					handleClick( e );
					return;
				}
			}
		}

		function shouldOpenModal( el ) {
			var parent = el.parentElement;
			var grandparent = parent.parentElement;

			// If Gallery is made up of individual Image blocks check for custom link before
			// loading carousel. The custom link may be the parent or could be a descendant
			// of the parent if the image has rounded corners.
			var parentHref = null;
			if ( grandparent && grandparent.classList.contains( 'wp-block-image' ) ) {
				parentHref = parent.getAttribute( 'href' );
			} else if (
				parent &&
				parent.classList.contains( 'wp-block-image' ) &&
				parent.querySelector( ':scope > a' )
			) {
				parentHref = parent.querySelector( ':scope > a' ).getAttribute( 'href' );
			}

			// If the link does not point to the attachment or media file then assume Image has
			// a custom link so don't load the carousel.
			if (
				parentHref &&
				parentHref.split( '?' )[ 0 ] !== el.getAttribute( 'data-orig-file' ).split( '?' )[ 0 ] &&
				parentHref !== el.getAttribute( 'data-permalink' )
			) {
				return false;
			}

			// Do not open the modal if we are looking at a gallery caption from before WP5, which may contain a link.
			if ( parent.classList.contains( 'gallery-caption' ) ) {
				return false;
			}

			// Do not open the modal if we are looking at a caption of a gallery block, which may contain a link.
			if ( domUtil.matches( parent, 'figcaption' ) ) {
				return false;
			}

			return true;
		}

		function handleClick( e ) {
			var isCompatible =
				window.CSS && window.CSS.supports && window.CSS.supports( 'display', 'grid' );

			// IE11 support is being dropped in August 2021. The new swiper.js libray is not IE11 compat
			// so just default to opening individual image attachment/media pages for IE.
			if ( ! isCompatible ) {
				return;
			}

			var target = e.target;
			var gallery = domUtil.closest( target, gallerySelector );

			if ( gallery ) {
				if ( ! testForData( gallery ) ) {
					return;
				}

				if ( ! shouldOpenModal( target ) ) {
					return;
				}

				// Set height to auto.
				// Fix some themes where closing carousel brings view back to top.
				document.documentElement.style.height = 'auto';

				e.preventDefault();

				// Stopping propagation in case there are parent elements
				// with .gallery or .tiled-gallery class
				e.stopPropagation();

				var item = domUtil.closest( target, itemSelector );
				var index = Array.prototype.indexOf.call( gallery.querySelectorAll( itemSelector ), item );
				loadSwiper( gallery, { startIndex: index } );
			}
		}

		// Handle lightbox (single image gallery) for images linking to 'Attachment Page'.
		if ( Number( jetpackCarouselStrings.single_image_gallery ) === 1 ) {
			processSingleImageGallery();
			document.body.addEventListener( 'is.post-load', function () {
				processSingleImageGallery();
			} );
		}

		// Makes carousel work on page load and when back button leads to same URL with carousel hash
		// (i.e. no actual document.ready trigger).
		window.addEventListener( 'hashchange', function () {
			var hashRegExp = /jp-carousel-(\d+)/;

			if ( ! window.location.hash || ! hashRegExp.test( window.location.hash ) ) {
				if ( carousel.isOpen ) {
					closeCarousel();
				}

				return;
			}

			if ( window.location.hash === lastKnownLocationHash && carousel.isOpen ) {
				return;
			}

			if ( window.location.hash && carousel.gallery && ! carousel.isOpen && history.back ) {
				history.back();
				return;
			}

			lastKnownLocationHash = window.location.hash;
			var matchList = window.location.hash.match( hashRegExp );
			var attachmentId = parseInt( matchList[ 1 ], 10 );
			var galleries = document.querySelectorAll( gallerySelector );

			// Find the first thumbnail that matches the attachment ID in the location
			// hash, then open the gallery that contains it.
			for ( var i = 0; i < galleries.length; i++ ) {
				var gallery = galleries[ i ];
				var selected;

				var images = gallery.querySelectorAll( 'img' );
				for ( var j = 0; j < images.length; j++ ) {
					if (
						parseInt( images[ j ].getAttribute( 'data-attachment-id' ), 10 ) === attachmentId ||
						parseInt( images[ j ].getAttribute( 'data-id' ), 10 ) === attachmentId
					) {
						selected = j;
						break;
					}
				}

				if ( selected !== undefined ) {
					openOrSelectSlide( gallery, selected );
					break;
				}
			}
		} );

		if ( window.location.hash ) {
			domUtil.emitEvent( window, 'hashchange' );
		}
	}

	if ( document.readyState !== 'loading' ) {
		init();
	} else {
		document.addEventListener( 'DOMContentLoaded', init );
	}
} )();

Youez - 2016 - github.com/yon3zu
LinuXploit