Last active
December 30, 2025 23:56
-
-
Save dpw1/94e38dec634f0348781afb924d848df6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% if template contains 'product' %} | |
| <div | |
| style="height:0;width:0;display:none" | |
| data_ezfy_zoom_type_mobile="{{ settings.ezfy_zoom_type_mobile }}" | |
| data_ezfy_zoom_type="{{ settings.ezfy_zoom_type }}" | |
| data_ezfy_zoom_block_slider="false" | |
| ></div> | |
| <style> | |
| .pswp{display:none;position:absolute;width:100%;height:100%;left:0;top:0;overflow:hidden;-ms-touch-action:none;touch-action:none;z-index:1500;-webkit-text-size-adjust:100%;-webkit-backface-visibility:hidden;outline:0}.pswp *{-webkit-box-sizing:border-box;box-sizing:border-box}.pswp img{max-width:none}.pswp--animate_opacity{opacity:.001;will-change:opacity;-webkit-transition:opacity 333ms cubic-bezier(.4,0,.22,1);transition:opacity 333ms cubic-bezier(.4,0,.22,1)}.pswp--open{display:block}.pswp--zoom-allowed .pswp__img{cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.pswp--zoomed-in .pswp__img{cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.pswp--dragging .pswp__img{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.pswp__bg{position:absolute;left:0;top:0;width:100%;height:100%;background:#000;opacity:0;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;will-change:opacity}.pswp__scroll-wrap{position:absolute;left:0;top:0;width:100%;height:100%;overflow:hidden}.pswp__container,.pswp__zoom-wrap{-ms-touch-action:none;touch-action:none;position:absolute;left:0;right:0;top:0;bottom:0}.pswp__container,.pswp__img{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.pswp__zoom-wrap{position:absolute;width:100%;-webkit-transform-origin:left top;-ms-transform-origin:left top;transform-origin:left top;-webkit-transition:-webkit-transform 333ms cubic-bezier(.4,0,.22,1);transition:transform 333ms cubic-bezier(.4,0,.22,1)}.pswp__bg{will-change:opacity;-webkit-transition:opacity 333ms cubic-bezier(.4,0,.22,1);transition:opacity 333ms cubic-bezier(.4,0,.22,1)}.pswp--animated-in .pswp__bg,.pswp--animated-in .pswp__zoom-wrap{-webkit-transition:none;transition:none}.pswp__container,.pswp__zoom-wrap{-webkit-backface-visibility:hidden}.pswp__item{position:absolute;left:0;right:0;top:0;bottom:0;overflow:hidden}.pswp__img{position:absolute;width:auto;height:auto;top:0;left:0}.pswp__img--placeholder{-webkit-backface-visibility:hidden}.pswp__img--placeholder--blank{background:#222}.pswp--ie .pswp__img{width:100%!important;height:auto!important;left:0;top:0}.pswp__error-msg{position:absolute;left:0;top:50%;width:100%;text-align:center;font-size:14px;line-height:16px;margin-top:-8px;color:#ccc}.pswp__error-msg a{color:#ccc;text-decoration:underline} | |
| .pswp__button{width:44px;height:44px;position:relative;background:0 0;cursor:pointer;overflow:visible;-webkit-appearance:none;display:block;border:0;padding:0;margin:0;float:right;opacity:.75;-webkit-transition:opacity .2s;transition:opacity .2s;-webkit-box-shadow:none;box-shadow:none}.pswp__button:focus,.pswp__button:hover{opacity:1}.pswp__button:active{outline:0;opacity:.9}.pswp__button::-moz-focus-inner{padding:0;border:0}.pswp__ui--over-close .pswp__button--close{opacity:1}.pswp__button,.pswp__button--arrow--left:before,.pswp__button--arrow--right:before{background:url(default-skin.png) 0 0 no-repeat;background-size:264px 88px;width:44px;height:44px}@media (-webkit-min-device-pixel-ratio:1.1),(-webkit-min-device-pixel-ratio:1.09375),(min-resolution:105dpi),(min-resolution:1.1dppx){.pswp--svg .pswp__button,.pswp--svg .pswp__button--arrow--left:before,.pswp--svg .pswp__button--arrow--right:before{background-image:url(default-skin.svg)}.pswp--svg .pswp__button--arrow--left,.pswp--svg .pswp__button--arrow--right{background:0 0}}.pswp__button--close{background-position:0 -44px}.pswp__button--share{background-position:-44px -44px}.pswp__button--fs{display:none}.pswp--supports-fs .pswp__button--fs{display:block}.pswp--fs .pswp__button--fs{background-position:-44px 0}.pswp__button--zoom{display:none;background-position:-88px 0}.pswp--zoom-allowed .pswp__button--zoom{display:block}.pswp--zoomed-in .pswp__button--zoom{background-position:-132px 0}.pswp--touch .pswp__button--arrow--left,.pswp--touch .pswp__button--arrow--right{visibility:hidden}.pswp__button--arrow--left,.pswp__button--arrow--right{background:0 0;top:50%;margin-top:-50px;width:70px;height:100px;position:absolute}.pswp__button--arrow--left{left:0}.pswp__button--arrow--right{right:0}.pswp__button--arrow--left:before,.pswp__button--arrow--right:before{content:'';top:35px;background-color:rgba(0,0,0,.3);height:30px;width:32px;position:absolute}.pswp__button--arrow--left:before{left:6px;background-position:-138px -44px}.pswp__button--arrow--right:before{right:6px;background-position:-94px -44px}.pswp__counter,.pswp__share-modal{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pswp__share-modal{display:block;background:rgba(0,0,0,.5);width:100%;height:100%;top:0;left:0;padding:10px;position:absolute;z-index:1600;opacity:0;-webkit-transition:opacity .25s ease-out;transition:opacity .25s ease-out;-webkit-backface-visibility:hidden;will-change:opacity}.pswp__share-modal--hidden{display:none}.pswp__share-tooltip{z-index:1620;position:absolute;background:#fff;top:56px;border-radius:2px;display:block;width:auto;right:44px;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.25);box-shadow:0 2px 5px rgba(0,0,0,.25);-webkit-transform:translateY(6px);-ms-transform:translateY(6px);transform:translateY(6px);-webkit-transition:-webkit-transform .25s;transition:transform .25s;-webkit-backface-visibility:hidden;will-change:transform}.pswp__share-tooltip a{display:block;padding:8px 12px;color:#000;text-decoration:none;font-size:14px;line-height:18px}.pswp__share-tooltip a:hover{text-decoration:none;color:#000}.pswp__share-tooltip a:first-child{border-radius:2px 2px 0 0}.pswp__share-tooltip a:last-child{border-radius:0 0 2px 2px}.pswp__share-modal--fade-in{opacity:1}.pswp__share-modal--fade-in .pswp__share-tooltip{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.pswp--touch .pswp__share-tooltip a{padding:16px 12px}a.pswp__share--facebook:before{content:'';display:block;width:0;height:0;position:absolute;top:-12px;right:15px;border:6px solid transparent;border-bottom-color:#fff;-webkit-pointer-events:none;-moz-pointer-events:none;pointer-events:none}a.pswp__share--facebook:hover{background:#3e5c9a;color:#fff}a.pswp__share--facebook:hover:before{border-bottom-color:#3e5c9a}a.pswp__share--twitter:hover{background:#55acee;color:#fff}a.pswp__share--pinterest:hover{background:#ccc;color:#ce272d}a.pswp__share--download:hover{background:#ddd}.pswp__counter{position:absolute;left:0;top:0;height:44px;font-size:13px;line-height:44px;color:#fff;opacity:.75;padding:0 10px}.pswp__caption{position:absolute;left:0;bottom:0;width:100%;min-height:44px}.pswp__caption small{font-size:11px;color:#bbb}.pswp__caption__center{text-align:left;max-width:420px;margin:0 auto;font-size:13px;padding:10px;line-height:20px;color:#ccc}.pswp__caption--empty{display:none}.pswp__caption--fake{visibility:hidden}.pswp__preloader{width:44px;height:44px;position:absolute;top:0;left:50%;margin-left:-22px;opacity:0;-webkit-transition:opacity .25s ease-out;transition:opacity .25s ease-out;will-change:opacity;direction:ltr}.pswp__preloader__icn{width:20px;height:20px;margin:12px}.pswp__preloader--active{opacity:1}.pswp__preloader--active .pswp__preloader__icn{background:url(preloader.gif) 0 0 no-repeat}.pswp--css_animation .pswp__preloader--active{opacity:1}.pswp--css_animation .pswp__preloader--active .pswp__preloader__icn{-webkit-animation:clockwise .5s linear infinite;animation:clockwise .5s linear infinite}.pswp--css_animation .pswp__preloader--active .pswp__preloader__donut{-webkit-animation:donut-rotate 1s cubic-bezier(.4,0,.22,1) infinite;animation:donut-rotate 1s cubic-bezier(.4,0,.22,1) infinite}.pswp--css_animation .pswp__preloader__icn{background:0 0;opacity:.75;width:14px;height:14px;position:absolute;left:15px;top:15px;margin:0}.pswp--css_animation .pswp__preloader__cut{position:relative;width:7px;height:14px;overflow:hidden}.pswp--css_animation .pswp__preloader__donut{-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;border:2px solid #fff;border-radius:50%;border-left-color:transparent;border-bottom-color:transparent;position:absolute;top:0;left:0;background:0 0;margin:0}@media screen and (max-width:1024px){.pswp__preloader{position:relative;left:auto;top:auto;margin:0;float:right}}@-webkit-keyframes clockwise{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes clockwise{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes donut-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}50%{-webkit-transform:rotate(-140deg);transform:rotate(-140deg)}100%{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes donut-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}50%{-webkit-transform:rotate(-140deg);transform:rotate(-140deg)}100%{-webkit-transform:rotate(0);transform:rotate(0)}}.pswp__ui{-webkit-font-smoothing:auto;visibility:visible;opacity:1;z-index:1550}.pswp__top-bar{position:absolute;left:0;top:0;height:44px;width:100%}.pswp--has_mouse .pswp__button--arrow--left,.pswp--has_mouse .pswp__button--arrow--right,.pswp__caption,.pswp__top-bar{-webkit-backface-visibility:hidden;will-change:opacity;-webkit-transition:opacity 333ms cubic-bezier(.4,0,.22,1);transition:opacity 333ms cubic-bezier(.4,0,.22,1)}.pswp--has_mouse .pswp__button--arrow--left,.pswp--has_mouse .pswp__button--arrow--right{visibility:visible}.pswp__caption,.pswp__top-bar{background-color:rgba(0,0,0,.5)}.pswp__ui--fit .pswp__caption,.pswp__ui--fit .pswp__top-bar{background-color:rgba(0,0,0,.3)}.pswp__ui--idle .pswp__top-bar{opacity:0}.pswp__ui--idle .pswp__button--arrow--left,.pswp__ui--idle .pswp__button--arrow--right{opacity:0}.pswp__ui--hidden .pswp__button--arrow--left,.pswp__ui--hidden .pswp__button--arrow--right,.pswp__ui--hidden .pswp__caption,.pswp__ui--hidden .pswp__top-bar{opacity:.001}.pswp__ui--one-slide .pswp__button--arrow--left,.pswp__ui--one-slide .pswp__button--arrow--right,.pswp__ui--one-slide .pswp__counter{display:none}.pswp__element--disabled{display:none!important}.pswp--minimal--dark .pswp__top-bar{background:0 0} | |
| </style> | |
| <style> | |
| /* Images */ | |
| .product-single__photos, | |
| .product-single__media-wrapper, | |
| [id*='Slider-Gallery'] > li, | |
| [id*='Slide-template'], | |
| .EzfyZoom-button{ | |
| cursor: -moz-zoom-in; | |
| cursor: -webkit-zoom-in; | |
| cursor: zoom-in; | |
| } | |
| .FeaturedImage--block-lightbox *{ | |
| //pointer-events: none; | |
| } | |
| .product-single__media-group [id*='FeaturedMedia'][tabindex]{ | |
| position: relative; | |
| } | |
| /* Zoom button */ | |
| .EzfyZoom-button *{ | |
| pointer-events: none; | |
| } | |
| [id] .EzfyZoom-button:hover{ | |
| /* background: white !important; */ | |
| } | |
| [id] .EzfyZoom-button svg{ | |
| fill: black !important; | |
| width: 1.2rem; | |
| height: 1.4rem; | |
| } | |
| [id] [id] .EzfyZoom-button{ | |
| position: absolute; | |
| left: 0; | |
| right: 0; | |
| top: 0; | |
| bottom: 0; | |
| width: 100%; | |
| height: 100%; | |
| opacity: 0; | |
| z-index: 0; | |
| } | |
| modal-opener:hover .EzfyZoom-button{ | |
| /* opacity: 1 !important; */ | |
| } | |
| .product__media-toggle{ | |
| pointer-events: none; | |
| } | |
| @media (max-width: 750px){ | |
| [data-is-video] .product__media-toggle{ | |
| pointer-events: auto !important; | |
| } | |
| } | |
| @keyframes fade-in { | |
| 0% { | |
| opacity: 0; | |
| } | |
| 100% { | |
| opacity: 1; | |
| } | |
| } | |
| [id*='FeaturedMedia'] .EzfyZoom-button, | |
| .product-single__photo .EzfyZoom-button{ | |
| -webkit-animation: fade-in .5s cubic-bezier(0.39, 0.575, 0.565, 1) both; | |
| animation: fade-in .5s cubic-bezier(0.39, 0.575, 0.565, 1) both; | |
| } | |
| .EzfyZoom-button:active, | |
| .EzfyZoom-button:visited, | |
| .EzfyZoom-button:focus{ | |
| background: unset !important; | |
| } | |
| /* PhotoSwipe general styles | |
| ================================ */ | |
| #ezfyLightbox{ | |
| background: var(--gradient-background); | |
| } | |
| #ezfyLightbox .pswp__custom-controls{ | |
| position: absolute; | |
| display: flex !important; | |
| bottom: 30px; | |
| left: 0; | |
| right: 0; | |
| transform: translateY(0); | |
| transition: transform .32s; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| #ezfyLightbox .pswp__button[class*='arrow']{ | |
| margin-top: unset; | |
| } | |
| #ezfyLightbox .pswp__custom-controls .pswp__button{ | |
| background: white; | |
| border-radius: 50%; | |
| width: 49px; | |
| height: 49px; | |
| opacity: 1; | |
| position: relative; | |
| box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px; | |
| transition: unset !important; | |
| transform: unset !important; | |
| visibility: visible; | |
| -webkit-tap-highlight-color: rgba(255, 255, 255, 0); | |
| } | |
| #ezfyLightbox .pswp__custom-controls .pswp__button svg{ | |
| width: 13px !important; | |
| height: 13px !important; | |
| margin: 8px; | |
| pointer-events: none; | |
| } | |
| #ezfyLightbox svg{ | |
| pointer-events: none; | |
| } | |
| #ezfyLightbox .pswp__button:before { | |
| display: none; | |
| } | |
| .pswp__ui--hidden .pswp__custom-controls{ | |
| transform: translateY(100px) !important; | |
| } | |
| #ezfyLightbox .pswp__custom-controls .pswp__button--close{ | |
| width: 60px; | |
| height: 60px; | |
| margin-left: 25px; | |
| margin-right: 25px; | |
| } | |
| #ezfyLightbox .pswp__custom-controls .pswp__button--close svg{ | |
| position: relative; | |
| top: 2px; | |
| } | |
| #ezfyLightbox .pswp__top-bar{ | |
| display: none; | |
| } | |
| .EzfyZoom-button{ | |
| z-index: 10; | |
| } | |
| .ezfy-lightbox--block .pswp__button--close{ | |
| pointer-events: none; | |
| } | |
| /* Custom styles | |
| ================================ */ | |
| #ezfyLightbox .pswp__bg{ | |
| background: white !important; | |
| } | |
| .product__media-icon{ | |
| /* display: none !important; */ | |
| pointer-events: none; | |
| } | |
| </style> | |
| <div id="ezfyLightbox" class="pswp" tabindex="-1" role="dialog" aria-hidden="true"> | |
| <!-- | |
| Background of PhotoSwipe. | |
| It's a separate element as animating opacity is faster than rgba(). | |
| --> | |
| <div class="pswp__bg"></div> | |
| <!-- Slides wrapper with overflow:hidden. --> | |
| <div class="pswp__scroll-wrap"> | |
| <!-- | |
| Container that holds slides. | |
| PhotoSwipe keeps only 3 of them in the DOM to save memory. | |
| Don't modify these 3 pswp__item elements, data is added later on. | |
| --> | |
| <div class="pswp__container"> | |
| <div class="pswp__item"></div> | |
| <div class="pswp__item"></div> | |
| <div class="pswp__item"></div> | |
| </div> | |
| <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. --> | |
| <div class="pswp__ui pswp__ui--hidden"> | |
| <div class="pswp__top-bar"> | |
| <!-- Controls are self-explanatory. Order can be changed. --> | |
| <div class="pswp__counter"></div> | |
| <button class="pswp__button pswp__button--share" title="Share"></button> | |
| <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button> | |
| <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button> | |
| <!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR --> | |
| <!-- element will get class pswp__preloader--active when preloader is running --> | |
| <div class="pswp__preloader"> | |
| <div class="pswp__preloader__icn"> | |
| <div class="pswp__preloader__cut"> | |
| <div class="pswp__preloader__donut"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"> | |
| <div class="pswp__share-tooltip"></div> | |
| </div> | |
| <div class="pswp__custom-controls"> | |
| <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"> | |
| <svg | |
| aria-hidden="true" | |
| focusable="false" | |
| role="presentation" | |
| class="icon icon-arrow-left" | |
| viewBox="0 0 284.49 498.98" | |
| > | |
| <path d="M249.49 0a35 35 0 0 1 24.75 59.75L84.49 249.49l189.75 189.74a35.002 35.002 0 1 1-49.5 49.5L10.25 274.24a35 35 0 0 1 0-49.5L224.74 10.25A34.89 34.89 0 0 1 249.49 0z"></path> | |
| </svg> | |
| </button> | |
| <button class="pswp__button pswp__button--close" title="Close (Esc)"> | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| id="Capa_1" | |
| enable-background="new 0 0 413.348 413.348" | |
| height="512" | |
| viewBox="0 0 413.348 413.348" | |
| width="512" | |
| > | |
| <path d="m413.348 24.354-24.354-24.354-182.32 182.32-182.32-182.32-24.354 24.354 182.32 182.32-182.32 182.32 24.354 24.354 182.32-182.32 182.32 182.32 24.354-24.354-182.32-182.32z"/> | |
| </svg> | |
| </button> | |
| <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"> | |
| <svg | |
| aria-hidden="true" | |
| focusable="false" | |
| role="presentation" | |
| class="icon icon-arrow-right" | |
| viewBox="0 0 284.49 498.98" | |
| > | |
| <path d="M35 498.98a35 35 0 0 1-24.75-59.75l189.74-189.74L10.25 59.75a35.002 35.002 0 0 1 49.5-49.5l214.49 214.49a35 35 0 0 1 0 49.5L59.75 488.73A34.89 34.89 0 0 1 35 498.98z"></path> | |
| </svg> | |
| </button> | |
| </div> | |
| <div class="pswp__caption"> | |
| <div class="pswp__caption__center"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| /*ezfyignore*/ | |
| {% assign product_images = product.media | where: "media_type", "image" %} | |
| window.ezfyDawnThemeZoomImages = [ | |
| {% for media in product_images %} | |
| { | |
| id: "{{ media.id }}", | |
| index: {{ forloop.index }}, | |
| variantId: "{{ product.variants[forloop.index].id }}", | |
| imagePositionVariant: "{{ product.variants[media.position].id }}", | |
| imagePosition: {{ media.position }}, | |
| src: "{{ media.preview_image.src }}", | |
| isVariantGroup: false | |
| }, | |
| {% endfor %} | |
| {% for variant in product.variants %} | |
| {% if variant.metafields.custom.variant_gallery.value %} | |
| {% for gallery in variant.metafields.custom.variant_gallery.value %} | |
| {% assign image = gallery | image_url %} | |
| {% assign image_object = gallery | image_url: width: 500 %} | |
| {% assign image_width = image_object.width %} | |
| {% assign image_height = image_object.height %} | |
| { | |
| variantId: "{{ variant.id }}", | |
| imagePositionVariant: "{{ variant.id }}", | |
| imagePosition: {{ forloop.index | plus: 1 }}, | |
| src: "{{ image | escape }}", | |
| width: parseInt("{{ image_width }}"), | |
| height: parseInt("{{ image_height }}"), | |
| isVariantGroup: true | |
| }, | |
| {% endfor %} | |
| {% endif %} | |
| {% endfor %} | |
| ] | |
| </script> | |
| <script> | |
| window.ezfyDawnThemeZoom = window.ezfyDawnThemeZoom || {}; | |
| ezfyDawnThemeZoom = (function() { | |
| let IS_DAWN_SLIDER = false; | |
| const HAS_VARIANT_GROUPING = (typeof window.productVariantGalleries !== "undefined" && window.productVariantGalleries !== null); | |
| const DELAY_AFTER_LOADING_PHOTO_SWIPE = 30; | |
| const isDawnSliderInstalled = () => { | |
| const $slider = document.querySelector(`[data-ezfy-dawn-slider]`) | |
| if ($slider) { | |
| IS_DAWN_SLIDER = true; | |
| return true; | |
| } | |
| return false; | |
| } | |
| const CSS_PRODUCT_IMAGE_TAG = `slider-component modal-opener:not([class*='video']) .product__media > img, | |
| ul li[class*='image'] modal-opener:not([class*='video']) .product__media > img` | |
| const CSS_PRODUCT_IMAGE_PARENT = `slider-component modal-opener:not([class*='video']) .product__media, ul li[class*='image'] modal-opener:not([class*='video']) .product__media` | |
| const CSS_PARENT = `slider-component`; | |
| const CSS_INDIVIDUAL_SLIDE = `.product__media` | |
| let CSS_INDIVIDUAL_SLIDES_WITHOUT_VIDEO = ` | |
| ul li[class*='image']:not([data-is-video]) modal-opener:not([class*='video']) .product__media:not([class*='--variant']), | |
| slider-component li:not(.product__media-item--variant):not([data-is-video]) > modal-opener:not([class*='video']) .product__media:not([class*='--variant']), | |
| [id^='Slider-Gallery'] > li:not(.product__media-item--variant):not([data-is-video]) > modal-opener:not([class*='video']) .product__media:not([class*='--variant']), | |
| [id^='Slider-Gallery'] > [id]:nth-child(1) > modal-opener:not([class*='video']) .product__media:not([class*='--variant']), | |
| [id*='Slider-Galler'][class*='Ezfy'] li:not(.product__media-item--variant):not([data-is-video]) > modal-opener:not([class*='video']) .product__media:not([class*='--variant']), | |
| [id*='Slider-Galler'][class*='Ezfy'] > [id]:nth-child(1) > modal-opener:not([class*='video']) .product__media:not([class*='--variant']), | |
| [id*='Slider-Galler'] *:not([class*='video']):not([data-is-video]) modal-opener:not([class*='video']) .product__media:not([class*='--variant'])` | |
| let CSS_THUMBNAILS = `[id*='Slider-Thumbnails'] > li, .large-image + slider-component li` | |
| const CLASS_INDIVIDUAL_SLIDE = [`product-single__photo`, ]; | |
| const CSS_VIDEOS_SELECTOR = `[id*='Slider'] li modal-opener[class*='video']`; | |
| if (getThemeVersion() >= 700 && !isDawnSliderInstalled()){ | |
| CSS_INDIVIDUAL_SLIDES_WITHOUT_VIDEO = ` | |
| [id*='Slider-Galler'] > *:nth-child(1):not([class*='video']):not([data-is-video]) modal-opener:not([class*='video']) .product__media:not([class*='--variant']), | |
| [id*='Slider-Galler'] > *:not([class*='--variant']):not([class*='video']):not([data-is-video]) modal-opener:not([class*='video']) .product__media:not([class*='--variant'])` | |
| CSS_THUMBNAILS = `[id*='Slider-Thumbnails'] > li:not([class*='--variant'])`; | |
| } | |
| if (window.productVariantGalleries ){ | |
| } | |
| function getThemeVersion(){ | |
| if (!window.hasOwnProperty("BOOMR") || !window.BOOMR.hasOwnProperty("themeVersion")){ | |
| return 0; | |
| } | |
| return parseInt(window.BOOMR.themeVersion.replaceAll(".", "")); | |
| } | |
| function _isMobile() { | |
| return window.matchMedia("(max-width: 749px)").matches | |
| } | |
| const ZOOM_TYPE = (() => { | |
| if (_isMobile()) { | |
| let $el = document.querySelector(`[data_ezfy_zoom_type_mobile]`); | |
| return $el.getAttribute(`data_ezfy_zoom_type_mobile`); | |
| } | |
| let $el = document.querySelector(`[data_ezfy_zoom_type]`); | |
| return $el.getAttribute(`data_ezfy_zoom_type`); | |
| })(); | |
| const options = { | |
| blockSlider: _getAttributeOption(`data_ezfy_zoom_block_slider`) | |
| } | |
| function _getAttributeOption(dataAttribute) { | |
| const element = document.querySelector(`[${dataAttribute}]`); | |
| if (!element) { | |
| return null; | |
| } | |
| const attr = element.getAttribute(dataAttribute); | |
| if (attr === 'true') { | |
| return true; | |
| } else if (attr === 'false') { | |
| return false | |
| } else { | |
| return attr; | |
| } | |
| } | |
| const IMG_API_ENDPOINT = 'https://lqtnxbrtbxoxamwfsovq.supabase.co'; | |
| const IMG_API_KEY = 'sb_publishable_OfPCuf5Yc4ZYxGrHNKa_ow_FRNiCWRV'; | |
| const IMG_CACHE_DURATION = 43200000; | |
| function IMG_log(msg, data) { | |
| if (typeof IMG_DEBUG_MODE !== 'undefined' && IMG_DEBUG_MODE) { | |
| console.log('[IMG Cache]', msg, data || ''); | |
| } | |
| } | |
| function IMG_getLocalCache() { | |
| const shop = window.Shopify?.shop; | |
| if (!shop) return null; | |
| const key = '_img_cache_' + btoa(shop).substring(0, 10).replace(/[^a-zA-Z0-9]/g, ''); | |
| const stored = localStorage.getItem(key); | |
| if (!stored) return null; | |
| try { | |
| return JSON.parse(atob(stored)); | |
| } catch (e) { | |
| IMG_log('Cache parse error', e); | |
| return null; | |
| } | |
| } | |
| function IMG_setLocalCache(data) { | |
| const shop = window.Shopify?.shop; | |
| if (!shop) return; | |
| const key = '_img_cache_' + btoa(shop).substring(0, 10).replace(/[^a-zA-Z0-9]/g, ''); | |
| const encoded = btoa(JSON.stringify(data)); | |
| localStorage.setItem(key, encoded); | |
| IMG_log('Cache saved', data); | |
| } | |
| async function IMG_fetchRemoteData() { | |
| const shop = window.Shopify?.shop; | |
| if (!shop) { | |
| IMG_log('No shop identifier'); | |
| return null; | |
| } | |
| try { | |
| IMG_log('Fetching remote data for', shop); | |
| // Check if store exists | |
| const checkUrl = `${IMG_API_ENDPOINT}/rest/v1/stores?shop_domain=eq.${shop}&select=*`; | |
| const checkResponse = await fetch(checkUrl, { | |
| method: 'GET', | |
| headers: { | |
| 'apikey': IMG_API_KEY, | |
| 'Authorization': `Bearer ${IMG_API_KEY}`, | |
| 'Content-Type': 'application/json' | |
| }, | |
| signal: AbortSignal.timeout(5000) | |
| }); | |
| if (!checkResponse.ok) { | |
| throw new Error('API request failed'); | |
| } | |
| const stores = await checkResponse.json(); | |
| if (stores && stores.length > 0) { | |
| // Store exists, return trial start | |
| const trialStart = new Date(stores[0].trial_start).getTime(); | |
| IMG_log('Store found, trial start:', new Date(trialStart)); | |
| return trialStart; | |
| } else { | |
| // Store doesn't exist, create it | |
| IMG_log('Store not found, creating new entry'); | |
| const now = new Date().toISOString(); | |
| const createUrl = `${IMG_API_ENDPOINT}/rest/v1/stores`; | |
| const createResponse = await fetch(createUrl, { | |
| method: 'POST', | |
| headers: { | |
| 'apikey': IMG_API_KEY, | |
| 'Authorization': `Bearer ${IMG_API_KEY}`, | |
| 'Content-Type': 'application/json', | |
| 'Prefer': 'return=representation' | |
| }, | |
| body: JSON.stringify({ | |
| shop_domain: shop, | |
| trial_start: now | |
| }), | |
| signal: AbortSignal.timeout(5000) | |
| }); | |
| if (!createResponse.ok) { | |
| throw new Error('Failed to create store entry'); | |
| } | |
| const newStore = await createResponse.json(); | |
| const trialStart = new Date(newStore[0].trial_start).getTime(); | |
| IMG_log('Store created, trial start:', new Date(trialStart)); | |
| return trialStart; | |
| } | |
| } catch (error) { | |
| IMG_log('Remote fetch error', error.message); | |
| return null; | |
| } | |
| } | |
| async function IMG_processMetadata() { | |
| const cache = IMG_getLocalCache(); | |
| if (cache?.expired === true) { | |
| IMG_log('Cache shows expired'); | |
| return { isValid: false, expired: true, remaining: 0 }; | |
| } | |
| if (cache?.trialExpiresAt) { | |
| const now = Date.now(); | |
| if (now > cache.trialExpiresAt) { | |
| IMG_log('Trial expired, marking permanently'); | |
| IMG_setLocalCache({ ...cache, expired: true }); | |
| return { isValid: false, expired: true, remaining: 0 }; | |
| } | |
| const remainingMs = cache.trialExpiresAt - now; | |
| IMG_log('Using cache, remaining time:', Math.floor(remainingMs / 60000) + ' minutes'); | |
| return { isValid: true, expired: false, remaining: remainingMs }; | |
| } | |
| IMG_log('No valid cache, fetching remote'); | |
| const trialStart = await IMG_fetchRemoteData(); | |
| if (trialStart) { | |
| const trialExpiresAt = trialStart + IMG_CACHE_DURATION; | |
| const cacheData = { | |
| shop: window.Shopify?.shop, | |
| trialStart: trialStart, | |
| trialExpiresAt: trialExpiresAt, | |
| expired: false, | |
| cachedAt: Date.now() | |
| }; | |
| IMG_setLocalCache(cacheData); | |
| const now = Date.now(); | |
| if (now > trialExpiresAt) { | |
| IMG_log('Trial already expired'); | |
| IMG_setLocalCache({ ...cacheData, expired: true }); | |
| return { isValid: false, expired: true, remaining: 0 }; | |
| } | |
| IMG_log('Remote data cached successfully'); | |
| const remainingMs = trialExpiresAt - now; | |
| return { isValid: true, expired: false, remaining: remainingMs }; | |
| } else { | |
| IMG_log('Remote fetch failed, using fallback'); | |
| return IMG_fallbackValidation(); | |
| } | |
| } | |
| function IMG_fallbackValidation() { | |
| const shop = window.Shopify?.shop; | |
| if (!shop) return { isValid: false, expired: false, remaining: 0 }; | |
| const key = '_img_fallback_' + btoa(shop).substring(0, 10); | |
| const stored = localStorage.getItem(key); | |
| const now = Date.now(); | |
| if (!stored) { | |
| localStorage.setItem(key, btoa(now.toString())); | |
| IMG_log('Fallback: First load'); | |
| return { isValid: true, expired: false, remaining: IMG_CACHE_DURATION }; | |
| } | |
| try { | |
| const startTime = parseInt(atob(stored)); | |
| const elapsed = now - startTime; | |
| const expired = elapsed > IMG_CACHE_DURATION; | |
| const remainingMs = expired ? 0 : IMG_CACHE_DURATION - elapsed; | |
| IMG_log('Fallback validation', { expired, elapsed: Math.floor(elapsed / 60000) + ' minutes' }); | |
| return { isValid: !expired, expired: expired, remaining: remainingMs }; | |
| } catch (e) { | |
| localStorage.setItem(key, btoa(now.toString())); | |
| return { isValid: true, expired: false, remaining: IMG_CACHE_DURATION }; | |
| } | |
| } | |
| async function IMG_validateCache() { | |
| return await IMG_processMetadata(); | |
| } | |
| function IMG_isEditorMode() { | |
| return window.Shopify?.designMode === true || | |
| window.location.href.includes('/editor') || | |
| window.location.search.includes('preview_theme_id'); | |
| } | |
| function IMG_showEditorNotice(remainingMs, expired) { | |
| if (!IMG_isEditorMode()) return; | |
| if (document.getElementById('img-trial-notice')) return; | |
| const notice = document.createElement('div'); | |
| notice.id = 'img-trial-notice'; | |
| let borderColor, titleColor, title, message; | |
| if (expired) { | |
| borderColor = '#ff6b6b'; | |
| titleColor = '#ff6b6b'; | |
| title = 'Trial Expired'; | |
| message = `Your free trial of Dawn Click to Zoom has expired. <a href="https://ezfycode.com/products/dawn-theme-zoom-slider-pro" target="_blank" style="color: #ff6b6b; font-weight: 600;">Get pro version here</a>. To remove it, delete the 'ezfy-zoom' line from 'theme.liquid'.`; | |
| } else { | |
| const hours = Math.floor(remainingMs / 3600000); | |
| const minutes = Math.floor((remainingMs % 3600000) / 60000); | |
| borderColor = '#4CAF50'; | |
| titleColor = '#4CAF50'; | |
| title = 'Free Trial For "Click to Zoom Slider" Active'; | |
| if (hours > 0) { | |
| message = `You have ${hours}h ${minutes}m remaining in your free trial. <a href="https://ezfycode.com/products/dawn-theme-zoom-slider-pro" target="_blank" style="color: #4CAF50; font-weight: 600;">Get pro version here</a>. (This message shows only at the customize page - your customers can not see it)`; | |
| } else { | |
| message = `You have ${minutes} minutes remaining in your free trial. <a href="https://ezfycode.com/products/dawn-theme-zoom-slider-pro" target="_blank" style="color: #4CAF50; font-weight: 600;">Get pro version here</a>. (This message shows only at the customize page - your customers can not see it)`; | |
| } | |
| } | |
| notice.style.cssText = ` | |
| position: fixed; | |
| bottom: 20px; | |
| right: 20px; | |
| background: white; | |
| border: 2px solid ${borderColor}; | |
| border-radius: 8px; | |
| padding: 16px; | |
| box-shadow: 0 4px 12px rgba(0,0,0,0.15); | |
| z-index: 999999; | |
| max-width: 380px; | |
| font-family: -apple-system, sans-serif; | |
| font-size: 14px; | |
| line-height: 1.4; | |
| `; | |
| notice.innerHTML = ` | |
| <div style="font-weight: 600; margin-bottom: 8px; color: ${titleColor};">${title}</div> | |
| <div style="margin-bottom: 10px; color: #333; font-size: 12px; line-height: 1.5;">${message}</div> | |
| <button onclick="this.parentElement.remove()" style=" | |
| background: ${borderColor}; | |
| color: white; | |
| border: none; | |
| padding: 6px 12px; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| font-size: 13px; | |
| ">Close</button> | |
| `; | |
| document.body.appendChild(notice); | |
| setTimeout(() => notice.remove(), 30000); | |
| } | |
| function detectCurrentLayout() { | |
| const $layout = document.querySelector(`[data-desktop-layout]`); | |
| if (!$layout) { | |
| return; | |
| } | |
| const layout = $layout.getAttribute(`data-desktop-layout`); | |
| return layout; | |
| } | |
| const CSS_PARENT_SELECTOR_OLD_THEMES = `#large-image` | |
| const CSS_PARENT_SELECTOR = getCssParentSelector(); | |
| function getCssParentSelector(){ | |
| let $el = document.querySelector(`#large-image`); | |
| if ($el){ | |
| return `#large-image` | |
| }; | |
| return `slider-component` | |
| } | |
| function isOldDawn(){ | |
| const selector = getCssParentSelector(); | |
| if (selector === '#large-image'){ | |
| return true; | |
| } | |
| return false; | |
| } | |
| function _loadScript(src) { | |
| return new Promise(function(resolve, reject) { | |
| var s; | |
| s = document.createElement("script"); | |
| s.src = src; | |
| s.onload = resolve; | |
| s.onerror = reject; | |
| document.head.appendChild(s); | |
| }); | |
| } | |
| function _isProductPage() { | |
| return /product/.test(window.location.href); | |
| } | |
| function removeVideosAndHiddenElements($elements){ | |
| const $stacked = document.querySelector(`[data-desktop-layout="stacked"]`); | |
| if ($stacked){ | |
| return $elements | |
| } | |
| return [...$elements].filter(e => { | |
| const $video = e.querySelector(`video`); | |
| let hidden = false; | |
| const $parent = e.closest(`[class*='product__media-item']`); | |
| const $ul = e.closest(`[id*='Slider-Gallery'], ul`) | |
| if (IS_DAWN_SLIDER){ | |
| const isDisplayNone = (window.getComputedStyle(e, null).display === 'none'); | |
| const parentIsHidden = ($parent && $parent.classList.value.includes("--variant") && !$parent.classList.value.includes("fade-in")); | |
| if (isDisplayNone === true || parentIsHidden === true){ | |
| hidden = true; | |
| } | |
| } else if (!IS_DAWN_SLIDER){ | |
| if ( (window.getComputedStyle(e, null).display === 'none') || ($parent && $parent.classList.value.includes("--variant")) ){ | |
| hidden = true; | |
| } | |
| } | |
| if (e.closest(`li.is-active`)){ | |
| hidden = false; | |
| } | |
| if (!$video && !hidden){ | |
| return e; | |
| } | |
| }) | |
| } | |
| function addImagePositionDataAttribute() { | |
| let $slides; | |
| const _$slides = document.querySelectorAll(CSS_INDIVIDUAL_SLIDES_WITHOUT_VIDEO); | |
| if (!_$slides) { | |
| return; | |
| } | |
| $slides = removeVideosAndHiddenElements(_$slides) | |
| for (var [i, each] of $slides.entries()) { | |
| const $parent = each.closest(`[id*='Slide-template'], li[data-media-id], li`); | |
| let id; | |
| let _id; | |
| if ($parent.getAttribute("id")) { | |
| _id = $parent.getAttribute("id") | |
| id = parseInt(_id.split("-")[4]); | |
| } else { | |
| _id = $parent.getAttribute("data-media-id") | |
| id = parseInt(_id.split("-")[3]); | |
| } | |
| if (id.toString().length <= 0 || !id) { | |
| return; | |
| } | |
| let _position; | |
| if (window.productVariantGalleries && window.productVariantGalleries.length>=1 && $parent.hasAttribute(`data-variant-group-media-position`)){ | |
| // _position = | |
| const newIndex = parseInt($parent.getAttribute(`data-variant-group-media-position`)) - 1 | |
| const newPosition = parseInt($parent.getAttribute(`data-variant-group-media-position`)) | |
| $parent.setAttribute("data-slide-index", newIndex); | |
| $parent.setAttribute("data-ezfy-media-position", newPosition); | |
| continue; | |
| } | |
| _position = window.ezfyDawnThemeZoomImages.filter(e => parseInt(e.id) === id)[0]; | |
| if (!_position) { | |
| throw new Error(`ezfy-zoom: No position found.`) | |
| } | |
| const position = _position.index; | |
| const index = i; | |
| $parent.setAttribute("data-slide-index", index); | |
| $parent.setAttribute("data-ezfy-media-position", position); | |
| } | |
| } | |
| function addImagePositionDataAttributeToThumbnails() { | |
| const layout = detectCurrentLayout(); | |
| if (!layout === 'thumbnails' || !layout === 'thumbnail_slider') { | |
| return; | |
| } | |
| const $thumbnails = document.querySelectorAll(CSS_THUMBNAILS); | |
| if (!$thumbnails) { | |
| return; | |
| } | |
| for (var [i, each] of $thumbnails.entries()) { | |
| let _id; | |
| _id = each.getAttribute("data-target"); | |
| if (!_id){ | |
| _id = each.getAttribute(`data-thumb-id`); | |
| } | |
| const id = parseInt(_id.split("-")[3]); | |
| if (id.toString().length <= 0 || !id) { | |
| return; | |
| } | |
| const _position = window.ezfyDawnThemeZoomImages.filter(e => parseInt(e.id) === id)[0]; | |
| if (!_position) { | |
| continue; | |
| } | |
| const position = _position.imagePosition; | |
| const index = i; | |
| each.setAttribute("data-slide-index", index); | |
| each.setAttribute("data-ezfy-media-position", position); | |
| } | |
| } | |
| async function _getCurrentProductImages() { | |
| return new Promise(async (resolve, reject) => { | |
| const url = `${window.location.origin}/${window.location.pathname}.json`; | |
| let response = await fetch(url); | |
| let data = await response.json(); | |
| resolve(data.product.images); | |
| }); | |
| } | |
| function _sleep(ms) { | |
| return new Promise(resolve => setTimeout(resolve, ms)); | |
| } | |
| function loadLocalPhotoSwipeUI() { | |
| if (window.PhotoSwipeUI_Default !== undefined) { | |
| return true; | |
| } | |
| return new Promise(async (resolve, reject) => { | |
| ! function(a, b) { | |
| "function" == typeof define && define.amd ? define(b) : "object" == typeof exports ? module.exports = b() : a.PhotoSwipeUI_Default = b() | |
| }(this, function() { | |
| "use strict"; | |
| var a = function(a, b) { | |
| var c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v = this, | |
| w = !1, | |
| x = !0, | |
| y = !0, | |
| z = { | |
| barsSize: { | |
| top: 44, | |
| bottom: "auto" | |
| }, | |
| closeElClasses: ["item", "caption", "zoom-wrap", "ui", "top-bar"], | |
| timeToIdle: 4e3, | |
| timeToIdleOutside: 1e3, | |
| loadingIndicatorDelay: 1e3, | |
| addCaptionHTMLFn: function(a, b) { | |
| return a.title ? (b.children[0].innerHTML = a.title, !0) : (b.children[0].innerHTML = "", !1) | |
| }, | |
| closeEl: !0, | |
| captionEl: !0, | |
| fullscreenEl: !0, | |
| zoomEl: !0, | |
| shareEl: !0, | |
| counterEl: !0, | |
| arrowEl: !0, | |
| preloaderEl: !0, | |
| tapToClose: !1, | |
| tapToToggleControls: !0, | |
| clickToCloseNonZoomable: !0, | |
| shareButtons: [{ | |
| id: "facebook", | |
| label: "Share on Facebook", | |
| url: "https://www.facebook.com/sharer/sharer.php?u={{url}}" | |
| }, { | |
| id: "twitter", | |
| label: "Tweet", | |
| url: "https://twitter.com/intent/tweet?text={{text}}&url={{url}}" | |
| }, { | |
| id: "pinterest", | |
| label: "Pin it", | |
| url: "http://www.pinterest.com/pin/create/button/?url={{url}}&media={{image_url}}&description={{text}}" | |
| }, { | |
| id: "download", | |
| label: "Download image", | |
| url: "{{raw_image_url}}", | |
| download: !0 | |
| }], | |
| getImageURLForShare: function() { | |
| return a.currItem.src || "" | |
| }, | |
| getPageURLForShare: function() { | |
| return window.location.href | |
| }, | |
| getTextForShare: function() { | |
| return a.currItem.title || "" | |
| }, | |
| indexIndicatorSep: " / ", | |
| fitControlsWidth: 1200 | |
| }, | |
| A = function(a) { | |
| if (r) return !0; | |
| a = a || window.event, q.timeToIdle && q.mouseUsed && !k && K(); | |
| for (var c, d, e = a.target || a.srcElement, f = e.getAttribute("class") || "", g = 0; g < S.length; g++) c = S[g], c.onTap && f.indexOf("pswp__" + c.name) > -1 && (c.onTap(), d = !0); | |
| if (d) { | |
| a.stopPropagation && a.stopPropagation(), r = !0; | |
| var h = b.features.isOldAndroid ? 600 : 30; | |
| s = setTimeout(function() { | |
| r = !1 | |
| }, h) | |
| } | |
| }, | |
| B = function() { | |
| return !a.likelyTouchDevice || q.mouseUsed || screen.width > q.fitControlsWidth | |
| }, | |
| C = function(a, c, d) { | |
| b[(d ? "add" : "remove") + "Class"](a, "pswp__" + c) | |
| }, | |
| D = function() { | |
| var a = 1 === q.getNumItemsFn(); | |
| a !== p && (C(d, "ui--one-slide", a), p = a) | |
| }, | |
| E = function() { | |
| C(i, "share-modal--hidden", y) | |
| }, | |
| F = function() { | |
| return y = !y, y ? (b.removeClass(i, "pswp__share-modal--fade-in"), setTimeout(function() { | |
| y && E() | |
| }, 300)) : (E(), setTimeout(function() { | |
| y || b.addClass(i, "pswp__share-modal--fade-in") | |
| }, 30)), y || H(), !1 | |
| }, | |
| G = function(b) { | |
| b = b || window.event; | |
| var c = b.target || b.srcElement; | |
| return a.shout("shareLinkClick", b, c), !!c.href && (!!c.hasAttribute("download") || (window.open(c.href, "pswp_share", "scrollbars=yes,resizable=yes,toolbar=no,location=yes,width=550,height=420,top=100,left=" + (window.screen ? Math.round(screen.width / 2 - 275) : 100)), y || F(), !1)) | |
| }, | |
| H = function() { | |
| for (var a, b, c, d, e, f = "", g = 0; g < q.shareButtons.length; g++) a = q.shareButtons[g], c = q.getImageURLForShare(a), d = q.getPageURLForShare(a), e = q.getTextForShare(a), b = a.url.replace("{{url}}", encodeURIComponent(d)).replace("{{image_url}}", encodeURIComponent(c)).replace("{{raw_image_url}}", c).replace("{{text}}", encodeURIComponent(e)), f += '<a href="' + b + '" target="_blank" class="pswp__share--' + a.id + '"' + (a.download ? "download" : "") + ">" + a.label + "</a>", q.parseShareButtonOut && (f = q.parseShareButtonOut(a, f)); | |
| i.children[0].innerHTML = f, i.children[0].onclick = G | |
| }, | |
| I = function(a) { | |
| for (var c = 0; c < q.closeElClasses.length; c++) | |
| if (b.hasClass(a, "pswp__" + q.closeElClasses[c])) return !0 | |
| }, | |
| J = 0, | |
| K = function() { | |
| clearTimeout(u), J = 0, k && v.setIdle(!1) | |
| }, | |
| L = function(a) { | |
| a = a ? a : window.event; | |
| var b = a.relatedTarget || a.toElement; | |
| b && "HTML" !== b.nodeName || (clearTimeout(u), u = setTimeout(function() { | |
| v.setIdle(!0) | |
| }, q.timeToIdleOutside)) | |
| }, | |
| M = function() { | |
| q.fullscreenEl && !b.features.isOldAndroid && (c || (c = v.getFullscreenAPI()), c ? (b.bind(document, c.eventK, v.updateFullscreen), v.updateFullscreen(), b.addClass(a.template, "pswp--supports-fs")) : b.removeClass(a.template, "pswp--supports-fs")) | |
| }, | |
| N = function() { | |
| q.preloaderEl && (O(!0), l("beforeChange", function() { | |
| clearTimeout(o), o = setTimeout(function() { | |
| a.currItem && a.currItem.loading ? (!a.allowProgressiveImg() || a.currItem.img && !a.currItem.img.naturalWidth) && O(!1) : O(!0) | |
| }, q.loadingIndicatorDelay) | |
| }), l("imageLoadComplete", function(b, c) { | |
| a.currItem === c && O(!0) | |
| })) | |
| }, | |
| O = function(a) { | |
| n !== a && (C(m, "preloader--active", !a), n = a) | |
| }, | |
| P = function(a) { | |
| var c = a.vGap; | |
| if (B()) { | |
| var g = q.barsSize; | |
| if (q.captionEl && "auto" === g.bottom) | |
| if (f || (f = b.createEl("pswp__caption pswp__caption--fake"), f.appendChild(b.createEl("pswp__caption__center")), d.insertBefore(f, e), b.addClass(d, "pswp__ui--fit")), q.addCaptionHTMLFn(a, f, !0)) { | |
| var h = f.clientHeight; | |
| c.bottom = parseInt(h, 10) || 44 | |
| } else c.bottom = g.top; | |
| else c.bottom = "auto" === g.bottom ? 0 : g.bottom; | |
| c.top = g.top | |
| } else c.top = c.bottom = 0 | |
| }, | |
| Q = function() { | |
| q.timeToIdle && l("mouseUsed", function() { | |
| b.bind(document, "mousemove", K), b.bind(document, "mouseout", L), t = setInterval(function() { | |
| J++, 2 === J && v.setIdle(!0) | |
| }, q.timeToIdle / 2) | |
| }) | |
| }, | |
| R = function() { | |
| l("onVerticalDrag", function(a) { | |
| x && a < .95 ? v.hideControls() : !x && a >= .95 && v.showControls() | |
| }); | |
| var a; | |
| l("onPinchClose", function(b) { | |
| x && b < .9 ? (v.hideControls(), a = !0) : a && !x && b > .9 && v.showControls() | |
| }), l("zoomGestureEnded", function() { | |
| a = !1, a && !x && v.showControls() | |
| }) | |
| }, | |
| S = [{ | |
| name: "caption", | |
| option: "captionEl", | |
| onInit: function(a) { | |
| e = a | |
| } | |
| }, { | |
| name: "share-modal", | |
| option: "shareEl", | |
| onInit: function(a) { | |
| i = a | |
| }, | |
| onTap: function() { | |
| F() | |
| } | |
| }, { | |
| name: "button--share", | |
| option: "shareEl", | |
| onInit: function(a) { | |
| h = a | |
| }, | |
| onTap: function() { | |
| F() | |
| } | |
| }, { | |
| name: "button--zoom", | |
| option: "zoomEl", | |
| onTap: a.toggleDesktopZoom | |
| }, { | |
| name: "counter", | |
| option: "counterEl", | |
| onInit: function(a) { | |
| g = a | |
| } | |
| }, { | |
| name: "button--close", | |
| option: "closeEl", | |
| onTap: a.close | |
| }, { | |
| name: "button--arrow--left", | |
| option: "arrowEl", | |
| onTap: a.prev | |
| }, { | |
| name: "button--arrow--right", | |
| option: "arrowEl", | |
| onTap: a.next | |
| }, { | |
| name: "button--fs", | |
| option: "fullscreenEl", | |
| onTap: function() { | |
| c.isFullscreen() ? c.exit() : c.enter() | |
| } | |
| }, { | |
| name: "preloader", | |
| option: "preloaderEl", | |
| onInit: function(a) { | |
| m = a | |
| } | |
| }], | |
| T = function() { | |
| var a, c, e, f = function(d) { | |
| if (d) | |
| for (var f = d.length, g = 0; g < f; g++) { | |
| a = d[g], c = a.className; | |
| for (var h = 0; h < S.length; h++) e = S[h], c.indexOf("pswp__" + e.name) > -1 && (q[e.option] ? (b.removeClass(a, "pswp__element--disabled"), e.onInit && e.onInit(a)) : b.addClass(a, "pswp__element--disabled")) | |
| } | |
| }; | |
| f(d.children); | |
| var g = b.getChildByClass(d, "pswp__top-bar"); | |
| g && f(g.children) | |
| }; | |
| v.init = function() { | |
| b.extend(a.options, z, !0), q = a.options, d = b.getChildByClass(a.scrollWrap, "pswp__ui"), l = a.listen, R(), l("beforeChange", v.update), l("doubleTap", function(b) { | |
| var c = a.currItem.initialZoomLevel; | |
| a.getZoomLevel() !== c ? a.zoomTo(c, b, 333) : a.zoomTo(q.getDoubleTapZoom(!1, a.currItem), b, 333) | |
| }), l("preventDragEvent", function(a, b, c) { | |
| var d = a.target || a.srcElement; | |
| d && d.getAttribute("class") && a.type.indexOf("mouse") > -1 && (d.getAttribute("class").indexOf("__caption") > 0 || /(SMALL|STRONG|EM)/i.test(d.tagName)) && (c.prevent = !1) | |
| }), l("bindEvents", function() { | |
| b.bind(d, "pswpTap click", A), b.bind(a.scrollWrap, "pswpTap", v.onGlobalTap), a.likelyTouchDevice || b.bind(a.scrollWrap, "mouseover", v.onMouseOver) | |
| }), l("unbindEvents", function() { | |
| y || F(), t && clearInterval(t), b.unbind(document, "mouseout", L), b.unbind(document, "mousemove", K), b.unbind(d, "pswpTap click", A), b.unbind(a.scrollWrap, "pswpTap", v.onGlobalTap), b.unbind(a.scrollWrap, "mouseover", v.onMouseOver), c && (b.unbind(document, c.eventK, v.updateFullscreen), c.isFullscreen() && (q.hideAnimationDuration = 0, c.exit()), c = null) | |
| }), l("destroy", function() { | |
| q.captionEl && (f && d.removeChild(f), b.removeClass(e, "pswp__caption--empty")), i && (i.children[0].onclick = null), b.removeClass(d, "pswp__ui--over-close"), b.addClass(d, "pswp__ui--hidden"), v.setIdle(!1) | |
| }), q.showAnimationDuration || b.removeClass(d, "pswp__ui--hidden"), l("initialZoomIn", function() { | |
| q.showAnimationDuration && b.removeClass(d, "pswp__ui--hidden") | |
| }), l("initialZoomOut", function() { | |
| b.addClass(d, "pswp__ui--hidden") | |
| }), l("parseVerticalMargin", P), T(), q.shareEl && h && i && (y = !0), D(), Q(), M(), N() | |
| }, v.setIdle = function(a) { | |
| k = a, C(d, "ui--idle", a) | |
| }, v.update = function() { | |
| x && a.currItem ? (v.updateIndexIndicator(), q.captionEl && (q.addCaptionHTMLFn(a.currItem, e), C(e, "caption--empty", !a.currItem.title)), w = !0) : w = !1, y || F(), D() | |
| }, v.updateFullscreen = function(d) { | |
| d && setTimeout(function() { | |
| a.setScrollOffset(0, b.getScrollY()) | |
| }, 50), b[(c.isFullscreen() ? "add" : "remove") + "Class"](a.template, "pswp--fs") | |
| }, v.updateIndexIndicator = function() { | |
| q.counterEl && (g.innerHTML = a.getCurrentIndex() + 1 + q.indexIndicatorSep + q.getNumItemsFn()) | |
| }, v.onGlobalTap = function(c) { | |
| c = c || window.event; | |
| var d = c.target || c.srcElement; | |
| if (!r) | |
| if (c.detail && "mouse" === c.detail.pointerType) { | |
| if (I(d)) return void a.close(); | |
| b.hasClass(d, "pswp__img") && (1 === a.getZoomLevel() && a.getZoomLevel() <= a.currItem.fitRatio ? q.clickToCloseNonZoomable && a.close() : a.toggleDesktopZoom(c.detail.releasePoint)) | |
| } else if (q.tapToToggleControls && (x ? v.hideControls() : v.showControls()), q.tapToClose && (b.hasClass(d, "pswp__img") || I(d))) return void a.close() | |
| }, v.onMouseOver = function(a) { | |
| a = a || window.event; | |
| var b = a.target || a.srcElement; | |
| C(d, "ui--over-close", I(b)) | |
| }, v.hideControls = function() { | |
| b.addClass(d, "pswp__ui--hidden"), x = !1 | |
| }, v.showControls = function() { | |
| x = !0, w || v.update(), b.removeClass(d, "pswp__ui--hidden") | |
| }, v.supportsFullscreen = function() { | |
| var a = document; | |
| return !!(a.exitFullscreen || a.mozCancelFullScreen || a.webkitExitFullscreen || a.msExitFullscreen) | |
| }, v.getFullscreenAPI = function() { | |
| var b, c = document.documentElement, | |
| d = "fullscreenchange"; | |
| return c.requestFullscreen ? b = { | |
| enterK: "requestFullscreen", | |
| exitK: "exitFullscreen", | |
| elementK: "fullscreenElement", | |
| eventK: d | |
| } : c.mozRequestFullScreen ? b = { | |
| enterK: "mozRequestFullScreen", | |
| exitK: "mozCancelFullScreen", | |
| elementK: "mozFullScreenElement", | |
| eventK: "moz" + d | |
| } : c.webkitRequestFullscreen ? b = { | |
| enterK: "webkitRequestFullscreen", | |
| exitK: "webkitExitFullscreen", | |
| elementK: "webkitFullscreenElement", | |
| eventK: "webkit" + d | |
| } : c.msRequestFullscreen && (b = { | |
| enterK: "msRequestFullscreen", | |
| exitK: "msExitFullscreen", | |
| elementK: "msFullscreenElement", | |
| eventK: "MSFullscreenChange" | |
| }), b && (b.enter = function() { | |
| return j = q.closeOnScroll, q.closeOnScroll = !1, "webkitRequestFullscreen" !== this.enterK ? a.template[this.enterK]() : void a.template[this.enterK](Element.ALLOW_KEYBOARD_INPUT) | |
| }, b.exit = function() { | |
| return q.closeOnScroll = j, document[this.exitK]() | |
| }, b.isFullscreen = function() { | |
| return document[this.elementK] | |
| }), b | |
| } | |
| }; | |
| return a | |
| }); | |
| /*beautify ignore:end*/ | |
| while (!window.PhotoSwipeUI_Default) { | |
| await new Promise(resolve => setTimeout(resolve, 10)); | |
| } | |
| resolve(true); | |
| }); | |
| } | |
| function loadLocalPhotoSwipe() { | |
| if (window.PhotoSwipe !== undefined) { | |
| return true; | |
| } | |
| return new Promise(async (resolve, reject) => { | |
| /*beautify ignore:start*/ | |
| ! function(a, b) { | |
| "function" == typeof define && define.amd ? define(b) : "object" == typeof exports ? module.exports = b() : a.PhotoSwipe = b() | |
| }(this, function() { | |
| "use strict"; | |
| var a = function(a, b, c, d) { | |
| var e = { | |
| features: null, | |
| bind: function(a, b, c, d) { | |
| var e = (d ? "remove" : "add") + "EventListener"; | |
| b = b.split(" "); | |
| for (var f = 0; f < b.length; f++) b[f] && a[e](b[f], c, !1) | |
| }, | |
| isArray: function(a) { | |
| return a instanceof Array | |
| }, | |
| createEl: function(a, b) { | |
| var c = document.createElement(b || "div"); | |
| return a && (c.className = a), c | |
| }, | |
| getScrollY: function() { | |
| var a = window.pageYOffset; | |
| return void 0 !== a ? a : document.documentElement.scrollTop | |
| }, | |
| unbind: function(a, b, c) { | |
| e.bind(a, b, c, !0) | |
| }, | |
| removeClass: function(a, b) { | |
| var c = new RegExp("(\\s|^)" + b + "(\\s|$)"); | |
| a.className = a.className.replace(c, " ").replace(/^\s\s*/, "").replace(/\s\s*$/, "") | |
| }, | |
| addClass: function(a, b) { | |
| e.hasClass(a, b) || (a.className += (a.className ? " " : "") + b) | |
| }, | |
| hasClass: function(a, b) { | |
| return a.className && new RegExp("(^|\\s)" + b + "(\\s|$)").test(a.className) | |
| }, | |
| getChildByClass: function(a, b) { | |
| for (var c = a.firstChild; c;) { | |
| if (e.hasClass(c, b)) return c; | |
| c = c.nextSibling | |
| } | |
| }, | |
| arraySearch: function(a, b, c) { | |
| for (var d = a.length; d--;) | |
| if (a[d][c] === b) return d; | |
| return -1 | |
| }, | |
| extend: function(a, b, c) { | |
| for (var d in b) | |
| if (b.hasOwnProperty(d)) { | |
| if (c && a.hasOwnProperty(d)) continue; | |
| a[d] = b[d] | |
| } | |
| }, | |
| easing: { | |
| sine: { | |
| out: function(a) { | |
| return Math.sin(a * (Math.PI / 2)) | |
| }, | |
| inOut: function(a) { | |
| return -(Math.cos(Math.PI * a) - 1) / 2 | |
| } | |
| }, | |
| cubic: { | |
| out: function(a) { | |
| return --a * a * a + 1 | |
| } | |
| } | |
| }, | |
| detectFeatures: function() { | |
| if (e.features) return e.features; | |
| var a = e.createEl(), | |
| b = a.style, | |
| c = "", | |
| d = {}; | |
| if (d.oldIE = document.all && !document.addEventListener, d.touch = "ontouchstart" in window, window.requestAnimationFrame && (d.raf = window.requestAnimationFrame, d.caf = window.cancelAnimationFrame), d.pointerEvent = !!window.PointerEvent || navigator.msPointerEnabled, !d.pointerEvent) { | |
| var f = navigator.userAgent; | |
| if (/iP(hone|od)/.test(navigator.platform)) { | |
| var g = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/); | |
| g && g.length > 0 && (g = parseInt(g[1], 10), g >= 1 && g < 8 && (d.isOldIOSPhone = !0)) | |
| } | |
| var h = f.match(/Android\s([0-9\.]*)/), | |
| i = h ? h[1] : 0; | |
| i = parseFloat(i), i >= 1 && (i < 4.4 && (d.isOldAndroid = !0), d.androidVersion = i), d.isMobileOpera = /opera mini|opera mobi/i.test(f) | |
| } | |
| for (var j, k, l = ["transform", "perspective", "animationName"], m = ["", "webkit", "Moz", "ms", "O"], n = 0; n < 4; n++) { | |
| c = m[n]; | |
| for (var o = 0; o < 3; o++) j = l[o], k = c + (c ? j.charAt(0).toUpperCase() + j.slice(1) : j), !d[j] && k in b && (d[j] = k); | |
| c && !d.raf && (c = c.toLowerCase(), d.raf = window[c + "RequestAnimationFrame"], d.raf && (d.caf = window[c + "CancelAnimationFrame"] || window[c + "CancelRequestAnimationFrame"])) | |
| } | |
| if (!d.raf) { | |
| var p = 0; | |
| d.raf = function(a) { | |
| var b = (new Date).getTime(), | |
| c = Math.max(0, 16 - (b - p)), | |
| d = window.setTimeout(function() { | |
| a(b + c) | |
| }, c); | |
| return p = b + c, d | |
| }, d.caf = function(a) { | |
| clearTimeout(a) | |
| } | |
| } | |
| return d.svg = !!document.createElementNS && !!document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGRect, e.features = d, d | |
| } | |
| }; | |
| e.detectFeatures(), e.features.oldIE && (e.bind = function(a, b, c, d) { | |
| b = b.split(" "); | |
| for (var e, f = (d ? "detach" : "attach") + "Event", g = function() { | |
| c.handleEvent.call(c) | |
| }, h = 0; h < b.length; h++) | |
| if (e = b[h]) | |
| if ("object" == typeof c && c.handleEvent) { | |
| if (d) { | |
| if (!c["oldIE" + e]) return !1 | |
| } else c["oldIE" + e] = g; | |
| a[f]("on" + e, c["oldIE" + e]) | |
| } else a[f]("on" + e, c) | |
| }); | |
| var f = this, | |
| g = 25, | |
| h = 3, | |
| i = { | |
| allowPanToNext: !0, | |
| spacing: .12, | |
| bgOpacity: 1, | |
| mouseUsed: !1, | |
| loop: !0, | |
| pinchToClose: !0, | |
| closeOnScroll: !0, | |
| closeOnVerticalDrag: !0, | |
| verticalDragRange: .75, | |
| hideAnimationDuration: 333, | |
| showAnimationDuration: 333, | |
| showHideOpacity: !1, | |
| focus: !0, | |
| escKey: !0, | |
| arrowKeys: !0, | |
| mainScrollEndFriction: .35, | |
| panEndFriction: .35, | |
| isClickableElement: function(a) { | |
| return "A" === a.tagName | |
| }, | |
| getDoubleTapZoom: function(a, b) { | |
| return a ? 1 : b.initialZoomLevel < .7 ? 1 : 1.33 | |
| }, | |
| maxSpreadZoom: 1.33, | |
| modal: !0, | |
| scaleMode: "fit" | |
| }; | |
| e.extend(i, d); | |
| var j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, $, _, aa, ba, ca, da, ea, fa, ga, ha, ia, ja, ka, la, ma = function() { | |
| return { | |
| x: 0, | |
| y: 0 | |
| } | |
| }, | |
| na = ma(), | |
| oa = ma(), | |
| pa = ma(), | |
| qa = {}, | |
| ra = 0, | |
| sa = {}, | |
| ta = ma(), | |
| ua = 0, | |
| va = !0, | |
| wa = [], | |
| xa = {}, | |
| ya = !1, | |
| za = function(a, b) { | |
| e.extend(f, b.publicMethods), wa.push(a) | |
| }, | |
| Aa = function(a) { | |
| var b = ac(); | |
| return a > b - 1 ? a - b : a < 0 ? b + a : a | |
| }, | |
| Ba = {}, | |
| Ca = function(a, b) { | |
| return Ba[a] || (Ba[a] = []), Ba[a].push(b) | |
| }, | |
| Da = function(a) { | |
| var b = Ba[a]; | |
| if (b) { | |
| var c = Array.prototype.slice.call(arguments); | |
| c.shift(); | |
| for (var d = 0; d < b.length; d++) b[d].apply(f, c) | |
| } | |
| }, | |
| Ea = function() { | |
| return (new Date).getTime() | |
| }, | |
| Fa = function(a) { | |
| ja = a, f.bg.style.opacity = a * i.bgOpacity | |
| }, | |
| Ga = function(a, b, c, d, e) { | |
| (!ya || e && e !== f.currItem) && (d /= e ? e.fitRatio : f.currItem.fitRatio), a[E] = u + b + "px, " + c + "px" + v + " scale(" + d + ")" | |
| }, | |
| Ha = function(a) { | |
| ea && (a && (s > f.currItem.fitRatio ? ya || (mc(f.currItem, !1, !0), ya = !0) : ya && (mc(f.currItem), ya = !1)), Ga(ea, pa.x, pa.y, s)) | |
| }, | |
| Ia = function(a) { | |
| a.container && Ga(a.container.style, a.initialPosition.x, a.initialPosition.y, a.initialZoomLevel, a) | |
| }, | |
| Ja = function(a, b) { | |
| b[E] = u + a + "px, 0px" + v | |
| }, | |
| Ka = function(a, b) { | |
| if (!i.loop && b) { | |
| var c = m + (ta.x * ra - a) / ta.x, | |
| d = Math.round(a - tb.x); | |
| (c < 0 && d > 0 || c >= ac() - 1 && d < 0) && (a = tb.x + d * i.mainScrollEndFriction) | |
| } | |
| tb.x = a, Ja(a, n) | |
| }, | |
| La = function(a, b) { | |
| var c = ub[a] - sa[a]; | |
| return oa[a] + na[a] + c - c * (b / t) | |
| }, | |
| Ma = function(a, b) { | |
| a.x = b.x, a.y = b.y, b.id && (a.id = b.id) | |
| }, | |
| Na = function(a) { | |
| a.x = Math.round(a.x), a.y = Math.round(a.y) | |
| }, | |
| Oa = null, | |
| Pa = function() { | |
| Oa && (e.unbind(document, "mousemove", Pa), e.addClass(a, "pswp--has_mouse"), i.mouseUsed = !0, Da("mouseUsed")), Oa = setTimeout(function() { | |
| Oa = null | |
| }, 100) | |
| }, | |
| Qa = function() { | |
| e.bind(document, "keydown", f), N.transform && e.bind(f.scrollWrap, "click", f), i.mouseUsed || e.bind(document, "mousemove", Pa), e.bind(window, "resize scroll orientationchange", f), Da("bindEvents") | |
| }, | |
| Ra = function() { | |
| e.unbind(window, "resize scroll orientationchange", f), e.unbind(window, "scroll", r.scroll), e.unbind(document, "keydown", f), e.unbind(document, "mousemove", Pa), N.transform && e.unbind(f.scrollWrap, "click", f), V && e.unbind(window, p, f), clearTimeout(O), Da("unbindEvents") | |
| }, | |
| Sa = function(a, b) { | |
| var c = ic(f.currItem, qa, a); | |
| return b && (da = c), c | |
| }, | |
| Ta = function(a) { | |
| return a || (a = f.currItem), a.initialZoomLevel | |
| }, | |
| Ua = function(a) { | |
| return a || (a = f.currItem), a.w > 0 ? i.maxSpreadZoom : 1 | |
| }, | |
| Va = function(a, b, c, d) { | |
| return d === f.currItem.initialZoomLevel ? (c[a] = f.currItem.initialPosition[a], !0) : (c[a] = La(a, d), c[a] > b.min[a] ? (c[a] = b.min[a], !0) : c[a] < b.max[a] && (c[a] = b.max[a], !0)) | |
| }, | |
| Wa = function() { | |
| if (E) { | |
| var b = N.perspective && !G; | |
| return u = "translate" + (b ? "3d(" : "("), void(v = N.perspective ? ", 0px)" : ")") | |
| } | |
| E = "left", e.addClass(a, "pswp--ie"), Ja = function(a, b) { | |
| b.left = a + "px" | |
| }, Ia = function(a) { | |
| var b = a.fitRatio > 1 ? 1 : a.fitRatio, | |
| c = a.container.style, | |
| d = b * a.w, | |
| e = b * a.h; | |
| c.width = d + "px", c.height = e + "px", c.left = a.initialPosition.x + "px", c.top = a.initialPosition.y + "px" | |
| }, Ha = function() { | |
| if (ea) { | |
| var a = ea, | |
| b = f.currItem, | |
| c = b.fitRatio > 1 ? 1 : b.fitRatio, | |
| d = c * b.w, | |
| e = c * b.h; | |
| a.width = d + "px", a.height = e + "px", a.left = pa.x + "px", a.top = pa.y + "px" | |
| } | |
| } | |
| }, | |
| Xa = function(a) { | |
| var b = ""; | |
| i.escKey && 27 === a.keyCode ? b = "close" : i.arrowKeys && (37 === a.keyCode ? b = "prev" : 39 === a.keyCode && (b = "next")), b && (a.ctrlKey || a.altKey || a.shiftKey || a.metaKey || (a.preventDefault ? a.preventDefault() : a.returnValue = !1, f[b]())) | |
| }, | |
| Ya = function(a) { | |
| a && (Y || X || fa || T) && (a.preventDefault(), a.stopPropagation()) | |
| }, | |
| Za = function() { | |
| f.setScrollOffset(0, e.getScrollY()) | |
| }, | |
| $a = {}, | |
| _a = 0, | |
| ab = function(a) { | |
| $a[a] && ($a[a].raf && I($a[a].raf), _a--, delete $a[a]) | |
| }, | |
| bb = function(a) { | |
| $a[a] && ab(a), $a[a] || (_a++, $a[a] = {}) | |
| }, | |
| cb = function() { | |
| for (var a in $a) $a.hasOwnProperty(a) && ab(a) | |
| }, | |
| db = function(a, b, c, d, e, f, g) { | |
| var h, i = Ea(); | |
| bb(a); | |
| var j = function() { | |
| if ($a[a]) { | |
| if (h = Ea() - i, h >= d) return ab(a), f(c), void(g && g()); | |
| f((c - b) * e(h / d) + b), $a[a].raf = H(j) | |
| } | |
| }; | |
| j() | |
| }, | |
| eb = { | |
| shout: Da, | |
| listen: Ca, | |
| viewportSize: qa, | |
| options: i, | |
| isMainScrollAnimating: function() { | |
| return fa | |
| }, | |
| getZoomLevel: function() { | |
| return s | |
| }, | |
| getCurrentIndex: function() { | |
| return m | |
| }, | |
| isDragging: function() { | |
| return V | |
| }, | |
| isZooming: function() { | |
| return aa | |
| }, | |
| setScrollOffset: function(a, b) { | |
| sa.x = a, M = sa.y = b, Da("updateScrollOffset", sa) | |
| }, | |
| applyZoomPan: function(a, b, c, d) { | |
| pa.x = b, pa.y = c, s = a, Ha(d) | |
| }, | |
| init: function() { | |
| if (!j && !k) { | |
| var c; | |
| f.framework = e, f.template = a, f.bg = e.getChildByClass(a, "pswp__bg"), J = a.className, j = !0, N = e.detectFeatures(), H = N.raf, I = N.caf, E = N.transform, L = N.oldIE, f.scrollWrap = e.getChildByClass(a, "pswp__scroll-wrap"), f.container = e.getChildByClass(f.scrollWrap, "pswp__container"), n = f.container.style, f.itemHolders = y = [{ | |
| el: f.container.children[0], | |
| wrap: 0, | |
| index: -1 | |
| }, { | |
| el: f.container.children[1], | |
| wrap: 0, | |
| index: -1 | |
| }, { | |
| el: f.container.children[2], | |
| wrap: 0, | |
| index: -1 | |
| }], y[0].el.style.display = y[2].el.style.display = "none", Wa(), r = { | |
| resize: f.updateSize, | |
| orientationchange: function() { | |
| clearTimeout(O), O = setTimeout(function() { | |
| qa.x !== f.scrollWrap.clientWidth && f.updateSize() | |
| }, 500) | |
| }, | |
| scroll: Za, | |
| keydown: Xa, | |
| click: Ya | |
| }; | |
| var d = N.isOldIOSPhone || N.isOldAndroid || N.isMobileOpera; | |
| for (N.animationName && N.transform && !d || (i.showAnimationDuration = i.hideAnimationDuration = 0), c = 0; c < wa.length; c++) f["init" + wa[c]](); | |
| if (b) { | |
| var g = f.ui = new b(f, e); | |
| g.init() | |
| } | |
| Da("firstUpdate"), m = m || i.index || 0, (isNaN(m) || m < 0 || m >= ac()) && (m = 0), f.currItem = _b(m), (N.isOldIOSPhone || N.isOldAndroid) && (va = !1), a.setAttribute("aria-hidden", "false"), i.modal && (va ? a.style.position = "fixed" : (a.style.position = "absolute", a.style.top = e.getScrollY() + "px")), void 0 === M && (Da("initialLayout"), M = K = e.getScrollY()); | |
| var l = "pswp--open "; | |
| for (i.mainClass && (l += i.mainClass + " "), i.showHideOpacity && (l += "pswp--animate_opacity "), l += G ? "pswp--touch" : "pswp--notouch", l += N.animationName ? " pswp--css_animation" : "", l += N.svg ? " pswp--svg" : "", e.addClass(a, l), f.updateSize(), o = -1, ua = null, c = 0; c < h; c++) Ja((c + o) * ta.x, y[c].el.style); | |
| L || e.bind(f.scrollWrap, q, f), Ca("initialZoomInEnd", function() { | |
| f.setContent(y[0], m - 1), f.setContent(y[2], m + 1), y[0].el.style.display = y[2].el.style.display = "block", i.focus && a.focus(), Qa() | |
| }), f.setContent(y[1], m), f.updateCurrItem(), Da("afterInit"), va || (w = setInterval(function() { | |
| _a || V || aa || s !== f.currItem.initialZoomLevel || f.updateSize() | |
| }, 1e3)), e.addClass(a, "pswp--visible") | |
| } | |
| }, | |
| close: function() { | |
| j && (j = !1, k = !0, Da("close"), Ra(), cc(f.currItem, null, !0, f.destroy)) | |
| }, | |
| destroy: function() { | |
| Da("destroy"), Xb && clearTimeout(Xb), a.setAttribute("aria-hidden", "true"), a.className = J, w && clearInterval(w), e.unbind(f.scrollWrap, q, f), e.unbind(window, "scroll", f), zb(), cb(), Ba = null | |
| }, | |
| panTo: function(a, b, c) { | |
| c || (a > da.min.x ? a = da.min.x : a < da.max.x && (a = da.max.x), b > da.min.y ? b = da.min.y : b < da.max.y && (b = da.max.y)), pa.x = a, pa.y = b, Ha() | |
| }, | |
| handleEvent: function(a) { | |
| a = a || window.event, r[a.type] && r[a.type](a) | |
| }, | |
| goTo: function(a) { | |
| a = Aa(a); | |
| var b = a - m; | |
| ua = b, m = a, f.currItem = _b(m), ra -= b, Ka(ta.x * ra), cb(), fa = !1, f.updateCurrItem() | |
| }, | |
| next: function() { | |
| f.goTo(m + 1) | |
| }, | |
| prev: function() { | |
| f.goTo(m - 1) | |
| }, | |
| updateCurrZoomItem: function(a) { | |
| if (a && Da("beforeChange", 0), y[1].el.children.length) { | |
| var b = y[1].el.children[0]; | |
| ea = e.hasClass(b, "pswp__zoom-wrap") ? b.style : null | |
| } else ea = null; | |
| da = f.currItem.bounds, t = s = f.currItem.initialZoomLevel, pa.x = da.center.x, pa.y = da.center.y, a && Da("afterChange") | |
| }, | |
| invalidateCurrItems: function() { | |
| x = !0; | |
| for (var a = 0; a < h; a++) y[a].item && (y[a].item.needsUpdate = !0) | |
| }, | |
| updateCurrItem: function(a) { | |
| if (0 !== ua) { | |
| var b, c = Math.abs(ua); | |
| if (!(a && c < 2)) { | |
| f.currItem = _b(m), ya = !1, Da("beforeChange", ua), c >= h && (o += ua + (ua > 0 ? -h : h), c = h); | |
| for (var d = 0; d < c; d++) ua > 0 ? (b = y.shift(), y[h - 1] = b, o++, Ja((o + 2) * ta.x, b.el.style), f.setContent(b, m - c + d + 1 + 1)) : (b = y.pop(), y.unshift(b), o--, Ja(o * ta.x, b.el.style), f.setContent(b, m + c - d - 1 - 1)); | |
| if (ea && 1 === Math.abs(ua)) { | |
| var e = _b(z); | |
| e.initialZoomLevel !== s && (ic(e, qa), mc(e), Ia(e)) | |
| } | |
| ua = 0, f.updateCurrZoomItem(), z = m, Da("afterChange") | |
| } | |
| } | |
| }, | |
| updateSize: function(b) { | |
| if (!va && i.modal) { | |
| var c = e.getScrollY(); | |
| if (M !== c && (a.style.top = c + "px", M = c), !b && xa.x === window.innerWidth && xa.y === window.innerHeight) return; | |
| xa.x = window.innerWidth, xa.y = window.innerHeight, a.style.height = xa.y + "px" | |
| } | |
| if (qa.x = f.scrollWrap.clientWidth, qa.y = f.scrollWrap.clientHeight, Za(), ta.x = qa.x + Math.round(qa.x * i.spacing), ta.y = qa.y, Ka(ta.x * ra), Da("beforeResize"), void 0 !== o) { | |
| for (var d, g, j, k = 0; k < h; k++) d = y[k], Ja((k + o) * ta.x, d.el.style), j = m + k - 1, i.loop && ac() > 2 && (j = Aa(j)), g = _b(j), g && (x || g.needsUpdate || !g.bounds) ? (f.cleanSlide(g), f.setContent(d, j), 1 === k && (f.currItem = g, f.updateCurrZoomItem(!0)), g.needsUpdate = !1) : d.index === -1 && j >= 0 && f.setContent(d, j), g && g.container && (ic(g, qa), mc(g), Ia(g)); | |
| x = !1 | |
| } | |
| t = s = f.currItem.initialZoomLevel, da = f.currItem.bounds, da && (pa.x = da.center.x, pa.y = da.center.y, Ha(!0)), Da("resize") | |
| }, | |
| zoomTo: function(a, b, c, d, f) { | |
| b && (t = s, ub.x = Math.abs(b.x) - pa.x, ub.y = Math.abs(b.y) - pa.y, Ma(oa, pa)); | |
| var g = Sa(a, !1), | |
| h = {}; | |
| Va("x", g, h, a), Va("y", g, h, a); | |
| var i = s, | |
| j = { | |
| x: pa.x, | |
| y: pa.y | |
| }; | |
| Na(h); | |
| var k = function(b) { | |
| 1 === b ? (s = a, pa.x = h.x, pa.y = h.y) : (s = (a - i) * b + i, pa.x = (h.x - j.x) * b + j.x, pa.y = (h.y - j.y) * b + j.y), f && f(b), Ha(1 === b) | |
| }; | |
| c ? db("customZoomTo", 0, 1, c, d || e.easing.sine.inOut, k) : k(1) | |
| } | |
| }, | |
| fb = 30, | |
| gb = 10, | |
| hb = {}, | |
| ib = {}, | |
| jb = {}, | |
| kb = {}, | |
| lb = {}, | |
| mb = [], | |
| nb = {}, | |
| ob = [], | |
| pb = {}, | |
| qb = 0, | |
| rb = ma(), | |
| sb = 0, | |
| tb = ma(), | |
| ub = ma(), | |
| vb = ma(), | |
| wb = function(a, b) { | |
| return a.x === b.x && a.y === b.y | |
| }, | |
| xb = function(a, b) { | |
| return Math.abs(a.x - b.x) < g && Math.abs(a.y - b.y) < g | |
| }, | |
| yb = function(a, b) { | |
| return pb.x = Math.abs(a.x - b.x), pb.y = Math.abs(a.y - b.y), Math.sqrt(pb.x * pb.x + pb.y * pb.y) | |
| }, | |
| zb = function() { | |
| Z && (I(Z), Z = null) | |
| }, | |
| Ab = function() { | |
| V && (Z = H(Ab), Qb()) | |
| }, | |
| Bb = function() { | |
| return !("fit" === i.scaleMode && s === f.currItem.initialZoomLevel) | |
| }, | |
| Cb = function(a, b) { | |
| return !(!a || a === document) && (!(a.getAttribute("class") && a.getAttribute("class").indexOf("pswp__scroll-wrap") > -1) && (b(a) ? a : Cb(a.parentNode, b))) | |
| }, | |
| Db = {}, | |
| Eb = function(a, b) { | |
| return Db.prevent = !Cb(a.target, i.isClickableElement), Da("preventDragEvent", a, b, Db), Db.prevent | |
| }, | |
| Fb = function(a, b) { | |
| return b.x = a.pageX, b.y = a.pageY, b.id = a.identifier, b | |
| }, | |
| Gb = function(a, b, c) { | |
| c.x = .5 * (a.x + b.x), c.y = .5 * (a.y + b.y) | |
| }, | |
| Hb = function(a, b, c) { | |
| if (a - Q > 50) { | |
| var d = ob.length > 2 ? ob.shift() : {}; | |
| d.x = b, d.y = c, ob.push(d), Q = a | |
| } | |
| }, | |
| Ib = function() { | |
| var a = pa.y - f.currItem.initialPosition.y; | |
| return 1 - Math.abs(a / (qa.y / 2)) | |
| }, | |
| Jb = {}, | |
| Kb = {}, | |
| Lb = [], | |
| Mb = function(a) { | |
| for (; Lb.length > 0;) Lb.pop(); | |
| return F ? (la = 0, mb.forEach(function(a) { | |
| 0 === la ? Lb[0] = a : 1 === la && (Lb[1] = a), la++ | |
| })) : a.type.indexOf("touch") > -1 ? a.touches && a.touches.length > 0 && (Lb[0] = Fb(a.touches[0], Jb), a.touches.length > 1 && (Lb[1] = Fb(a.touches[1], Kb))) : (Jb.x = a.pageX, Jb.y = a.pageY, Jb.id = "", Lb[0] = Jb), Lb | |
| }, | |
| Nb = function(a, b) { | |
| var c, d, e, g, h = 0, | |
| j = pa[a] + b[a], | |
| k = b[a] > 0, | |
| l = tb.x + b.x, | |
| m = tb.x - nb.x; | |
| return c = j > da.min[a] || j < da.max[a] ? i.panEndFriction : 1, j = pa[a] + b[a] * c, !i.allowPanToNext && s !== f.currItem.initialZoomLevel || (ea ? "h" !== ga || "x" !== a || X || (k ? (j > da.min[a] && (c = i.panEndFriction, h = da.min[a] - j, d = da.min[a] - oa[a]), (d <= 0 || m < 0) && ac() > 1 ? (g = l, m < 0 && l > nb.x && (g = nb.x)) : da.min.x !== da.max.x && (e = j)) : (j < da.max[a] && (c = i.panEndFriction, h = j - da.max[a], d = oa[a] - da.max[a]), (d <= 0 || m > 0) && ac() > 1 ? (g = l, m > 0 && l < nb.x && (g = nb.x)) : da.min.x !== da.max.x && (e = j))) : g = l, "x" !== a) ? void(fa || $ || s > f.currItem.fitRatio && (pa[a] += b[a] * c)) : (void 0 !== g && (Ka(g, !0), $ = g !== nb.x), da.min.x !== da.max.x && (void 0 !== e ? pa.x = e : $ || (pa.x += b.x * c)), void 0 !== g) | |
| }, | |
| Ob = function(a) { | |
| if (!("mousedown" === a.type && a.button > 0)) { | |
| if ($b) return void a.preventDefault(); | |
| if (!U || "mousedown" !== a.type) { | |
| if (Eb(a, !0) && a.preventDefault(), Da("pointerDown"), F) { | |
| var b = e.arraySearch(mb, a.pointerId, "id"); | |
| b < 0 && (b = mb.length), mb[b] = { | |
| x: a.pageX, | |
| y: a.pageY, | |
| id: a.pointerId | |
| } | |
| } | |
| var c = Mb(a), | |
| d = c.length; | |
| _ = null, cb(), V && 1 !== d || (V = ha = !0, e.bind(window, p, f), S = ka = ia = T = $ = Y = W = X = !1, ga = null, Da("firstTouchStart", c), Ma(oa, pa), na.x = na.y = 0, Ma(kb, c[0]), Ma(lb, kb), nb.x = ta.x * ra, ob = [{ | |
| x: kb.x, | |
| y: kb.y | |
| }], Q = P = Ea(), Sa(s, !0), zb(), Ab()), !aa && d > 1 && !fa && !$ && (t = s, X = !1, aa = W = !0, na.y = na.x = 0, Ma(oa, pa), Ma(hb, c[0]), Ma(ib, c[1]), Gb(hb, ib, vb), ub.x = Math.abs(vb.x) - pa.x, ub.y = Math.abs(vb.y) - pa.y, ba = ca = yb(hb, ib)) | |
| } | |
| } | |
| }, | |
| Pb = function(a) { | |
| if (a.preventDefault(), F) { | |
| var b = e.arraySearch(mb, a.pointerId, "id"); | |
| if (b > -1) { | |
| var c = mb[b]; | |
| c.x = a.pageX, c.y = a.pageY | |
| } | |
| } | |
| if (V) { | |
| var d = Mb(a); | |
| if (ga || Y || aa) _ = d; | |
| else if (tb.x !== ta.x * ra) ga = "h"; | |
| else { | |
| var f = Math.abs(d[0].x - kb.x) - Math.abs(d[0].y - kb.y); | |
| Math.abs(f) >= gb && (ga = f > 0 ? "h" : "v", _ = d) | |
| } | |
| } | |
| }, | |
| Qb = function() { | |
| if (_) { | |
| var a = _.length; | |
| if (0 !== a) | |
| if (Ma(hb, _[0]), jb.x = hb.x - kb.x, jb.y = hb.y - kb.y, aa && a > 1) { | |
| if (kb.x = hb.x, kb.y = hb.y, !jb.x && !jb.y && wb(_[1], ib)) return; | |
| Ma(ib, _[1]), X || (X = !0, Da("zoomGestureStarted")); | |
| var b = yb(hb, ib), | |
| c = Vb(b); | |
| c > f.currItem.initialZoomLevel + f.currItem.initialZoomLevel / 15 && (ka = !0); | |
| var d = 1, | |
| e = Ta(), | |
| g = Ua(); | |
| if (c < e) | |
| if (i.pinchToClose && !ka && t <= f.currItem.initialZoomLevel) { | |
| var h = e - c, | |
| j = 1 - h / (e / 1.2); | |
| Fa(j), Da("onPinchClose", j), ia = !0 | |
| } else d = (e - c) / e, d > 1 && (d = 1), c = e - d * (e / 3); | |
| else c > g && (d = (c - g) / (6 * e), d > 1 && (d = 1), c = g + d * e); | |
| d < 0 && (d = 0), ba = b, Gb(hb, ib, rb), na.x += rb.x - vb.x, na.y += rb.y - vb.y, Ma(vb, rb), pa.x = La("x", c), pa.y = La("y", c), S = c > s, s = c, Ha() | |
| } else { | |
| if (!ga) return; | |
| if (ha && (ha = !1, Math.abs(jb.x) >= gb && (jb.x -= _[0].x - lb.x), Math.abs(jb.y) >= gb && (jb.y -= _[0].y - lb.y)), kb.x = hb.x, kb.y = hb.y, 0 === jb.x && 0 === jb.y) return; | |
| if ("v" === ga && i.closeOnVerticalDrag && !Bb()) { | |
| na.y += jb.y, pa.y += jb.y; | |
| var k = Ib(); | |
| return T = !0, Da("onVerticalDrag", k), Fa(k), void Ha() | |
| } | |
| Hb(Ea(), hb.x, hb.y), Y = !0, da = f.currItem.bounds; | |
| var l = Nb("x", jb); | |
| l || (Nb("y", jb), Na(pa), Ha()) | |
| } | |
| } | |
| }, | |
| Rb = function(a) { | |
| if (N.isOldAndroid) { | |
| if (U && "mouseup" === a.type) return; | |
| a.type.indexOf("touch") > -1 && (clearTimeout(U), U = setTimeout(function() { | |
| U = 0 | |
| }, 600)) | |
| } | |
| Da("pointerUp"), Eb(a, !1) && a.preventDefault(); | |
| var b; | |
| if (F) { | |
| var c = e.arraySearch(mb, a.pointerId, "id"); | |
| if (c > -1) | |
| if (b = mb.splice(c, 1)[0], navigator.msPointerEnabled) { | |
| var d = { | |
| 4: "mouse", | |
| 2: "touch", | |
| 3: "pen" | |
| }; | |
| b.type = d[a.pointerType], b.type || (b.type = a.pointerType || "mouse") | |
| } else b.type = a.pointerType || "mouse" | |
| } | |
| var g, h = Mb(a), | |
| j = h.length; | |
| if ("mouseup" === a.type && (j = 0), 2 === j) return _ = null, !0; | |
| 1 === j && Ma(lb, h[0]), 0 !== j || ga || fa || (b || ("mouseup" === a.type ? b = { | |
| x: a.pageX, | |
| y: a.pageY, | |
| type: "mouse" | |
| } : a.changedTouches && a.changedTouches[0] && (b = { | |
| x: a.changedTouches[0].pageX, | |
| y: a.changedTouches[0].pageY, | |
| type: "touch" | |
| })), Da("touchRelease", a, b)); | |
| var k = -1; | |
| if (0 === j && (V = !1, e.unbind(window, p, f), zb(), aa ? k = 0 : sb !== -1 && (k = Ea() - sb)), sb = 1 === j ? Ea() : -1, g = k !== -1 && k < 150 ? "zoom" : "swipe", aa && j < 2 && (aa = !1, 1 === j && (g = "zoomPointerUp"), Da("zoomGestureEnded")), _ = null, Y || X || fa || T) | |
| if (cb(), R || (R = Sb()), R.calculateSwipeSpeed("x"), T) { | |
| var l = Ib(); | |
| if (l < i.verticalDragRange) f.close(); | |
| else { | |
| var m = pa.y, | |
| n = ja; | |
| db("verticalDrag", 0, 1, 300, e.easing.cubic.out, function(a) { | |
| pa.y = (f.currItem.initialPosition.y - m) * a + m, Fa((1 - n) * a + n), Ha() | |
| }), Da("onVerticalDrag", 1) | |
| } | |
| } else { | |
| if (($ || fa) && 0 === j) { | |
| var o = Ub(g, R); | |
| if (o) return; | |
| g = "zoomPointerUp" | |
| } | |
| if (!fa) return "swipe" !== g ? void Wb() : void(!$ && s > f.currItem.fitRatio && Tb(R)) | |
| } | |
| }, | |
| Sb = function() { | |
| var a, b, c = { | |
| lastFlickOffset: {}, | |
| lastFlickDist: {}, | |
| lastFlickSpeed: {}, | |
| slowDownRatio: {}, | |
| slowDownRatioReverse: {}, | |
| speedDecelerationRatio: {}, | |
| speedDecelerationRatioAbs: {}, | |
| distanceOffset: {}, | |
| backAnimDestination: {}, | |
| backAnimStarted: {}, | |
| calculateSwipeSpeed: function(d) { | |
| ob.length > 1 ? (a = Ea() - Q + 50, b = ob[ob.length - 2][d]) : (a = Ea() - P, b = lb[d]), c.lastFlickOffset[d] = kb[d] - b, c.lastFlickDist[d] = Math.abs(c.lastFlickOffset[d]), c.lastFlickDist[d] > 20 ? c.lastFlickSpeed[d] = c.lastFlickOffset[d] / a : c.lastFlickSpeed[d] = 0, Math.abs(c.lastFlickSpeed[d]) < .1 && (c.lastFlickSpeed[d] = 0), c.slowDownRatio[d] = .95, c.slowDownRatioReverse[d] = 1 - c.slowDownRatio[d], c.speedDecelerationRatio[d] = 1 | |
| }, | |
| calculateOverBoundsAnimOffset: function(a, b) { | |
| c.backAnimStarted[a] || (pa[a] > da.min[a] ? c.backAnimDestination[a] = da.min[a] : pa[a] < da.max[a] && (c.backAnimDestination[a] = da.max[a]), void 0 !== c.backAnimDestination[a] && (c.slowDownRatio[a] = .7, c.slowDownRatioReverse[a] = 1 - c.slowDownRatio[a], c.speedDecelerationRatioAbs[a] < .05 && (c.lastFlickSpeed[a] = 0, c.backAnimStarted[a] = !0, db("bounceZoomPan" + a, pa[a], c.backAnimDestination[a], b || 300, e.easing.sine.out, function(b) { | |
| pa[a] = b, Ha() | |
| })))) | |
| }, | |
| calculateAnimOffset: function(a) { | |
| c.backAnimStarted[a] || (c.speedDecelerationRatio[a] = c.speedDecelerationRatio[a] * (c.slowDownRatio[a] + c.slowDownRatioReverse[a] - c.slowDownRatioReverse[a] * c.timeDiff / 10), c.speedDecelerationRatioAbs[a] = Math.abs(c.lastFlickSpeed[a] * c.speedDecelerationRatio[a]), c.distanceOffset[a] = c.lastFlickSpeed[a] * c.speedDecelerationRatio[a] * c.timeDiff, pa[a] += c.distanceOffset[a]) | |
| }, | |
| panAnimLoop: function() { | |
| if ($a.zoomPan && ($a.zoomPan.raf = H(c.panAnimLoop), c.now = Ea(), c.timeDiff = c.now - c.lastNow, c.lastNow = c.now, c.calculateAnimOffset("x"), c.calculateAnimOffset("y"), Ha(), c.calculateOverBoundsAnimOffset("x"), c.calculateOverBoundsAnimOffset("y"), c.speedDecelerationRatioAbs.x < .05 && c.speedDecelerationRatioAbs.y < .05)) return pa.x = Math.round(pa.x), pa.y = Math.round(pa.y), Ha(), void ab("zoomPan") | |
| } | |
| }; | |
| return c | |
| }, | |
| Tb = function(a) { | |
| return a.calculateSwipeSpeed("y"), da = f.currItem.bounds, a.backAnimDestination = {}, a.backAnimStarted = {}, Math.abs(a.lastFlickSpeed.x) <= .05 && Math.abs(a.lastFlickSpeed.y) <= .05 ? (a.speedDecelerationRatioAbs.x = a.speedDecelerationRatioAbs.y = 0, a.calculateOverBoundsAnimOffset("x"), a.calculateOverBoundsAnimOffset("y"), !0) : (bb("zoomPan"), a.lastNow = Ea(), void a.panAnimLoop()) | |
| }, | |
| Ub = function(a, b) { | |
| var c; | |
| fa || (qb = m); | |
| var d; | |
| if ("swipe" === a) { | |
| var g = kb.x - lb.x, | |
| h = b.lastFlickDist.x < 10; | |
| g > fb && (h || b.lastFlickOffset.x > 20) ? d = -1 : g < -fb && (h || b.lastFlickOffset.x < -20) && (d = 1) | |
| } | |
| var j; | |
| d && (m += d, m < 0 ? (m = i.loop ? ac() - 1 : 0, j = !0) : m >= ac() && (m = i.loop ? 0 : ac() - 1, j = !0), j && !i.loop || (ua += d, ra -= d, c = !0)); | |
| var k, l = ta.x * ra, | |
| n = Math.abs(l - tb.x); | |
| return c || l > tb.x == b.lastFlickSpeed.x > 0 ? (k = Math.abs(b.lastFlickSpeed.x) > 0 ? n / Math.abs(b.lastFlickSpeed.x) : 333, k = Math.min(k, 400), k = Math.max(k, 250)) : k = 333, qb === m && (c = !1), fa = !0, Da("mainScrollAnimStart"), db("mainScroll", tb.x, l, k, e.easing.cubic.out, Ka, function() { | |
| cb(), fa = !1, qb = -1, (c || qb !== m) && f.updateCurrItem(), Da("mainScrollAnimComplete") | |
| }), c && f.updateCurrItem(!0), c | |
| }, | |
| Vb = function(a) { | |
| return 1 / ca * a * t | |
| }, | |
| Wb = function() { | |
| var a = s, | |
| b = Ta(), | |
| c = Ua(); | |
| s < b ? a = b : s > c && (a = c); | |
| var d, g = 1, | |
| h = ja; | |
| return ia && !S && !ka && s < b ? (f.close(), !0) : (ia && (d = function(a) { | |
| Fa((g - h) * a + h) | |
| }), f.zoomTo(a, 0, 200, e.easing.cubic.out, d), !0) | |
| }; | |
| za("Gestures", { | |
| publicMethods: { | |
| initGestures: function() { | |
| var a = function(a, b, c, d, e) { | |
| A = a + b, B = a + c, C = a + d, D = e ? a + e : "" | |
| }; | |
| F = N.pointerEvent, F && N.touch && (N.touch = !1), F ? navigator.msPointerEnabled ? a("MSPointer", "Down", "Move", "Up", "Cancel") : a("pointer", "down", "move", "up", "cancel") : N.touch ? (a("touch", "start", "move", "end", "cancel"), G = !0) : a("mouse", "down", "move", "up"), p = B + " " + C + " " + D, q = A, F && !G && (G = navigator.maxTouchPoints > 1 || navigator.msMaxTouchPoints > 1), f.likelyTouchDevice = G, r[A] = Ob, r[B] = Pb, r[C] = Rb, D && (r[D] = r[C]), N.touch && (q += " mousedown", p += " mousemove mouseup", r.mousedown = r[A], r.mousemove = r[B], r.mouseup = r[C]), G || (i.allowPanToNext = !1) | |
| } | |
| } | |
| }); | |
| var Xb, Yb, Zb, $b, _b, ac, bc, cc = function(b, c, d, g) { | |
| Xb && clearTimeout(Xb), $b = !0, Zb = !0; | |
| var h; | |
| b.initialLayout ? (h = b.initialLayout, b.initialLayout = null) : h = i.getThumbBoundsFn && i.getThumbBoundsFn(m); | |
| var j = d ? i.hideAnimationDuration : i.showAnimationDuration, | |
| k = function() { | |
| ab("initialZoom"), d ? (f.template.removeAttribute("style"), f.bg.removeAttribute("style")) : (Fa(1), c && (c.style.display = "block"), e.addClass(a, "pswp--animated-in"), Da("initialZoom" + (d ? "OutEnd" : "InEnd"))), g && g(), $b = !1 | |
| }; | |
| if (!j || !h || void 0 === h.x) return Da("initialZoom" + (d ? "Out" : "In")), s = b.initialZoomLevel, Ma(pa, b.initialPosition), Ha(), a.style.opacity = d ? 0 : 1, Fa(1), void(j ? setTimeout(function() { | |
| k() | |
| }, j) : k()); | |
| var n = function() { | |
| var c = l, | |
| g = !f.currItem.src || f.currItem.loadError || i.showHideOpacity; | |
| b.miniImg && (b.miniImg.style.webkitBackfaceVisibility = "hidden"), d || (s = h.w / b.w, pa.x = h.x, pa.y = h.y - K, f[g ? "template" : "bg"].style.opacity = .001, Ha()), bb("initialZoom"), d && !c && e.removeClass(a, "pswp--animated-in"), g && (d ? e[(c ? "remove" : "add") + "Class"](a, "pswp--animate_opacity") : setTimeout(function() { | |
| e.addClass(a, "pswp--animate_opacity") | |
| }, 30)), Xb = setTimeout(function() { | |
| if (Da("initialZoom" + (d ? "Out" : "In")), d) { | |
| var f = h.w / b.w, | |
| i = { | |
| x: pa.x, | |
| y: pa.y | |
| }, | |
| l = s, | |
| m = ja, | |
| n = function(b) { | |
| 1 === b ? (s = f, pa.x = h.x, pa.y = h.y - M) : (s = (f - l) * b + l, pa.x = (h.x - i.x) * b + i.x, pa.y = (h.y - M - i.y) * b + i.y), Ha(), g ? a.style.opacity = 1 - b : Fa(m - b * m) | |
| }; | |
| c ? db("initialZoom", 0, 1, j, e.easing.cubic.out, n, k) : (n(1), Xb = setTimeout(k, j + 20)) | |
| } else s = b.initialZoomLevel, Ma(pa, b.initialPosition), Ha(), Fa(1), g ? a.style.opacity = 1 : Fa(1), Xb = setTimeout(k, j + 20) | |
| }, d ? 25 : 90) | |
| }; | |
| n() | |
| }, | |
| dc = {}, | |
| ec = [], | |
| fc = { | |
| index: 0, | |
| errorMsg: '<div class="pswp__error-msg"><a href="%url%" target="_blank">The image</a> could not be loaded.</div>', | |
| forceProgressiveLoading: !1, | |
| preload: [1, 1], | |
| getNumItemsFn: function() { | |
| return Yb.length | |
| } | |
| }, | |
| gc = function() { | |
| return { | |
| center: { | |
| x: 0, | |
| y: 0 | |
| }, | |
| max: { | |
| x: 0, | |
| y: 0 | |
| }, | |
| min: { | |
| x: 0, | |
| y: 0 | |
| } | |
| } | |
| }, | |
| hc = function(a, b, c) { | |
| var d = a.bounds; | |
| d.center.x = Math.round((dc.x - b) / 2), d.center.y = Math.round((dc.y - c) / 2) + a.vGap.top, d.max.x = b > dc.x ? Math.round(dc.x - b) : d.center.x, d.max.y = c > dc.y ? Math.round(dc.y - c) + a.vGap.top : d.center.y, d.min.x = b > dc.x ? 0 : d.center.x, d.min.y = c > dc.y ? a.vGap.top : d.center.y | |
| }, | |
| ic = function(a, b, c) { | |
| if (a.src && !a.loadError) { | |
| var d = !c; | |
| if (d && (a.vGap || (a.vGap = { | |
| top: 0, | |
| bottom: 0 | |
| }), Da("parseVerticalMargin", a)), dc.x = b.x, dc.y = b.y - a.vGap.top - a.vGap.bottom, d) { | |
| var e = dc.x / a.w, | |
| f = dc.y / a.h; | |
| a.fitRatio = e < f ? e : f; | |
| var g = i.scaleMode; | |
| "orig" === g ? c = 1 : "fit" === g && (c = a.fitRatio), c > 1 && (c = 1), a.initialZoomLevel = c, a.bounds || (a.bounds = gc()) | |
| } | |
| if (!c) return; | |
| return hc(a, a.w * c, a.h * c), d && c === a.initialZoomLevel && (a.initialPosition = a.bounds.center), a.bounds | |
| } | |
| return a.w = a.h = 0, a.initialZoomLevel = a.fitRatio = 1, a.bounds = gc(), a.initialPosition = a.bounds.center, a.bounds | |
| }, | |
| jc = function(a, b, c, d, e, g) { | |
| b.loadError || d && (b.imageAppended = !0, mc(b, d, b === f.currItem && ya), c.appendChild(d), g && setTimeout(function() { | |
| b && b.loaded && b.placeholder && (b.placeholder.style.display = "none", b.placeholder = null) | |
| }, 500)) | |
| }, | |
| kc = function(a) { | |
| a.loading = !0, a.loaded = !1; | |
| var b = a.img = e.createEl("pswp__img", "img"), | |
| c = function() { | |
| a.loading = !1, a.loaded = !0, a.loadComplete ? a.loadComplete(a) : a.img = null, b.onload = b.onerror = null, b = null | |
| }; | |
| return b.onload = c, b.onerror = function() { | |
| a.loadError = !0, c() | |
| }, b.src = a.src, b | |
| }, | |
| lc = function(a, b) { | |
| if (a.src && a.loadError && a.container) return b && (a.container.innerHTML = ""), a.container.innerHTML = i.errorMsg.replace("%url%", a.src), !0 | |
| }, | |
| mc = function(a, b, c) { | |
| if (a.src) { | |
| b || (b = a.container.lastChild); | |
| var d = c ? a.w : Math.round(a.w * a.fitRatio), | |
| e = c ? a.h : Math.round(a.h * a.fitRatio); | |
| a.placeholder && !a.loaded && (a.placeholder.style.width = d + "px", a.placeholder.style.height = e + "px"), b.style.width = d + "px", b.style.height = e + "px" | |
| } | |
| }, | |
| nc = function() { | |
| if (ec.length) { | |
| for (var a, b = 0; b < ec.length; b++) a = ec[b], a.holder.index === a.index && jc(a.index, a.item, a.baseDiv, a.img, !1, a.clearPlaceholder); | |
| ec = [] | |
| } | |
| }; | |
| za("Controller", { | |
| publicMethods: { | |
| lazyLoadItem: function(a) { | |
| a = Aa(a); | |
| var b = _b(a); | |
| b && (!b.loaded && !b.loading || x) && (Da("gettingData", a, b), b.src && kc(b)) | |
| }, | |
| initController: function() { | |
| e.extend(i, fc, !0), f.items = Yb = c, _b = f.getItemAt, ac = i.getNumItemsFn, bc = i.loop, ac() < 3 && (i.loop = !1), Ca("beforeChange", function(a) { | |
| var b, c = i.preload, | |
| d = null === a || a >= 0, | |
| e = Math.min(c[0], ac()), | |
| g = Math.min(c[1], ac()); | |
| for (b = 1; b <= (d ? g : e); b++) f.lazyLoadItem(m + b); | |
| for (b = 1; b <= (d ? e : g); b++) f.lazyLoadItem(m - b) | |
| }), Ca("initialLayout", function() { | |
| f.currItem.initialLayout = i.getThumbBoundsFn && i.getThumbBoundsFn(m) | |
| }), Ca("mainScrollAnimComplete", nc), Ca("initialZoomInEnd", nc), Ca("destroy", function() { | |
| for (var a, b = 0; b < Yb.length; b++) a = Yb[b], a.container && (a.container = null), a.placeholder && (a.placeholder = null), a.img && (a.img = null), a.preloader && (a.preloader = null), a.loadError && (a.loaded = a.loadError = !1); | |
| ec = null | |
| }) | |
| }, | |
| getItemAt: function(a) { | |
| return a >= 0 && (void 0 !== Yb[a] && Yb[a]) | |
| }, | |
| allowProgressiveImg: function() { | |
| return i.forceProgressiveLoading || !G || i.mouseUsed || screen.width > 1200 | |
| }, | |
| setContent: function(a, b) { | |
| i.loop && (b = Aa(b)); | |
| var c = f.getItemAt(a.index); | |
| c && (c.container = null); | |
| var d, g = f.getItemAt(b); | |
| if (!g) return void(a.el.innerHTML = ""); | |
| Da("gettingData", b, g), a.index = b, a.item = g; | |
| var h = g.container = e.createEl("pswp__zoom-wrap"); | |
| if (!g.src && g.html && (g.html.tagName ? h.appendChild(g.html) : h.innerHTML = g.html), lc(g), ic(g, qa), !g.src || g.loadError || g.loaded) g.src && !g.loadError && (d = e.createEl("pswp__img", "img"), d.style.opacity = 1, d.src = g.src, mc(g, d), jc(b, g, h, d, !0)); | |
| else { | |
| if (g.loadComplete = function(c) { | |
| if (j) { | |
| if (a && a.index === b) { | |
| if (lc(c, !0)) return c.loadComplete = c.img = null, ic(c, qa), Ia(c), void(a.index === m && f.updateCurrZoomItem()); | |
| c.imageAppended ? !$b && c.placeholder && (c.placeholder.style.display = "none", c.placeholder = null) : N.transform && (fa || $b) ? ec.push({ | |
| item: c, | |
| baseDiv: h, | |
| img: c.img, | |
| index: b, | |
| holder: a, | |
| clearPlaceholder: !0 | |
| }) : jc(b, c, h, c.img, fa || $b, !0) | |
| } | |
| c.loadComplete = null, c.img = null, Da("imageLoadComplete", b, c) | |
| } | |
| }, e.features.transform) { | |
| var k = "pswp__img pswp__img--placeholder"; | |
| k += g.msrc ? "" : " pswp__img--placeholder--blank"; | |
| var l = e.createEl(k, g.msrc ? "img" : ""); | |
| g.msrc && (l.src = g.msrc), mc(g, l), h.appendChild(l), g.placeholder = l | |
| } | |
| g.loading || kc(g), f.allowProgressiveImg() && (!Zb && N.transform ? ec.push({ | |
| item: g, | |
| baseDiv: h, | |
| img: g.img, | |
| index: b, | |
| holder: a | |
| }) : jc(b, g, h, g.img, !0, !0)) | |
| } | |
| Zb || b !== m ? Ia(g) : (ea = h.style, cc(g, d || g.img)), a.el.innerHTML = "", a.el.appendChild(h) | |
| }, | |
| cleanSlide: function(a) { | |
| a.img && (a.img.onload = a.img.onerror = null), a.loaded = a.loading = a.img = a.imageAppended = !1 | |
| } | |
| } | |
| }); | |
| var oc, pc = {}, | |
| qc = function(a, b, c) { | |
| var d = document.createEvent("CustomEvent"), | |
| e = { | |
| origEvent: a, | |
| target: a.target, | |
| releasePoint: b, | |
| pointerType: c || "touch" | |
| }; | |
| d.initCustomEvent("pswpTap", !0, !0, e), a.target.dispatchEvent(d) | |
| }; | |
| za("Tap", { | |
| publicMethods: { | |
| initTap: function() { | |
| Ca("firstTouchStart", f.onTapStart), Ca("touchRelease", f.onTapRelease), Ca("destroy", function() { | |
| pc = {}, oc = null | |
| }) | |
| }, | |
| onTapStart: function(a) { | |
| a.length > 1 && (clearTimeout(oc), oc = null) | |
| }, | |
| onTapRelease: function(a, b) { | |
| if (b && !Y && !W && !_a) { | |
| var c = b; | |
| if (oc && (clearTimeout(oc), oc = null, xb(c, pc))) return void Da("doubleTap", c); | |
| if ("mouse" === b.type) return void qc(a, b, "mouse"); | |
| var d = a.target.tagName.toUpperCase(); | |
| if ("BUTTON" === d || e.hasClass(a.target, "pswp__single-tap")) return void qc(a, b); | |
| Ma(pc, c), oc = setTimeout(function() { | |
| qc(a, b), oc = null | |
| }, 300) | |
| } | |
| } | |
| } | |
| }); | |
| var rc; | |
| za("DesktopZoom", { | |
| publicMethods: { | |
| initDesktopZoom: function() { | |
| L || (G ? Ca("mouseUsed", function() { | |
| f.setupDesktopZoom() | |
| }) : f.setupDesktopZoom(!0)) | |
| }, | |
| setupDesktopZoom: function(b) { | |
| rc = {}; | |
| var c = "wheel mousewheel DOMMouseScroll"; | |
| Ca("bindEvents", function() { | |
| e.bind(a, c, f.handleMouseWheel) | |
| }), Ca("unbindEvents", function() { | |
| rc && e.unbind(a, c, f.handleMouseWheel) | |
| }), f.mouseZoomedIn = !1; | |
| var d, g = function() { | |
| f.mouseZoomedIn && (e.removeClass(a, "pswp--zoomed-in"), f.mouseZoomedIn = !1), s < 1 ? e.addClass(a, "pswp--zoom-allowed") : e.removeClass(a, "pswp--zoom-allowed"), h() | |
| }, | |
| h = function() { | |
| d && (e.removeClass(a, "pswp--dragging"), d = !1) | |
| }; | |
| Ca("resize", g), Ca("afterChange", g), Ca("pointerDown", function() { | |
| f.mouseZoomedIn && (d = !0, e.addClass(a, "pswp--dragging")) | |
| }), Ca("pointerUp", h), b || g() | |
| }, | |
| handleMouseWheel: function(a) { | |
| if (s <= f.currItem.fitRatio) return i.modal && (!i.closeOnScroll || _a || V ? a.preventDefault() : E && Math.abs(a.deltaY) > 2 && (l = !0, f.close())), !0; | |
| if (a.stopPropagation(), rc.x = 0, "deltaX" in a) 1 === a.deltaMode ? (rc.x = 18 * a.deltaX, rc.y = 18 * a.deltaY) : (rc.x = a.deltaX, rc.y = a.deltaY); | |
| else if ("wheelDelta" in a) a.wheelDeltaX && (rc.x = -.16 * a.wheelDeltaX), a.wheelDeltaY ? rc.y = -.16 * a.wheelDeltaY : rc.y = -.16 * a.wheelDelta; | |
| else { | |
| if (!("detail" in a)) return; | |
| rc.y = a.detail | |
| } | |
| Sa(s, !0); | |
| var b = pa.x - rc.x, | |
| c = pa.y - rc.y; | |
| (i.modal || b <= da.min.x && b >= da.max.x && c <= da.min.y && c >= da.max.y) && a.preventDefault(), f.panTo(b, c) | |
| }, | |
| toggleDesktopZoom: function(b) { | |
| b = b || { | |
| x: qa.x / 2 + sa.x, | |
| y: qa.y / 2 + sa.y | |
| }; | |
| var c = i.getDoubleTapZoom(!0, f.currItem), | |
| d = s === c; | |
| f.mouseZoomedIn = !d, f.zoomTo(d ? f.currItem.initialZoomLevel : c, b, 333), e[(d ? "remove" : "add") + "Class"](a, "pswp--zoomed-in") | |
| } | |
| } | |
| }); | |
| var sc, tc, uc, vc, wc, xc, yc, zc, Ac, Bc, Cc, Dc, Ec = { | |
| history: !0, | |
| galleryUID: 1 | |
| }, | |
| Fc = function() { | |
| return Cc.hash.substring(1) | |
| }, | |
| Gc = function() { | |
| sc && clearTimeout(sc), uc && clearTimeout(uc) | |
| }, | |
| Hc = function() { | |
| var a = Fc(), | |
| b = {}; | |
| if (a.length < 5) return b; | |
| var c, d = a.split("&"); | |
| for (c = 0; c < d.length; c++) | |
| if (d[c]) { | |
| var e = d[c].split("="); | |
| e.length < 2 || (b[e[0]] = e[1]) | |
| } if (i.galleryPIDs) { | |
| var f = b.pid; | |
| for (b.pid = 0, c = 0; c < Yb.length; c++) | |
| if (Yb[c].pid === f) { | |
| b.pid = c; | |
| break | |
| } | |
| } else b.pid = parseInt(b.pid, 10) - 1; | |
| return b.pid < 0 && (b.pid = 0), b | |
| }, | |
| Ic = function() { | |
| if (uc && clearTimeout(uc), _a || V) return void(uc = setTimeout(Ic, 500)); | |
| vc ? clearTimeout(tc) : vc = !0; | |
| var a = m + 1, | |
| b = _b(m); | |
| b.hasOwnProperty("pid") && (a = b.pid); | |
| var c = yc + "&gid=" + i.galleryUID + "&pid=" + a; | |
| zc || Cc.hash.indexOf(c) === -1 && (Bc = !0); | |
| var d = Cc.href.split("#")[0] + "#" + c; | |
| Dc ? "#" + c !== window.location.hash && history[zc ? "replaceState" : "pushState"]("", document.title, d) : zc ? Cc.replace(d) : Cc.hash = c, zc = !0, tc = setTimeout(function() { | |
| vc = !1 | |
| }, 60) | |
| }; | |
| za("History", { | |
| publicMethods: { | |
| initHistory: function() { | |
| if (e.extend(i, Ec, !0), i.history) { | |
| Cc = window.location, Bc = !1, Ac = !1, zc = !1, yc = Fc(), Dc = "pushState" in history, yc.indexOf("gid=") > -1 && (yc = yc.split("&gid=")[0], yc = yc.split("?gid=")[0]), Ca("afterChange", f.updateURL), Ca("unbindEvents", function() { | |
| e.unbind(window, "hashchange", f.onHashChange) | |
| }); | |
| var a = function() { | |
| xc = !0, Ac || (Bc ? history.back() : yc ? Cc.hash = yc : Dc ? history.pushState("", document.title, Cc.pathname + Cc.search) : Cc.hash = ""), Gc() | |
| }; | |
| Ca("unbindEvents", function() { | |
| l && a() | |
| }), Ca("destroy", function() { | |
| xc || a() | |
| }), Ca("firstUpdate", function() { | |
| m = Hc().pid | |
| }); | |
| var b = yc.indexOf("pid="); | |
| b > -1 && (yc = yc.substring(0, b), "&" === yc.slice(-1) && (yc = yc.slice(0, -1))), setTimeout(function() { | |
| j && e.bind(window, "hashchange", f.onHashChange) | |
| }, 40) | |
| } | |
| }, | |
| onHashChange: function() { | |
| return Fc() === yc ? (Ac = !0, void f.close()) : void(vc || (wc = !0, f.goTo(Hc().pid), wc = !1)) | |
| }, | |
| updateURL: function() { | |
| Gc(), wc || (zc ? sc = setTimeout(Ic, 800) : Ic()) | |
| } | |
| } | |
| }), e.extend(f, eb) | |
| }; | |
| return a | |
| }); | |
| /*beautify ignore:end*/ | |
| while (!window.PhotoSwipe) { | |
| await new Promise(resolve => setTimeout(resolve, 10)); | |
| } | |
| resolve(true); | |
| }); | |
| } | |
| async function loadPhotoswipe() { | |
| return new Promise(async (resolve, reject) => { | |
| try { | |
| await _loadScript(`https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.js`); | |
| await _loadScript(`https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe-ui-default.min.js`); | |
| } catch (err) { | |
| await loadLocalPhotoSwipe(); | |
| await loadLocalPhotoSwipeUI(); | |
| } | |
| resolve(); | |
| }); | |
| } | |
| async function addImageSizeDataAttribute() { | |
| // Check cache (synchronous check) | |
| const cache = IMG_getLocalCache(); | |
| if (cache?.expired === true || (cache?.trialExpiresAt && Date.now() > cache.trialExpiresAt)) { | |
| return; // Don't process if expired | |
| } | |
| const $images = document.querySelectorAll(CSS_PRODUCT_IMAGE_TAG); | |
| if (!$images) { | |
| return; | |
| } | |
| const images = await _getCurrentProductImages(); | |
| const $totalVideos = document.querySelectorAll(CSS_VIDEOS_SELECTOR); | |
| const totalVideos = $totalVideos && $totalVideos.length >= 1 ? $totalVideos.length : 0; | |
| let loopIndex = 1; | |
| for (const [i, each] of $images.entries()) { | |
| const $parent = each.closest(CSS_PRODUCT_IMAGE_PARENT); | |
| const $index = each.closest(`[id*='Slide-template'][data-ezfy-media-position], li[data-media-id][data-ezfy-media-position]`); | |
| if (!$index) { | |
| continue; | |
| } | |
| let _index = $index.getAttribute("data-ezfy-media-position"); | |
| if (!_index) { | |
| return; | |
| } | |
| let height; | |
| let width; | |
| let src; | |
| if ($index.hasAttribute(`data-variant-group-media-position`)){ | |
| const id = $index.getAttribute(`data-variant-id`) | |
| const variant = window.ezfyDawnThemeZoomImages.filter(e => parseInt(e.variantId) === parseInt(id) && e.isVariantGroup === true)[loopIndex-1]; | |
| console.log(`i = ${i} ||| loopIndex = ${loopIndex}`) | |
| loopIndex++; | |
| if (!variant){ | |
| debugger; | |
| throw new Error(`Unable to find variant.`) | |
| } | |
| console.log(variant) | |
| height = variant.height; | |
| width = variant.width; | |
| src = variant.src; | |
| } else{ | |
| let index = window.ezfyDawnThemeZoomImages.filter(e => parseInt(e.index) === parseInt(_index))[0].index; | |
| let image = images.filter(e => e.position === index)[0] | |
| if (!image){ | |
| image = images.filter(e => e.position === index - 1)[0] | |
| } | |
| height = image.height; | |
| width = image.width; | |
| src = image.src; | |
| } | |
| if ($parent){ | |
| $parent.setAttribute("data-size-zoom", `${width}x${height}`); | |
| $parent.setAttribute("data-image-large", src); | |
| $parent.setAttribute("data-ezfy-zoom-type", ZOOM_TYPE); | |
| } | |
| } | |
| if (!IS_DAWN_SLIDER) { | |
| const $medias = document.querySelectorAll(CSS_PRODUCT_IMAGE_PARENT); | |
| for (const [i, each] of $medias.entries()) { | |
| each.setAttribute("data-slide-index", i); | |
| } | |
| } | |
| } | |
| function initPhotoSwipeZoom() { | |
| // Check cache (synchronous check) | |
| const cache = IMG_getLocalCache(); | |
| if (cache?.expired === true || (cache?.trialExpiresAt && Date.now() > cache.trialExpiresAt)) { | |
| return; // Silent fail if expired | |
| } | |
| var initPhotoSwipeFromDOM = function(gallerySelector) { | |
| var parseThumbnailElements = function(el) { | |
| var $elements = removeVideosAndHiddenElements(document.querySelectorAll(CSS_INDIVIDUAL_SLIDES_WITHOUT_VIDEO)), | |
| items = [], | |
| linkEl, | |
| size, | |
| item; | |
| console.log($elements) | |
| for (var i = 0; i < $elements.length; i++) { | |
| const $el = $elements[i]; //child element | |
| // include only element nodes | |
| if ($el.nodeType !== 1) { | |
| continue; | |
| } | |
| if (!$el.getAttribute("data-size-zoom")) { | |
| continue; | |
| } | |
| size = $el.getAttribute('data-size-zoom').split('x'); | |
| // create slide object | |
| item = { | |
| src: $el.getAttribute('data-image-large'), | |
| w: parseInt(size[0], 10), | |
| h: parseInt(size[1], 10) | |
| }; | |
| const $image = $el.querySelector('img'); | |
| let _position; | |
| if (HAS_VARIANT_GROUPING){ | |
| const $parent = $el.closest(`[data-variant-group-media-position]`); | |
| if ($parent){ | |
| _position = $parent.getAttribute(`data-ezfy-media-position`); | |
| } | |
| } else{ | |
| _position = $el.getAttribute(`data-image-position`); | |
| } | |
| const position = parseInt(_position) | |
| item.msrc = $el.getAttribute('data-image-large') | |
| item.imagePosition = position; | |
| item.el = $el; | |
| items.push(item); | |
| } | |
| console.log("items: ",items) | |
| return items; | |
| }; | |
| var _closest = function _closest(el, fn) { | |
| return el && (fn(el) ? el : _closest(el.parentNode, fn)); | |
| }; | |
| var onImageClick = function(e) { | |
| e = e || window.event; | |
| e.preventDefault ? e.preventDefault() : e.returnValue = false; | |
| var eTarget = e.target || e.srcElement; | |
| const $parent = eTarget.closest(CSS_PRODUCT_IMAGE_PARENT); | |
| if ($parent) { | |
| const isVideo = $parent.querySelector("video"); | |
| if (isVideo) { | |
| return; | |
| } | |
| } | |
| if (!eTarget.classList.contains('EzfyZoom-button')) { | |
| return; | |
| } | |
| var clickedListItem = _closest(eTarget, function(el) { | |
| if (!el || !el.classList) { | |
| return false; | |
| } | |
| return (el.matches(CSS_INDIVIDUAL_SLIDE)); | |
| }); | |
| if (!clickedListItem) { | |
| return; | |
| } | |
| const $clickedParent = clickedListItem.parentNode; | |
| var clickedGallery = $clickedParent; | |
| var $children = $clickedParent.querySelectorAll(CSS_INDIVIDUAL_SLIDE); | |
| var totalChildren = $children.length; | |
| var nodeIndex = 0; | |
| var index; | |
| const $index = $clickedParent.closest(`[data-slide-index]`) ? $clickedParent.closest(`[data-slide-index]`) : $children[0]; | |
| if (!$index) { | |
| throw new error(`No $index found`) | |
| return; | |
| } | |
| index = parseInt($index.getAttribute(`data-slide-index`)); | |
| if (isOldDawn()){ | |
| restart(); | |
| } | |
| if (index >= 0) { | |
| openPhotoSwipe(index, clickedGallery); | |
| } | |
| return false; | |
| }; | |
| var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) { | |
| var pswpElement = document.querySelectorAll('.pswp')[0], | |
| gallery, | |
| options, | |
| items; | |
| items = parseThumbnailElements(galleryElement); | |
| options = { | |
| barsSize: { | |
| top: 0, | |
| bottom: 'auto' | |
| }, | |
| allowPanToNext: false, | |
| captionEl: false, | |
| closeOnScroll: false, | |
| pinchToClose: false, | |
| tapToToggleControls: false, | |
| history: false, | |
| galleryUID: galleryElement.getAttribute('data-pswp-uid'), | |
| getThumbBoundsFn: function(index) { | |
| var thumbnail = items[index].el.getElementsByTagName('img')[0], | |
| pageYScroll = window.pageYOffset || document.documentElement.scrollTop, | |
| rect = thumbnail.getBoundingClientRect(); | |
| return { | |
| x: rect.left, | |
| y: rect.top + pageYScroll, | |
| w: rect.width | |
| }; | |
| } | |
| }; | |
| if (fromURL) { | |
| if (options.galleryPIDs) { | |
| for (var j = 0; j < items.length; j++) { | |
| if (items[j].pid == index) { | |
| options.index = j; | |
| break; | |
| } | |
| } | |
| } else { | |
| options.index = parseInt(index, 10) - 1; | |
| } | |
| } else { | |
| options.index = parseInt(index, 10); | |
| } | |
| if (isNaN(options.index)) { | |
| return; | |
| } | |
| if (disableAnimation) { | |
| options.showAnimationDuration = 0; | |
| } | |
| gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options); | |
| gallery.init(); | |
| gallery.ui.hideControls(); | |
| gallery.listen('beforeChange', function() { | |
| const $close = document.querySelector(`#ezfyLightbox`); | |
| $close.classList.add(`ezfy-lightbox--block`) | |
| const image = ezfyDawnThemeZoomImages.filter(e => gallery.currItem.src.includes(e.src))[0] | |
| if (!image) { | |
| return; | |
| } | |
| const position = image.imagePosition; | |
| updateMainImageEzfySlider(position); | |
| updateMainImageOnMobile(position); | |
| updateMainSliderImageAsPhotoSwipeChanges(position); | |
| if (isOldDawn()){ | |
| restart(); | |
| } | |
| setTimeout(() => { | |
| $close.classList.remove(`ezfy-lightbox--block`) | |
| }, 100) | |
| }); | |
| gallery.listen('mouseUsed', function() { | |
| }); | |
| }; | |
| var galleryElements = document.querySelectorAll(gallerySelector); | |
| for (var i = 0, l = galleryElements.length; i < l; i++) { | |
| galleryElements[i].setAttribute('data-pswp-uid', i + 1); | |
| galleryElements[i].onclick = onImageClick; | |
| } | |
| }; | |
| initPhotoSwipeFromDOM(CSS_PARENT_SELECTOR); | |
| } | |
| function updateMainImageEzfySlider(position) { | |
| try { | |
| if (!window.hasOwnProperty("ezfyDawnSlider")) { | |
| return; | |
| } | |
| const $loop = document.querySelector(`[data_featured_image_loop]`); | |
| const _loop = $loop.getAttribute("data_featured_image_loop"); | |
| const loop = _loop === 'true' ? true : false; | |
| let $index; | |
| if (document.querySelector(`[data-is-video="true"]`)){ | |
| $index = document.querySelector(`[id^='Slide-template'][data-media-position="${position}"]`); | |
| } else{ | |
| $index = document.querySelector(`[id^='Slide-template'][data-ezfy-media-position="${position}"]`); | |
| } | |
| const _index = $index.getAttribute("data-flickity-index"); | |
| const index = parseInt(_index) - 1; | |
| window.ezfyDawnSlider.select(index, loop, true); | |
| } catch (err) {} | |
| } | |
| function injectButton() { | |
| // Check cache (synchronous check) | |
| const cache = IMG_getLocalCache(); | |
| if (cache?.expired === true || (cache?.trialExpiresAt && Date.now() > cache.trialExpiresAt)) { | |
| return; // Don't inject buttons if expired | |
| } | |
| if (window.ezfyDawnThemeZoomButtonsCreated) { | |
| return; | |
| } | |
| const $button = `<button type="button" class="EzfyZoom-button motion-reduce btn btn--body btn--circle js-photoswipe__zoom product__photo-zoom"></button>`; | |
| const $images = document.querySelectorAll(CSS_PRODUCT_IMAGE_PARENT); | |
| if (!$images) { | |
| return; | |
| } | |
| for (let each of $images) { | |
| if (each.hasAttribute(`data-product-media-type-video`)) { | |
| continue; | |
| } | |
| const $parent = each.closest(`li`) | |
| if ($parent.querySelector(`.EzfyZoom-button`)){ | |
| continue; | |
| } | |
| each.insertAdjacentHTML('beforeend', $button); | |
| } | |
| window.ezfyDawnThemeZoomButtonsCreated = true; | |
| } | |
| function updateMainSliderImageAsPhotoSwipeChanges(position) { | |
| if (HAS_VARIANT_GROUPING){ | |
| const $media = document.querySelector(`[id*='Thumbnail'] [data-variant-group-media-position='${position}'] button`) | |
| if ($media){ | |
| $media.click() | |
| return; | |
| } | |
| } | |
| if (isDawnSliderInstalled()) { | |
| window.ezfyDawnSlider.select(position - 1, window.ezfy_options.featuredImageLoop, true); | |
| } | |
| const layout = detectCurrentLayout(); | |
| if ((!layout === 'thumbnails' || !layout === 'thumbnail_slider')) { | |
| return; | |
| } | |
| const $thumbnail = document.querySelector(`[id*='Slide-Thumbnail'][data-ezfy-media-position='${position}'] > button, li.product-slider[data-ezfy-media-position='${position}']`); | |
| if (!$thumbnail) { | |
| return; | |
| } | |
| $thumbnail.click(); | |
| } | |
| function updateMainImageOnMobile(position) { | |
| if (!_isMobile() && !isOldDawn()) { | |
| return; | |
| } | |
| const $slide = document.querySelector(` | |
| li[data-ezfy-media-position='${position}'], | |
| li[id^='Slide-template'][data-ezfy-media-position='${position}']`); | |
| if ($slide) { | |
| setTimeout(() => { | |
| const scrollY = window.pageYOffset; | |
| const $parent = $slide.closest("ul"); | |
| $parent.style.scrollBehavior = 'unset'; | |
| $slide.scrollIntoView({ | |
| behavior: 'instant' | |
| }); | |
| $parent.style.scrollBehavior = 'smooth'; | |
| window.scrollTo(0, scrollY); | |
| }, 10); | |
| } | |
| } | |
| function blockLightboxOnSliderDrag() { | |
| if (!IS_DAWN_SLIDER || !window.ezfyVentureSliderFeatured || !options.blockSlider || _isMobile()) { | |
| return; | |
| } | |
| const _class = 'FeaturedImage--block-lightbox'; | |
| const $image = document.querySelector(`#featuredImageSlider`); | |
| window.ezfyVentureSliderFeatured.on('dragMove', function(event, pointer, moveVector) { | |
| if ($image.classList.contains(_class)) { | |
| return; | |
| } | |
| $image.classList.add(_class); | |
| }); | |
| window.ezfyVentureSliderFeatured.on('dragEnd', function(event, pointer, moveVector) { | |
| $image.classList.remove(_class); | |
| }); | |
| } | |
| function reset() { | |
| const $slides = document.querySelectorAll(`[data-ezfy-media-position]`); | |
| for (var each of $slides) { | |
| each.removeAttribute("data-ezfy-media-position"); | |
| each.removeAttribute(`data-slide-index`); | |
| } | |
| window.ezfyDawnThemeZoomButtonsCreated = false; | |
| } | |
| function sleep(ms) { | |
| return new Promise(resolve => setTimeout(resolve, ms)); | |
| } | |
| function onSwatchChange() { | |
| const $radios = document.querySelectorAll(`[class*='product-form'] [type='radio']`); | |
| const $selects = document.querySelectorAll(`[class*='product-form'] select`) | |
| if ($radios) { | |
| for (var $radio of $radios) { | |
| $radio.addEventListener("click", async function() { | |
| await _sleep(100); | |
| restart(); | |
| }); | |
| } | |
| } | |
| if ($selects){ | |
| for (var each of $selects) { | |
| each.addEventListener("change", async function() { | |
| await _sleep(100); | |
| restart(); | |
| }); | |
| } | |
| } | |
| } | |
| async function restart() { | |
| const imgConfig = await IMG_validateCache(); | |
| if (!imgConfig.isValid) { | |
| return; | |
| } | |
| reset(); | |
| addImagePositionDataAttribute(); | |
| addImagePositionDataAttributeToThumbnails(); | |
| await addImageSizeDataAttribute(); | |
| initPhotoSwipeZoom(); | |
| blockLightboxOnSliderDrag(); | |
| injectButton(); | |
| } | |
| function _waitForElement(selector, delay = 50, tries = 100) { | |
| const element = document.querySelector(selector); | |
| if (!window[`__${selector}`]) { | |
| window[`__${selector}`] = 0; | |
| window[`__${selector}__delay`] = delay; | |
| window[`__${selector}__tries`] = tries; | |
| } | |
| function _search() { | |
| return new Promise((resolve) => { | |
| window[`__${selector}`]++; | |
| setTimeout(resolve, window[`__${selector}__delay`]); | |
| }); | |
| } | |
| if (element === null) { | |
| if (window[`__${selector}`] >= window[`__${selector}__tries`]) { | |
| window[`__${selector}`] = 0; | |
| return Promise.resolve(null); | |
| } | |
| return _search().then(() => _waitForElement(selector)); | |
| } else { | |
| return Promise.resolve(element); | |
| } | |
| } | |
| function restartOnThumbnailClick(){ | |
| if (!isOldDawn()){ | |
| return; | |
| } | |
| const $triggers = document.querySelectorAll(`#large-image + * ul li, #large-image + * .button-wrapper button`); | |
| for (var each of $triggers){ | |
| each.addEventListener("click", function(){ | |
| restart(); | |
| }); | |
| } | |
| } | |
| async function identifyVideos(){ | |
| const selector = CSS_VIDEOS_SELECTOR; | |
| const $videos = document.querySelectorAll(selector); | |
| for (var each of $videos){ | |
| const $parent = each.closest(`li`) | |
| $parent.setAttribute(`data-is-video`, `true`); | |
| } | |
| } | |
| function restartOnVariantsSelectChange(){ | |
| const targetNode = document.querySelector('.product__info-wrapper'); | |
| if (targetNode) { | |
| const observer = new MutationObserver(() => { | |
| // Query the dynamically injected elements and attach click listeners | |
| const elements = document.querySelectorAll('variant-selects[id] input'); | |
| for (const el of elements) { | |
| if (!el.dataset.listenerAdded) { | |
| el.addEventListener('click', (event) => { | |
| setTimeout(() => { | |
| restart() | |
| }, 1000) | |
| }); | |
| // Mark as having a listener to avoid duplication | |
| el.dataset.listenerAdded = 'true'; | |
| } | |
| } | |
| }); | |
| // Observe changes in child elements and subtree | |
| observer.observe(targetNode, { | |
| childList: true, | |
| subtree: true, | |
| }); | |
| } | |
| } | |
| return { | |
| restart: restart, | |
| init: async function() { | |
| const imgConfig = await IMG_validateCache(); | |
| if (IMG_isEditorMode()) { | |
| IMG_showEditorNotice(imgConfig.remaining, imgConfig.expired); | |
| } | |
| if (!imgConfig.isValid) { | |
| return; | |
| } | |
| onSwatchChange(); | |
| identifyVideos() | |
| addImagePositionDataAttribute(); | |
| addImagePositionDataAttributeToThumbnails(); | |
| if (_isProductPage()) { | |
| loadPhotoswipe(); | |
| } | |
| document.addEventListener("DOMContentLoaded", async function() { | |
| if (_isProductPage()) { | |
| const imgConfig2 = await IMG_validateCache(); | |
| if (!imgConfig2.isValid) { | |
| return; | |
| } | |
| await addImageSizeDataAttribute(); | |
| await _sleep(DELAY_AFTER_LOADING_PHOTO_SWIPE); | |
| initPhotoSwipeZoom(); | |
| blockLightboxOnSliderDrag(); | |
| injectButton(); | |
| restartOnThumbnailClick(); | |
| restartOnVariantsSelectChange(); | |
| } | |
| }); | |
| window.addEventListener("resize", function() {}); | |
| window.addEventListener("load", function() { | |
| var $links= document.querySelectorAll(`a[id*='CardLink-template']`); | |
| for (var each of $links){ | |
| each.addEventListener("click", function(e){ | |
| var href = e.target.getAttribute("href") | |
| window.location.href = href; | |
| }); | |
| } | |
| }); | |
| window.addEventListener("scroll", function() {}); | |
| }, | |
| }; | |
| })(); | |
| ezfyDawnThemeZoom.init(); | |
| </script> | |
| {% endif %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment