From 494a1a774d7769db0ffe701dddcd983624c9ab2f Mon Sep 17 00:00:00 2001 From: sherwinski Date: Thu, 18 Feb 2021 13:01:01 -0800 Subject: [PATCH] chore(release): 1.4.2 --- CHANGELOG.md | 8 ++++++++ bower.json | 2 +- dist/Drift.js | 2 +- dist/Drift.min.js | 2 +- dist/Drift.min.js.map | 2 +- dist/drift-basic.min.css | 2 +- package-lock.json | 2 +- package.json | 2 +- src/js/Drift.js | 2 +- 9 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8c05088..47eac85b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.4.2](https://github.com/imgix/drift/compare/v1.4.1...v1.4.2) (2021-02-18) + + +### Bug Fixes + +* correct demo url on readme.md file ([#580](https://github.com/imgix/drift/issues/580)) ([72fa50e](https://github.com/imgix/drift/commit/72fa50ef984322169842cdb1cc2bc22239f4abc7)) +* favor directly modifying DOM attributes over using `setAttribute()` ([598](https://github.com/imgix/drift/pull/598)) + ### [1.4.1](https://github.com/imgix/drift/compare/v1.4.0...v1.4.1) (2020-10-09) * chore: syncs dependency updates diff --git a/bower.json b/bower.json index a3224f6e..649f885b 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "drift", - "version": "1.4.1", + "version": "1.4.2", "description": "Easily add \"zoom on hover\" functionality to your site's images. Lightweight, no-dependency JavaScript.", "main": [ "dist/Drift.min.js", diff --git a/dist/Drift.js b/dist/Drift.js index 47830f26..9faef7bb 100644 --- a/dist/Drift.js +++ b/dist/Drift.js @@ -1,2 +1,2 @@ -var u="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this;function v(){v=function(){},u.Symbol||(u.Symbol=A)}var B=0;function A(t){return"jscomp_symbol_"+(t||"")+B++}!function(t){function i(n){if(e[n])return e[n].T;var s=e[n]={ja:n,fa:!1,T:{}};return t[n].call(s.T,s,s.T,i),s.fa=!0,s.T}var e={};i.u=t,i.h=e,i.c=function(t,e,n){i.g(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){v(),v(),"undefined"!=typeof Symbol&&Symbol.toStringTag&&(v(),Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})),Object.defineProperty(t,"__esModule",{value:!0})},i.m=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.ba)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)i.c(n,s,function(i){return t[i]}.bind(null,s));return n},i.i=function(t){var e=t&&t.ba?function(){return t.default}:function(){return t};return i.c(e,"a",e),e},i.g=function(t,i){return Object.prototype.hasOwnProperty.call(t,i)},i.o="",i(i.v=0)}([function(t,i,e){function n(t,i){if(i=void 0===i?{}:i,this.h=t,this.g=this.g.bind(this),!a(this.h))throw new TypeError("`new Drift` requires a DOM element as its first argument.");t=i.namespace||null;var e=i.showWhitespaceAtEdges||!1,n=i.containInline||!1,s=i.inlineOffsetX||0,o=i.inlineOffsetY||0,h=i.inlineContainer||document.body,r=i.sourceAttribute||"data-zoom",d=i.zoomFactor||3,u=void 0===i.paneContainer?document.body:i.paneContainer,c=i.inlinePane||375,f=!("handleTouch"in i)||!!i.handleTouch,p=i.onShow||null,l=i.onHide||null,b=!("injectBaseStyles"in i)||!!i.injectBaseStyles,v=i.hoverDelay||0,m=i.touchDelay||0,y=i.hoverBoundingBox||!1,g=i.touchBoundingBox||!1;if(i=i.boundingBoxContainer||document.body,!0!==c&&!a(u))throw new TypeError("`paneContainer` must be a DOM element when `inlinePane !== true`");if(!a(h))throw new TypeError("`inlineContainer` must be a DOM element");this.a={j:t,P:e,I:n,K:s,L:o,w:h,R:r,f:d,ga:u,ea:c,C:f,O:p,N:l,da:b,F:v,A:m,D:y,G:g,H:i},this.a.da&&!document.querySelector(".drift-base-styles")&&((i=document.createElement("style")).type="text/css",i.classList.add("drift-base-styles"),i.appendChild(document.createTextNode(".drift-bounding-box,.drift-zoom-pane{position:absolute;pointer-events:none}@keyframes noop{0%{zoom:1}}@-webkit-keyframes noop{0%{zoom:1}}.drift-zoom-pane.drift-open{display:block}.drift-zoom-pane.drift-closing,.drift-zoom-pane.drift-opening{animation:noop 1ms;-webkit-animation:noop 1ms}.drift-zoom-pane{overflow:hidden;width:100%;height:100%;top:0;left:0}.drift-zoom-pane-loader{display:none}.drift-zoom-pane img{position:absolute;display:block;max-width:none;max-height:none}")),(t=document.head).insertBefore(i,t.firstChild)),this.v(),this.u()}function s(t){t=void 0===t?{}:t,this.h=this.h.bind(this),this.g=this.g.bind(this),this.m=this.m.bind(this),this.s=!1;var i=void 0===t.J?null:t.J,e=void 0===t.f?c():t.f,n=void 0===t.U?c():t.U,s=void 0===t.j?null:t.j,o=void 0===t.P?c():t.P,h=void 0===t.I?c():t.I;this.a={J:i,f:e,U:n,j:s,P:o,I:h,K:void 0===t.K?0:t.K,L:void 0===t.L?0:t.L,w:void 0===t.w?document.body:t.w},this.o=this.i("open"),this.Y=this.i("opening"),this.u=this.i("closing"),this.v=this.i("inline"),this.V=this.i("loading"),this.ha()}function o(t){t=void 0===t?{}:t,this.m=this.m.bind(this),this.B=this.B.bind(this),this.g=this.g.bind(this),this.c=this.c.bind(this);var i=t;t=void 0===i.b?c():i.b;var e=void 0===i.l?c():i.l,n=void 0===i.R?c():i.R,s=void 0===i.C?c():i.C,o=void 0===i.O?null:i.O,a=void 0===i.N?null:i.N,r=void 0===i.F?0:i.F,d=void 0===i.A?0:i.A,u=void 0===i.D?c():i.D,f=void 0===i.G?c():i.G,p=void 0===i.j?null:i.j,l=void 0===i.f?c():i.f;i=void 0===i.H?c():i.H,this.a={b:t,l:e,R:n,C:s,O:o,N:a,F:r,A:d,D:u,G:f,j:p,f:l,H:i},(this.a.D||this.a.G)&&(this.o=new h({j:this.a.j,f:this.a.f,S:this.a.H})),this.enabled=!0,this.M()}function h(t){this.s=!1;var i=void 0===t.j?null:t.j,e=void 0===t.f?c():t.f;t=void 0===t.S?c():t.S,this.a={j:i,f:e,S:t},this.c=this.g("open"),this.h()}function a(t){return f?t instanceof HTMLElement:t&&"object"==typeof t&&null!==t&&1===t.nodeType&&"string"==typeof t.nodeName}function r(t,i){i.forEach((function(i){t.classList.add(i)}))}function d(t,i){i.forEach((function(i){t.classList.remove(i)}))}function c(){throw Error("Missing parameter")}e.r(i);var f="object"==typeof HTMLElement;h.prototype.g=function(t){var i=["drift-"+t],e=this.a.j;return e&&i.push(e+"-"+t),i},h.prototype.h=function(){this.b=document.createElement("div"),r(this.b,this.g("bounding-box"))},h.prototype.show=function(t,i){this.s=!0,this.a.S.appendChild(this.b);var e=this.b.style;e.width=Math.round(t/this.a.f)+"px",e.height=Math.round(i/this.a.f)+"px",r(this.b,this.c)},h.prototype.W=function(){this.s&&this.a.S.removeChild(this.b),this.s=!1,d(this.b,this.c)},h.prototype.setPosition=function(t,i,e){var n=window.pageXOffset,s=window.pageYOffset;t=e.left+t*e.width-this.b.clientWidth/2+n,i=e.top+i*e.height-this.b.clientHeight/2+s,te.left+e.width+n&&(t=e.left+e.width-this.b.clientWidth+n),ie.top+e.height+s&&(i=e.top+e.height-this.b.clientHeight+s),this.b.style.left=t+"px",this.b.style.top=i+"px"},o.prototype.i=function(t){t.preventDefault()},o.prototype.u=function(t){this.a.A&&this.V(t)&&!this.s||t.preventDefault()},o.prototype.V=function(t){return!!t.touches},o.prototype.M=function(){this.a.b.addEventListener("mouseenter",this.g,!1),this.a.b.addEventListener("mouseleave",this.B,!1),this.a.b.addEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.addEventListener("touchstart",this.g,!1),this.a.b.addEventListener("touchend",this.B,!1),this.a.b.addEventListener("touchmove",this.c,!1)):(this.a.b.addEventListener("touchstart",this.i,!1),this.a.b.addEventListener("touchend",this.i,!1),this.a.b.addEventListener("touchmove",this.i,!1))},o.prototype.ca=function(){this.a.b.removeEventListener("mouseenter",this.g,!1),this.a.b.removeEventListener("mouseleave",this.B,!1),this.a.b.removeEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.removeEventListener("touchstart",this.g,!1),this.a.b.removeEventListener("touchend",this.B,!1),this.a.b.removeEventListener("touchmove",this.c,!1)):(this.a.b.removeEventListener("touchstart",this.i,!1),this.a.b.removeEventListener("touchend",this.i,!1),this.a.b.removeEventListener("touchmove",this.i,!1))},o.prototype.g=function(t){this.u(t),this.h=t,"mouseenter"==t.type&&this.a.F?this.v=setTimeout(this.m,this.a.F):this.a.A?this.v=setTimeout(this.m,this.a.A):this.m()},o.prototype.m=function(){if(this.enabled){var t=this.a.O;t&&"function"==typeof t&&t(),this.a.l.show(this.a.b.getAttribute(this.a.R),this.a.b.clientWidth,this.a.b.clientHeight),this.h&&((t=this.h.touches)&&this.a.G||!t&&this.a.D)&&this.o.show(this.a.l.b.clientWidth,this.a.l.b.clientHeight),this.c()}},o.prototype.B=function(t){t&&this.u(t),this.h=null,this.v&&clearTimeout(this.v),this.o&&this.o.W(),(t=this.a.N)&&"function"==typeof t&&t(),this.a.l.W()},o.prototype.c=function(t){if(t)this.u(t),this.h=t;else{if(!this.h)return;t=this.h}if(t.touches)var i=(t=t.touches[0]).clientX,e=t.clientY;else i=t.clientX,e=t.clientY;i=(i-(t=this.a.b.getBoundingClientRect()).left)/this.a.b.clientWidth,e=(e-t.top)/this.a.b.clientHeight,this.o&&this.o.setPosition(i,e,t),this.a.l.setPosition(i,e,t)},u.Object.defineProperties(o.prototype,{s:{configurable:!0,enumerable:!0,get:function(){return this.a.l.s}}}),t=document.createElement("div").style;var p="undefined"!=typeof document&&("animation"in t||"webkitAnimation"in t);s.prototype.i=function(t){var i=["drift-"+t],e=this.a.j;return e&&i.push(e+"-"+t),i},s.prototype.ha=function(){this.b=document.createElement("div"),r(this.b,this.i("zoom-pane"));var t=document.createElement("div");r(t,this.i("zoom-pane-loader")),this.b.appendChild(t),this.c=document.createElement("img"),this.b.appendChild(this.c)},s.prototype.X=function(t){this.c.setAttribute("src",t)},s.prototype.Z=function(t,i){this.c.style.width=t*this.a.f+"px",this.c.style.height=i*this.a.f+"px"},s.prototype.setPosition=function(t,i,e){var n=this.c.offsetWidth,s=this.c.offsetHeight,o=this.b.offsetWidth,h=this.b.offsetHeight,a=o/2-n*t,r=h/2-s*i,d=o-n,u=h-s,c=0e.left+e.width+f&&(t=e.left+e.width-o+f),ie.top+e.height+c&&(i=e.top+e.height-h+c)),this.b.style.left=t+"px",this.b.style.top=i+"px"),this.a.P||(a>s?a=s:an?r=n:re.left+e.width+n&&(t=e.left+e.width-this.b.clientWidth+n),ie.top+e.height+s&&(i=e.top+e.height-this.b.clientHeight+s),this.b.style.left=t+"px",this.b.style.top=i+"px"},o.prototype.i=function(t){t.preventDefault()},o.prototype.u=function(t){this.a.A&&this.V(t)&&!this.s||t.preventDefault()},o.prototype.V=function(t){return!!t.touches},o.prototype.M=function(){this.a.b.addEventListener("mouseenter",this.g,!1),this.a.b.addEventListener("mouseleave",this.B,!1),this.a.b.addEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.addEventListener("touchstart",this.g,!1),this.a.b.addEventListener("touchend",this.B,!1),this.a.b.addEventListener("touchmove",this.c,!1)):(this.a.b.addEventListener("touchstart",this.i,!1),this.a.b.addEventListener("touchend",this.i,!1),this.a.b.addEventListener("touchmove",this.i,!1))},o.prototype.ca=function(){this.a.b.removeEventListener("mouseenter",this.g,!1),this.a.b.removeEventListener("mouseleave",this.B,!1),this.a.b.removeEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.removeEventListener("touchstart",this.g,!1),this.a.b.removeEventListener("touchend",this.B,!1),this.a.b.removeEventListener("touchmove",this.c,!1)):(this.a.b.removeEventListener("touchstart",this.i,!1),this.a.b.removeEventListener("touchend",this.i,!1),this.a.b.removeEventListener("touchmove",this.i,!1))},o.prototype.g=function(t){this.u(t),this.h=t,"mouseenter"==t.type&&this.a.F?this.v=setTimeout(this.m,this.a.F):this.a.A?this.v=setTimeout(this.m,this.a.A):this.m()},o.prototype.m=function(){if(this.enabled){var t=this.a.O;t&&"function"==typeof t&&t(),this.a.l.show(this.a.b.getAttribute(this.a.R),this.a.b.clientWidth,this.a.b.clientHeight),this.h&&((t=this.h.touches)&&this.a.G||!t&&this.a.D)&&this.o.show(this.a.l.b.clientWidth,this.a.l.b.clientHeight),this.c()}},o.prototype.B=function(t){t&&this.u(t),this.h=null,this.v&&clearTimeout(this.v),this.o&&this.o.W(),(t=this.a.N)&&"function"==typeof t&&t(),this.a.l.W()},o.prototype.c=function(t){if(t)this.u(t),this.h=t;else{if(!this.h)return;t=this.h}if(t.touches)var i=(t=t.touches[0]).clientX,e=t.clientY;else i=t.clientX,e=t.clientY;i=(i-(t=this.a.b.getBoundingClientRect()).left)/this.a.b.clientWidth,e=(e-t.top)/this.a.b.clientHeight,this.o&&this.o.setPosition(i,e,t),this.a.l.setPosition(i,e,t)},u.Object.defineProperties(o.prototype,{s:{configurable:!0,enumerable:!0,get:function(){return this.a.l.s}}}),t=document.createElement("div").style;var p="undefined"!=typeof document&&("animation"in t||"webkitAnimation"in t);s.prototype.i=function(t){var i=["drift-"+t],e=this.a.j;return e&&i.push(e+"-"+t),i},s.prototype.ha=function(){this.b=document.createElement("div"),r(this.b,this.i("zoom-pane"));var t=document.createElement("div");r(t,this.i("zoom-pane-loader")),this.b.appendChild(t),this.c=document.createElement("img"),this.b.appendChild(this.c)},s.prototype.X=function(t){this.c.setAttribute("src",t)},s.prototype.Z=function(t,i){this.c.style.width=t*this.a.f+"px",this.c.style.height=i*this.a.f+"px"},s.prototype.setPosition=function(t,i,e){var n=this.c.offsetWidth,s=this.c.offsetHeight,o=this.b.offsetWidth,h=this.b.offsetHeight,a=o/2-n*t,r=h/2-s*i,d=o-n,u=h-s,c=0e.left+e.width+f&&(t=e.left+e.width-o+f),ie.top+e.height+c&&(i=e.top+e.height-h+c)),this.b.style.left=t+"px",this.b.style.top=i+"px"),this.a.P||(a>s?a=s:an?r=n:re.left+e.width+n&&(t=e.left+e.width-this.b.clientWidth+n),ie.top+e.height+s&&(i=e.top+e.height-this.b.clientHeight+s),this.b.style.left=t+"px",this.b.style.top=i+"px"},o.prototype.i=function(t){t.preventDefault()},o.prototype.u=function(t){this.a.A&&this.V(t)&&!this.s||t.preventDefault()},o.prototype.V=function(t){return!!t.touches},o.prototype.M=function(){this.a.b.addEventListener("mouseenter",this.g,!1),this.a.b.addEventListener("mouseleave",this.B,!1),this.a.b.addEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.addEventListener("touchstart",this.g,!1),this.a.b.addEventListener("touchend",this.B,!1),this.a.b.addEventListener("touchmove",this.c,!1)):(this.a.b.addEventListener("touchstart",this.i,!1),this.a.b.addEventListener("touchend",this.i,!1),this.a.b.addEventListener("touchmove",this.i,!1))},o.prototype.ca=function(){this.a.b.removeEventListener("mouseenter",this.g,!1),this.a.b.removeEventListener("mouseleave",this.B,!1),this.a.b.removeEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.removeEventListener("touchstart",this.g,!1),this.a.b.removeEventListener("touchend",this.B,!1),this.a.b.removeEventListener("touchmove",this.c,!1)):(this.a.b.removeEventListener("touchstart",this.i,!1),this.a.b.removeEventListener("touchend",this.i,!1),this.a.b.removeEventListener("touchmove",this.i,!1))},o.prototype.g=function(t){this.u(t),this.h=t,"mouseenter"==t.type&&this.a.F?this.v=setTimeout(this.m,this.a.F):this.a.A?this.v=setTimeout(this.m,this.a.A):this.m()},o.prototype.m=function(){if(this.enabled){var t=this.a.O;t&&"function"==typeof t&&t(),this.a.l.show(this.a.b.getAttribute(this.a.R),this.a.b.clientWidth,this.a.b.clientHeight),this.h&&((t=this.h.touches)&&this.a.G||!t&&this.a.D)&&this.o.show(this.a.l.b.clientWidth,this.a.l.b.clientHeight),this.c()}},o.prototype.B=function(t){t&&this.u(t),this.h=null,this.v&&clearTimeout(this.v),this.o&&this.o.W(),(t=this.a.N)&&"function"==typeof t&&t(),this.a.l.W()},o.prototype.c=function(t){if(t)this.u(t),this.h=t;else{if(!this.h)return;t=this.h}if(t.touches)var i=(t=t.touches[0]).clientX,e=t.clientY;else i=t.clientX,e=t.clientY;i=(i-(t=this.a.b.getBoundingClientRect()).left)/this.a.b.clientWidth,e=(e-t.top)/this.a.b.clientHeight,this.o&&this.o.setPosition(i,e,t),this.a.l.setPosition(i,e,t)},u.Object.defineProperties(o.prototype,{s:{configurable:!0,enumerable:!0,get:function(){return this.a.l.s}}}),t=document.createElement("div").style;var p="undefined"!=typeof document&&("animation"in t||"webkitAnimation"in t);s.prototype.i=function(t){var i=["drift-"+t],e=this.a.j;return e&&i.push(e+"-"+t),i},s.prototype.ha=function(){this.b=document.createElement("div"),r(this.b,this.i("zoom-pane"));var t=document.createElement("div");r(t,this.i("zoom-pane-loader")),this.b.appendChild(t),this.c=document.createElement("img"),this.b.appendChild(this.c)},s.prototype.X=function(t){this.c.setAttribute("src",t)},s.prototype.Z=function(t,i){this.c.style.width=t*this.a.f+"px",this.c.style.height=i*this.a.f+"px"},s.prototype.setPosition=function(t,i,e){var n=this.c.offsetWidth,s=this.c.offsetHeight,o=this.b.offsetWidth,h=this.b.offsetHeight,a=o/2-n*t,r=h/2-s*i,d=o-n,u=h-s,c=0e.left+e.width+f&&(t=e.left+e.width-o+f),ie.top+e.height+c&&(i=e.top+e.height-h+c)),this.b.style.left=t+"px",this.b.style.top=i+"px"),this.a.P||(a>s?a=s:an?r=n:re.left+e.width+n&&(t=e.left+e.width-this.b.clientWidth+n),ie.top+e.height+s&&(i=e.top+e.height-this.b.clientHeight+s),this.b.style.left=t+"px",this.b.style.top=i+"px"},o.prototype.i=function(t){t.preventDefault()},o.prototype.u=function(t){this.a.A&&this.V(t)&&!this.s||t.preventDefault()},o.prototype.V=function(t){return!!t.touches},o.prototype.M=function(){this.a.b.addEventListener("mouseenter",this.g,!1),this.a.b.addEventListener("mouseleave",this.B,!1),this.a.b.addEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.addEventListener("touchstart",this.g,!1),this.a.b.addEventListener("touchend",this.B,!1),this.a.b.addEventListener("touchmove",this.c,!1)):(this.a.b.addEventListener("touchstart",this.i,!1),this.a.b.addEventListener("touchend",this.i,!1),this.a.b.addEventListener("touchmove",this.i,!1))},o.prototype.ca=function(){this.a.b.removeEventListener("mouseenter",this.g,!1),this.a.b.removeEventListener("mouseleave",this.B,!1),this.a.b.removeEventListener("mousemove",this.c,!1),this.a.C?(this.a.b.removeEventListener("touchstart",this.g,!1),this.a.b.removeEventListener("touchend",this.B,!1),this.a.b.removeEventListener("touchmove",this.c,!1)):(this.a.b.removeEventListener("touchstart",this.i,!1),this.a.b.removeEventListener("touchend",this.i,!1),this.a.b.removeEventListener("touchmove",this.i,!1))},o.prototype.g=function(t){this.u(t),this.h=t,"mouseenter"==t.type&&this.a.F?this.v=setTimeout(this.m,this.a.F):this.a.A?this.v=setTimeout(this.m,this.a.A):this.m()},o.prototype.m=function(){if(this.enabled){var t=this.a.O;t&&"function"==typeof t&&t(),this.a.l.show(this.a.b.getAttribute(this.a.R),this.a.b.clientWidth,this.a.b.clientHeight),this.h&&((t=this.h.touches)&&this.a.G||!t&&this.a.D)&&this.o.show(this.a.l.b.clientWidth,this.a.l.b.clientHeight),this.c()}},o.prototype.B=function(t){t&&this.u(t),this.h=null,this.v&&clearTimeout(this.v),this.o&&this.o.W(),(t=this.a.N)&&"function"==typeof t&&t(),this.a.l.W()},o.prototype.c=function(t){if(t)this.u(t),this.h=t;else{if(!this.h)return;t=this.h}if(t.touches)var i=(t=t.touches[0]).clientX,e=t.clientY;else i=t.clientX,e=t.clientY;i=(i-(t=this.a.b.getBoundingClientRect()).left)/this.a.b.clientWidth,e=(e-t.top)/this.a.b.clientHeight,this.o&&this.o.setPosition(i,e,t),this.a.l.setPosition(i,e,t)},u.Object.defineProperties(o.prototype,{s:{configurable:!0,enumerable:!0,get:function(){return this.a.l.s}}}),t=document.createElement("div").style;var p="undefined"!=typeof document&&("animation"in t||"webkitAnimation"in t);s.prototype.i=function(t){var i=["drift-"+t],e=this.a.j;return e&&i.push(e+"-"+t),i},s.prototype.ha=function(){this.b=document.createElement("div"),r(this.b,this.i("zoom-pane"));var t=document.createElement("div");r(t,this.i("zoom-pane-loader")),this.b.appendChild(t),this.c=document.createElement("img"),this.b.appendChild(this.c)},s.prototype.X=function(t){this.c.setAttribute("src",t)},s.prototype.Z=function(t,i){this.c.style.width=t*this.a.f+"px",this.c.style.height=i*this.a.f+"px"},s.prototype.setPosition=function(t,i,e){var n=this.c.offsetWidth,s=this.c.offsetHeight,o=this.b.offsetWidth,h=this.b.offsetHeight,a=o/2-n*t,r=h/2-s*i,d=o-n,u=h-s,c=0e.left+e.width+f&&(t=e.left+e.width-o+f),ie.top+e.height+c&&(i=e.top+e.height-h+c)),this.b.style.left=t+"px",this.b.style.top=i+"px"),this.a.P||(a>s?a=s:an?r=n:r triggerRect.left + triggerRect.width + pageXOffset) {\n inlineLeft = triggerRect.left + triggerRect.width - this.el.clientWidth + pageXOffset;\n }\n\n if (inlineTop < triggerRect.top + pageYOffset) {\n inlineTop = triggerRect.top + pageYOffset;\n } else if (inlineTop + this.el.clientHeight > triggerRect.top + triggerRect.height + pageYOffset) {\n inlineTop = triggerRect.top + triggerRect.height - this.el.clientHeight + pageYOffset;\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n}\n\n// CONCATENATED MODULE: ./src/js/Trigger.js\n\n\n\nclass Trigger_Trigger {\n constructor(options = {}) {\n this._show = this._show.bind(this);\n this._hide = this._hide.bind(this);\n this._handleEntry = this._handleEntry.bind(this);\n this._handleMovement = this._handleMovement.bind(this);\n\n const {\n el = throwIfMissing(),\n zoomPane = throwIfMissing(),\n sourceAttribute = throwIfMissing(),\n handleTouch = throwIfMissing(),\n onShow = null,\n onHide = null,\n hoverDelay = 0,\n touchDelay = 0,\n hoverBoundingBox = throwIfMissing(),\n touchBoundingBox = throwIfMissing(),\n namespace = null,\n zoomFactor = throwIfMissing(),\n boundingBoxContainer = throwIfMissing(),\n } = options;\n\n this.settings = {\n el,\n zoomPane,\n sourceAttribute,\n handleTouch,\n onShow,\n onHide,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n namespace,\n zoomFactor,\n boundingBoxContainer,\n };\n\n if (this.settings.hoverBoundingBox || this.settings.touchBoundingBox) {\n this.boundingBox = new BoundingBox_BoundingBox({\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n containerEl: this.settings.boundingBoxContainer,\n });\n }\n\n this.enabled = true;\n\n this._bindEvents();\n }\n\n get isShowing() {\n return this.settings.zoomPane.isShowing;\n }\n\n _preventDefault(event) {\n event.preventDefault();\n }\n\n _preventDefaultAllowTouchScroll(event) {\n if (!this.settings.touchDelay || !this._isTouchEvent(event) || this.isShowing) {\n event.preventDefault();\n }\n }\n\n _isTouchEvent(event) {\n return !!event.touches;\n }\n\n _bindEvents() {\n this.settings.el.addEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.addEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.addEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.addEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.addEventListener(\"touchend\", this._hide, false);\n this.settings.el.addEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.addEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _unbindEvents() {\n this.settings.el.removeEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.removeEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.removeEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"touchend\", this._hide, false);\n this.settings.el.removeEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.removeEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _handleEntry(e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n\n if (e.type == \"mouseenter\" && this.settings.hoverDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.hoverDelay);\n } else if (this.settings.touchDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.touchDelay);\n } else {\n this._show();\n }\n }\n\n _show() {\n if (!this.enabled) {\n return;\n }\n\n const onShow = this.settings.onShow;\n if (onShow && typeof onShow === \"function\") {\n onShow();\n }\n\n this.settings.zoomPane.show(\n this.settings.el.getAttribute(this.settings.sourceAttribute),\n this.settings.el.clientWidth,\n this.settings.el.clientHeight\n );\n\n if (this._lastMovement) {\n const touchActivated = this._lastMovement.touches;\n if ((touchActivated && this.settings.touchBoundingBox) || (!touchActivated && this.settings.hoverBoundingBox)) {\n this.boundingBox.show(this.settings.zoomPane.el.clientWidth, this.settings.zoomPane.el.clientHeight);\n }\n }\n\n this._handleMovement();\n }\n\n _hide(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n }\n\n this._lastMovement = null;\n\n if (this.entryTimeout) {\n clearTimeout(this.entryTimeout);\n }\n\n if (this.boundingBox) {\n this.boundingBox.hide();\n }\n\n const onHide = this.settings.onHide;\n if (onHide && typeof onHide === \"function\") {\n onHide();\n }\n\n this.settings.zoomPane.hide();\n }\n\n _handleMovement(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n } else if (this._lastMovement) {\n e = this._lastMovement;\n } else {\n return;\n }\n\n let movementX;\n let movementY;\n\n if (e.touches) {\n const firstTouch = e.touches[0];\n movementX = firstTouch.clientX;\n movementY = firstTouch.clientY;\n } else {\n movementX = e.clientX;\n movementY = e.clientY;\n }\n\n const el = this.settings.el;\n const rect = el.getBoundingClientRect();\n const offsetX = movementX - rect.left;\n const offsetY = movementY - rect.top;\n\n const percentageOffsetX = offsetX / this.settings.el.clientWidth;\n const percentageOffsetY = offsetY / this.settings.el.clientHeight;\n\n if (this.boundingBox) {\n this.boundingBox.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n\n this.settings.zoomPane.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n}\n\n// CONCATENATED MODULE: ./src/js/ZoomPane.js\n\n\n\n// All officially-supported browsers have this, but it's easy to\n// account for, just in case.\nconst divStyle = document.createElement(\"div\").style;\n\nconst HAS_ANIMATION =\n typeof document === \"undefined\" ? false : \"animation\" in divStyle || \"webkitAnimation\" in divStyle;\n\nclass ZoomPane_ZoomPane {\n constructor(options = {}) {\n this._completeShow = this._completeShow.bind(this);\n this._completeHide = this._completeHide.bind(this);\n this._handleLoad = this._handleLoad.bind(this);\n\n this.isShowing = false;\n\n const {\n container = null,\n zoomFactor = throwIfMissing(),\n inline = throwIfMissing(),\n namespace = null,\n showWhitespaceAtEdges = throwIfMissing(),\n containInline = throwIfMissing(),\n inlineOffsetX = 0,\n inlineOffsetY = 0,\n inlineContainer = document.body,\n } = options;\n\n this.settings = {\n container,\n zoomFactor,\n inline,\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n };\n\n this.openClasses = this._buildClasses(\"open\");\n this.openingClasses = this._buildClasses(\"opening\");\n this.closingClasses = this._buildClasses(\"closing\");\n this.inlineClasses = this._buildClasses(\"inline\");\n this.loadingClasses = this._buildClasses(\"loading\");\n\n this._buildElement();\n }\n\n _buildClasses(suffix) {\n const classes = [`drift-${suffix}`];\n\n const ns = this.settings.namespace;\n if (ns) {\n classes.push(`${ns}-${suffix}`);\n }\n\n return classes;\n }\n\n _buildElement() {\n this.el = document.createElement(\"div\");\n addClasses(this.el, this._buildClasses(\"zoom-pane\"));\n\n const loaderEl = document.createElement(\"div\");\n addClasses(loaderEl, this._buildClasses(\"zoom-pane-loader\"));\n this.el.appendChild(loaderEl);\n\n this.imgEl = document.createElement(\"img\");\n this.el.appendChild(this.imgEl);\n }\n\n _setImageURL(imageURL) {\n this.imgEl.setAttribute(\"src\", imageURL);\n }\n\n _setImageSize(triggerWidth, triggerHeight) {\n this.imgEl.style.width = `${triggerWidth * this.settings.zoomFactor}px`;\n this.imgEl.style.height = `${triggerHeight * this.settings.zoomFactor}px`;\n }\n\n // `percentageOffsetX` and `percentageOffsetY` must be percentages\n // expressed as floats between `0' and `1`.\n setPosition(percentageOffsetX, percentageOffsetY, triggerRect) {\n const imgElWidth = this.imgEl.offsetWidth;\n const imgElHeight = this.imgEl.offsetHeight;\n const elWidth = this.el.offsetWidth;\n const elHeight = this.el.offsetHeight;\n\n const centreOfContainerX = elWidth / 2;\n const centreOfContainerY = elHeight / 2;\n\n const targetImgXToBeCentre = imgElWidth * percentageOffsetX;\n const targetImgYToBeCentre = imgElHeight * percentageOffsetY;\n\n let left = centreOfContainerX - targetImgXToBeCentre;\n let top = centreOfContainerY - targetImgYToBeCentre;\n\n const differenceBetweenContainerWidthAndImgWidth = elWidth - imgElWidth;\n const differenceBetweenContainerHeightAndImgHeight = elHeight - imgElHeight;\n const isContainerLargerThanImgX = differenceBetweenContainerWidthAndImgWidth > 0;\n const isContainerLargerThanImgY = differenceBetweenContainerHeightAndImgHeight > 0;\n\n const minLeft = isContainerLargerThanImgX ? differenceBetweenContainerWidthAndImgWidth / 2 : 0;\n const minTop = isContainerLargerThanImgY ? differenceBetweenContainerHeightAndImgHeight / 2 : 0;\n\n const maxLeft = isContainerLargerThanImgX\n ? differenceBetweenContainerWidthAndImgWidth / 2\n : differenceBetweenContainerWidthAndImgWidth;\n const maxTop = isContainerLargerThanImgY\n ? differenceBetweenContainerHeightAndImgHeight / 2\n : differenceBetweenContainerHeightAndImgHeight;\n\n if (this.el.parentElement === this.settings.inlineContainer) {\n // This may be needed in the future to deal with browser event\n // inconsistencies, but it's difficult to tell for sure.\n // let scrollX = isTouch ? 0 : window.scrollX;\n // let scrollY = isTouch ? 0 : window.scrollY;\n const scrollX = window.pageXOffset;\n const scrollY = window.pageYOffset;\n\n let inlineLeft =\n triggerRect.left + percentageOffsetX * triggerRect.width - elWidth / 2 + this.settings.inlineOffsetX + scrollX;\n let inlineTop =\n triggerRect.top + percentageOffsetY * triggerRect.height - elHeight / 2 + this.settings.inlineOffsetY + scrollY;\n\n if (this.settings.containInline) {\n if (inlineLeft < triggerRect.left + scrollX) {\n inlineLeft = triggerRect.left + scrollX;\n } else if (inlineLeft + elWidth > triggerRect.left + triggerRect.width + scrollX) {\n inlineLeft = triggerRect.left + triggerRect.width - elWidth + scrollX;\n }\n\n if (inlineTop < triggerRect.top + scrollY) {\n inlineTop = triggerRect.top + scrollY;\n } else if (inlineTop + elHeight > triggerRect.top + triggerRect.height + scrollY) {\n inlineTop = triggerRect.top + triggerRect.height - elHeight + scrollY;\n }\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n\n if (!this.settings.showWhitespaceAtEdges) {\n if (left > minLeft) {\n left = minLeft;\n } else if (left < maxLeft) {\n left = maxLeft;\n }\n\n if (top > minTop) {\n top = minTop;\n } else if (top < maxTop) {\n top = maxTop;\n }\n }\n\n this.imgEl.style.transform = `translate(${left}px, ${top}px)`;\n this.imgEl.style.webkitTransform = `translate(${left}px, ${top}px)`;\n }\n\n get _isInline() {\n const inline = this.settings.inline;\n\n return inline === true || (typeof inline === \"number\" && window.innerWidth <= inline);\n }\n\n _removeListenersAndResetClasses() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n }\n\n show(imageURL, triggerWidth, triggerHeight) {\n this._removeListenersAndResetClasses();\n this.isShowing = true;\n\n addClasses(this.el, this.openClasses);\n\n if (this.imgEl.getAttribute(\"src\") != imageURL) {\n addClasses(this.el, this.loadingClasses);\n this.imgEl.addEventListener(\"load\", this._handleLoad, false);\n this._setImageURL(imageURL);\n }\n\n this._setImageSize(triggerWidth, triggerHeight);\n\n if (this._isInline) {\n this._showInline();\n } else {\n this._showInContainer();\n }\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeShow, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n addClasses(this.el, this.openingClasses);\n }\n }\n\n _showInline() {\n this.settings.inlineContainer.appendChild(this.el);\n addClasses(this.el, this.inlineClasses);\n }\n\n _showInContainer() {\n this.settings.container.appendChild(this.el);\n }\n\n hide() {\n this._removeListenersAndResetClasses();\n this.isShowing = false;\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeHide, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n addClasses(this.el, this.closingClasses);\n } else {\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.inlineClasses);\n }\n }\n\n _completeShow() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n\n removeClasses(this.el, this.openingClasses);\n }\n\n _completeHide() {\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n removeClasses(this.el, this.inlineClasses);\n\n this.el.setAttribute(\"style\", \"\");\n\n // The window could have been resized above or below `inline`\n // limits since the ZoomPane was shown. Because of this, we\n // can't rely on `this._isInline` here.\n if (this.el.parentElement === this.settings.container) {\n this.settings.container.removeChild(this.el);\n } else if (this.el.parentElement === this.settings.inlineContainer) {\n this.settings.inlineContainer.removeChild(this.el);\n }\n }\n\n _handleLoad() {\n this.imgEl.removeEventListener(\"load\", this._handleLoad, false);\n removeClasses(this.el, this.loadingClasses);\n }\n}\n\n// CONCATENATED MODULE: ./src/js/Drift.js\n\n\n\n\n\n\nclass Drift_Drift {\n constructor(triggerEl, options = {}) {\n this.VERSION = \"1.4.1\";\n this.triggerEl = triggerEl;\n\n this.destroy = this.destroy.bind(this);\n\n if (!isDOMElement(this.triggerEl)) {\n throw new TypeError(\"`new Drift` requires a DOM element as its first argument.\");\n }\n\n // Prefix for generated element class names (e.g. `my-ns` will\n // result in classes such as `my-ns-pane`. Default `drift-`\n // prefixed classes will always be added as well.\n const namespace = options[\"namespace\"] || null;\n // Whether the ZoomPane should show whitespace when near the edges.\n const showWhitespaceAtEdges = options[\"showWhitespaceAtEdges\"] || false;\n // Whether the inline ZoomPane should stay inside\n // the bounds of its image.\n const containInline = options[\"containInline\"] || false;\n // How much to offset the ZoomPane from the\n // interaction point when inline.\n const inlineOffsetX = options[\"inlineOffsetX\"] || 0;\n const inlineOffsetY = options[\"inlineOffsetY\"] || 0;\n // A DOM element to append the inline ZoomPane to\n const inlineContainer = options[\"inlineContainer\"] || document.body;\n // Which trigger attribute to pull the ZoomPane image source from.\n const sourceAttribute = options[\"sourceAttribute\"] || \"data-zoom\";\n // How much to magnify the trigger by in the ZoomPane.\n // (e.g., `zoomFactor: 3` will result in a 900 px wide ZoomPane imag\n // if the trigger is displayed at 300 px wide)\n const zoomFactor = options[\"zoomFactor\"] || 3;\n // A DOM element to append the non-inline ZoomPane to.\n // Required if `inlinePane !== true`.\n const paneContainer = options[\"paneContainer\"] === undefined ? document.body : options[\"paneContainer\"];\n // When to switch to an inline ZoomPane. This can be a boolean or\n // an integer. If `true`, the ZoomPane will always be inline,\n // if `false`, it will switch to inline when `windowWidth <= inlinePane`\n const inlinePane = options[\"inlinePane\"] || 375;\n // If `true`, touch events will trigger the zoom, like mouse events.\n const handleTouch = \"handleTouch\" in options ? !!options[\"handleTouch\"] : true;\n // If present (and a function), this will be called\n // whenever the ZoomPane is shown.\n const onShow = options[\"onShow\"] || null;\n // If present (and a function), this will be called\n // whenever the ZoomPane is hidden.\n const onHide = options[\"onHide\"] || null;\n // Add base styles to the page. See the \"Theming\"\n // section of README.md for more information.\n const injectBaseStyles = \"injectBaseStyles\" in options ? !!options[\"injectBaseStyles\"] : true;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `mouseenter` event.\n const hoverDelay = options[\"hoverDelay\"] || 0;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `touchstart` event.\n // It's unlikely that you would want to use this option, since\n // \"tap and hold\" is much more intentional than a hover event.\n const touchDelay = options[\"touchDelay\"] || 0;\n // If true, a bounding box will show the area currently being previewed\n // during mouse hover\n const hoverBoundingBox = options[\"hoverBoundingBox\"] || false;\n // If true, a bounding box will show the area currently being previewed\n // during touch events\n const touchBoundingBox = options[\"touchBoundingBox\"] || false;\n // A DOM element to append the bounding box to.\n const boundingBoxContainer = options[\"boundingBoxContainer\"] || document.body;\n\n if (inlinePane !== true && !isDOMElement(paneContainer)) {\n throw new TypeError(\"`paneContainer` must be a DOM element when `inlinePane !== true`\");\n }\n if (!isDOMElement(inlineContainer)) {\n throw new TypeError(\"`inlineContainer` must be a DOM element\");\n }\n\n this.settings = {\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n sourceAttribute,\n zoomFactor,\n paneContainer,\n inlinePane,\n handleTouch,\n onShow,\n onHide,\n injectBaseStyles,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n boundingBoxContainer,\n };\n\n if (this.settings.injectBaseStyles) {\n injectBaseStylesheet();\n }\n\n this._buildZoomPane();\n this._buildTrigger();\n }\n\n get isShowing() {\n return this.zoomPane.isShowing;\n }\n\n get zoomFactor() {\n return this.settings.zoomFactor;\n }\n\n set zoomFactor(zf) {\n this.settings.zoomFactor = zf;\n this.zoomPane.settings.zoomFactor = zf;\n this.trigger.settings.zoomFactor = zf;\n this.boundingBox.settings.zoomFactor = zf;\n }\n\n _buildZoomPane() {\n this.zoomPane = new ZoomPane_ZoomPane({\n container: this.settings.paneContainer,\n zoomFactor: this.settings.zoomFactor,\n showWhitespaceAtEdges: this.settings.showWhitespaceAtEdges,\n containInline: this.settings.containInline,\n inline: this.settings.inlinePane,\n namespace: this.settings.namespace,\n inlineOffsetX: this.settings.inlineOffsetX,\n inlineOffsetY: this.settings.inlineOffsetY,\n inlineContainer: this.settings.inlineContainer,\n });\n }\n\n _buildTrigger() {\n this.trigger = new Trigger_Trigger({\n el: this.triggerEl,\n zoomPane: this.zoomPane,\n handleTouch: this.settings.handleTouch,\n onShow: this.settings.onShow,\n onHide: this.settings.onHide,\n sourceAttribute: this.settings.sourceAttribute,\n hoverDelay: this.settings.hoverDelay,\n touchDelay: this.settings.touchDelay,\n hoverBoundingBox: this.settings.hoverBoundingBox,\n touchBoundingBox: this.settings.touchBoundingBox,\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n boundingBoxContainer: this.settings.boundingBoxContainer,\n });\n }\n\n setZoomImageURL(imageURL) {\n this.zoomPane._setImageURL(imageURL);\n }\n\n disable() {\n this.trigger.enabled = false;\n }\n\n enable() {\n this.trigger.enabled = true;\n }\n\n destroy() {\n this.trigger._hide();\n this.trigger._unbindEvents();\n }\n}\n\n// Public API\n/* eslint-disable no-self-assign */\nObject.defineProperty(Drift_Drift.prototype, \"isShowing\", {\n get: function () {\n return this.isShowing;\n },\n});\nObject.defineProperty(Drift_Drift.prototype, \"zoomFactor\", {\n get: function () {\n return this.zoomFactor;\n },\n set: function (value) {\n this.zoomFactor = value;\n },\n});\nDrift_Drift.prototype[\"setZoomImageURL\"] = Drift_Drift.prototype.setZoomImageURL;\nDrift_Drift.prototype[\"disable\"] = Drift_Drift.prototype.disable;\nDrift_Drift.prototype[\"enable\"] = Drift_Drift.prototype.enable;\nDrift_Drift.prototype[\"destroy\"] = Drift_Drift.prototype.destroy;\n/* eslint-enable no-self-assign */\n\n// CONCATENATED MODULE: ./src/js/Drift-browser.js\n// This file is used for the standalone browser build\n\n\n\nwindow[\"Drift\"] = Drift_Drift;\n\n\n/***/ })\n/******/ ]);"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import { isDOMElement } from \"./util/dom\";\nimport injectBaseStylesheet from \"./injectBaseStylesheet\";\n\nimport Trigger from \"./Trigger\";\nimport ZoomPane from \"./ZoomPane\";\n\nexport default class Drift {\n constructor(triggerEl, options = {}) {\n this.VERSION = \"1.4.1\";\n this.triggerEl = triggerEl;\n\n this.destroy = this.destroy.bind(this);\n\n if (!isDOMElement(this.triggerEl)) {\n throw new TypeError(\"`new Drift` requires a DOM element as its first argument.\");\n }\n\n // Prefix for generated element class names (e.g. `my-ns` will\n // result in classes such as `my-ns-pane`. Default `drift-`\n // prefixed classes will always be added as well.\n const namespace = options[\"namespace\"] || null;\n // Whether the ZoomPane should show whitespace when near the edges.\n const showWhitespaceAtEdges = options[\"showWhitespaceAtEdges\"] || false;\n // Whether the inline ZoomPane should stay inside\n // the bounds of its image.\n const containInline = options[\"containInline\"] || false;\n // How much to offset the ZoomPane from the\n // interaction point when inline.\n const inlineOffsetX = options[\"inlineOffsetX\"] || 0;\n const inlineOffsetY = options[\"inlineOffsetY\"] || 0;\n // A DOM element to append the inline ZoomPane to\n const inlineContainer = options[\"inlineContainer\"] || document.body;\n // Which trigger attribute to pull the ZoomPane image source from.\n const sourceAttribute = options[\"sourceAttribute\"] || \"data-zoom\";\n // How much to magnify the trigger by in the ZoomPane.\n // (e.g., `zoomFactor: 3` will result in a 900 px wide ZoomPane imag\n // if the trigger is displayed at 300 px wide)\n const zoomFactor = options[\"zoomFactor\"] || 3;\n // A DOM element to append the non-inline ZoomPane to.\n // Required if `inlinePane !== true`.\n const paneContainer = options[\"paneContainer\"] === undefined ? document.body : options[\"paneContainer\"];\n // When to switch to an inline ZoomPane. This can be a boolean or\n // an integer. If `true`, the ZoomPane will always be inline,\n // if `false`, it will switch to inline when `windowWidth <= inlinePane`\n const inlinePane = options[\"inlinePane\"] || 375;\n // If `true`, touch events will trigger the zoom, like mouse events.\n const handleTouch = \"handleTouch\" in options ? !!options[\"handleTouch\"] : true;\n // If present (and a function), this will be called\n // whenever the ZoomPane is shown.\n const onShow = options[\"onShow\"] || null;\n // If present (and a function), this will be called\n // whenever the ZoomPane is hidden.\n const onHide = options[\"onHide\"] || null;\n // Add base styles to the page. See the \"Theming\"\n // section of README.md for more information.\n const injectBaseStyles = \"injectBaseStyles\" in options ? !!options[\"injectBaseStyles\"] : true;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `mouseenter` event.\n const hoverDelay = options[\"hoverDelay\"] || 0;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `touchstart` event.\n // It's unlikely that you would want to use this option, since\n // \"tap and hold\" is much more intentional than a hover event.\n const touchDelay = options[\"touchDelay\"] || 0;\n // If true, a bounding box will show the area currently being previewed\n // during mouse hover\n const hoverBoundingBox = options[\"hoverBoundingBox\"] || false;\n // If true, a bounding box will show the area currently being previewed\n // during touch events\n const touchBoundingBox = options[\"touchBoundingBox\"] || false;\n // A DOM element to append the bounding box to.\n const boundingBoxContainer = options[\"boundingBoxContainer\"] || document.body;\n\n if (inlinePane !== true && !isDOMElement(paneContainer)) {\n throw new TypeError(\"`paneContainer` must be a DOM element when `inlinePane !== true`\");\n }\n if (!isDOMElement(inlineContainer)) {\n throw new TypeError(\"`inlineContainer` must be a DOM element\");\n }\n\n this.settings = {\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n sourceAttribute,\n zoomFactor,\n paneContainer,\n inlinePane,\n handleTouch,\n onShow,\n onHide,\n injectBaseStyles,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n boundingBoxContainer,\n };\n\n if (this.settings.injectBaseStyles) {\n injectBaseStylesheet();\n }\n\n this._buildZoomPane();\n this._buildTrigger();\n }\n\n get isShowing() {\n return this.zoomPane.isShowing;\n }\n\n get zoomFactor() {\n return this.settings.zoomFactor;\n }\n\n set zoomFactor(zf) {\n this.settings.zoomFactor = zf;\n this.zoomPane.settings.zoomFactor = zf;\n this.trigger.settings.zoomFactor = zf;\n this.boundingBox.settings.zoomFactor = zf;\n }\n\n _buildZoomPane() {\n this.zoomPane = new ZoomPane({\n container: this.settings.paneContainer,\n zoomFactor: this.settings.zoomFactor,\n showWhitespaceAtEdges: this.settings.showWhitespaceAtEdges,\n containInline: this.settings.containInline,\n inline: this.settings.inlinePane,\n namespace: this.settings.namespace,\n inlineOffsetX: this.settings.inlineOffsetX,\n inlineOffsetY: this.settings.inlineOffsetY,\n inlineContainer: this.settings.inlineContainer,\n });\n }\n\n _buildTrigger() {\n this.trigger = new Trigger({\n el: this.triggerEl,\n zoomPane: this.zoomPane,\n handleTouch: this.settings.handleTouch,\n onShow: this.settings.onShow,\n onHide: this.settings.onHide,\n sourceAttribute: this.settings.sourceAttribute,\n hoverDelay: this.settings.hoverDelay,\n touchDelay: this.settings.touchDelay,\n hoverBoundingBox: this.settings.hoverBoundingBox,\n touchBoundingBox: this.settings.touchBoundingBox,\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n boundingBoxContainer: this.settings.boundingBoxContainer,\n });\n }\n\n setZoomImageURL(imageURL) {\n this.zoomPane._setImageURL(imageURL);\n }\n\n disable() {\n this.trigger.enabled = false;\n }\n\n enable() {\n this.trigger.enabled = true;\n }\n\n destroy() {\n this.trigger._hide();\n this.trigger._unbindEvents();\n }\n}\n\n// Public API\n/* eslint-disable no-self-assign */\nObject.defineProperty(Drift.prototype, \"isShowing\", {\n get: function () {\n return this.isShowing;\n },\n});\nObject.defineProperty(Drift.prototype, \"zoomFactor\", {\n get: function () {\n return this.zoomFactor;\n },\n set: function (value) {\n this.zoomFactor = value;\n },\n});\nDrift.prototype[\"setZoomImageURL\"] = Drift.prototype.setZoomImageURL;\nDrift.prototype[\"disable\"] = Drift.prototype.disable;\nDrift.prototype[\"enable\"] = Drift.prototype.enable;\nDrift.prototype[\"destroy\"] = Drift.prototype.destroy;\n/* eslint-enable no-self-assign */\n","/* UNMINIFIED RULES\n\nconst RULES = `\n@keyframes noop {\n 0% { zoom: 1; }\n}\n\n@-webkit-keyframes noop {\n 0% { zoom: 1; }\n}\n\n.drift-zoom-pane.drift-open {\n display: block;\n}\n\n.drift-zoom-pane.drift-opening, .drift-zoom-pane.drift-closing {\n animation: noop 1ms;\n -webkit-animation: noop 1ms;\n}\n\n.drift-zoom-pane {\n position: absolute;\n overflow: hidden;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n pointer-events: none;\n}\n\n.drift-zoom-pane-loader {\n display: none;\n}\n\n.drift-zoom-pane img {\n position: absolute;\n display: block;\n max-width: none;\n max-height: none;\n}\n\n.drift-bounding-box {\n position: absolute;\n pointer-events: none;\n}\n`;\n\n*/\n\nconst RULES =\n \".drift-bounding-box,.drift-zoom-pane{position:absolute;pointer-events:none}@keyframes noop{0%{zoom:1}}@-webkit-keyframes noop{0%{zoom:1}}.drift-zoom-pane.drift-open{display:block}.drift-zoom-pane.drift-closing,.drift-zoom-pane.drift-opening{animation:noop 1ms;-webkit-animation:noop 1ms}.drift-zoom-pane{overflow:hidden;width:100%;height:100%;top:0;left:0}.drift-zoom-pane-loader{display:none}.drift-zoom-pane img{position:absolute;display:block;max-width:none;max-height:none}\";\n\nexport default function injectBaseStylesheet() {\n if (document.querySelector(\".drift-base-styles\")) {\n return;\n }\n\n const styleEl = document.createElement(\"style\");\n styleEl.type = \"text/css\";\n styleEl.classList.add(\"drift-base-styles\");\n\n styleEl.appendChild(document.createTextNode(RULES));\n\n const head = document.head;\n head.insertBefore(styleEl, head.firstChild);\n}\n","import throwIfMissing from \"./util/throwIfMissing\";\nimport { addClasses, removeClasses } from \"./util/dom\";\n\n// All officially-supported browsers have this, but it's easy to\n// account for, just in case.\nconst divStyle = document.createElement(\"div\").style;\n\nconst HAS_ANIMATION =\n typeof document === \"undefined\" ? false : \"animation\" in divStyle || \"webkitAnimation\" in divStyle;\n\nexport default class ZoomPane {\n constructor(options = {}) {\n this._completeShow = this._completeShow.bind(this);\n this._completeHide = this._completeHide.bind(this);\n this._handleLoad = this._handleLoad.bind(this);\n\n this.isShowing = false;\n\n const {\n container = null,\n zoomFactor = throwIfMissing(),\n inline = throwIfMissing(),\n namespace = null,\n showWhitespaceAtEdges = throwIfMissing(),\n containInline = throwIfMissing(),\n inlineOffsetX = 0,\n inlineOffsetY = 0,\n inlineContainer = document.body,\n } = options;\n\n this.settings = {\n container,\n zoomFactor,\n inline,\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n };\n\n this.openClasses = this._buildClasses(\"open\");\n this.openingClasses = this._buildClasses(\"opening\");\n this.closingClasses = this._buildClasses(\"closing\");\n this.inlineClasses = this._buildClasses(\"inline\");\n this.loadingClasses = this._buildClasses(\"loading\");\n\n this._buildElement();\n }\n\n _buildClasses(suffix) {\n const classes = [`drift-${suffix}`];\n\n const ns = this.settings.namespace;\n if (ns) {\n classes.push(`${ns}-${suffix}`);\n }\n\n return classes;\n }\n\n _buildElement() {\n this.el = document.createElement(\"div\");\n addClasses(this.el, this._buildClasses(\"zoom-pane\"));\n\n const loaderEl = document.createElement(\"div\");\n addClasses(loaderEl, this._buildClasses(\"zoom-pane-loader\"));\n this.el.appendChild(loaderEl);\n\n this.imgEl = document.createElement(\"img\");\n this.el.appendChild(this.imgEl);\n }\n\n _setImageURL(imageURL) {\n this.imgEl.setAttribute(\"src\", imageURL);\n }\n\n _setImageSize(triggerWidth, triggerHeight) {\n this.imgEl.style.width = `${triggerWidth * this.settings.zoomFactor}px`;\n this.imgEl.style.height = `${triggerHeight * this.settings.zoomFactor}px`;\n }\n\n // `percentageOffsetX` and `percentageOffsetY` must be percentages\n // expressed as floats between `0' and `1`.\n setPosition(percentageOffsetX, percentageOffsetY, triggerRect) {\n const imgElWidth = this.imgEl.offsetWidth;\n const imgElHeight = this.imgEl.offsetHeight;\n const elWidth = this.el.offsetWidth;\n const elHeight = this.el.offsetHeight;\n\n const centreOfContainerX = elWidth / 2;\n const centreOfContainerY = elHeight / 2;\n\n const targetImgXToBeCentre = imgElWidth * percentageOffsetX;\n const targetImgYToBeCentre = imgElHeight * percentageOffsetY;\n\n let left = centreOfContainerX - targetImgXToBeCentre;\n let top = centreOfContainerY - targetImgYToBeCentre;\n\n const differenceBetweenContainerWidthAndImgWidth = elWidth - imgElWidth;\n const differenceBetweenContainerHeightAndImgHeight = elHeight - imgElHeight;\n const isContainerLargerThanImgX = differenceBetweenContainerWidthAndImgWidth > 0;\n const isContainerLargerThanImgY = differenceBetweenContainerHeightAndImgHeight > 0;\n\n const minLeft = isContainerLargerThanImgX ? differenceBetweenContainerWidthAndImgWidth / 2 : 0;\n const minTop = isContainerLargerThanImgY ? differenceBetweenContainerHeightAndImgHeight / 2 : 0;\n\n const maxLeft = isContainerLargerThanImgX\n ? differenceBetweenContainerWidthAndImgWidth / 2\n : differenceBetweenContainerWidthAndImgWidth;\n const maxTop = isContainerLargerThanImgY\n ? differenceBetweenContainerHeightAndImgHeight / 2\n : differenceBetweenContainerHeightAndImgHeight;\n\n if (this.el.parentElement === this.settings.inlineContainer) {\n // This may be needed in the future to deal with browser event\n // inconsistencies, but it's difficult to tell for sure.\n // let scrollX = isTouch ? 0 : window.scrollX;\n // let scrollY = isTouch ? 0 : window.scrollY;\n const scrollX = window.pageXOffset;\n const scrollY = window.pageYOffset;\n\n let inlineLeft =\n triggerRect.left + percentageOffsetX * triggerRect.width - elWidth / 2 + this.settings.inlineOffsetX + scrollX;\n let inlineTop =\n triggerRect.top + percentageOffsetY * triggerRect.height - elHeight / 2 + this.settings.inlineOffsetY + scrollY;\n\n if (this.settings.containInline) {\n if (inlineLeft < triggerRect.left + scrollX) {\n inlineLeft = triggerRect.left + scrollX;\n } else if (inlineLeft + elWidth > triggerRect.left + triggerRect.width + scrollX) {\n inlineLeft = triggerRect.left + triggerRect.width - elWidth + scrollX;\n }\n\n if (inlineTop < triggerRect.top + scrollY) {\n inlineTop = triggerRect.top + scrollY;\n } else if (inlineTop + elHeight > triggerRect.top + triggerRect.height + scrollY) {\n inlineTop = triggerRect.top + triggerRect.height - elHeight + scrollY;\n }\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n\n if (!this.settings.showWhitespaceAtEdges) {\n if (left > minLeft) {\n left = minLeft;\n } else if (left < maxLeft) {\n left = maxLeft;\n }\n\n if (top > minTop) {\n top = minTop;\n } else if (top < maxTop) {\n top = maxTop;\n }\n }\n\n this.imgEl.style.transform = `translate(${left}px, ${top}px)`;\n this.imgEl.style.webkitTransform = `translate(${left}px, ${top}px)`;\n }\n\n get _isInline() {\n const inline = this.settings.inline;\n\n return inline === true || (typeof inline === \"number\" && window.innerWidth <= inline);\n }\n\n _removeListenersAndResetClasses() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n }\n\n show(imageURL, triggerWidth, triggerHeight) {\n this._removeListenersAndResetClasses();\n this.isShowing = true;\n\n addClasses(this.el, this.openClasses);\n\n if (this.imgEl.getAttribute(\"src\") != imageURL) {\n addClasses(this.el, this.loadingClasses);\n this.imgEl.addEventListener(\"load\", this._handleLoad, false);\n this._setImageURL(imageURL);\n }\n\n this._setImageSize(triggerWidth, triggerHeight);\n\n if (this._isInline) {\n this._showInline();\n } else {\n this._showInContainer();\n }\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeShow, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n addClasses(this.el, this.openingClasses);\n }\n }\n\n _showInline() {\n this.settings.inlineContainer.appendChild(this.el);\n addClasses(this.el, this.inlineClasses);\n }\n\n _showInContainer() {\n this.settings.container.appendChild(this.el);\n }\n\n hide() {\n this._removeListenersAndResetClasses();\n this.isShowing = false;\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeHide, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n addClasses(this.el, this.closingClasses);\n } else {\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.inlineClasses);\n }\n }\n\n _completeShow() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n\n removeClasses(this.el, this.openingClasses);\n }\n\n _completeHide() {\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n removeClasses(this.el, this.inlineClasses);\n\n this.el.setAttribute(\"style\", \"\");\n\n // The window could have been resized above or below `inline`\n // limits since the ZoomPane was shown. Because of this, we\n // can't rely on `this._isInline` here.\n if (this.el.parentElement === this.settings.container) {\n this.settings.container.removeChild(this.el);\n } else if (this.el.parentElement === this.settings.inlineContainer) {\n this.settings.inlineContainer.removeChild(this.el);\n }\n }\n\n _handleLoad() {\n this.imgEl.removeEventListener(\"load\", this._handleLoad, false);\n removeClasses(this.el, this.loadingClasses);\n }\n}\n","import throwIfMissing from \"./util/throwIfMissing\";\nimport BoundingBox from \"./BoundingBox\";\n\nexport default class Trigger {\n constructor(options = {}) {\n this._show = this._show.bind(this);\n this._hide = this._hide.bind(this);\n this._handleEntry = this._handleEntry.bind(this);\n this._handleMovement = this._handleMovement.bind(this);\n\n const {\n el = throwIfMissing(),\n zoomPane = throwIfMissing(),\n sourceAttribute = throwIfMissing(),\n handleTouch = throwIfMissing(),\n onShow = null,\n onHide = null,\n hoverDelay = 0,\n touchDelay = 0,\n hoverBoundingBox = throwIfMissing(),\n touchBoundingBox = throwIfMissing(),\n namespace = null,\n zoomFactor = throwIfMissing(),\n boundingBoxContainer = throwIfMissing(),\n } = options;\n\n this.settings = {\n el,\n zoomPane,\n sourceAttribute,\n handleTouch,\n onShow,\n onHide,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n namespace,\n zoomFactor,\n boundingBoxContainer,\n };\n\n if (this.settings.hoverBoundingBox || this.settings.touchBoundingBox) {\n this.boundingBox = new BoundingBox({\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n containerEl: this.settings.boundingBoxContainer,\n });\n }\n\n this.enabled = true;\n\n this._bindEvents();\n }\n\n get isShowing() {\n return this.settings.zoomPane.isShowing;\n }\n\n _preventDefault(event) {\n event.preventDefault();\n }\n\n _preventDefaultAllowTouchScroll(event) {\n if (!this.settings.touchDelay || !this._isTouchEvent(event) || this.isShowing) {\n event.preventDefault();\n }\n }\n\n _isTouchEvent(event) {\n return !!event.touches;\n }\n\n _bindEvents() {\n this.settings.el.addEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.addEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.addEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.addEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.addEventListener(\"touchend\", this._hide, false);\n this.settings.el.addEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.addEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _unbindEvents() {\n this.settings.el.removeEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.removeEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.removeEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"touchend\", this._hide, false);\n this.settings.el.removeEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.removeEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _handleEntry(e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n\n if (e.type == \"mouseenter\" && this.settings.hoverDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.hoverDelay);\n } else if (this.settings.touchDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.touchDelay);\n } else {\n this._show();\n }\n }\n\n _show() {\n if (!this.enabled) {\n return;\n }\n\n const onShow = this.settings.onShow;\n if (onShow && typeof onShow === \"function\") {\n onShow();\n }\n\n this.settings.zoomPane.show(\n this.settings.el.getAttribute(this.settings.sourceAttribute),\n this.settings.el.clientWidth,\n this.settings.el.clientHeight\n );\n\n if (this._lastMovement) {\n const touchActivated = this._lastMovement.touches;\n if ((touchActivated && this.settings.touchBoundingBox) || (!touchActivated && this.settings.hoverBoundingBox)) {\n this.boundingBox.show(this.settings.zoomPane.el.clientWidth, this.settings.zoomPane.el.clientHeight);\n }\n }\n\n this._handleMovement();\n }\n\n _hide(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n }\n\n this._lastMovement = null;\n\n if (this.entryTimeout) {\n clearTimeout(this.entryTimeout);\n }\n\n if (this.boundingBox) {\n this.boundingBox.hide();\n }\n\n const onHide = this.settings.onHide;\n if (onHide && typeof onHide === \"function\") {\n onHide();\n }\n\n this.settings.zoomPane.hide();\n }\n\n _handleMovement(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n } else if (this._lastMovement) {\n e = this._lastMovement;\n } else {\n return;\n }\n\n let movementX;\n let movementY;\n\n if (e.touches) {\n const firstTouch = e.touches[0];\n movementX = firstTouch.clientX;\n movementY = firstTouch.clientY;\n } else {\n movementX = e.clientX;\n movementY = e.clientY;\n }\n\n const el = this.settings.el;\n const rect = el.getBoundingClientRect();\n const offsetX = movementX - rect.left;\n const offsetY = movementY - rect.top;\n\n const percentageOffsetX = offsetX / this.settings.el.clientWidth;\n const percentageOffsetY = offsetY / this.settings.el.clientHeight;\n\n if (this.boundingBox) {\n this.boundingBox.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n\n this.settings.zoomPane.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n}\n","import throwIfMissing from \"./util/throwIfMissing\";\nimport { addClasses, removeClasses } from \"./util/dom\";\n\nexport default class BoundingBox {\n constructor(options) {\n this.isShowing = false;\n\n const { namespace = null, zoomFactor = throwIfMissing(), containerEl = throwIfMissing() } = options;\n\n this.settings = { namespace, zoomFactor, containerEl };\n\n this.openClasses = this._buildClasses(\"open\");\n\n this._buildElement();\n }\n\n _buildClasses(suffix) {\n const classes = [`drift-${suffix}`];\n\n const ns = this.settings.namespace;\n if (ns) {\n classes.push(`${ns}-${suffix}`);\n }\n\n return classes;\n }\n\n _buildElement() {\n this.el = document.createElement(\"div\");\n addClasses(this.el, this._buildClasses(\"bounding-box\"));\n }\n\n show(zoomPaneWidth, zoomPaneHeight) {\n this.isShowing = true;\n\n this.settings.containerEl.appendChild(this.el);\n\n const style = this.el.style;\n style.width = `${Math.round(zoomPaneWidth / this.settings.zoomFactor)}px`;\n style.height = `${Math.round(zoomPaneHeight / this.settings.zoomFactor)}px`;\n\n addClasses(this.el, this.openClasses);\n }\n\n hide() {\n if (this.isShowing) {\n this.settings.containerEl.removeChild(this.el);\n }\n\n this.isShowing = false;\n\n removeClasses(this.el, this.openClasses);\n }\n\n setPosition(percentageOffsetX, percentageOffsetY, triggerRect) {\n const pageXOffset = window.pageXOffset;\n const pageYOffset = window.pageYOffset;\n\n let inlineLeft = triggerRect.left + percentageOffsetX * triggerRect.width - this.el.clientWidth / 2 + pageXOffset;\n let inlineTop = triggerRect.top + percentageOffsetY * triggerRect.height - this.el.clientHeight / 2 + pageYOffset;\n\n if (inlineLeft < triggerRect.left + pageXOffset) {\n inlineLeft = triggerRect.left + pageXOffset;\n } else if (inlineLeft + this.el.clientWidth > triggerRect.left + triggerRect.width + pageXOffset) {\n inlineLeft = triggerRect.left + triggerRect.width - this.el.clientWidth + pageXOffset;\n }\n\n if (inlineTop < triggerRect.top + pageYOffset) {\n inlineTop = triggerRect.top + pageYOffset;\n } else if (inlineTop + this.el.clientHeight > triggerRect.top + triggerRect.height + pageYOffset) {\n inlineTop = triggerRect.top + triggerRect.height - this.el.clientHeight + pageYOffset;\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n}\n","// This is not really a perfect check, but works fine.\n// From http://stackoverflow.com/questions/384286\nconst HAS_DOM_2 = typeof HTMLElement === \"object\";\n\nexport function isDOMElement(obj) {\n return HAS_DOM_2\n ? obj instanceof HTMLElement\n : obj && typeof obj === \"object\" && obj !== null && obj.nodeType === 1 && typeof obj.nodeName === \"string\";\n}\n\nexport function addClasses(el, classNames) {\n classNames.forEach(function (className) {\n el.classList.add(className);\n });\n}\n\nexport function removeClasses(el, classNames) {\n classNames.forEach(function (className) {\n el.classList.remove(className);\n });\n}\n","export default function throwIfMissing() {\n throw new Error(\"Missing parameter\");\n}\n","// This file is used for the standalone browser build\n\nimport Drift from \"./Drift\";\n\nwindow[\"Drift\"] = Drift;\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:/// [synthetic:util/global] ","webpack:/// [synthetic:es6/symbol] ","webpack:///Drift.min.js","webpack:///webpack/bootstrap","webpack:///./src/js/Drift.js","webpack:///./src/js/injectBaseStylesheet.js","webpack:///./src/js/ZoomPane.js","webpack:///./src/js/Trigger.js","webpack:///./src/js/BoundingBox.js","webpack:///./src/js/util/dom.js","webpack:///./src/js/util/throwIfMissing.js","webpack:///./src/js/Drift-browser.js"],"names":["$jscomp.global","$jscomp.initSymbol","$jscomp.Symbol","$jscomp.symbolCounter_","$jscomp.SYMBOL_PREFIX","modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","d","__webpack_require__.d","name","getter","o","Object","defineProperty","enumerable","get","r","__webpack_require__.r","Symbol","toStringTag","value","t","__webpack_require__.t","mode","__esModule","ns","create","key","bind","n","__webpack_require__.n","getDefault","getModuleExports","__webpack_require__.o","object","property","prototype","hasOwnProperty","p","s","__webpack_exports__","constructor","Drift_Drift","triggerEl","options","destroy","isDOMElement","TypeError","namespace","showWhitespaceAtEdges","containInline","inlineOffsetX","inlineOffsetY","inlineContainer","document","body","sourceAttribute","zoomFactor","paneContainer","undefined","inlinePane","handleTouch","onShow","onHide","injectBaseStyles","hoverDelay","touchDelay","hoverBoundingBox","touchBoundingBox","boundingBoxContainer","settings","querySelector","styleEl","createElement","type","classList","textContent","RULES","allHeadElements","head","getElementsByTagName","innerHTML","_buildZoomPane","_buildTrigger","ZoomPane_ZoomPane","_completeShow","_completeHide","_handleLoad","isShowing","container","throwIfMissing","inline","openClasses","_buildClasses","openingClasses","closingClasses","inlineClasses","loadingClasses","_buildElement","Trigger_Trigger","_show","_hide","_handleEntry","_handleMovement","el","zoomPane","boundingBox","BoundingBox_BoundingBox","containerEl","enabled","_bindEvents","obj","HAS_DOM_2","HTMLElement","nodeType","nodeName","addClasses","classNames","forEach","className","add","removeClasses","remove","Error","suffix","classes","push","show","zoomPaneWidth","zoomPaneHeight","appendChild","style","width","Math","round","height","hide","removeChild","setPosition","percentageOffsetX","percentageOffsetY","triggerRect","pageXOffset","window","pageYOffset","inlineLeft","left","clientWidth","inlineTop","top","clientHeight","_preventDefault","event","preventDefault","_preventDefaultAllowTouchScroll","_isTouchEvent","touches","addEventListener","_unbindEvents","removeEventListener","e","_lastMovement","entryTimeout","setTimeout","getAttribute","touchActivated","clearTimeout","movementX","firstTouch","clientX","movementY","clientY","rect","getBoundingClientRect","$jscomp.global.Object.defineProperties","divStyle","HAS_ANIMATION","loaderEl","imgEl","_setImageURL","imageURL","setAttribute","_setImageSize","triggerWidth","triggerHeight","imgElWidth","offsetWidth","imgElHeight","offsetHeight","elWidth","elHeight","differenceBetweenContainerWidthAndImgWidth","differenceBetweenContainerHeightAndImgHeight","isContainerLargerThanImgX","isContainerLargerThanImgY","minLeft","minTop","maxLeft","maxTop","parentElement","scrollX","scrollY","transform","webkitTransform","_removeListenersAndResetClasses","_isInline","_showInline","_showInContainer","innerWidth","trigger","setZoomImageURL","disable","enable","zf","set"],"mappings":"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","file":"Drift.min.js","sourcesContent":[null,null,"/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// CONCATENATED MODULE: ./src/js/util/dom.js\n// This is not really a perfect check, but works fine.\n// From http://stackoverflow.com/questions/384286\nconst HAS_DOM_2 = typeof HTMLElement === \"object\";\n\nfunction isDOMElement(obj) {\n return HAS_DOM_2\n ? obj instanceof HTMLElement\n : obj && typeof obj === \"object\" && obj !== null && obj.nodeType === 1 && typeof obj.nodeName === \"string\";\n}\n\nfunction addClasses(el, classNames) {\n classNames.forEach(function (className) {\n el.classList.add(className);\n });\n}\n\nfunction removeClasses(el, classNames) {\n classNames.forEach(function (className) {\n el.classList.remove(className);\n });\n}\n\n// CONCATENATED MODULE: ./src/js/injectBaseStylesheet.js\n/* UNMINIFIED RULES\n\nconst RULES = `\n@keyframes noop {\n 0% { zoom: 1; }\n}\n\n@-webkit-keyframes noop {\n 0% { zoom: 1; }\n}\n\n.drift-zoom-pane.drift-open {\n display: block;\n}\n\n.drift-zoom-pane.drift-opening, .drift-zoom-pane.drift-closing {\n animation: noop 1ms;\n -webkit-animation: noop 1ms;\n}\n\n.drift-zoom-pane {\n position: absolute;\n overflow: hidden;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n pointer-events: none;\n}\n\n.drift-zoom-pane-loader {\n display: none;\n}\n\n.drift-zoom-pane img {\n position: absolute;\n display: block;\n max-width: none;\n max-height: none;\n}\n\n.drift-bounding-box {\n position: absolute;\n pointer-events: none;\n}\n`;\n\n*/\n\nconst RULES =\n \".drift-bounding-box,.drift-zoom-pane{position:absolute;pointer-events:none}@keyframes noop{0%{zoom:1}}@-webkit-keyframes noop{0%{zoom:1}}.drift-zoom-pane.drift-open{display:block}.drift-zoom-pane.drift-closing,.drift-zoom-pane.drift-opening{animation:noop 1ms;-webkit-animation:noop 1ms}.drift-zoom-pane{overflow:hidden;width:100%;height:100%;top:0;left:0}.drift-zoom-pane-loader{display:none}.drift-zoom-pane img{position:absolute;display:block;max-width:none;max-height:none}\";\n\nfunction injectBaseStylesheet() {\n if (document.querySelector(\".drift-base-styles\")) {\n return;\n }\n\n const styleEl = document.createElement(\"style\");\n styleEl.type = \"text/css\";\n styleEl.classList = \"drift-base-styles\";\n\n styleEl.textContent = RULES;\n const head = document.head;\n\n const allHeadElements = head.getElementsByTagName(\"*\");\n allHeadElements.innerHTML = styleEl + allHeadElements.innerHTML;\n}\n\n// CONCATENATED MODULE: ./src/js/util/throwIfMissing.js\nfunction throwIfMissing() {\n throw new Error(\"Missing parameter\");\n}\n\n// CONCATENATED MODULE: ./src/js/BoundingBox.js\n\n\n\nclass BoundingBox_BoundingBox {\n constructor(options) {\n this.isShowing = false;\n\n const { namespace = null, zoomFactor = throwIfMissing(), containerEl = throwIfMissing() } = options;\n\n this.settings = { namespace, zoomFactor, containerEl };\n\n this.openClasses = this._buildClasses(\"open\");\n\n this._buildElement();\n }\n\n _buildClasses(suffix) {\n const classes = [`drift-${suffix}`];\n\n const ns = this.settings.namespace;\n if (ns) {\n classes.push(`${ns}-${suffix}`);\n }\n\n return classes;\n }\n\n _buildElement() {\n this.el = document.createElement(\"div\");\n addClasses(this.el, this._buildClasses(\"bounding-box\"));\n }\n\n show(zoomPaneWidth, zoomPaneHeight) {\n this.isShowing = true;\n\n this.settings.containerEl.appendChild(this.el);\n\n const style = this.el.style;\n style.width = `${Math.round(zoomPaneWidth / this.settings.zoomFactor)}px`;\n style.height = `${Math.round(zoomPaneHeight / this.settings.zoomFactor)}px`;\n\n addClasses(this.el, this.openClasses);\n }\n\n hide() {\n if (this.isShowing) {\n this.settings.containerEl.removeChild(this.el);\n }\n\n this.isShowing = false;\n\n removeClasses(this.el, this.openClasses);\n }\n\n setPosition(percentageOffsetX, percentageOffsetY, triggerRect) {\n const pageXOffset = window.pageXOffset;\n const pageYOffset = window.pageYOffset;\n\n let inlineLeft = triggerRect.left + percentageOffsetX * triggerRect.width - this.el.clientWidth / 2 + pageXOffset;\n let inlineTop = triggerRect.top + percentageOffsetY * triggerRect.height - this.el.clientHeight / 2 + pageYOffset;\n\n if (inlineLeft < triggerRect.left + pageXOffset) {\n inlineLeft = triggerRect.left + pageXOffset;\n } else if (inlineLeft + this.el.clientWidth > triggerRect.left + triggerRect.width + pageXOffset) {\n inlineLeft = triggerRect.left + triggerRect.width - this.el.clientWidth + pageXOffset;\n }\n\n if (inlineTop < triggerRect.top + pageYOffset) {\n inlineTop = triggerRect.top + pageYOffset;\n } else if (inlineTop + this.el.clientHeight > triggerRect.top + triggerRect.height + pageYOffset) {\n inlineTop = triggerRect.top + triggerRect.height - this.el.clientHeight + pageYOffset;\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n}\n\n// CONCATENATED MODULE: ./src/js/Trigger.js\n\n\n\nclass Trigger_Trigger {\n constructor(options = {}) {\n this._show = this._show.bind(this);\n this._hide = this._hide.bind(this);\n this._handleEntry = this._handleEntry.bind(this);\n this._handleMovement = this._handleMovement.bind(this);\n\n const {\n el = throwIfMissing(),\n zoomPane = throwIfMissing(),\n sourceAttribute = throwIfMissing(),\n handleTouch = throwIfMissing(),\n onShow = null,\n onHide = null,\n hoverDelay = 0,\n touchDelay = 0,\n hoverBoundingBox = throwIfMissing(),\n touchBoundingBox = throwIfMissing(),\n namespace = null,\n zoomFactor = throwIfMissing(),\n boundingBoxContainer = throwIfMissing(),\n } = options;\n\n this.settings = {\n el,\n zoomPane,\n sourceAttribute,\n handleTouch,\n onShow,\n onHide,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n namespace,\n zoomFactor,\n boundingBoxContainer,\n };\n\n if (this.settings.hoverBoundingBox || this.settings.touchBoundingBox) {\n this.boundingBox = new BoundingBox_BoundingBox({\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n containerEl: this.settings.boundingBoxContainer,\n });\n }\n\n this.enabled = true;\n\n this._bindEvents();\n }\n\n get isShowing() {\n return this.settings.zoomPane.isShowing;\n }\n\n _preventDefault(event) {\n event.preventDefault();\n }\n\n _preventDefaultAllowTouchScroll(event) {\n if (!this.settings.touchDelay || !this._isTouchEvent(event) || this.isShowing) {\n event.preventDefault();\n }\n }\n\n _isTouchEvent(event) {\n return !!event.touches;\n }\n\n _bindEvents() {\n this.settings.el.addEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.addEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.addEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.addEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.addEventListener(\"touchend\", this._hide, false);\n this.settings.el.addEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.addEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _unbindEvents() {\n this.settings.el.removeEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.removeEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.removeEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"touchend\", this._hide, false);\n this.settings.el.removeEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.removeEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _handleEntry(e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n\n if (e.type == \"mouseenter\" && this.settings.hoverDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.hoverDelay);\n } else if (this.settings.touchDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.touchDelay);\n } else {\n this._show();\n }\n }\n\n _show() {\n if (!this.enabled) {\n return;\n }\n\n const onShow = this.settings.onShow;\n if (onShow && typeof onShow === \"function\") {\n onShow();\n }\n\n this.settings.zoomPane.show(\n this.settings.el.getAttribute(this.settings.sourceAttribute),\n this.settings.el.clientWidth,\n this.settings.el.clientHeight\n );\n\n if (this._lastMovement) {\n const touchActivated = this._lastMovement.touches;\n if ((touchActivated && this.settings.touchBoundingBox) || (!touchActivated && this.settings.hoverBoundingBox)) {\n this.boundingBox.show(this.settings.zoomPane.el.clientWidth, this.settings.zoomPane.el.clientHeight);\n }\n }\n\n this._handleMovement();\n }\n\n _hide(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n }\n\n this._lastMovement = null;\n\n if (this.entryTimeout) {\n clearTimeout(this.entryTimeout);\n }\n\n if (this.boundingBox) {\n this.boundingBox.hide();\n }\n\n const onHide = this.settings.onHide;\n if (onHide && typeof onHide === \"function\") {\n onHide();\n }\n\n this.settings.zoomPane.hide();\n }\n\n _handleMovement(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n } else if (this._lastMovement) {\n e = this._lastMovement;\n } else {\n return;\n }\n\n let movementX;\n let movementY;\n\n if (e.touches) {\n const firstTouch = e.touches[0];\n movementX = firstTouch.clientX;\n movementY = firstTouch.clientY;\n } else {\n movementX = e.clientX;\n movementY = e.clientY;\n }\n\n const el = this.settings.el;\n const rect = el.getBoundingClientRect();\n const offsetX = movementX - rect.left;\n const offsetY = movementY - rect.top;\n\n const percentageOffsetX = offsetX / this.settings.el.clientWidth;\n const percentageOffsetY = offsetY / this.settings.el.clientHeight;\n\n if (this.boundingBox) {\n this.boundingBox.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n\n this.settings.zoomPane.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n}\n\n// CONCATENATED MODULE: ./src/js/ZoomPane.js\n\n\n\n// All officially-supported browsers have this, but it's easy to\n// account for, just in case.\nconst divStyle = document.createElement(\"div\").style;\n\nconst HAS_ANIMATION =\n typeof document === \"undefined\" ? false : \"animation\" in divStyle || \"webkitAnimation\" in divStyle;\n\nclass ZoomPane_ZoomPane {\n constructor(options = {}) {\n this._completeShow = this._completeShow.bind(this);\n this._completeHide = this._completeHide.bind(this);\n this._handleLoad = this._handleLoad.bind(this);\n\n this.isShowing = false;\n\n const {\n container = null,\n zoomFactor = throwIfMissing(),\n inline = throwIfMissing(),\n namespace = null,\n showWhitespaceAtEdges = throwIfMissing(),\n containInline = throwIfMissing(),\n inlineOffsetX = 0,\n inlineOffsetY = 0,\n inlineContainer = document.body,\n } = options;\n\n this.settings = {\n container,\n zoomFactor,\n inline,\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n };\n\n this.openClasses = this._buildClasses(\"open\");\n this.openingClasses = this._buildClasses(\"opening\");\n this.closingClasses = this._buildClasses(\"closing\");\n this.inlineClasses = this._buildClasses(\"inline\");\n this.loadingClasses = this._buildClasses(\"loading\");\n\n this._buildElement();\n }\n\n _buildClasses(suffix) {\n const classes = [`drift-${suffix}`];\n\n const ns = this.settings.namespace;\n if (ns) {\n classes.push(`${ns}-${suffix}`);\n }\n\n return classes;\n }\n\n _buildElement() {\n this.el = document.createElement(\"div\");\n addClasses(this.el, this._buildClasses(\"zoom-pane\"));\n\n const loaderEl = document.createElement(\"div\");\n addClasses(loaderEl, this._buildClasses(\"zoom-pane-loader\"));\n this.el.appendChild(loaderEl);\n\n this.imgEl = document.createElement(\"img\");\n this.el.appendChild(this.imgEl);\n }\n\n _setImageURL(imageURL) {\n this.imgEl.setAttribute(\"src\", imageURL);\n }\n\n _setImageSize(triggerWidth, triggerHeight) {\n this.imgEl.style.width = `${triggerWidth * this.settings.zoomFactor}px`;\n this.imgEl.style.height = `${triggerHeight * this.settings.zoomFactor}px`;\n }\n\n // `percentageOffsetX` and `percentageOffsetY` must be percentages\n // expressed as floats between `0' and `1`.\n setPosition(percentageOffsetX, percentageOffsetY, triggerRect) {\n const imgElWidth = this.imgEl.offsetWidth;\n const imgElHeight = this.imgEl.offsetHeight;\n const elWidth = this.el.offsetWidth;\n const elHeight = this.el.offsetHeight;\n\n const centreOfContainerX = elWidth / 2;\n const centreOfContainerY = elHeight / 2;\n\n const targetImgXToBeCentre = imgElWidth * percentageOffsetX;\n const targetImgYToBeCentre = imgElHeight * percentageOffsetY;\n\n let left = centreOfContainerX - targetImgXToBeCentre;\n let top = centreOfContainerY - targetImgYToBeCentre;\n\n const differenceBetweenContainerWidthAndImgWidth = elWidth - imgElWidth;\n const differenceBetweenContainerHeightAndImgHeight = elHeight - imgElHeight;\n const isContainerLargerThanImgX = differenceBetweenContainerWidthAndImgWidth > 0;\n const isContainerLargerThanImgY = differenceBetweenContainerHeightAndImgHeight > 0;\n\n const minLeft = isContainerLargerThanImgX ? differenceBetweenContainerWidthAndImgWidth / 2 : 0;\n const minTop = isContainerLargerThanImgY ? differenceBetweenContainerHeightAndImgHeight / 2 : 0;\n\n const maxLeft = isContainerLargerThanImgX\n ? differenceBetweenContainerWidthAndImgWidth / 2\n : differenceBetweenContainerWidthAndImgWidth;\n const maxTop = isContainerLargerThanImgY\n ? differenceBetweenContainerHeightAndImgHeight / 2\n : differenceBetweenContainerHeightAndImgHeight;\n\n if (this.el.parentElement === this.settings.inlineContainer) {\n // This may be needed in the future to deal with browser event\n // inconsistencies, but it's difficult to tell for sure.\n // let scrollX = isTouch ? 0 : window.scrollX;\n // let scrollY = isTouch ? 0 : window.scrollY;\n const scrollX = window.pageXOffset;\n const scrollY = window.pageYOffset;\n\n let inlineLeft =\n triggerRect.left + percentageOffsetX * triggerRect.width - elWidth / 2 + this.settings.inlineOffsetX + scrollX;\n let inlineTop =\n triggerRect.top + percentageOffsetY * triggerRect.height - elHeight / 2 + this.settings.inlineOffsetY + scrollY;\n\n if (this.settings.containInline) {\n if (inlineLeft < triggerRect.left + scrollX) {\n inlineLeft = triggerRect.left + scrollX;\n } else if (inlineLeft + elWidth > triggerRect.left + triggerRect.width + scrollX) {\n inlineLeft = triggerRect.left + triggerRect.width - elWidth + scrollX;\n }\n\n if (inlineTop < triggerRect.top + scrollY) {\n inlineTop = triggerRect.top + scrollY;\n } else if (inlineTop + elHeight > triggerRect.top + triggerRect.height + scrollY) {\n inlineTop = triggerRect.top + triggerRect.height - elHeight + scrollY;\n }\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n\n if (!this.settings.showWhitespaceAtEdges) {\n if (left > minLeft) {\n left = minLeft;\n } else if (left < maxLeft) {\n left = maxLeft;\n }\n\n if (top > minTop) {\n top = minTop;\n } else if (top < maxTop) {\n top = maxTop;\n }\n }\n\n this.imgEl.style.transform = `translate(${left}px, ${top}px)`;\n this.imgEl.style.webkitTransform = `translate(${left}px, ${top}px)`;\n }\n\n get _isInline() {\n const inline = this.settings.inline;\n\n return inline === true || (typeof inline === \"number\" && window.innerWidth <= inline);\n }\n\n _removeListenersAndResetClasses() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n }\n\n show(imageURL, triggerWidth, triggerHeight) {\n this._removeListenersAndResetClasses();\n this.isShowing = true;\n\n addClasses(this.el, this.openClasses);\n\n if (this.imgEl.getAttribute(\"src\") != imageURL) {\n addClasses(this.el, this.loadingClasses);\n this.imgEl.addEventListener(\"load\", this._handleLoad, false);\n this._setImageURL(imageURL);\n }\n\n this._setImageSize(triggerWidth, triggerHeight);\n\n if (this._isInline) {\n this._showInline();\n } else {\n this._showInContainer();\n }\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeShow, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n addClasses(this.el, this.openingClasses);\n }\n }\n\n _showInline() {\n this.settings.inlineContainer.appendChild(this.el);\n addClasses(this.el, this.inlineClasses);\n }\n\n _showInContainer() {\n this.settings.container.appendChild(this.el);\n }\n\n hide() {\n this._removeListenersAndResetClasses();\n this.isShowing = false;\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeHide, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n addClasses(this.el, this.closingClasses);\n } else {\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.inlineClasses);\n }\n }\n\n _completeShow() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n\n removeClasses(this.el, this.openingClasses);\n }\n\n _completeHide() {\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n removeClasses(this.el, this.inlineClasses);\n\n this.el.style = \"\";\n\n // The window could have been resized above or below `inline`\n // limits since the ZoomPane was shown. Because of this, we\n // can't rely on `this._isInline` here.\n if (this.el.parentElement === this.settings.container) {\n this.settings.container.removeChild(this.el);\n } else if (this.el.parentElement === this.settings.inlineContainer) {\n this.settings.inlineContainer.removeChild(this.el);\n }\n }\n\n _handleLoad() {\n this.imgEl.removeEventListener(\"load\", this._handleLoad, false);\n removeClasses(this.el, this.loadingClasses);\n }\n}\n\n// CONCATENATED MODULE: ./src/js/Drift.js\n\n\n\n\n\n\nclass Drift_Drift {\n constructor(triggerEl, options = {}) {\n this.VERSION = \"1.4.2\";\n this.triggerEl = triggerEl;\n\n this.destroy = this.destroy.bind(this);\n\n if (!isDOMElement(this.triggerEl)) {\n throw new TypeError(\"`new Drift` requires a DOM element as its first argument.\");\n }\n\n // Prefix for generated element class names (e.g. `my-ns` will\n // result in classes such as `my-ns-pane`. Default `drift-`\n // prefixed classes will always be added as well.\n const namespace = options[\"namespace\"] || null;\n // Whether the ZoomPane should show whitespace when near the edges.\n const showWhitespaceAtEdges = options[\"showWhitespaceAtEdges\"] || false;\n // Whether the inline ZoomPane should stay inside\n // the bounds of its image.\n const containInline = options[\"containInline\"] || false;\n // How much to offset the ZoomPane from the\n // interaction point when inline.\n const inlineOffsetX = options[\"inlineOffsetX\"] || 0;\n const inlineOffsetY = options[\"inlineOffsetY\"] || 0;\n // A DOM element to append the inline ZoomPane to\n const inlineContainer = options[\"inlineContainer\"] || document.body;\n // Which trigger attribute to pull the ZoomPane image source from.\n const sourceAttribute = options[\"sourceAttribute\"] || \"data-zoom\";\n // How much to magnify the trigger by in the ZoomPane.\n // (e.g., `zoomFactor: 3` will result in a 900 px wide ZoomPane imag\n // if the trigger is displayed at 300 px wide)\n const zoomFactor = options[\"zoomFactor\"] || 3;\n // A DOM element to append the non-inline ZoomPane to.\n // Required if `inlinePane !== true`.\n const paneContainer = options[\"paneContainer\"] === undefined ? document.body : options[\"paneContainer\"];\n // When to switch to an inline ZoomPane. This can be a boolean or\n // an integer. If `true`, the ZoomPane will always be inline,\n // if `false`, it will switch to inline when `windowWidth <= inlinePane`\n const inlinePane = options[\"inlinePane\"] || 375;\n // If `true`, touch events will trigger the zoom, like mouse events.\n const handleTouch = \"handleTouch\" in options ? !!options[\"handleTouch\"] : true;\n // If present (and a function), this will be called\n // whenever the ZoomPane is shown.\n const onShow = options[\"onShow\"] || null;\n // If present (and a function), this will be called\n // whenever the ZoomPane is hidden.\n const onHide = options[\"onHide\"] || null;\n // Add base styles to the page. See the \"Theming\"\n // section of README.md for more information.\n const injectBaseStyles = \"injectBaseStyles\" in options ? !!options[\"injectBaseStyles\"] : true;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `mouseenter` event.\n const hoverDelay = options[\"hoverDelay\"] || 0;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `touchstart` event.\n // It's unlikely that you would want to use this option, since\n // \"tap and hold\" is much more intentional than a hover event.\n const touchDelay = options[\"touchDelay\"] || 0;\n // If true, a bounding box will show the area currently being previewed\n // during mouse hover\n const hoverBoundingBox = options[\"hoverBoundingBox\"] || false;\n // If true, a bounding box will show the area currently being previewed\n // during touch events\n const touchBoundingBox = options[\"touchBoundingBox\"] || false;\n // A DOM element to append the bounding box to.\n const boundingBoxContainer = options[\"boundingBoxContainer\"] || document.body;\n\n if (inlinePane !== true && !isDOMElement(paneContainer)) {\n throw new TypeError(\"`paneContainer` must be a DOM element when `inlinePane !== true`\");\n }\n if (!isDOMElement(inlineContainer)) {\n throw new TypeError(\"`inlineContainer` must be a DOM element\");\n }\n\n this.settings = {\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n sourceAttribute,\n zoomFactor,\n paneContainer,\n inlinePane,\n handleTouch,\n onShow,\n onHide,\n injectBaseStyles,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n boundingBoxContainer,\n };\n\n if (this.settings.injectBaseStyles) {\n injectBaseStylesheet();\n }\n\n this._buildZoomPane();\n this._buildTrigger();\n }\n\n get isShowing() {\n return this.zoomPane.isShowing;\n }\n\n get zoomFactor() {\n return this.settings.zoomFactor;\n }\n\n set zoomFactor(zf) {\n this.settings.zoomFactor = zf;\n this.zoomPane.settings.zoomFactor = zf;\n this.trigger.settings.zoomFactor = zf;\n this.boundingBox.settings.zoomFactor = zf;\n }\n\n _buildZoomPane() {\n this.zoomPane = new ZoomPane_ZoomPane({\n container: this.settings.paneContainer,\n zoomFactor: this.settings.zoomFactor,\n showWhitespaceAtEdges: this.settings.showWhitespaceAtEdges,\n containInline: this.settings.containInline,\n inline: this.settings.inlinePane,\n namespace: this.settings.namespace,\n inlineOffsetX: this.settings.inlineOffsetX,\n inlineOffsetY: this.settings.inlineOffsetY,\n inlineContainer: this.settings.inlineContainer,\n });\n }\n\n _buildTrigger() {\n this.trigger = new Trigger_Trigger({\n el: this.triggerEl,\n zoomPane: this.zoomPane,\n handleTouch: this.settings.handleTouch,\n onShow: this.settings.onShow,\n onHide: this.settings.onHide,\n sourceAttribute: this.settings.sourceAttribute,\n hoverDelay: this.settings.hoverDelay,\n touchDelay: this.settings.touchDelay,\n hoverBoundingBox: this.settings.hoverBoundingBox,\n touchBoundingBox: this.settings.touchBoundingBox,\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n boundingBoxContainer: this.settings.boundingBoxContainer,\n });\n }\n\n setZoomImageURL(imageURL) {\n this.zoomPane._setImageURL(imageURL);\n }\n\n disable() {\n this.trigger.enabled = false;\n }\n\n enable() {\n this.trigger.enabled = true;\n }\n\n destroy() {\n this.trigger._hide();\n this.trigger._unbindEvents();\n }\n}\n\n// Public API\n/* eslint-disable no-self-assign */\nObject.defineProperty(Drift_Drift.prototype, \"isShowing\", {\n get: function () {\n return this.isShowing;\n },\n});\nObject.defineProperty(Drift_Drift.prototype, \"zoomFactor\", {\n get: function () {\n return this.zoomFactor;\n },\n set: function (value) {\n this.zoomFactor = value;\n },\n});\nDrift_Drift.prototype[\"setZoomImageURL\"] = Drift_Drift.prototype.setZoomImageURL;\nDrift_Drift.prototype[\"disable\"] = Drift_Drift.prototype.disable;\nDrift_Drift.prototype[\"enable\"] = Drift_Drift.prototype.enable;\nDrift_Drift.prototype[\"destroy\"] = Drift_Drift.prototype.destroy;\n/* eslint-enable no-self-assign */\n\n// CONCATENATED MODULE: ./src/js/Drift-browser.js\n// This file is used for the standalone browser build\n\n\n\nwindow[\"Drift\"] = Drift_Drift;\n\n\n/***/ })\n/******/ ]);"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import { isDOMElement } from \"./util/dom\";\nimport injectBaseStylesheet from \"./injectBaseStylesheet\";\n\nimport Trigger from \"./Trigger\";\nimport ZoomPane from \"./ZoomPane\";\n\nexport default class Drift {\n constructor(triggerEl, options = {}) {\n this.VERSION = \"1.4.2\";\n this.triggerEl = triggerEl;\n\n this.destroy = this.destroy.bind(this);\n\n if (!isDOMElement(this.triggerEl)) {\n throw new TypeError(\"`new Drift` requires a DOM element as its first argument.\");\n }\n\n // Prefix for generated element class names (e.g. `my-ns` will\n // result in classes such as `my-ns-pane`. Default `drift-`\n // prefixed classes will always be added as well.\n const namespace = options[\"namespace\"] || null;\n // Whether the ZoomPane should show whitespace when near the edges.\n const showWhitespaceAtEdges = options[\"showWhitespaceAtEdges\"] || false;\n // Whether the inline ZoomPane should stay inside\n // the bounds of its image.\n const containInline = options[\"containInline\"] || false;\n // How much to offset the ZoomPane from the\n // interaction point when inline.\n const inlineOffsetX = options[\"inlineOffsetX\"] || 0;\n const inlineOffsetY = options[\"inlineOffsetY\"] || 0;\n // A DOM element to append the inline ZoomPane to\n const inlineContainer = options[\"inlineContainer\"] || document.body;\n // Which trigger attribute to pull the ZoomPane image source from.\n const sourceAttribute = options[\"sourceAttribute\"] || \"data-zoom\";\n // How much to magnify the trigger by in the ZoomPane.\n // (e.g., `zoomFactor: 3` will result in a 900 px wide ZoomPane imag\n // if the trigger is displayed at 300 px wide)\n const zoomFactor = options[\"zoomFactor\"] || 3;\n // A DOM element to append the non-inline ZoomPane to.\n // Required if `inlinePane !== true`.\n const paneContainer = options[\"paneContainer\"] === undefined ? document.body : options[\"paneContainer\"];\n // When to switch to an inline ZoomPane. This can be a boolean or\n // an integer. If `true`, the ZoomPane will always be inline,\n // if `false`, it will switch to inline when `windowWidth <= inlinePane`\n const inlinePane = options[\"inlinePane\"] || 375;\n // If `true`, touch events will trigger the zoom, like mouse events.\n const handleTouch = \"handleTouch\" in options ? !!options[\"handleTouch\"] : true;\n // If present (and a function), this will be called\n // whenever the ZoomPane is shown.\n const onShow = options[\"onShow\"] || null;\n // If present (and a function), this will be called\n // whenever the ZoomPane is hidden.\n const onHide = options[\"onHide\"] || null;\n // Add base styles to the page. See the \"Theming\"\n // section of README.md for more information.\n const injectBaseStyles = \"injectBaseStyles\" in options ? !!options[\"injectBaseStyles\"] : true;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `mouseenter` event.\n const hoverDelay = options[\"hoverDelay\"] || 0;\n // An optional number that determines how long to wait before\n // showing the ZoomPane because of a `touchstart` event.\n // It's unlikely that you would want to use this option, since\n // \"tap and hold\" is much more intentional than a hover event.\n const touchDelay = options[\"touchDelay\"] || 0;\n // If true, a bounding box will show the area currently being previewed\n // during mouse hover\n const hoverBoundingBox = options[\"hoverBoundingBox\"] || false;\n // If true, a bounding box will show the area currently being previewed\n // during touch events\n const touchBoundingBox = options[\"touchBoundingBox\"] || false;\n // A DOM element to append the bounding box to.\n const boundingBoxContainer = options[\"boundingBoxContainer\"] || document.body;\n\n if (inlinePane !== true && !isDOMElement(paneContainer)) {\n throw new TypeError(\"`paneContainer` must be a DOM element when `inlinePane !== true`\");\n }\n if (!isDOMElement(inlineContainer)) {\n throw new TypeError(\"`inlineContainer` must be a DOM element\");\n }\n\n this.settings = {\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n sourceAttribute,\n zoomFactor,\n paneContainer,\n inlinePane,\n handleTouch,\n onShow,\n onHide,\n injectBaseStyles,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n boundingBoxContainer,\n };\n\n if (this.settings.injectBaseStyles) {\n injectBaseStylesheet();\n }\n\n this._buildZoomPane();\n this._buildTrigger();\n }\n\n get isShowing() {\n return this.zoomPane.isShowing;\n }\n\n get zoomFactor() {\n return this.settings.zoomFactor;\n }\n\n set zoomFactor(zf) {\n this.settings.zoomFactor = zf;\n this.zoomPane.settings.zoomFactor = zf;\n this.trigger.settings.zoomFactor = zf;\n this.boundingBox.settings.zoomFactor = zf;\n }\n\n _buildZoomPane() {\n this.zoomPane = new ZoomPane({\n container: this.settings.paneContainer,\n zoomFactor: this.settings.zoomFactor,\n showWhitespaceAtEdges: this.settings.showWhitespaceAtEdges,\n containInline: this.settings.containInline,\n inline: this.settings.inlinePane,\n namespace: this.settings.namespace,\n inlineOffsetX: this.settings.inlineOffsetX,\n inlineOffsetY: this.settings.inlineOffsetY,\n inlineContainer: this.settings.inlineContainer,\n });\n }\n\n _buildTrigger() {\n this.trigger = new Trigger({\n el: this.triggerEl,\n zoomPane: this.zoomPane,\n handleTouch: this.settings.handleTouch,\n onShow: this.settings.onShow,\n onHide: this.settings.onHide,\n sourceAttribute: this.settings.sourceAttribute,\n hoverDelay: this.settings.hoverDelay,\n touchDelay: this.settings.touchDelay,\n hoverBoundingBox: this.settings.hoverBoundingBox,\n touchBoundingBox: this.settings.touchBoundingBox,\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n boundingBoxContainer: this.settings.boundingBoxContainer,\n });\n }\n\n setZoomImageURL(imageURL) {\n this.zoomPane._setImageURL(imageURL);\n }\n\n disable() {\n this.trigger.enabled = false;\n }\n\n enable() {\n this.trigger.enabled = true;\n }\n\n destroy() {\n this.trigger._hide();\n this.trigger._unbindEvents();\n }\n}\n\n// Public API\n/* eslint-disable no-self-assign */\nObject.defineProperty(Drift.prototype, \"isShowing\", {\n get: function () {\n return this.isShowing;\n },\n});\nObject.defineProperty(Drift.prototype, \"zoomFactor\", {\n get: function () {\n return this.zoomFactor;\n },\n set: function (value) {\n this.zoomFactor = value;\n },\n});\nDrift.prototype[\"setZoomImageURL\"] = Drift.prototype.setZoomImageURL;\nDrift.prototype[\"disable\"] = Drift.prototype.disable;\nDrift.prototype[\"enable\"] = Drift.prototype.enable;\nDrift.prototype[\"destroy\"] = Drift.prototype.destroy;\n/* eslint-enable no-self-assign */\n","/* UNMINIFIED RULES\n\nconst RULES = `\n@keyframes noop {\n 0% { zoom: 1; }\n}\n\n@-webkit-keyframes noop {\n 0% { zoom: 1; }\n}\n\n.drift-zoom-pane.drift-open {\n display: block;\n}\n\n.drift-zoom-pane.drift-opening, .drift-zoom-pane.drift-closing {\n animation: noop 1ms;\n -webkit-animation: noop 1ms;\n}\n\n.drift-zoom-pane {\n position: absolute;\n overflow: hidden;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n pointer-events: none;\n}\n\n.drift-zoom-pane-loader {\n display: none;\n}\n\n.drift-zoom-pane img {\n position: absolute;\n display: block;\n max-width: none;\n max-height: none;\n}\n\n.drift-bounding-box {\n position: absolute;\n pointer-events: none;\n}\n`;\n\n*/\n\nconst RULES =\n \".drift-bounding-box,.drift-zoom-pane{position:absolute;pointer-events:none}@keyframes noop{0%{zoom:1}}@-webkit-keyframes noop{0%{zoom:1}}.drift-zoom-pane.drift-open{display:block}.drift-zoom-pane.drift-closing,.drift-zoom-pane.drift-opening{animation:noop 1ms;-webkit-animation:noop 1ms}.drift-zoom-pane{overflow:hidden;width:100%;height:100%;top:0;left:0}.drift-zoom-pane-loader{display:none}.drift-zoom-pane img{position:absolute;display:block;max-width:none;max-height:none}\";\n\nexport default function injectBaseStylesheet() {\n if (document.querySelector(\".drift-base-styles\")) {\n return;\n }\n\n const styleEl = document.createElement(\"style\");\n styleEl.type = \"text/css\";\n styleEl.classList = \"drift-base-styles\";\n\n styleEl.textContent = RULES;\n const head = document.head;\n\n const allHeadElements = head.getElementsByTagName(\"*\");\n allHeadElements.innerHTML = styleEl + allHeadElements.innerHTML;\n}\n","import throwIfMissing from \"./util/throwIfMissing\";\nimport { addClasses, removeClasses } from \"./util/dom\";\n\n// All officially-supported browsers have this, but it's easy to\n// account for, just in case.\nconst divStyle = document.createElement(\"div\").style;\n\nconst HAS_ANIMATION =\n typeof document === \"undefined\" ? false : \"animation\" in divStyle || \"webkitAnimation\" in divStyle;\n\nexport default class ZoomPane {\n constructor(options = {}) {\n this._completeShow = this._completeShow.bind(this);\n this._completeHide = this._completeHide.bind(this);\n this._handleLoad = this._handleLoad.bind(this);\n\n this.isShowing = false;\n\n const {\n container = null,\n zoomFactor = throwIfMissing(),\n inline = throwIfMissing(),\n namespace = null,\n showWhitespaceAtEdges = throwIfMissing(),\n containInline = throwIfMissing(),\n inlineOffsetX = 0,\n inlineOffsetY = 0,\n inlineContainer = document.body,\n } = options;\n\n this.settings = {\n container,\n zoomFactor,\n inline,\n namespace,\n showWhitespaceAtEdges,\n containInline,\n inlineOffsetX,\n inlineOffsetY,\n inlineContainer,\n };\n\n this.openClasses = this._buildClasses(\"open\");\n this.openingClasses = this._buildClasses(\"opening\");\n this.closingClasses = this._buildClasses(\"closing\");\n this.inlineClasses = this._buildClasses(\"inline\");\n this.loadingClasses = this._buildClasses(\"loading\");\n\n this._buildElement();\n }\n\n _buildClasses(suffix) {\n const classes = [`drift-${suffix}`];\n\n const ns = this.settings.namespace;\n if (ns) {\n classes.push(`${ns}-${suffix}`);\n }\n\n return classes;\n }\n\n _buildElement() {\n this.el = document.createElement(\"div\");\n addClasses(this.el, this._buildClasses(\"zoom-pane\"));\n\n const loaderEl = document.createElement(\"div\");\n addClasses(loaderEl, this._buildClasses(\"zoom-pane-loader\"));\n this.el.appendChild(loaderEl);\n\n this.imgEl = document.createElement(\"img\");\n this.el.appendChild(this.imgEl);\n }\n\n _setImageURL(imageURL) {\n this.imgEl.setAttribute(\"src\", imageURL);\n }\n\n _setImageSize(triggerWidth, triggerHeight) {\n this.imgEl.style.width = `${triggerWidth * this.settings.zoomFactor}px`;\n this.imgEl.style.height = `${triggerHeight * this.settings.zoomFactor}px`;\n }\n\n // `percentageOffsetX` and `percentageOffsetY` must be percentages\n // expressed as floats between `0' and `1`.\n setPosition(percentageOffsetX, percentageOffsetY, triggerRect) {\n const imgElWidth = this.imgEl.offsetWidth;\n const imgElHeight = this.imgEl.offsetHeight;\n const elWidth = this.el.offsetWidth;\n const elHeight = this.el.offsetHeight;\n\n const centreOfContainerX = elWidth / 2;\n const centreOfContainerY = elHeight / 2;\n\n const targetImgXToBeCentre = imgElWidth * percentageOffsetX;\n const targetImgYToBeCentre = imgElHeight * percentageOffsetY;\n\n let left = centreOfContainerX - targetImgXToBeCentre;\n let top = centreOfContainerY - targetImgYToBeCentre;\n\n const differenceBetweenContainerWidthAndImgWidth = elWidth - imgElWidth;\n const differenceBetweenContainerHeightAndImgHeight = elHeight - imgElHeight;\n const isContainerLargerThanImgX = differenceBetweenContainerWidthAndImgWidth > 0;\n const isContainerLargerThanImgY = differenceBetweenContainerHeightAndImgHeight > 0;\n\n const minLeft = isContainerLargerThanImgX ? differenceBetweenContainerWidthAndImgWidth / 2 : 0;\n const minTop = isContainerLargerThanImgY ? differenceBetweenContainerHeightAndImgHeight / 2 : 0;\n\n const maxLeft = isContainerLargerThanImgX\n ? differenceBetweenContainerWidthAndImgWidth / 2\n : differenceBetweenContainerWidthAndImgWidth;\n const maxTop = isContainerLargerThanImgY\n ? differenceBetweenContainerHeightAndImgHeight / 2\n : differenceBetweenContainerHeightAndImgHeight;\n\n if (this.el.parentElement === this.settings.inlineContainer) {\n // This may be needed in the future to deal with browser event\n // inconsistencies, but it's difficult to tell for sure.\n // let scrollX = isTouch ? 0 : window.scrollX;\n // let scrollY = isTouch ? 0 : window.scrollY;\n const scrollX = window.pageXOffset;\n const scrollY = window.pageYOffset;\n\n let inlineLeft =\n triggerRect.left + percentageOffsetX * triggerRect.width - elWidth / 2 + this.settings.inlineOffsetX + scrollX;\n let inlineTop =\n triggerRect.top + percentageOffsetY * triggerRect.height - elHeight / 2 + this.settings.inlineOffsetY + scrollY;\n\n if (this.settings.containInline) {\n if (inlineLeft < triggerRect.left + scrollX) {\n inlineLeft = triggerRect.left + scrollX;\n } else if (inlineLeft + elWidth > triggerRect.left + triggerRect.width + scrollX) {\n inlineLeft = triggerRect.left + triggerRect.width - elWidth + scrollX;\n }\n\n if (inlineTop < triggerRect.top + scrollY) {\n inlineTop = triggerRect.top + scrollY;\n } else if (inlineTop + elHeight > triggerRect.top + triggerRect.height + scrollY) {\n inlineTop = triggerRect.top + triggerRect.height - elHeight + scrollY;\n }\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n\n if (!this.settings.showWhitespaceAtEdges) {\n if (left > minLeft) {\n left = minLeft;\n } else if (left < maxLeft) {\n left = maxLeft;\n }\n\n if (top > minTop) {\n top = minTop;\n } else if (top < maxTop) {\n top = maxTop;\n }\n }\n\n this.imgEl.style.transform = `translate(${left}px, ${top}px)`;\n this.imgEl.style.webkitTransform = `translate(${left}px, ${top}px)`;\n }\n\n get _isInline() {\n const inline = this.settings.inline;\n\n return inline === true || (typeof inline === \"number\" && window.innerWidth <= inline);\n }\n\n _removeListenersAndResetClasses() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n }\n\n show(imageURL, triggerWidth, triggerHeight) {\n this._removeListenersAndResetClasses();\n this.isShowing = true;\n\n addClasses(this.el, this.openClasses);\n\n if (this.imgEl.getAttribute(\"src\") != imageURL) {\n addClasses(this.el, this.loadingClasses);\n this.imgEl.addEventListener(\"load\", this._handleLoad, false);\n this._setImageURL(imageURL);\n }\n\n this._setImageSize(triggerWidth, triggerHeight);\n\n if (this._isInline) {\n this._showInline();\n } else {\n this._showInContainer();\n }\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeShow, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n addClasses(this.el, this.openingClasses);\n }\n }\n\n _showInline() {\n this.settings.inlineContainer.appendChild(this.el);\n addClasses(this.el, this.inlineClasses);\n }\n\n _showInContainer() {\n this.settings.container.appendChild(this.el);\n }\n\n hide() {\n this._removeListenersAndResetClasses();\n this.isShowing = false;\n\n if (HAS_ANIMATION) {\n this.el.addEventListener(\"animationend\", this._completeHide, false);\n this.el.addEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n addClasses(this.el, this.closingClasses);\n } else {\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.inlineClasses);\n }\n }\n\n _completeShow() {\n this.el.removeEventListener(\"animationend\", this._completeShow, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeShow, false);\n\n removeClasses(this.el, this.openingClasses);\n }\n\n _completeHide() {\n this.el.removeEventListener(\"animationend\", this._completeHide, false);\n this.el.removeEventListener(\"webkitAnimationEnd\", this._completeHide, false);\n\n removeClasses(this.el, this.openClasses);\n removeClasses(this.el, this.closingClasses);\n removeClasses(this.el, this.inlineClasses);\n\n this.el.style = \"\";\n\n // The window could have been resized above or below `inline`\n // limits since the ZoomPane was shown. Because of this, we\n // can't rely on `this._isInline` here.\n if (this.el.parentElement === this.settings.container) {\n this.settings.container.removeChild(this.el);\n } else if (this.el.parentElement === this.settings.inlineContainer) {\n this.settings.inlineContainer.removeChild(this.el);\n }\n }\n\n _handleLoad() {\n this.imgEl.removeEventListener(\"load\", this._handleLoad, false);\n removeClasses(this.el, this.loadingClasses);\n }\n}\n","import throwIfMissing from \"./util/throwIfMissing\";\nimport BoundingBox from \"./BoundingBox\";\n\nexport default class Trigger {\n constructor(options = {}) {\n this._show = this._show.bind(this);\n this._hide = this._hide.bind(this);\n this._handleEntry = this._handleEntry.bind(this);\n this._handleMovement = this._handleMovement.bind(this);\n\n const {\n el = throwIfMissing(),\n zoomPane = throwIfMissing(),\n sourceAttribute = throwIfMissing(),\n handleTouch = throwIfMissing(),\n onShow = null,\n onHide = null,\n hoverDelay = 0,\n touchDelay = 0,\n hoverBoundingBox = throwIfMissing(),\n touchBoundingBox = throwIfMissing(),\n namespace = null,\n zoomFactor = throwIfMissing(),\n boundingBoxContainer = throwIfMissing(),\n } = options;\n\n this.settings = {\n el,\n zoomPane,\n sourceAttribute,\n handleTouch,\n onShow,\n onHide,\n hoverDelay,\n touchDelay,\n hoverBoundingBox,\n touchBoundingBox,\n namespace,\n zoomFactor,\n boundingBoxContainer,\n };\n\n if (this.settings.hoverBoundingBox || this.settings.touchBoundingBox) {\n this.boundingBox = new BoundingBox({\n namespace: this.settings.namespace,\n zoomFactor: this.settings.zoomFactor,\n containerEl: this.settings.boundingBoxContainer,\n });\n }\n\n this.enabled = true;\n\n this._bindEvents();\n }\n\n get isShowing() {\n return this.settings.zoomPane.isShowing;\n }\n\n _preventDefault(event) {\n event.preventDefault();\n }\n\n _preventDefaultAllowTouchScroll(event) {\n if (!this.settings.touchDelay || !this._isTouchEvent(event) || this.isShowing) {\n event.preventDefault();\n }\n }\n\n _isTouchEvent(event) {\n return !!event.touches;\n }\n\n _bindEvents() {\n this.settings.el.addEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.addEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.addEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.addEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.addEventListener(\"touchend\", this._hide, false);\n this.settings.el.addEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.addEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.addEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _unbindEvents() {\n this.settings.el.removeEventListener(\"mouseenter\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"mouseleave\", this._hide, false);\n this.settings.el.removeEventListener(\"mousemove\", this._handleMovement, false);\n\n if (this.settings.handleTouch) {\n this.settings.el.removeEventListener(\"touchstart\", this._handleEntry, false);\n this.settings.el.removeEventListener(\"touchend\", this._hide, false);\n this.settings.el.removeEventListener(\"touchmove\", this._handleMovement, false);\n } else {\n this.settings.el.removeEventListener(\"touchstart\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchend\", this._preventDefault, false);\n this.settings.el.removeEventListener(\"touchmove\", this._preventDefault, false);\n }\n }\n\n _handleEntry(e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n\n if (e.type == \"mouseenter\" && this.settings.hoverDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.hoverDelay);\n } else if (this.settings.touchDelay) {\n this.entryTimeout = setTimeout(this._show, this.settings.touchDelay);\n } else {\n this._show();\n }\n }\n\n _show() {\n if (!this.enabled) {\n return;\n }\n\n const onShow = this.settings.onShow;\n if (onShow && typeof onShow === \"function\") {\n onShow();\n }\n\n this.settings.zoomPane.show(\n this.settings.el.getAttribute(this.settings.sourceAttribute),\n this.settings.el.clientWidth,\n this.settings.el.clientHeight\n );\n\n if (this._lastMovement) {\n const touchActivated = this._lastMovement.touches;\n if ((touchActivated && this.settings.touchBoundingBox) || (!touchActivated && this.settings.hoverBoundingBox)) {\n this.boundingBox.show(this.settings.zoomPane.el.clientWidth, this.settings.zoomPane.el.clientHeight);\n }\n }\n\n this._handleMovement();\n }\n\n _hide(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n }\n\n this._lastMovement = null;\n\n if (this.entryTimeout) {\n clearTimeout(this.entryTimeout);\n }\n\n if (this.boundingBox) {\n this.boundingBox.hide();\n }\n\n const onHide = this.settings.onHide;\n if (onHide && typeof onHide === \"function\") {\n onHide();\n }\n\n this.settings.zoomPane.hide();\n }\n\n _handleMovement(e) {\n if (e) {\n this._preventDefaultAllowTouchScroll(e);\n this._lastMovement = e;\n } else if (this._lastMovement) {\n e = this._lastMovement;\n } else {\n return;\n }\n\n let movementX;\n let movementY;\n\n if (e.touches) {\n const firstTouch = e.touches[0];\n movementX = firstTouch.clientX;\n movementY = firstTouch.clientY;\n } else {\n movementX = e.clientX;\n movementY = e.clientY;\n }\n\n const el = this.settings.el;\n const rect = el.getBoundingClientRect();\n const offsetX = movementX - rect.left;\n const offsetY = movementY - rect.top;\n\n const percentageOffsetX = offsetX / this.settings.el.clientWidth;\n const percentageOffsetY = offsetY / this.settings.el.clientHeight;\n\n if (this.boundingBox) {\n this.boundingBox.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n\n this.settings.zoomPane.setPosition(percentageOffsetX, percentageOffsetY, rect);\n }\n}\n","import throwIfMissing from \"./util/throwIfMissing\";\nimport { addClasses, removeClasses } from \"./util/dom\";\n\nexport default class BoundingBox {\n constructor(options) {\n this.isShowing = false;\n\n const { namespace = null, zoomFactor = throwIfMissing(), containerEl = throwIfMissing() } = options;\n\n this.settings = { namespace, zoomFactor, containerEl };\n\n this.openClasses = this._buildClasses(\"open\");\n\n this._buildElement();\n }\n\n _buildClasses(suffix) {\n const classes = [`drift-${suffix}`];\n\n const ns = this.settings.namespace;\n if (ns) {\n classes.push(`${ns}-${suffix}`);\n }\n\n return classes;\n }\n\n _buildElement() {\n this.el = document.createElement(\"div\");\n addClasses(this.el, this._buildClasses(\"bounding-box\"));\n }\n\n show(zoomPaneWidth, zoomPaneHeight) {\n this.isShowing = true;\n\n this.settings.containerEl.appendChild(this.el);\n\n const style = this.el.style;\n style.width = `${Math.round(zoomPaneWidth / this.settings.zoomFactor)}px`;\n style.height = `${Math.round(zoomPaneHeight / this.settings.zoomFactor)}px`;\n\n addClasses(this.el, this.openClasses);\n }\n\n hide() {\n if (this.isShowing) {\n this.settings.containerEl.removeChild(this.el);\n }\n\n this.isShowing = false;\n\n removeClasses(this.el, this.openClasses);\n }\n\n setPosition(percentageOffsetX, percentageOffsetY, triggerRect) {\n const pageXOffset = window.pageXOffset;\n const pageYOffset = window.pageYOffset;\n\n let inlineLeft = triggerRect.left + percentageOffsetX * triggerRect.width - this.el.clientWidth / 2 + pageXOffset;\n let inlineTop = triggerRect.top + percentageOffsetY * triggerRect.height - this.el.clientHeight / 2 + pageYOffset;\n\n if (inlineLeft < triggerRect.left + pageXOffset) {\n inlineLeft = triggerRect.left + pageXOffset;\n } else if (inlineLeft + this.el.clientWidth > triggerRect.left + triggerRect.width + pageXOffset) {\n inlineLeft = triggerRect.left + triggerRect.width - this.el.clientWidth + pageXOffset;\n }\n\n if (inlineTop < triggerRect.top + pageYOffset) {\n inlineTop = triggerRect.top + pageYOffset;\n } else if (inlineTop + this.el.clientHeight > triggerRect.top + triggerRect.height + pageYOffset) {\n inlineTop = triggerRect.top + triggerRect.height - this.el.clientHeight + pageYOffset;\n }\n\n this.el.style.left = `${inlineLeft}px`;\n this.el.style.top = `${inlineTop}px`;\n }\n}\n","// This is not really a perfect check, but works fine.\n// From http://stackoverflow.com/questions/384286\nconst HAS_DOM_2 = typeof HTMLElement === \"object\";\n\nexport function isDOMElement(obj) {\n return HAS_DOM_2\n ? obj instanceof HTMLElement\n : obj && typeof obj === \"object\" && obj !== null && obj.nodeType === 1 && typeof obj.nodeName === \"string\";\n}\n\nexport function addClasses(el, classNames) {\n classNames.forEach(function (className) {\n el.classList.add(className);\n });\n}\n\nexport function removeClasses(el, classNames) {\n classNames.forEach(function (className) {\n el.classList.remove(className);\n });\n}\n","export default function throwIfMissing() {\n throw new Error(\"Missing parameter\");\n}\n","// This file is used for the standalone browser build\n\nimport Drift from \"./Drift\";\n\nwindow[\"Drift\"] = Drift;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/drift-basic.min.css b/dist/drift-basic.min.css index 6b9dce6c..6a726719 100644 --- a/dist/drift-basic.min.css +++ b/dist/drift-basic.min.css @@ -1 +1 @@ -@keyframes a{0%{transform:scale(1.5);opacity:0}to{transform:scale(1);opacity:1}}@keyframes b{0%{transform:scale(1);opacity:1}15%{transform:scale(1.1);opacity:1}to{transform:scale(.5);opacity:0}}@keyframes c{0%{transform:translate(-50%,-50%) rotate(0)}50%{transform:translate(-50%,-50%) rotate(-180deg)}to{transform:translate(-50%,-50%) rotate(-1turn)}}@keyframes d{0%{transform:scale(1)}10%{transform:scale(1.2) translateX(6px)}25%{transform:scale(1.3) translateX(8px)}40%{transform:scale(1.2) translateX(6px)}50%{transform:scale(1)}60%{transform:scale(.8) translateX(6px)}75%{transform:scale(.7) translateX(8px)}90%{transform:scale(.8) translateX(6px)}to{transform:scale(1)}}@keyframes e{0%{transform:scale(1)}10%{transform:scale(1.2) translateX(-6px)}25%{transform:scale(1.3) translateX(-8px)}40%{transform:scale(1.2) translateX(-6px)}50%{transform:scale(1)}60%{transform:scale(.8) translateX(-6px)}75%{transform:scale(.7) translateX(-8px)}90%{transform:scale(.8) translateX(-6px)}to{transform:scale(1)}}@-webkit-keyframes a{0%{-webkit-transform:scale(1.5);opacity:0}to{-webkit-transform:scale(1);opacity:1}}@-webkit-keyframes b{0%{-webkit-transform:scale(1);opacity:1}15%{-webkit-transform:scale(1.1);opacity:1}to{-webkit-transform:scale(.5);opacity:0}}@-webkit-keyframes c{0%{-webkit-transform:translate(-50%,-50%) rotate(0)}50%{-webkit-transform:translate(-50%,-50%) rotate(-180deg)}to{-webkit-transform:translate(-50%,-50%) rotate(-1turn)}}@-webkit-keyframes d{0%{-webkit-transform:scale(1)}10%{-webkit-transform:scale(1.2) translateX(6px)}25%{-webkit-transform:scale(1.3) translateX(8px)}40%{-webkit-transform:scale(1.2) translateX(6px)}50%{-webkit-transform:scale(1)}60%{-webkit-transform:scale(.8) translateX(6px)}75%{-webkit-transform:scale(.7) translateX(8px)}90%{-webkit-transform:scale(.8) translateX(6px)}to{-webkit-transform:scale(1)}}@-webkit-keyframes e{0%{-webkit-transform:scale(1)}10%{-webkit-transform:scale(1.2) translateX(-6px)}25%{-webkit-transform:scale(1.3) translateX(-8px)}40%{-webkit-transform:scale(1.2) translateX(-6px)}50%{-webkit-transform:scale(1)}60%{-webkit-transform:scale(.8) translateX(-6px)}75%{-webkit-transform:scale(.7) translateX(-8px)}90%{-webkit-transform:scale(.8) translateX(-6px)}to{-webkit-transform:scale(1)}}.drift-zoom-pane{background:rgba(0,0,0,.5);transform:translateZ(0);-webkit-transform:translateZ(0)}.drift-zoom-pane.drift-opening{animation:a .18s ease-out;-webkit-animation:a .18s ease-out}.drift-zoom-pane.drift-closing{animation:b .21s ease-in;-webkit-animation:b .21s ease-in}.drift-zoom-pane.drift-inline{position:absolute;width:150px;height:150px;border-radius:75px;box-shadow:0 6px 18px rgba(0,0,0,.3)}.drift-loading .drift-zoom-pane-loader{display:block;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-webkit-transform:translate(-50%,-50%);width:66px;height:20px;animation:c 1.8s linear infinite;-webkit-animation:c 1.8s linear infinite}.drift-zoom-pane-loader:after,.drift-zoom-pane-loader:before{content:"";display:block;width:20px;height:20px;position:absolute;top:50%;margin-top:-10px;border-radius:20px;background:hsla(0,0%,100%,.9)}.drift-zoom-pane-loader:before{left:0;animation:d 1.8s linear infinite;-webkit-animation:d 1.8s linear infinite}.drift-zoom-pane-loader:after{right:0;animation:e 1.8s linear infinite;-webkit-animation:e 1.8s linear infinite;animation-delay:-.9s;-webkit-animation-delay:-.9s}.drift-bounding-box{background-color:rgba(0,0,0,.4)} \ No newline at end of file +@keyframes a{0%{transform:scale(1.5);opacity:0}to{transform:scale(1);opacity:1}}@keyframes b{0%{transform:scale(1);opacity:1}15%{transform:scale(1.1);opacity:1}to{transform:scale(.5);opacity:0}}@keyframes c{0%{transform:translate(-50%,-50%) rotate(0)}50%{transform:translate(-50%,-50%) rotate(-180deg)}to{transform:translate(-50%,-50%) rotate(-1turn)}}@keyframes d{0%{transform:scale(1)}10%{transform:scale(1.2) translateX(6px)}25%{transform:scale(1.3) translateX(8px)}40%{transform:scale(1.2) translateX(6px)}50%{transform:scale(1)}60%{transform:scale(.8) translateX(6px)}75%{transform:scale(.7) translateX(8px)}90%{transform:scale(.8) translateX(6px)}to{transform:scale(1)}}@keyframes e{0%{transform:scale(1)}10%{transform:scale(1.2) translateX(-6px)}25%{transform:scale(1.3) translateX(-8px)}40%{transform:scale(1.2) translateX(-6px)}50%{transform:scale(1)}60%{transform:scale(.8) translateX(-6px)}75%{transform:scale(.7) translateX(-8px)}90%{transform:scale(.8) translateX(-6px)}to{transform:scale(1)}}.drift-zoom-pane{background:rgba(0,0,0,.5);transform:translateZ(0);-webkit-transform:translateZ(0)}.drift-zoom-pane.drift-opening{animation:a .18s ease-out;-webkit-animation:a .18s ease-out}.drift-zoom-pane.drift-closing{animation:b .21s ease-in;-webkit-animation:b .21s ease-in}.drift-zoom-pane.drift-inline{position:absolute;width:150px;height:150px;border-radius:75px;box-shadow:0 6px 18px rgba(0,0,0,.3)}.drift-loading .drift-zoom-pane-loader{display:block;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-webkit-transform:translate(-50%,-50%);width:66px;height:20px;animation:c 1.8s linear infinite;-webkit-animation:c 1.8s linear infinite}.drift-zoom-pane-loader:after,.drift-zoom-pane-loader:before{content:"";display:block;width:20px;height:20px;position:absolute;top:50%;margin-top:-10px;border-radius:20px;background:hsla(0,0%,100%,.9)}.drift-zoom-pane-loader:before{left:0;animation:d 1.8s linear infinite;-webkit-animation:d 1.8s linear infinite}.drift-zoom-pane-loader:after{right:0;animation:e 1.8s linear infinite;-webkit-animation:e 1.8s linear infinite;animation-delay:-.9s;-webkit-animation-delay:-.9s}.drift-bounding-box{background-color:rgba(0,0,0,.4)} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b169c514..4c982339 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "drift-zoom", - "version": "1.4.1", + "version": "1.4.2", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index e22267f2..5a3c0b04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "drift-zoom", - "version": "1.4.1", + "version": "1.4.2", "description": "Easily add \"zoom on hover\" functionality to your site's images. Lightweight, no-dependency JavaScript.", "contributors": [ "Frederick Fogerty (https://github.com/frederickfogerty)", diff --git a/src/js/Drift.js b/src/js/Drift.js index 6759befc..f826cf9b 100644 --- a/src/js/Drift.js +++ b/src/js/Drift.js @@ -6,7 +6,7 @@ import ZoomPane from "./ZoomPane"; export default class Drift { constructor(triggerEl, options = {}) { - this.VERSION = "1.4.1"; + this.VERSION = "1.4.2"; this.triggerEl = triggerEl; this.destroy = this.destroy.bind(this);