Difference between revisions of "Team:Cornell NY/Team"

Line 1: Line 1:
 
{{Cornell_NY}}
 
{{Cornell_NY}}
 
<html>
 
<html>
<script>/*!
+
<script>
 +
/*!
 
  * Viewer.js v0.5.0
 
  * Viewer.js v0.5.0
 
  * https://github.com/fengyuanchen/viewerjs
 
  * https://github.com/fengyuanchen/viewerjs
Line 10: Line 11:
 
  * Date: 2016-07-22T08:46:05.003Z
 
  * Date: 2016-07-22T08:46:05.003Z
 
  */
 
  */
!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("Viewer requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function i(e){return Ae.call(e).slice(8,-1).toLowerCase()}function n(e){return"string"==typeof e}function a(e){return"number"==typeof e&&!isNaN(e)}function o(e){return"undefined"==typeof e}function r(e){return"object"==typeof e&&null!==e}function s(e){var t,i;if(!r(e))return!1;try{return t=e.constructor,i=t.prototype,t&&i&&Re.call(i,"isPrototypeOf")}catch(n){return!1}}function l(e){return"function"===i(e)}function u(e){return Array.isArray?Array.isArray(e):"array"===i(e)}function c(e,t){return t=t>=0?t:0,Array.from?Array.from(e).slice(t):We.call(e,t)}function d(e,t){var i=-1;return t.indexOf?t.indexOf(e):(h(t,function(t,n){if(t===e)return i=n,!1}),i)}function m(e){return n(e)&&(e=e.trim?e.trim():e.replace(ke,"1")),e}function h(e,t){var i,n;if(e&&l(t))if(u(e)||a(e.length))for(n=0,i=e.length;n<i&&t.call(e,e[n],n,e)!==!1;n++);else if(r(e))for(n in e)if(e.hasOwnProperty(n)&&t.call(e,e[n],n,e)===!1)break;return e}function f(e){var t;if(arguments.length>1){if(t=c(arguments),Object.assign)return Object.assign.apply(Object,t);t.shift(),h(t,function(t){h(t,function(t,i){e[i]=t})})}return e}function v(e,t){var i=c(arguments,2);return function(){return e.apply(t,i.concat(c(arguments)))}}function g(e,t){var i=e.style;h(t,function(e,t){Le.test(t)&&a(e)&&(e+="px"),i[t]=e})}function w(t){return e.getComputedStyle?e.getComputedStyle(t,null):t.currentStyle}function p(e,t){return e.classList?e.classList.contains(t):e.className.indexOf(t)>-1}function b(e,t){var i;if(t){if(a(e.length))return h(e,function(e){b(e,t)});if(e.classList)return e.classList.add(t);i=m(e.className),i?i.indexOf(t)<0&&(e.className=i+" "+t):e.className=t}}function y(e,t){if(t)return a(e.length)?h(e,function(e){y(e,t)}):e.classList?e.classList.remove(t):void(e.className.indexOf(t)>=0&&(e.className=e.className.replace(t,"")))}function x(e,t,i){return a(e.length)?h(e,function(e){x(e,t,i)}):void(i?b(e,t):y(e,t))}function z(e){return e.replace(Ye,"$1-$2").toLowerCase()}function E(e,t){return r(e[t])?e[t]:e.dataset?e.dataset[t]:e.getAttribute("data-"+z(t))}function D(e,t,i){r(i)?e[t]=i:e.dataset?e.dataset[t]=i:e.setAttribute("data-"+z(t),i)}function I(e,t){r(e[t])?delete e[t]:e.dataset?delete e.dataset[t]:e.removeAttribute("data-"+z(t))}function L(e,t,i,n){var a=m(t).split(Te),o=i;return a.length>1?h(a,function(t){L(e,t,i)}):(n&&(i=function(){return Y(e,t,i),o.apply(e,arguments)}),void(e.addEventListener?e.addEventListener(t,i,!1):e.attachEvent&&e.attachEvent("on"+t,i)))}function Y(e,t,i){var n=m(t).split(Te);return n.length>1?h(n,function(t){Y(e,t,i)}):void(e.removeEventListener?e.removeEventListener(t,i,!1):e.detachEvent&&e.detachEvent("on"+t,i))}function k(e,t,i){var n;return e.dispatchEvent?(l(j)&&l(CustomEvent)?n=o(i)?new j(t,{bubbles:!0,cancelable:!0}):new CustomEvent(t,{detail:i,bubbles:!0,cancelable:!0}):o(i)?(n=H.createEvent("Event"),n.initEvent(t,!0,!0)):(n=H.createEvent("CustomEvent"),n.initCustomEvent(t,!0,!0,i)),e.dispatchEvent(n)):e.fireEvent?e.fireEvent("on"+t):void 0}function T(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function F(t){var i,n=t||e.event;return n.target||(n.target=n.srcElement||H),a(n.pageX)||(i=H.documentElement,n.pageX=n.clientX+(e.scrollX||i&&i.scrollLeft||0)-(i&&i.clientLeft||0),n.pageY=n.clientY+(e.scrollY||i&&i.scrollTop||0)-(i&&i.clientTop||0)),n}function X(t){var i=H.documentElement,n=t.getBoundingClientRect();return{left:n.left+(e.scrollX||i&&i.scrollLeft||0)-(i&&i.clientLeft||0),top:n.top+(e.scrollY||i&&i.scrollTop||0)-(i&&i.clientTop||0)}}function S(e){var t=e.length,i=0,n=0;return t&&(h(e,function(e){i+=e.pageX,n+=e.pageY}),i/=t,n/=t),{pageX:i,pageY:n}}function V(e,t){return e.getElementsByTagName(t)}function N(e,t){return e.getElementsByClassName?e.getElementsByClassName(t):e.querySelectorAll("."+t)}function C(e,t){return t.length?h(t,function(t){C(e,t)}):void e.appendChild(t)}function P(e){e.parentNode&&e.parentNode.removeChild(e)}function A(e){for(;e.firstChild;)e.removeChild(e.firstChild)}function R(e,t){o(e.textContent)?e.innerText=t:e.textContent=t}function W(e){return e.offsetWidth}function _(e){return n(e)?e.replace(/^.*\//,"").replace(/[\?&#].*$/,""):""}function q(e,t){var i;return e.naturalWidth?t(e.naturalWidth,e.naturalHeight):(i=H.createElement("img"),i.onload=function(){t(this.width,this.height)},void(i.src=e.src))}function M(e){var t=[],i=e.rotate,n=e.scaleX,o=e.scaleY;return a(i)&&t.push("rotate("+i+"deg)"),a(n)&&t.push("scaleX("+n+")"),a(o)&&t.push("scaleY("+o+")"),t.length?t.join(" "):"none"}function B(e){switch(e){case 2:return J;case 3:return Q;case 4:return ee}}function O(e,t){var i=this;i.element=e,i.options=f({},O.DEFAULTS,s(t)&&t),i.isImg=!1,i.isBuilt=!1,i.isShown=!1,i.isViewed=!1,i.isFulled=!1,i.isPlayed=!1,i.wheeling=!1,i.playing=!1,i.fading=!1,i.tooltiping=!1,i.transitioning=!1,i.action=!1,i.target=!1,i.timeout=!1,i.index=0,i.length=0,i.init()}var H=e.document,j=e.Event,U="viewer",Z=U+"-fixed",$=U+"-open",K=U+"-show",G=U+"-hide",J="viewer-hide-xs-down",Q="viewer-hide-sm-down",ee="viewer-hide-md-down",te=U+"-fade",ie=U+"-in",ne=U+"-move",ae=U+"-active",oe=U+"-invisible",re=U+"-transition",se=U+"-fullscreen",le=U+"-fullscreen-exit",ue=U+"-close",ce="mousedown touchstart pointerdown MSPointerDown",de="mousemove touchmove pointermove MSPointerMove",me="mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel",he="wheel mousewheel DOMMouseScroll",fe="transitionend",ve="load",ge="keydown",we="click",pe="resize",be="ready",ye="show",xe="shown",ze="hide",Ee="hidden",De="view",Ie="viewed",Le=/^(width|height|left|top|marginLeft|marginTop)$/,Ye=/([a-z\d])([A-Z])/g,ke=/^\s+(.*)\s+$/,Te=/\s+/,Fe="undefined"!=typeof H.createElement(U).style.transition,Xe=Math.min,Se=Math.max,Ve=Math.abs,Ne=Math.sqrt,Ce=Math.round,Pe=Object.prototype,Ae=Pe.toString,Re=Pe.hasOwnProperty,We=Array.prototype.slice;O.prototype={constructor:O,init:function(){var t=this,i=t.options,n=t.element,a="img"===n.tagName.toLowerCase(),o=a?[n]:V(n,"img"),r=o.length,s=v(t.ready,t);E(n,U)||(D(n,U,t),r&&(l(i.ready)&&L(n,be,i.ready,!0),Fe||(i.transition=!1),t.isImg=a,t.length=r,t.count=0,t.images=o,t.body=H.body,t.scrollbarWidth=e.innerWidth-H.body.clientWidth,i.inline?(L(n,be,function(){t.view()},!0),h(o,function(e){e.complete?s():L(e,ve,s,!0)})):L(n,we,t._start=v(t.start,t))))},ready:function(){var e=this;e.count++,e.count===e.length&&e.build()},build:function(){var e,t,i,n,a,o,r,s,l=this,u=l.options,c=l.element;l.isBuilt||(e=H.createElement("div"),e.innerHTML=O.TEMPLATE,l.parent=t=c.parentNode,l.viewer=i=N(e,"viewer-container")[0],l.canvas=N(i,"viewer-canvas")[0],l.footer=N(i,"viewer-footer")[0],l.title=r=N(i,"viewer-title")[0],l.toolbar=a=N(i,"viewer-toolbar")[0],l.navbar=o=N(i,"viewer-navbar")[0],l.button=n=N(i,"viewer-button")[0],l.tooltipBox=N(i,"viewer-tooltip")[0],l.player=N(i,"viewer-player")[0],l.list=N(i,"viewer-list")[0],b(r,u.title?B(u.title):G),b(a,u.toolbar?B(u.toolbar):G),b(o,u.navbar?B(u.navbar):G),x(n,G,!u.button),x(a.querySelector(".viewer-one-to-one"),oe,!u.zoomable),x(a.querySelectorAll('li[class*="zoom"]'),oe,!u.zoomable),x(a.querySelectorAll('li[class*="flip"]'),oe,!u.scalable),u.rotatable||(s=a.querySelectorAll('li[class*="rotate"]'),b(s,oe),C(a,s)),u.inline?(b(n,se),g(i,{zIndex:u.zIndexInline}),"static"===w(t).position&&g(t,{position:"relative"})):(b(n,ue),b(i,Z),b(i,te),b(i,G),g(i,{zIndex:u.zIndex})),t.insertBefore(i,c.nextSibling),u.inline&&(l.render(),l.bind(),l.isShown=!0),l.isBuilt=!0,k(c,be))},unbuild:function(){var e=this;e.isBuilt&&(e.isBuilt=!1,P(e.viewer))},bind:function(){var t=this,i=t.options,n=t.element,a=t.viewer;l(i.view)&&L(n,De,i.view),l(i.viewed)&&L(n,Ie,i.viewed),L(a,we,t._click=v(t.click,t)),L(a,he,t._wheel=v(t.wheel,t)),L(t.canvas,ce,t._mousedown=v(t.mousedown,t)),L(H,de,t._mousemove=v(t.mousemove,t)),L(H,me,t._mouseup=v(t.mouseup,t)),L(H,ge,t._keydown=v(t.keydown,t)),L(e,pe,t._resize=v(t.resize,t))},unbind:function(){var t=this,i=t.options,n=t.element,a=t.viewer;l(i.view)&&Y(n,De,i.view),l(i.viewed)&&Y(n,Ie,i.viewed),Y(a,we,t._click),Y(a,he,t._wheel),Y(t.canvas,ce,t._mousedown),Y(H,de,t._mousemove),Y(H,me,t._mouseup),Y(H,ge,t._keydown),Y(e,pe,t._resize)},render:function(){var e=this;e.initContainer(),e.initViewer(),e.initList(),e.renderViewer()},initContainer:function(){var t=this;t.containerData={width:e.innerWidth,height:e.innerHeight}},initViewer:function(){var e,t=this,i=t.options,n=t.parent;i.inline&&(t.parentData=e={width:Se(n.offsetWidth,i.minWidth),height:Se(n.offsetHeight,i.minHeight)}),!t.isFulled&&e||(e=t.containerData),t.viewerData=f({},e)},renderViewer:function(){var e=this;e.options.inline&&!e.isFulled&&g(e.viewer,e.viewerData)},initList:function(){var e=this,t=e.options,i=e.element,a=e.list,o=[];h(e.images,function(e,i){var a=e.src,r=e.alt||_(a),s=t.url;a&&(n(s)?s=e.getAttribute(s):l(s)&&(s=s.call(e,e)),o.push('<li><img src="'+a+'" data-action="view" data-index="'+i+'" data-original-url="'+(s||a)+'" alt="'+r+'"></li>'))}),a.innerHTML=o.join(""),h(V(a,"img"),function(t){D(t,"filled",!0),L(t,ve,v(e.loadImage,e),!0)}),e.items=V(a,"li"),t.transition&&L(i,Ie,function(){b(a,re)},!0)},renderList:function(e){var t=this,i=e||t.index,n=t.items[i].offsetWidth||30,a=n+1;g(t.list,{width:a*t.length,marginLeft:(t.viewerData.width-n)/2-a*i})},resetList:function(){var e=this;A(e.list),y(e.list,re),g({marginLeft:0})},initImage:function(e){var t=this,i=t.options,n=t.image,a=t.viewerData,o=t.footer.offsetHeight,r=a.width,s=Se(a.height-o,o),u=t.imageData||{};q(n,function(n,a){var o,c,d=n/a,m=r,h=s;s*d>r?h=r/d:m=s*d,m=Xe(.9*m,n),h=Xe(.9*h,a),c={naturalWidth:n,naturalHeight:a,aspectRatio:d,ratio:m/n,width:m,height:h,left:(r-m)/2,top:(s-h)/2},o=f({},c),i.rotatable&&(c.rotate=u.rotate||0,o.rotate=0),i.scalable&&(c.scaleX=u.scaleX||1,c.scaleY=u.scaleY||1,o.scaleX=1,o.scaleY=1),t.imageData=c,t.initialImageData=o,l(e)&&e()})},renderImage:function(e){var t=this,i=t.image,n=t.imageData,a=M(n);g(i,{width:n.width,height:n.height,marginLeft:n.left,marginTop:n.top,WebkitTransform:a,msTransform:a,transform:a}),l(e)&&(t.transitioning?L(i,fe,e,!0):e())},resetImage:function(){var e=this;e.image&&(P(e.image),e.image=null)},start:function(e){var t=this,i=F(e),n=i.target;"img"===n.tagName.toLowerCase()&&(t.target=n,t.show())},click:function(e){var t=this,i=F(e),n=i.target,a=E(n,"action"),o=t.imageData;switch(a){case"mix":t.isPlayed?t.stop():t.options.inline?t.isFulled?t.exit():t.full():t.hide();break;case"view":t.view(E(n,"index"));break;case"zoom-in":t.zoom(.1,!0);break;case"zoom-out":t.zoom(-.1,!0);break;case"one-to-one":t.toggle();break;case"reset":t.reset();break;case"prev":t.prev();break;case"play":t.play();break;case"next":t.next();break;case"rotate-left":t.rotate(-90);break;case"rotate-right":t.rotate(90);break;case"flip-horizontal":t.scaleX(-o.scaleX||-1);break;case"flip-vertical":t.scaleY(-o.scaleY||-1);break;default:t.isPlayed&&t.stop()}},load:function(){var e=this,t=e.options,i=e.image,n=e.index,a=e.viewerData;e.timeout&&(clearTimeout(e.timeout),e.timeout=!1),y(i,oe),i.style.cssText="width:0;height:0;margin-left:"+a.width/2+"px;margin-top:"+a.height/2+"px;max-width:none!important;visibility:visible;",e.initImage(function(){x(i,re,t.transition),x(i,ne,t.movable),e.renderImage(function(){e.isViewed=!0,k(e.element,Ie,{originalImage:e.images[n],index:n,image:i})})})},loadImage:function(e){var t=F(e),i=t.target,n=i.parentNode,a=n.offsetWidth||30,o=n.offsetHeight||50,r=!!E(i,"filled");q(i,function(e,t){var n=e/t,s=a,l=o;o*n>a?r?s=o*n:l=a/n:r?l=a/n:s=o*n,g(i,{width:s,height:l,marginLeft:(a-s)/2,marginTop:(o-l)/2})})},resize:function(){var e=this;e.initContainer(),e.initViewer(),e.renderViewer(),e.renderList(),e.isViewed&&e.initImage(function(){e.renderImage()}),e.isPlayed&&h(V(e.player,"img"),function(t){L(t,ve,v(e.loadImage,e),!0),k(t,ve)})},wheel:function(e){var t=this,i=F(e),n=Number(t.options.zoomRatio)||.1,a=1;t.isViewed&&(T(i),t.wheeling||(t.wheeling=!0,setTimeout(function(){t.wheeling=!1},50),i.deltaY?a=i.deltaY>0?1:-1:i.wheelDelta?a=-i.wheelDelta/120:i.detail&&(a=i.detail>0?1:-1),t.zoom(-a*n,!0,i)))},keydown:function(e){var t=this,i=F(e),n=t.options,a=i.keyCode||i.which||i.charCode;if(t.isFulled&&n.keyboard)switch(a){case 27:t.isPlayed?t.stop():n.inline?t.isFulled&&t.exit():t.hide();break;case 32:t.isPlayed&&t.stop();break;case 37:t.prev();break;case 38:T(i),t.zoom(n.zoomRatio,!0);break;case 39:t.next();break;case 40:T(i),t.zoom(-n.zoomRatio,!0);break;case 48:case 49:(i.ctrlKey||i.shiftKey)&&(T(i),t.toggle())}},mousedown:function(e){var t,i,n=this,a=n.options,o=F(e),r=!!a.movable&&"move",s=o.touches;if(n.isViewed){if(s){if(t=s.length,t>1){if(!a.zoomable||2!==t)return;i=s[1],n.startX2=i.pageX,n.startY2=i.pageY,r="zoom"}else n.isSwitchable()&&(r="switch");i=s[0]}r&&(T(o),n.action=r,n.startX=i?i.pageX:o.pageX,n.startY=i?i.pageY:o.pageY)}},mousemove:function(e){var t,i,n=this,a=n.options,o=F(e),r=n.action,s=n.image,l=o.touches;if(n.isViewed){if(l){if(t=l.length,t>1){if(!a.zoomable||2!==t)return;i=l[1],n.endX2=i.pageX,n.endY2=i.pageY}i=l[0]}r&&(T(o),"move"===r&&a.transition&&p(s,re)&&y(s,re),n.endX=i?i.pageX:o.pageX,n.endY=i?i.pageY:o.pageY,n.change(o))}},mouseup:function(e){var t=this,i=F(e),n=t.action;n&&(T(i),"move"===n&&t.options.transition&&b(t.image,re),t.action=!1)},show:function(){var e,t=this,i=t.options,n=t.element;return i.inline||t.transitioning?t:(t.isBuilt||t.build(),e=t.viewer,l(i.show)&&L(n,ye,i.show,!0),k(n,ye)===!1?t:(t.open(),y(e,G),L(n,xe,function(){t.view(t.target?d(t.target,c(t.images)):t.index),t.target=!1},!0),i.transition?(t.transitioning=!0,b(e,re),W(e),L(e,fe,v(t.shown,t),!0),b(e,ie)):(b(e,ie),t.shown()),t))},hide:function(){var e=this,t=e.options,i=e.element,n=e.viewer;return t.inline||e.transitioning||!e.isShown?e:(l(t.hide)&&L(i,ze,t.hide,!0),k(i,ze)===!1?e:(e.isViewed&&t.transition?(e.transitioning=!0,L(e.image,fe,function(){L(n,fe,v(e.hidden,e),!0),y(n,ie)},!0),e.zoomTo(0,!1,!1,!0)):(y(n,ie),e.hidden()),e))},view:function(e){var t,i,n,a,o,r=this,s=r.element,l=r.title,u=r.canvas;return e=Number(e)||0,!r.isShown||r.isPlayed||e<0||e>=r.length||r.isViewed&&e===r.index?r:(i=r.items[e],n=V(i,"img")[0],a=E(n,"originalUrl"),o=n.getAttribute("alt"),t=H.createElement("img"),t.src=a,t.alt=o,k(s,De,{originalImage:r.images[e],index:e,image:t})===!1?r:(r.image=t,r.isViewed&&y(r.items[r.index],ae),b(i,ae),r.isViewed=!1,r.index=e,r.imageData=null,b(t,oe),A(u),C(u,t),r.renderList(),A(l),L(s,Ie,function(){var e=r.imageData,t=e.naturalWidth,i=e.naturalHeight;R(l,o+" ("+t+" × "+i+")")},!0),t.complete?r.load():(L(t,ve,v(r.load,r),!0),r.timeout&&clearTimeout(r.timeout),r.timeout=setTimeout(function(){y(t,oe),r.timeout=!1},1e3)),r))},prev:function(){var e=this;return e.view(Se(e.index-1,0)),e},next:function(){var e=this;return e.view(Xe(e.index+1,e.length-1)),e},move:function(e,t){var i=this,n=i.imageData;return i.moveTo(o(e)?e:n.left+Number(e),o(t)?t:n.top+Number(t)),i},moveTo:function(e,t){var i=this,n=i.imageData,r=!1;return o(t)&&(t=e),e=Number(e),t=Number(t),i.isViewed&&!i.isPlayed&&i.options.movable&&(a(e)&&(n.left=e,r=!0),a(t)&&(n.top=t,r=!0),r&&i.renderImage()),i},zoom:function(e,t,i){var n=this,a=n.imageData;return e=Number(e),e=e<0?1/(1-e):1+e,n.zoomTo(a.width*e/a.naturalWidth,t,i),n},zoomTo:function(e,t,i,n){var o,r,s,l,u=this,c=u.options,d=.01,m=100,h=u.imageData;return e=Se(0,e),a(e)&&u.isViewed&&!u.isPlayed&&(n||c.zoomable)&&(n||(d=Se(d,c.minZoomRatio),m=Xe(m,c.maxZoomRatio),e=Xe(Se(e,d),m)),e>.95&&e<1.05&&(e=1),o=h.naturalWidth*e,r=h.naturalHeight*e,i?(s=X(u.viewer),l=i.touches?S(i.touches):{pageX:i.pageX,pageY:i.pageY},h.left-=(o-h.width)*((l.pageX-s.left-h.left)/h.width),h.top-=(r-h.height)*((l.pageY-s.top-h.top)/h.height)):(h.left-=(o-h.width)/2,h.top-=(r-h.height)/2),h.width=o,h.height=r,h.ratio=e,u.renderImage(),t&&u.tooltip()),u},rotate:function(e){var t=this;return t.rotateTo((t.imageData.rotate||0)+Number(e)),t},rotateTo:function(e){var t=this,i=t.imageData;return e=Number(e),a(e)&&t.isViewed&&!t.isPlayed&&t.options.rotatable&&(i.rotate=e,t.renderImage()),t},scale:function(e,t){var i=this,n=i.imageData,r=!1;return o(t)&&(t=e),e=Number(e),t=Number(t),i.isViewed&&!i.isPlayed&&i.options.scalable&&(a(e)&&(n.scaleX=e,r=!0),a(t)&&(n.scaleY=t,r=!0),r&&i.renderImage()),i},scaleX:function(e){var t=this;return t.scale(e,t.imageData.scaleY),t},scaleY:function(e){var t=this;return t.scale(t.imageData.scaleX,e),t},play:function(){var e,t=this,i=t.options,n=t.player,o=v(t.loadImage,t),r=[],s=0,l=0;return!t.isShown||t.isPlayed?t:(i.fullscreen&&t.requestFullscreen(),t.isPlayed=!0,b(n,K),h(t.items,function(e,t){var a=V(e,"img")[0],u=H.createElement("img");u.src=E(a,"originalUrl"),u.alt=a.getAttribute("alt"),s++,b(u,te),x(u,re,i.transition),p(e,ae)&&(b(u,ie),l=t),r.push(u),L(u,ve,o,!0),C(n,u)}),a(i.interval)&&i.interval>0&&(e=function(){t.playing=setTimeout(function(){y(r[l],ie),l++,l=l<s?l:0,b(r[l],ie),e()},i.interval)},s>1&&e()),t)},stop:function(){var e=this,t=e.player;return e.isPlayed?(e.options.fullscreen&&e.exitFullscreen(),e.isPlayed=!1,clearTimeout(e.playing),y(t,K),A(t),e):e},full:function(){var e=this,t=e.options,i=e.viewer,n=e.image,a=e.list;return!e.isShown||e.isPlayed||e.isFulled||!t.inline?e:(e.isFulled=!0,e.open(),b(e.button,le),t.transition&&(y(n,re),y(a,re)),b(i,Z),i.setAttribute("style",""),g(i,{zIndex:t.zIndex}),e.initContainer(),e.viewerData=f({},e.containerData),e.renderList(),e.initImage(function(){e.renderImage(function(){t.transition&&setTimeout(function(){b(n,re),b(a,re)},0)})}),e)},exit:function(){var e=this,t=e.options,i=e.viewer,n=e.image,a=e.list;return e.isFulled?(e.isFulled=!1,e.close(),y(e.button,le),t.transition&&(y(n,re),y(a,re)),y(i,Z),g(i,{zIndex:t.zIndexInline}),e.viewerData=f({},e.parentData),e.renderViewer(),e.renderList(),e.initImage(function(){e.renderImage(function(){t.transition&&setTimeout(function(){b(n,re),b(a,re)},0)})}),e):e},tooltip:function(){var e=this,t=e.options,i=e.tooltipBox,n=e.imageData;return e.isViewed&&!e.isPlayed&&t.tooltip?(R(i,Ce(100*n.ratio)+"%"),e.tooltiping?clearTimeout(e.tooltiping):t.transition?(e.fading&&k(i,fe),b(i,K),b(i,te),b(i,re),W(i),b(i,ie)):b(i,K),e.tooltiping=setTimeout(function(){t.transition?(L(i,fe,function(){y(i,K),y(i,te),y(i,re),e.fading=!1},!0),y(i,ie),e.fading=!0):y(i,K),e.tooltiping=!1},1e3),e):e},toggle:function(){var e=this;return 1===e.imageData.ratio?e.zoomTo(e.initialImageData.ratio,!0):e.zoomTo(1,!0),e},reset:function(){var e=this;return e.isViewed&&!e.isPlayed&&(e.imageData=f({},e.initialImageData),e.renderImage()),e},update:function(){var e,t=this,i=[];return t.isImg&&!t.element.parentNode?t.destroy():(t.length=t.images.length,t.isBuilt&&(h(t.items,function(e,n){var a=V(e,"img")[0],o=t.images[n];o?o.src!==a.src&&i.push(n):i.push(n)}),g(t.list,{width:"auto"}),t.initList(),t.isShown&&(t.length?t.isViewed&&(e=d(t.index,i),e>=0?(t.isViewed=!1,t.view(Se(t.index-(e+1),0))):b(t.items[t.index],ae)):(t.image=null,t.isViewed=!1,t.index=0,t.imageData=null,A(t.canvas),A(t.title)))),t)},destroy:function(){var e=this,t=e.element;return e.options.inline?e.unbind():(e.isShown&&e.unbind(),Y(t,we,e._start)),e.unbuild(),I(t,U),e},open:function(){var e=this.body;b(e,$),e.style.paddingRight=this.scrollbarWidth+"px"},close:function(){var e=this.body;y(e,$),e.style.paddingRight=0},shown:function(){var e=this,t=e.options,i=e.element;e.transitioning=!1,e.isFulled=!0,e.isShown=!0,e.isVisible=!0,e.render(),e.bind(),l(t.shown)&&L(i,xe,t.shown,!0),k(i,xe)},hidden:function(){var e=this,t=e.options,i=e.element;e.transitioning=!1,e.isViewed=!1,e.isFulled=!1,e.isShown=!1,e.isVisible=!1,e.unbind(),e.close(),b(e.viewer,G),e.resetList(),e.resetImage(),l(t.hidden)&&L(i,Ee,t.hidden,!0),k(i,Ee)},requestFullscreen:function(){var e=this,t=H.documentElement;!e.isFulled||H.fullscreenElement||H.mozFullScreenElement||H.webkitFullscreenElement||H.msFullscreenElement||(t.requestFullscreen?t.requestFullscreen():t.msRequestFullscreen?t.msRequestFullscreen():t.mozRequestFullScreen?t.mozRequestFullScreen():t.webkitRequestFullscreen&&t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT))},exitFullscreen:function(){var e=this;e.isFulled&&(H.exitFullscreen?H.exitFullscreen():H.msExitFullscreen?H.msExitFullscreen():H.mozCancelFullScreen?H.mozCancelFullScreen():H.webkitExitFullscreen&&H.webkitExitFullscreen())},change:function(e){var t=this,i=t.endX-t.startX,n=t.endY-t.startY;switch(t.action){case"move":t.move(i,n);break;case"zoom":t.zoom(function(e,t,i,n){var a=Ne(e*e+t*t),o=Ne(i*i+n*n);return(o-a)/a}(Ve(t.startX-t.startX2),Ve(t.startY-t.startY2),Ve(t.endX-t.endX2),Ve(t.endY-t.endY2)),!1,e),t.startX2=t.endX2,t.startY2=t.endY2;break;case"switch":t.action="switched",Ve(i)>Ve(n)&&(i>1?t.prev():i<-1&&t.next())}t.startX=t.endX,t.startY=t.endY},isSwitchable:function(){var e=this,t=e.imageData,i=e.viewerData;return t.left>=0&&t.top>=0&&t.width<=i.width&&t.height<=i.height}},O.DEFAULTS={inline:!1,button:!0,navbar:!0,title:!0,toolbar:!0,tooltip:!0,movable:!0,zoomable:!0,rotatable:!0,scalable:!0,transition:!0,fullscreen:!0,keyboard:!0,interval:5e3,minWidth:200,minHeight:100,zoomRatio:.1,minZoomRatio:.01,maxZoomRatio:100,zIndex:2015,zIndexInline:0,url:"src",build:null,built:null,show:null,shown:null,hide:null,hidden:null,view:null,viewed:null},O.TEMPLATE='<div class="viewer-container"><div class="viewer-canvas"></div><div class="viewer-footer"><div class="viewer-title"></div><ul class="viewer-toolbar"><li class="viewer-zoom-in" data-action="zoom-in"></li><li class="viewer-zoom-out" data-action="zoom-out"></li><li class="viewer-one-to-one" data-action="one-to-one"></li><li class="viewer-reset" data-action="reset"></li><li class="viewer-prev" data-action="prev"></li><li class="viewer-play" data-action="play"></li><li class="viewer-next" data-action="next"></li><li class="viewer-rotate-left" data-action="rotate-left"></li><li class="viewer-rotate-right" data-action="rotate-right"></li><li class="viewer-flip-horizontal" data-action="flip-horizontal"></li><li class="viewer-flip-vertical" data-action="flip-vertical"></li></ul><div class="viewer-navbar"><ul class="viewer-list"></ul></div></div><div class="viewer-tooltip"></div><div class="viewer-button" data-action="mix"></div><div class="viewer-player"></div></div>';var _e=e.Viewer;return O.noConflict=function(){return e.Viewer=_e,O},O.setDefaults=function(e){f(O.DEFAULTS,e)},"function"==typeof define&&define.amd&&define("viewer",[],function(){return O}),t||(e.Viewer=O),O});
+
 
 +
(function (global, factory) {
 +
  if (typeof module === 'object' && typeof module.exports === 'object') {
 +
    module.exports = global.document ? factory(global, true) : function (window) {
 +
      if (!window.document) {
 +
        throw new Error('Viewer requires a window with a document');
 +
      }
 +
 
 +
      return factory(window);
 +
    };
 +
  } else {
 +
    factory(global);
 +
  }
 +
})(typeof window !== 'undefined' ? window : this, function (window, noGlobal) {
 +
 
 +
  'use strict';
 +
 
 +
  var document = window.document;
 +
  var Event = window.Event;
 +
 
 +
  // Constants
 +
  var NAMESPACE = 'viewer';
 +
 
 +
  // Classes
 +
  var CLASS_FIXED = NAMESPACE + '-fixed';
 +
  var CLASS_OPEN = NAMESPACE + '-open';
 +
  var CLASS_SHOW = NAMESPACE + '-show';
 +
  var CLASS_HIDE = NAMESPACE + '-hide';
 +
  var CLASS_HIDE_XS_DOWN = 'viewer-hide-xs-down';
 +
  var CLASS_HIDE_SM_DOWN = 'viewer-hide-sm-down';
 +
  var CLASS_HIDE_MD_DOWN = 'viewer-hide-md-down';
 +
  var CLASS_FADE = NAMESPACE + '-fade';
 +
  var CLASS_IN = NAMESPACE + '-in';
 +
  var CLASS_MOVE = NAMESPACE + '-move';
 +
  var CLASS_ACTIVE = NAMESPACE + '-active';
 +
  var CLASS_INVISIBLE = NAMESPACE + '-invisible';
 +
  var CLASS_TRANSITION = NAMESPACE + '-transition';
 +
  var CLASS_FULLSCREEN = NAMESPACE + '-fullscreen';
 +
  var CLASS_FULLSCREEN_EXIT = NAMESPACE + '-fullscreen-exit';
 +
  var CLASS_CLOSE = NAMESPACE + '-close';
 +
 
 +
  // Events
 +
  var EVENT_MOUSEDOWN = 'mousedown touchstart pointerdown MSPointerDown';
 +
  var EVENT_MOUSEMOVE = 'mousemove touchmove pointermove MSPointerMove';
 +
  var EVENT_MOUSEUP = 'mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel';
 +
  var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';
 +
  var EVENT_TRANSITIONEND = 'transitionend';
 +
  var EVENT_LOAD = 'load';
 +
  var EVENT_KEYDOWN = 'keydown';
 +
  var EVENT_CLICK = 'click';
 +
  var EVENT_RESIZE = 'resize';
 +
  var EVENT_READY = 'ready';
 +
  var EVENT_SHOW = 'show';
 +
  var EVENT_SHOWN = 'shown';
 +
  var EVENT_HIDE = 'hide';
 +
  var EVENT_HIDDEN = 'hidden';
 +
  var EVENT_VIEW = 'view';
 +
  var EVENT_VIEWED = 'viewed';
 +
 
 +
  // RegExps
 +
  var REGEXP_SUFFIX = /^(width|height|left|top|marginLeft|marginTop)$/;
 +
  var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g;
 +
  var REGEXP_TRIM = /^\s+(.*)\s+$/;
 +
  var REGEXP_SPACES = /\s+/;
 +
 
 +
  // Supports
 +
  var SUPPORT_TRANSITION = typeof document.createElement(NAMESPACE).style.transition !== 'undefined';
 +
 
 +
  // Maths
 +
  var min = Math.min;
 +
  var max = Math.max;
 +
  var abs = Math.abs;
 +
  var sqrt = Math.sqrt;
 +
  var round = Math.round;
 +
 
 +
  // Utilities
 +
  var objectProto = Object.prototype;
 +
  var toString = objectProto.toString;
 +
  var hasOwnProperty = objectProto.hasOwnProperty;
 +
  var slice = Array.prototype.slice;
 +
 
 +
  function typeOf(obj) {
 +
    return toString.call(obj).slice(8, -1).toLowerCase();
 +
  }
 +
 
 +
  function isString(str) {
 +
    return typeof str === 'string';
 +
  }
 +
 
 +
  function isNumber(num) {
 +
    return typeof num === 'number' && !isNaN(num);
 +
  }
 +
 
 +
  function isUndefined(obj) {
 +
    return typeof obj === 'undefined';
 +
  }
 +
 
 +
  function isObject(obj) {
 +
    return typeof obj === 'object' && obj !== null;
 +
  }
 +
 
 +
  function isPlainObject(obj) {
 +
    var constructor;
 +
    var prototype;
 +
 
 +
    if (!isObject(obj)) {
 +
      return false;
 +
    }
 +
 
 +
    try {
 +
      constructor = obj.constructor;
 +
      prototype = constructor.prototype;
 +
 
 +
      return constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
 +
    } catch (e) {
 +
      return false;
 +
    }
 +
  }
 +
 
 +
  function isFunction(fn) {
 +
    return typeOf(fn) === 'function';
 +
  }
 +
 
 +
  function isArray(arr) {
 +
    return Array.isArray ? Array.isArray(arr) : typeOf(arr) === 'array';
 +
  }
 +
 
 +
  function toArray(obj, offset) {
 +
    offset = offset >= 0 ? offset : 0;
 +
 
 +
    if (Array.from) {
 +
      return Array.from(obj).slice(offset);
 +
    }
 +
 
 +
    return slice.call(obj, offset);
 +
  }
 +
 
 +
  function inArray(value, arr) {
 +
    var index = -1;
 +
 
 +
    if (arr.indexOf) {
 +
      return arr.indexOf(value);
 +
    } else {
 +
      each(arr, function (n, i) {
 +
        if (n === value) {
 +
          index = i;
 +
          return false;
 +
        }
 +
      });
 +
    }
 +
 
 +
    return index;
 +
  }
 +
 
 +
  function trim(str) {
 +
    if (isString(str)) {
 +
      str = str.trim ? str.trim() : str.replace(REGEXP_TRIM, '1');
 +
    }
 +
 
 +
    return str;
 +
  }
 +
 
 +
  function each(obj, callback) {
 +
    var length;
 +
    var i;
 +
 
 +
    if (obj && isFunction(callback)) {
 +
      if (isArray(obj) || isNumber(obj.length)/* array-like */) {
 +
        for (i = 0, length = obj.length; i < length; i++) {
 +
          if (callback.call(obj, obj[i], i, obj) === false) {
 +
            break;
 +
          }
 +
        }
 +
      } else if (isObject(obj)) {
 +
        for (i in obj) {
 +
          if (obj.hasOwnProperty(i)) {
 +
            if (callback.call(obj, obj[i], i, obj) === false) {
 +
              break;
 +
            }
 +
          }
 +
        }
 +
      }
 +
    }
 +
 
 +
    return obj;
 +
  }
 +
 
 +
  function extend(obj) {
 +
    var args;
 +
 
 +
    if (arguments.length > 1) {
 +
      args = toArray(arguments);
 +
 
 +
      if (Object.assign) {
 +
        return Object.assign.apply(Object, args);
 +
      }
 +
 
 +
      args.shift();
 +
 
 +
      each(args, function (arg) {
 +
        each(arg, function (prop, i) {
 +
          obj[i] = prop;
 +
        });
 +
      });
 +
    }
 +
 
 +
    return obj;
 +
  }
 +
 
 +
  function proxy(fn, context) {
 +
    var args = toArray(arguments, 2);
 +
 
 +
    return function () {
 +
      return fn.apply(context, args.concat(toArray(arguments)));
 +
    };
 +
  }
 +
 
 +
  function setStyle(element, styles) {
 +
    var style = element.style;
 +
 
 +
    each(styles, function (value, property) {
 +
      if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
 +
        value += 'px';
 +
      }
 +
 
 +
      style[property] = value;
 +
    });
 +
  }
 +
 
 +
  function getStyle(element) {
 +
    return window.getComputedStyle ?
 +
      window.getComputedStyle(element, null) :
 +
      element.currentStyle;
 +
  }
 +
 
 +
  function hasClass(element, value) {
 +
    return element.classList ?
 +
      element.classList.contains(value) :
 +
      element.className.indexOf(value) > -1;
 +
  }
 +
 
 +
  function addClass(element, value) {
 +
    var className;
 +
 
 +
    if (!value) {
 +
      return;
 +
    }
 +
 
 +
    if (isNumber(element.length)) {
 +
      return each(element, function (elem) {
 +
        addClass(elem, value);
 +
      });
 +
    }
 +
 
 +
    if (element.classList) {
 +
      return element.classList.add(value);
 +
    }
 +
 
 +
    className = trim(element.className);
 +
 
 +
    if (!className) {
 +
      element.className = value;
 +
    } else if (className.indexOf(value) < 0) {
 +
      element.className = className + ' ' + value;
 +
    }
 +
  }
 +
 
 +
  function removeClass(element, value) {
 +
    if (!value) {
 +
      return;
 +
    }
 +
 
 +
    if (isNumber(element.length)) {
 +
      return each(element, function (elem) {
 +
        removeClass(elem, value);
 +
      });
 +
    }
 +
 
 +
    if (element.classList) {
 +
      return element.classList.remove(value);
 +
    }
 +
 
 +
    if (element.className.indexOf(value) >= 0) {
 +
      element.className = element.className.replace(value, '');
 +
    }
 +
  }
 +
 
 +
  function toggleClass(element, value, added) {
 +
    if (isNumber(element.length)) {
 +
      return each(element, function (elem) {
 +
        toggleClass(elem, value, added);
 +
      });
 +
    }
 +
 
 +
    // IE10-11 doesn't support the second parameter of `classList.toggle`
 +
    if (added) {
 +
      addClass(element, value);
 +
    } else {
 +
      removeClass(element, value);
 +
    }
 +
  }
 +
 
 +
  function hyphenate(str) {
 +
    return str.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();
 +
  }
 +
 
 +
  function getData(element, name) {
 +
    if (isObject(element[name])) {
 +
      return element[name];
 +
    } else if (element.dataset) {
 +
      return element.dataset[name];
 +
    }
 +
 
 +
    return element.getAttribute('data-' + hyphenate(name));
 +
  }
 +
 
 +
  function setData(element, name, data) {
 +
    if (isObject(data)) {
 +
      element[name] = data;
 +
    } else if (element.dataset) {
 +
      element.dataset[name] = data;
 +
    } else {
 +
      element.setAttribute('data-' + hyphenate(name), data);
 +
    }
 +
  }
 +
 
 +
  function removeData(element, name) {
 +
    if (isObject(element[name])) {
 +
      delete element[name];
 +
    } else if (element.dataset) {
 +
      delete element.dataset[name];
 +
    } else {
 +
      element.removeAttribute('data-' + hyphenate(name));
 +
    }
 +
  }
 +
 
 +
  function addListener(element, type, handler, once) {
 +
    var types = trim(type).split(REGEXP_SPACES);
 +
    var originalHandler = handler;
 +
 
 +
    if (types.length > 1) {
 +
      return each(types, function (type) {
 +
        addListener(element, type, handler);
 +
      });
 +
    }
 +
 
 +
    if (once) {
 +
      handler = function () {
 +
        removeListener(element, type, handler);
 +
 
 +
        return originalHandler.apply(element, arguments);
 +
      };
 +
    }
 +
 
 +
    if (element.addEventListener) {
 +
      element.addEventListener(type, handler, false);
 +
    } else if (element.attachEvent) {
 +
      element.attachEvent('on' + type, handler);
 +
    }
 +
  }
 +
 
 +
  function removeListener(element, type, handler) {
 +
    var types = trim(type).split(REGEXP_SPACES);
 +
 
 +
    if (types.length > 1) {
 +
      return each(types, function (type) {
 +
        removeListener(element, type, handler);
 +
      });
 +
    }
 +
 
 +
    if (element.removeEventListener) {
 +
      element.removeEventListener(type, handler, false);
 +
    } else if (element.detachEvent) {
 +
      element.detachEvent('on' + type, handler);
 +
    }
 +
  }
 +
 
 +
  function dispatchEvent(element, type, data) {
 +
    var event;
 +
 
 +
    if (element.dispatchEvent) {
 +
 
 +
      // Event and CustomEvent on IE9-11 are global objects, not constructors
 +
      if (isFunction(Event) && isFunction(CustomEvent)) {
 +
        if (isUndefined(data)) {
 +
          event = new Event(type, {
 +
            bubbles: true,
 +
            cancelable: true
 +
          });
 +
        } else {
 +
          event = new CustomEvent(type, {
 +
            detail: data,
 +
            bubbles: true,
 +
            cancelable: true
 +
          });
 +
        }
 +
      } else {
 +
        // IE9-11
 +
        if (isUndefined(data)) {
 +
          event = document.createEvent('Event');
 +
          event.initEvent(type, true, true);
 +
        } else {
 +
          event = document.createEvent('CustomEvent');
 +
          event.initCustomEvent(type, true, true, data);
 +
        }
 +
      }
 +
 
 +
      // IE9+
 +
      return element.dispatchEvent(event);
 +
    } else if (element.fireEvent) {
 +
 
 +
      // IE6-10 (native events only)
 +
      return element.fireEvent('on' + type);
 +
    }
 +
  }
 +
 
 +
  function preventDefault(e) {
 +
    if (e.preventDefault) {
 +
      e.preventDefault();
 +
    } else {
 +
      e.returnValue = false;
 +
    }
 +
  }
 +
 
 +
  function getEvent(event) {
 +
    var e = event || window.event;
 +
    var doc;
 +
 
 +
    // Fix target property (IE8)
 +
    if (!e.target) {
 +
      e.target = e.srcElement || document;
 +
    }
 +
 
 +
    if (!isNumber(e.pageX)) {
 +
      doc = document.documentElement;
 +
      e.pageX = e.clientX + (window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0);
 +
      e.pageY = e.clientY + (window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0);
 +
    }
 +
 
 +
    return e;
 +
  }
 +
 
 +
  function getOffset(element) {
 +
    var doc = document.documentElement;
 +
    var box = element.getBoundingClientRect();
 +
 
 +
    return {
 +
      left: box.left + (window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0),
 +
      top: box.top + (window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0)
 +
    };
 +
  }
 +
 
 +
  function getTouchesCenter(touches) {
 +
    var length = touches.length;
 +
    var pageX = 0;
 +
    var pageY = 0;
 +
 
 +
    if (length) {
 +
      each(touches, function (touch) {
 +
        pageX += touch.pageX;
 +
        pageY += touch.pageY;
 +
      });
 +
 
 +
      pageX /= length;
 +
      pageY /= length;
 +
    }
 +
 
 +
    return {
 +
      pageX: pageX,
 +
      pageY: pageY
 +
    };
 +
  }
 +
 
 +
  function getByTag(element, tagName) {
 +
    return element.getElementsByTagName(tagName);
 +
  }
 +
 
 +
  function getByClass(element, className) {
 +
    return element.getElementsByClassName ?
 +
      element.getElementsByClassName(className) :
 +
      element.querySelectorAll('.' + className);
 +
  }
 +
 
 +
  function appendChild(element, elem) {
 +
    if (elem.length) {
 +
      return each(elem, function (el) {
 +
        appendChild(element, el);
 +
      });
 +
    }
 +
 
 +
    element.appendChild(elem);
 +
  }
 +
 
 +
  function removeChild(element) {
 +
    if (element.parentNode) {
 +
      element.parentNode.removeChild(element);
 +
    }
 +
  }
 +
 
 +
  function empty(element) {
 +
    while (element.firstChild) {
 +
      element.removeChild(element.firstChild);
 +
    }
 +
  }
 +
 
 +
  function setText(element, text) {
 +
    if (!isUndefined(element.textContent)) {
 +
      element.textContent = text;
 +
    } else {
 +
      element.innerText = text;
 +
    }
 +
  }
 +
 
 +
  // Force reflow to enable CSS3 transition
 +
  function forceReflow(element) {
 +
    return element.offsetWidth;
 +
  }
 +
 
 +
  // e.g.: http://domain.com/path/to/picture.jpg?size=1280×960 -> picture.jpg
 +
  function getImageName(url) {
 +
    return isString(url) ? url.replace(/^.*\//, '').replace(/[\?&#].*$/, '') : '';
 +
  }
 +
 
 +
  function getImageSize(image, callback) {
 +
    var newImage;
 +
 
 +
    // Modern browsers
 +
    if (image.naturalWidth) {
 +
      return callback(image.naturalWidth, image.naturalHeight);
 +
    }
 +
 
 +
    // IE8: Don't use `new Image()` here
 +
    newImage = document.createElement('img');
 +
 
 +
    newImage.onload = function () {
 +
      callback(this.width, this.height);
 +
    };
 +
 
 +
    newImage.src = image.src;
 +
  }
 +
 
 +
  function getTransform(data) {
 +
    var transforms = [];
 +
    var rotate = data.rotate;
 +
    var scaleX = data.scaleX;
 +
    var scaleY = data.scaleY;
 +
 
 +
    // Rotate should come first before scale
 +
    if (isNumber(rotate)) {
 +
      transforms.push('rotate(' + rotate + 'deg)');
 +
    }
 +
 
 +
    if (isNumber(scaleX)) {
 +
      transforms.push('scaleX(' + scaleX + ')');
 +
    }
 +
 
 +
    if (isNumber(scaleY)) {
 +
      transforms.push('scaleY(' + scaleY + ')');
 +
    }
 +
 
 +
    return transforms.length ? transforms.join(' ') : 'none';
 +
  }
 +
 
 +
  function getResponsiveClass(option) {
 +
    switch (option) {
 +
      case 2:
 +
        return CLASS_HIDE_XS_DOWN;
 +
 
 +
      case 3:
 +
        return CLASS_HIDE_SM_DOWN;
 +
 
 +
      case 4:
 +
        return CLASS_HIDE_MD_DOWN;
 +
    }
 +
  }
 +
 
 +
  function Viewer(element, options) {
 +
    var _this = this;
 +
 
 +
    _this.element = element;
 +
    _this.options = extend({}, Viewer.DEFAULTS, isPlainObject(options) && options);
 +
    _this.isImg = false;
 +
    _this.isBuilt = false;
 +
    _this.isShown = false;
 +
    _this.isViewed = false;
 +
    _this.isFulled = false;
 +
    _this.isPlayed = false;
 +
    _this.wheeling = false;
 +
    _this.playing = false;
 +
    _this.fading = false;
 +
    _this.tooltiping = false;
 +
    _this.transitioning = false;
 +
    _this.action = false;
 +
    _this.target = false;
 +
    _this.timeout = false;
 +
    _this.index = 0;
 +
    _this.length = 0;
 +
    _this.init();
 +
  }
 +
 
 +
  Viewer.prototype = {
 +
    constructor: Viewer,
 +
 
 +
    init: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
      var isImg = element.tagName.toLowerCase() === 'img';
 +
      var images = isImg ? [element] : getByTag(element, 'img');
 +
      var length = images.length;
 +
      var ready = proxy(_this.ready, _this);
 +
 
 +
      if (getData(element, NAMESPACE)) {
 +
        return;
 +
      }
 +
 
 +
      setData(element, NAMESPACE, _this);
 +
 
 +
      if (!length) {
 +
        return;
 +
      }
 +
 
 +
      if (isFunction(options.ready)) {
 +
        addListener(element, EVENT_READY, options.ready, true);
 +
      }
 +
 
 +
      // Override `transition` option if it is not supported
 +
      if (!SUPPORT_TRANSITION) {
 +
        options.transition = false;
 +
      }
 +
 
 +
      _this.isImg = isImg;
 +
      _this.length = length;
 +
      _this.count = 0;
 +
      _this.images = images;
 +
      _this.body = document.body;
 +
      _this.scrollbarWidth = window.innerWidth - document.body.clientWidth;
 +
 
 +
      if (options.inline) {
 +
        addListener(element, EVENT_READY, function () {
 +
          _this.view();
 +
        }, true);
 +
 
 +
        each(images, function (image) {
 +
          if (image.complete) {
 +
            ready();
 +
          } else {
 +
            addListener(image, EVENT_LOAD, ready, true);
 +
          }
 +
        });
 +
      } else {
 +
        addListener(element, EVENT_CLICK, (_this._start = proxy(_this.start, _this)));
 +
      }
 +
    },
 +
 
 +
    ready: function () {
 +
      var _this = this;
 +
 
 +
      _this.count++;
 +
 
 +
      if (_this.count === _this.length) {
 +
        _this.build();
 +
      }
 +
    },
 +
 
 +
    build: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
      var template;
 +
      var parent;
 +
      var viewer;
 +
      var button;
 +
      var toolbar;
 +
      var navbar;
 +
      var title;
 +
      var rotate;
 +
 
 +
      if (_this.isBuilt) {
 +
        return;
 +
      }
 +
 
 +
      template = document.createElement('div');
 +
      template.innerHTML = Viewer.TEMPLATE;
 +
 
 +
      _this.parent = parent = element.parentNode;
 +
      _this.viewer = viewer = getByClass(template, 'viewer-container')[0];
 +
      _this.canvas = getByClass(viewer, 'viewer-canvas')[0];
 +
      _this.footer = getByClass(viewer, 'viewer-footer')[0];
 +
      _this.title = title = getByClass(viewer, 'viewer-title')[0];
 +
      _this.toolbar = toolbar = getByClass(viewer, 'viewer-toolbar')[0];
 +
      _this.navbar = navbar = getByClass(viewer, 'viewer-navbar')[0];
 +
      _this.button = button = getByClass(viewer, 'viewer-button')[0];
 +
      _this.tooltipBox = getByClass(viewer, 'viewer-tooltip')[0];
 +
      _this.player = getByClass(viewer, 'viewer-player')[0];
 +
      _this.list = getByClass(viewer, 'viewer-list')[0];
 +
 
 +
      addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(options.title));
 +
      addClass(toolbar, !options.toolbar ? CLASS_HIDE : getResponsiveClass(options.toolbar));
 +
      addClass(navbar, !options.navbar ? CLASS_HIDE : getResponsiveClass(options.navbar));
 +
      toggleClass(button, CLASS_HIDE, !options.button);
 +
 
 +
      toggleClass(toolbar.querySelector('.viewer-one-to-one'), CLASS_INVISIBLE, !options.zoomable);
 +
      toggleClass(toolbar.querySelectorAll('li[class*="zoom"]'), CLASS_INVISIBLE, !options.zoomable);
 +
      toggleClass(toolbar.querySelectorAll('li[class*="flip"]'), CLASS_INVISIBLE, !options.scalable);
 +
 
 +
      if (!options.rotatable) {
 +
        rotate = toolbar.querySelectorAll('li[class*="rotate"]');
 +
        addClass(rotate, CLASS_INVISIBLE);
 +
        appendChild(toolbar, rotate);
 +
      }
 +
 
 +
      if (options.inline) {
 +
        addClass(button, CLASS_FULLSCREEN);
 +
        setStyle(viewer, {
 +
          zIndex: options.zIndexInline
 +
        });
 +
 
 +
        if (getStyle(parent).position === 'static') {
 +
          setStyle(parent, {
 +
            position: 'relative'
 +
          });
 +
        }
 +
      } else {
 +
        addClass(button, CLASS_CLOSE);
 +
        addClass(viewer, CLASS_FIXED);
 +
        addClass(viewer, CLASS_FADE);
 +
        addClass(viewer, CLASS_HIDE);
 +
 
 +
        setStyle(viewer, {
 +
          zIndex: options.zIndex
 +
        });
 +
      }
 +
 
 +
      // Inserts the viewer after to the current element
 +
      parent.insertBefore(viewer, element.nextSibling);
 +
 
 +
      if (options.inline) {
 +
        _this.render();
 +
        _this.bind();
 +
        _this.isShown = true;
 +
      }
 +
 
 +
      _this.isBuilt = true;
 +
 
 +
      dispatchEvent(element, EVENT_READY);
 +
    },
 +
 
 +
    unbuild: function () {
 +
      var _this = this;
 +
 
 +
      if (!_this.isBuilt) {
 +
        return;
 +
      }
 +
 
 +
      _this.isBuilt = false;
 +
      removeChild(_this.viewer);
 +
    },
 +
 
 +
    bind: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
      var viewer = _this.viewer;
 +
 
 +
      if (isFunction(options.view)) {
 +
        addListener(element, EVENT_VIEW, options.view);
 +
      }
 +
 
 +
      if (isFunction(options.viewed)) {
 +
        addListener(element, EVENT_VIEWED, options.viewed);
 +
      }
 +
 
 +
      addListener(viewer, EVENT_CLICK, (_this._click = proxy(_this.click, _this)));
 +
      addListener(viewer, EVENT_WHEEL, (_this._wheel = proxy(_this.wheel, _this)));
 +
      addListener(_this.canvas, EVENT_MOUSEDOWN, (_this._mousedown = proxy(_this.mousedown, _this)));
 +
      addListener(document, EVENT_MOUSEMOVE, (_this._mousemove = proxy(_this.mousemove, _this)));
 +
      addListener(document, EVENT_MOUSEUP, (_this._mouseup = proxy(_this.mouseup, _this)));
 +
      addListener(document, EVENT_KEYDOWN, (_this._keydown = proxy(_this.keydown, _this)));
 +
      addListener(window, EVENT_RESIZE, (_this._resize = proxy(_this.resize, _this)));
 +
    },
 +
 
 +
    unbind: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
      var viewer = _this.viewer;
 +
 
 +
      if (isFunction(options.view)) {
 +
        removeListener(element, EVENT_VIEW, options.view);
 +
      }
 +
 
 +
      if (isFunction(options.viewed)) {
 +
        removeListener(element, EVENT_VIEWED, options.viewed);
 +
      }
 +
 
 +
      removeListener(viewer, EVENT_CLICK, _this._click);
 +
      removeListener(viewer, EVENT_WHEEL, _this._wheel);
 +
      removeListener(_this.canvas, EVENT_MOUSEDOWN, _this._mousedown);
 +
      removeListener(document, EVENT_MOUSEMOVE, _this._mousemove);
 +
      removeListener(document, EVENT_MOUSEUP, _this._mouseup);
 +
      removeListener(document, EVENT_KEYDOWN, _this._keydown);
 +
      removeListener(window, EVENT_RESIZE, _this._resize);
 +
    },
 +
 
 +
    render: function () {
 +
      var _this = this;
 +
 
 +
      _this.initContainer();
 +
      _this.initViewer();
 +
      _this.initList();
 +
      _this.renderViewer();
 +
    },
 +
 
 +
    initContainer: function () {
 +
      var _this = this;
 +
 
 +
      _this.containerData = {
 +
        width: window.innerWidth,
 +
        height: window.innerHeight
 +
      };
 +
    },
 +
 
 +
    initViewer: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var parent = _this.parent;
 +
      var viewerData;
 +
 
 +
      if (options.inline) {
 +
        _this.parentData = viewerData = {
 +
          width: max(parent.offsetWidth, options.minWidth),
 +
          height: max(parent.offsetHeight, options.minHeight)
 +
        };
 +
      }
 +
 
 +
      if (_this.isFulled || !viewerData) {
 +
        viewerData = _this.containerData;
 +
      }
 +
 
 +
      _this.viewerData = extend({}, viewerData);
 +
    },
 +
 
 +
    renderViewer: function () {
 +
      var _this = this;
 +
 
 +
      if (_this.options.inline && !_this.isFulled) {
 +
        setStyle(_this.viewer, _this.viewerData);
 +
      }
 +
    },
 +
 
 +
    initList: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
      var list = _this.list;
 +
      var items = [];
 +
 
 +
      each(_this.images, function (image, i) {
 +
        var src = image.src;
 +
        var alt = image.alt || getImageName(src);
 +
        var url = options.url;
 +
 
 +
        if (!src) {
 +
          return;
 +
        }
 +
 
 +
        if (isString(url)) {
 +
          url = image.getAttribute(url);
 +
        } else if (isFunction(url)) {
 +
          url = url.call(image, image);
 +
        }
 +
 
 +
        items.push(
 +
          '<li>' +
 +
            '<img' +
 +
              ' src="' + src + '"' +
 +
              ' data-action="view"' +
 +
              ' data-index="' +  i + '"' +
 +
              ' data-original-url="' +  (url || src) + '"' +
 +
              ' alt="' +  alt + '"' +
 +
            '>' +
 +
          '</li>'
 +
        );
 +
      });
 +
 
 +
      list.innerHTML = items.join('');
 +
 
 +
      each(getByTag(list, 'img'), function (image) {
 +
        setData(image, 'filled', true);
 +
        addListener(image, EVENT_LOAD, proxy(_this.loadImage, _this), true);
 +
      });
 +
 
 +
      _this.items = getByTag(list, 'li');
 +
 
 +
      if (options.transition) {
 +
        addListener(element, EVENT_VIEWED, function () {
 +
          addClass(list, CLASS_TRANSITION);
 +
        }, true);
 +
      }
 +
    },
 +
 
 +
    renderList: function (index) {
 +
      var _this = this;
 +
      var i = index || _this.index;
 +
      var width = _this.items[i].offsetWidth || 30;
 +
      var outerWidth = width + 1; // 1 pixel of `margin-left` width
 +
 
 +
      // Place the active item in the center of the screen
 +
      setStyle(_this.list, {
 +
        width: outerWidth * _this.length,
 +
        marginLeft: (_this.viewerData.width - width) / 2 - outerWidth * i
 +
      });
 +
    },
 +
 
 +
    resetList: function () {
 +
      var _this = this;
 +
 
 +
      empty(_this.list);
 +
      removeClass(_this.list, CLASS_TRANSITION);
 +
      setStyle({
 +
        marginLeft: 0
 +
      });
 +
    },
 +
 
 +
    initImage: function (callback) {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var image = _this.image;
 +
      var viewerData = _this.viewerData;
 +
      var footerHeight = _this.footer.offsetHeight;
 +
      var viewerWidth = viewerData.width;
 +
      var viewerHeight = max(viewerData.height - footerHeight, footerHeight);
 +
      var oldImageData = _this.imageData || {};
 +
 
 +
      getImageSize(image, function (naturalWidth, naturalHeight) {
 +
        var aspectRatio = naturalWidth / naturalHeight;
 +
        var width = viewerWidth;
 +
        var height = viewerHeight;
 +
        var initialImageData;
 +
        var imageData;
 +
 
 +
        if (viewerHeight * aspectRatio > viewerWidth) {
 +
          height = viewerWidth / aspectRatio;
 +
        } else {
 +
          width = viewerHeight * aspectRatio;
 +
        }
 +
 
 +
        width = min(width * 0.9, naturalWidth);
 +
        height = min(height * 0.9, naturalHeight);
 +
 
 +
        imageData = {
 +
          naturalWidth: naturalWidth,
 +
          naturalHeight: naturalHeight,
 +
          aspectRatio: aspectRatio,
 +
          ratio: width / naturalWidth,
 +
          width: width,
 +
          height: height,
 +
          left: (viewerWidth - width) / 2,
 +
          top: (viewerHeight - height) / 2
 +
        };
 +
 
 +
        initialImageData = extend({}, imageData);
 +
 
 +
        if (options.rotatable) {
 +
          imageData.rotate = oldImageData.rotate || 0;
 +
          initialImageData.rotate = 0;
 +
        }
 +
 
 +
        if (options.scalable) {
 +
          imageData.scaleX = oldImageData.scaleX || 1;
 +
          imageData.scaleY = oldImageData.scaleY || 1;
 +
          initialImageData.scaleX = 1;
 +
          initialImageData.scaleY = 1;
 +
        }
 +
 
 +
        _this.imageData = imageData;
 +
        _this.initialImageData = initialImageData;
 +
 
 +
        if (isFunction(callback)) {
 +
          callback();
 +
        }
 +
      });
 +
    },
 +
 
 +
    renderImage: function (callback) {
 +
      var _this = this;
 +
      var image = _this.image;
 +
      var imageData = _this.imageData;
 +
      var transform = getTransform(imageData);
 +
 
 +
      setStyle(image, {
 +
        width: imageData.width,
 +
        height: imageData.height,
 +
        marginLeft: imageData.left,
 +
        marginTop: imageData.top,
 +
        WebkitTransform: transform,
 +
        msTransform: transform,
 +
        transform: transform
 +
      });
 +
 
 +
      if (isFunction(callback)) {
 +
        if (_this.transitioning) {
 +
          addListener(image, EVENT_TRANSITIONEND, callback, true);
 +
        } else {
 +
          callback();
 +
        }
 +
      }
 +
    },
 +
 
 +
    resetImage: function () {
 +
      var _this = this;
 +
 
 +
      // this.image only defined after viewed
 +
      if (_this.image) {
 +
        removeChild(_this.image);
 +
        _this.image = null;
 +
      }
 +
    },
 +
 
 +
    start: function (event) {
 +
      var _this = this;
 +
      var e = getEvent(event);
 +
      var target = e.target;
 +
 
 +
      if (target.tagName.toLowerCase() === 'img') {
 +
        _this.target = target;
 +
        _this.show();
 +
      }
 +
    },
 +
 
 +
    click: function (event) {
 +
      var _this = this;
 +
      var e = getEvent(event);
 +
      var target = e.target;
 +
      var action = getData(target, 'action');
 +
      var imageData = _this.imageData;
 +
 
 +
      switch (action) {
 +
        case 'mix':
 +
          if (_this.isPlayed) {
 +
            _this.stop();
 +
          } else {
 +
            if (_this.options.inline) {
 +
              if (_this.isFulled) {
 +
                _this.exit();
 +
              } else {
 +
                _this.full();
 +
              }
 +
            } else {
 +
              _this.hide();
 +
            }
 +
          }
 +
 
 +
          break;
 +
 
 +
        case 'view':
 +
          _this.view(getData(target, 'index'));
 +
          break;
 +
 
 +
        case 'zoom-in':
 +
          _this.zoom(0.1, true);
 +
          break;
 +
 
 +
        case 'zoom-out':
 +
          _this.zoom(-0.1, true);
 +
          break;
 +
 
 +
        case 'one-to-one':
 +
          _this.toggle();
 +
          break;
 +
 
 +
        case 'reset':
 +
          _this.reset();
 +
          break;
 +
 
 +
        case 'prev':
 +
          _this.prev();
 +
          break;
 +
 
 +
        case 'play':
 +
          _this.play();
 +
          break;
 +
 
 +
        case 'next':
 +
          _this.next();
 +
          break;
 +
 
 +
        case 'rotate-left':
 +
          _this.rotate(-90);
 +
          break;
 +
 
 +
        case 'rotate-right':
 +
          _this.rotate(90);
 +
          break;
 +
 
 +
        case 'flip-horizontal':
 +
          _this.scaleX(-imageData.scaleX || -1);
 +
          break;
 +
 
 +
        case 'flip-vertical':
 +
          _this.scaleY(-imageData.scaleY || -1);
 +
          break;
 +
 
 +
        default:
 +
          if (_this.isPlayed) {
 +
            _this.stop();
 +
          }
 +
      }
 +
    },
 +
 
 +
    load: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var image = _this.image;
 +
      var index = _this.index;
 +
      var viewerData = _this.viewerData;
 +
 
 +
      if (_this.timeout) {
 +
        clearTimeout(_this.timeout);
 +
        _this.timeout = false;
 +
      }
 +
 
 +
      removeClass(image, CLASS_INVISIBLE);
 +
 
 +
      image.style.cssText = (
 +
        'width:0;' +
 +
        'height:0;' +
 +
        'margin-left:' + viewerData.width / 2 + 'px;' +
 +
        'margin-top:' + viewerData.height / 2 + 'px;' +
 +
        'max-width:none!important;' +
 +
        'visibility:visible;'
 +
      );
 +
 
 +
      _this.initImage(function () {
 +
        toggleClass(image, CLASS_TRANSITION, options.transition);
 +
        toggleClass(image, CLASS_MOVE, options.movable);
 +
 
 +
        _this.renderImage(function () {
 +
          _this.isViewed = true;
 +
          dispatchEvent(_this.element, EVENT_VIEWED, {
 +
            originalImage: _this.images[index],
 +
            index: index,
 +
            image: image
 +
          });
 +
        });
 +
      });
 +
    },
 +
 
 +
    loadImage: function (event) {
 +
      var e = getEvent(event);
 +
      var image = e.target;
 +
      var parent = image.parentNode;
 +
      var parentWidth = parent.offsetWidth || 30;
 +
      var parentHeight = parent.offsetHeight || 50;
 +
      var filled = !!getData(image, 'filled');
 +
 
 +
      getImageSize(image, function (naturalWidth, naturalHeight) {
 +
        var aspectRatio = naturalWidth / naturalHeight;
 +
        var width = parentWidth;
 +
        var height = parentHeight;
 +
 
 +
        if (parentHeight * aspectRatio > parentWidth) {
 +
          if (filled) {
 +
            width = parentHeight * aspectRatio;
 +
          } else {
 +
            height = parentWidth / aspectRatio;
 +
          }
 +
        } else {
 +
          if (filled) {
 +
            height = parentWidth / aspectRatio;
 +
          } else {
 +
            width = parentHeight * aspectRatio;
 +
          }
 +
        }
 +
 
 +
        setStyle(image, {
 +
          width: width,
 +
          height: height,
 +
          marginLeft: (parentWidth - width) / 2,
 +
          marginTop: (parentHeight - height) / 2
 +
        });
 +
      });
 +
    },
 +
 
 +
    resize: function () {
 +
      var _this = this;
 +
 
 +
      _this.initContainer();
 +
      _this.initViewer();
 +
      _this.renderViewer();
 +
      _this.renderList();
 +
 
 +
      if (_this.isViewed) {
 +
        _this.initImage(function () {
 +
          _this.renderImage();
 +
        });
 +
      }
 +
 
 +
      if (_this.isPlayed) {
 +
        each(getByTag(_this.player, 'img'), function (image) {
 +
          addListener(image, EVENT_LOAD, proxy(_this.loadImage, _this), true);
 +
          dispatchEvent(image, EVENT_LOAD);
 +
        });
 +
      }
 +
    },
 +
 
 +
    wheel: function (event) {
 +
      var _this = this;
 +
      var e = getEvent(event);
 +
      var ratio = Number(_this.options.zoomRatio) || 0.1;
 +
      var delta = 1;
 +
 
 +
      if (!_this.isViewed) {
 +
        return;
 +
      }
 +
 
 +
      preventDefault(e);
 +
 
 +
      // Limit wheel speed to prevent zoom too fast
 +
      if (_this.wheeling) {
 +
        return;
 +
      }
 +
 
 +
      _this.wheeling = true;
 +
 
 +
      setTimeout(function () {
 +
        _this.wheeling = false;
 +
      }, 50);
 +
 
 +
      if (e.deltaY) {
 +
        delta = e.deltaY > 0 ? 1 : -1;
 +
      } else if (e.wheelDelta) {
 +
        delta = -e.wheelDelta / 120;
 +
      } else if (e.detail) {
 +
        delta = e.detail > 0 ? 1 : -1;
 +
      }
 +
 
 +
      _this.zoom(-delta * ratio, true, e);
 +
    },
 +
 
 +
    keydown: function (event) {
 +
      var _this = this;
 +
      var e = getEvent(event);
 +
      var options = _this.options;
 +
      var key = e.keyCode || e.which || e.charCode;
 +
 
 +
      if (!_this.isFulled || !options.keyboard) {
 +
        return;
 +
      }
 +
 
 +
      switch (key) {
 +
 
 +
        // (Key: Esc)
 +
        case 27:
 +
          if (_this.isPlayed) {
 +
            _this.stop();
 +
          } else {
 +
            if (options.inline) {
 +
              if (_this.isFulled) {
 +
                _this.exit();
 +
              }
 +
            } else {
 +
              _this.hide();
 +
            }
 +
          }
 +
 
 +
          break;
 +
 
 +
        // (Key: Space)
 +
        case 32:
 +
          if (_this.isPlayed) {
 +
            _this.stop();
 +
          }
 +
 
 +
          break;
 +
 
 +
        // View previous (Key: ←)
 +
        case 37:
 +
          _this.prev();
 +
          break;
 +
 
 +
        // Zoom in (Key: ↑)
 +
        case 38:
 +
 
 +
          // Prevent scroll on Firefox
 +
          preventDefault(e);
 +
 
 +
          _this.zoom(options.zoomRatio, true);
 +
          break;
 +
 
 +
        // View next (Key: →)
 +
        case 39:
 +
          _this.next();
 +
          break;
 +
 
 +
        // Zoom out (Key: ↓)
 +
        case 40:
 +
 
 +
          // Prevent scroll on Firefox
 +
          preventDefault(e);
 +
 
 +
          _this.zoom(-options.zoomRatio, true);
 +
          break;
 +
 
 +
        // Zoom out to initial size (Key: Ctrl + 0)
 +
        case 48:
 +
          // Go to next
 +
 
 +
        // Zoom in to natural size (Key: Ctrl + 1)
 +
        case 49:
 +
          if (e.ctrlKey || e.shiftKey) {
 +
            preventDefault(e);
 +
            _this.toggle();
 +
          }
 +
 
 +
          break;
 +
 
 +
        // No default
 +
      }
 +
    },
 +
 
 +
    mousedown: function (event) {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var e = getEvent(event);
 +
      var action = options.movable ? 'move' : false;
 +
      var touches = e.touches;
 +
      var touchesLength;
 +
      var touch;
 +
 
 +
      if (!_this.isViewed) {
 +
        return;
 +
      }
 +
 
 +
      if (touches) {
 +
        touchesLength = touches.length;
 +
 
 +
        if (touchesLength > 1) {
 +
          if (options.zoomable && touchesLength === 2) {
 +
            touch = touches[1];
 +
            _this.startX2 = touch.pageX;
 +
            _this.startY2 = touch.pageY;
 +
            action = 'zoom';
 +
          } else {
 +
            return;
 +
          }
 +
        } else {
 +
          if (_this.isSwitchable()) {
 +
            action = 'switch';
 +
          }
 +
        }
 +
 
 +
        touch = touches[0];
 +
      }
 +
 
 +
      if (action) {
 +
        preventDefault(e);
 +
        _this.action = action;
 +
        _this.startX = touch ? touch.pageX : e.pageX;
 +
        _this.startY = touch ? touch.pageY : e.pageY;
 +
      }
 +
    },
 +
 
 +
    mousemove: function (event) {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var e = getEvent(event);
 +
      var action = _this.action;
 +
      var image = _this.image;
 +
      var touches = e.touches;
 +
      var touchesLength;
 +
      var touch;
 +
 
 +
      if (!_this.isViewed) {
 +
        return;
 +
      }
 +
 
 +
      if (touches) {
 +
        touchesLength = touches.length;
 +
 
 +
        if (touchesLength > 1) {
 +
          if (options.zoomable && touchesLength === 2) {
 +
            touch = touches[1];
 +
            _this.endX2 = touch.pageX;
 +
            _this.endY2 = touch.pageY;
 +
          } else {
 +
            return;
 +
          }
 +
        }
 +
 
 +
        touch = touches[0];
 +
      }
 +
 
 +
      if (action) {
 +
        preventDefault(e);
 +
 
 +
        if (action === 'move' && options.transition && hasClass(image, CLASS_TRANSITION)) {
 +
          removeClass(image, CLASS_TRANSITION);
 +
        }
 +
 
 +
        _this.endX = touch ? touch.pageX : e.pageX;
 +
        _this.endY = touch ? touch.pageY : e.pageY;
 +
 
 +
        _this.change(e);
 +
      }
 +
    },
 +
 
 +
    mouseup: function (event) {
 +
      var _this = this;
 +
      var e = getEvent(event);
 +
      var action = _this.action;
 +
 
 +
      if (action) {
 +
        preventDefault(e);
 +
 
 +
        if (action === 'move' && _this.options.transition) {
 +
          addClass(_this.image, CLASS_TRANSITION);
 +
        }
 +
 
 +
        _this.action = false;
 +
      }
 +
    },
 +
 
 +
    // Show the viewer (only available in modal mode)
 +
    show: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
      var viewer;
 +
 
 +
      if (options.inline || _this.transitioning) {
 +
        return _this;
 +
      }
 +
 
 +
      if (!_this.isBuilt) {
 +
        _this.build();
 +
      }
 +
 
 +
      viewer = _this.viewer;
 +
 
 +
      if (isFunction(options.show)) {
 +
        addListener(element, EVENT_SHOW, options.show, true);
 +
      }
 +
 
 +
      if (dispatchEvent(element, EVENT_SHOW) === false) {
 +
        return _this;
 +
      }
 +
 
 +
      _this.open();
 +
      removeClass(viewer, CLASS_HIDE);
 +
 
 +
      addListener(element, EVENT_SHOWN, function () {
 +
        _this.view(_this.target ? inArray(_this.target, toArray(_this.images)) : _this.index);
 +
        _this.target = false;
 +
      }, true);
 +
 
 +
      if (options.transition) {
 +
        _this.transitioning = true;
 +
        addClass(viewer, CLASS_TRANSITION);
 +
        forceReflow(viewer);
 +
        addListener(viewer, EVENT_TRANSITIONEND, proxy(_this.shown, _this), true);
 +
        addClass(viewer, CLASS_IN);
 +
      } else {
 +
        addClass(viewer, CLASS_IN);
 +
        _this.shown();
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Hide the viewer (only available in modal mode)
 +
    hide: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
      var viewer = _this.viewer;
 +
 
 +
      if (options.inline || _this.transitioning || !_this.isShown) {
 +
        return _this;
 +
      }
 +
 
 +
      if (isFunction(options.hide)) {
 +
        addListener(element, EVENT_HIDE, options.hide, true);
 +
      }
 +
 
 +
      if (dispatchEvent(element, EVENT_HIDE) === false) {
 +
        return _this;
 +
      }
 +
 
 +
      if (_this.isViewed && options.transition) {
 +
        _this.transitioning = true;
 +
        addListener(_this.image, EVENT_TRANSITIONEND, function () {
 +
          addListener(viewer, EVENT_TRANSITIONEND, proxy(_this.hidden, _this), true);
 +
          removeClass(viewer, CLASS_IN);
 +
        }, true);
 +
        _this.zoomTo(0, false, false, true);
 +
      } else {
 +
        removeClass(viewer, CLASS_IN);
 +
        _this.hidden();
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * View one of the images with image's index
 +
    *
 +
    * @param {Number} index
 +
    */
 +
    view: function (index) {
 +
      var _this = this;
 +
      var element = _this.element;
 +
      var title = _this.title;
 +
      var canvas = _this.canvas;
 +
      var image;
 +
      var item;
 +
      var img;
 +
      var url;
 +
      var alt;
 +
 
 +
      index = Number(index) || 0;
 +
 
 +
      if (!_this.isShown || _this.isPlayed || index < 0 || index >= _this.length ||
 +
        _this.isViewed && index === _this.index) {
 +
        return _this;
 +
      }
 +
 
 +
      item = _this.items[index];
 +
      img = getByTag(item, 'img')[0];
 +
      url = getData(img, 'originalUrl');
 +
      alt = img.getAttribute('alt');
 +
 
 +
      image = document.createElement('img');
 +
      image.src = url;
 +
      image.alt = alt;
 +
 
 +
      if (dispatchEvent(element, EVENT_VIEW, {
 +
        originalImage: _this.images[index],
 +
        index: index,
 +
        image: image
 +
      }) === false) {
 +
        return _this;
 +
      }
 +
 
 +
      _this.image = image;
 +
 
 +
      if (_this.isViewed) {
 +
        removeClass(_this.items[_this.index], CLASS_ACTIVE);
 +
      }
 +
 
 +
      addClass(item, CLASS_ACTIVE);
 +
 
 +
      _this.isViewed = false;
 +
      _this.index = index;
 +
      _this.imageData = null;
 +
 
 +
      addClass(image, CLASS_INVISIBLE);
 +
      empty(canvas);
 +
      appendChild(canvas, image);
 +
 
 +
      // Center current item
 +
      _this.renderList();
 +
 
 +
      // Clear title
 +
      empty(title);
 +
 
 +
      // Generate title after viewed
 +
      addListener(element, EVENT_VIEWED, function () {
 +
        var imageData = _this.imageData;
 +
        var width = imageData.naturalWidth;
 +
        var height = imageData.naturalHeight;
 +
 
 +
        setText(title, alt + ' (' + width + ' × ' + height + ')');
 +
      }, true);
 +
 
 +
      if (image.complete) {
 +
        _this.load();
 +
      } else {
 +
        addListener(image, EVENT_LOAD, proxy(_this.load, _this), true);
 +
 
 +
        if (_this.timeout) {
 +
          clearTimeout(_this.timeout);
 +
        }
 +
 
 +
        // Make the image visible if it fails to load within 1s
 +
        _this.timeout = setTimeout(function () {
 +
          removeClass(image, CLASS_INVISIBLE);
 +
          _this.timeout = false;
 +
        }, 1000);
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // View the previous image
 +
    prev: function () {
 +
      var _this = this;
 +
 
 +
      _this.view(max(_this.index - 1, 0));
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // View the next image
 +
    next: function () {
 +
      var _this = this;
 +
 
 +
      _this.view(min(_this.index + 1, _this.length - 1));
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Move the image with relative offsets
 +
    *
 +
    * @param {Number} offsetX
 +
    * @param {Number} offsetY (optional)
 +
    */
 +
    move: function (offsetX, offsetY) {
 +
      var _this = this;
 +
      var imageData = _this.imageData;
 +
 
 +
      _this.moveTo(
 +
        isUndefined(offsetX) ? offsetX : imageData.left + Number(offsetX),
 +
        isUndefined(offsetY) ? offsetY : imageData.top + Number(offsetY)
 +
      );
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Move the image to an absolute point
 +
    *
 +
    * @param {Number} x
 +
    * @param {Number} y (optional)
 +
    */
 +
    moveTo: function (x, y) {
 +
      var _this = this;
 +
      var imageData = _this.imageData;
 +
      var changed = false;
 +
 
 +
      // If "y" is not present, its default value is "x"
 +
      if (isUndefined(y)) {
 +
        y = x;
 +
      }
 +
 
 +
      x = Number(x);
 +
      y = Number(y);
 +
 
 +
      if (_this.isViewed && !_this.isPlayed && _this.options.movable) {
 +
        if (isNumber(x)) {
 +
          imageData.left = x;
 +
          changed = true;
 +
        }
 +
 
 +
        if (isNumber(y)) {
 +
          imageData.top = y;
 +
          changed = true;
 +
        }
 +
 
 +
        if (changed) {
 +
          _this.renderImage();
 +
        }
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Zoom the image with a relative ratio
 +
    *
 +
    * @param {Number} ratio
 +
    * @param {Boolean} hasTooltip (optional)
 +
    * @param {Event} _originalEvent (private)
 +
    */
 +
    zoom: function (ratio, hasTooltip, _originalEvent) {
 +
      var _this = this;
 +
      var imageData = _this.imageData;
 +
 
 +
      ratio = Number(ratio);
 +
 
 +
      if (ratio < 0) {
 +
        ratio =  1 / (1 - ratio);
 +
      } else {
 +
        ratio = 1 + ratio;
 +
      }
 +
 
 +
      _this.zoomTo(imageData.width * ratio / imageData.naturalWidth, hasTooltip, _originalEvent);
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Zoom the image to an absolute ratio
 +
    *
 +
    * @param {Number} ratio
 +
    * @param {Boolean} hasTooltip (optional)
 +
    * @param {Event} _originalEvent (private)
 +
    * @param {Boolean} _zoomable (private)
 +
    */
 +
    zoomTo: function (ratio, hasTooltip, _originalEvent, _zoomable) {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var minZoomRatio = 0.01;
 +
      var maxZoomRatio = 100;
 +
      var imageData = _this.imageData;
 +
      var newWidth;
 +
      var newHeight;
 +
      var offset;
 +
      var center;
 +
 
 +
      ratio = max(0, ratio);
 +
 
 +
      if (isNumber(ratio) && _this.isViewed && !_this.isPlayed && (_zoomable || options.zoomable)) {
 +
        if (!_zoomable) {
 +
          minZoomRatio = max(minZoomRatio, options.minZoomRatio);
 +
          maxZoomRatio = min(maxZoomRatio, options.maxZoomRatio);
 +
          ratio = min(max(ratio, minZoomRatio), maxZoomRatio);
 +
        }
 +
 
 +
        if (ratio > 0.95 && ratio < 1.05) {
 +
          ratio = 1;
 +
        }
 +
 
 +
        newWidth = imageData.naturalWidth * ratio;
 +
        newHeight = imageData.naturalHeight * ratio;
 +
 
 +
        if (_originalEvent) {
 +
          offset = getOffset(_this.viewer);
 +
          center = _originalEvent.touches ? getTouchesCenter(_originalEvent.touches) : {
 +
            pageX: _originalEvent.pageX,
 +
            pageY: _originalEvent.pageY
 +
          };
 +
 
 +
          // Zoom from the triggering point of the event
 +
          imageData.left -= (newWidth - imageData.width) * (
 +
            ((center.pageX - offset.left) - imageData.left) / imageData.width
 +
          );
 +
          imageData.top -= (newHeight - imageData.height) * (
 +
            ((center.pageY - offset.top) - imageData.top) / imageData.height
 +
          );
 +
        } else {
 +
 
 +
          // Zoom from the center of the image
 +
          imageData.left -= (newWidth - imageData.width) / 2;
 +
          imageData.top -= (newHeight - imageData.height) / 2;
 +
        }
 +
 
 +
        imageData.width = newWidth;
 +
        imageData.height = newHeight;
 +
        imageData.ratio = ratio;
 +
        _this.renderImage();
 +
 
 +
        if (hasTooltip) {
 +
          _this.tooltip();
 +
        }
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Rotate the image with a relative degree
 +
    *
 +
    * @param {Number} degree
 +
    */
 +
    rotate: function (degree) {
 +
      var _this = this;
 +
 
 +
      _this.rotateTo((_this.imageData.rotate || 0) + Number(degree));
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Rotate the image to an absolute degree
 +
    * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#rotate()
 +
    *
 +
    * @param {Number} degree
 +
    */
 +
    rotateTo: function (degree) {
 +
      var _this = this;
 +
      var imageData = _this.imageData;
 +
 
 +
      degree = Number(degree);
 +
 
 +
      if (isNumber(degree) && _this.isViewed && !_this.isPlayed && _this.options.rotatable) {
 +
        imageData.rotate = degree;
 +
        _this.renderImage();
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Scale the image
 +
    * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#scale()
 +
    *
 +
    * @param {Number} scaleX
 +
    * @param {Number} scaleY (optional)
 +
    */
 +
    scale: function (scaleX, scaleY) {
 +
      var _this = this;
 +
      var imageData = _this.imageData;
 +
      var changed = false;
 +
 
 +
      // If "scaleY" is not present, its default value is "scaleX"
 +
      if (isUndefined(scaleY)) {
 +
        scaleY = scaleX;
 +
      }
 +
 
 +
      scaleX = Number(scaleX);
 +
      scaleY = Number(scaleY);
 +
 
 +
      if (_this.isViewed && !_this.isPlayed && _this.options.scalable) {
 +
        if (isNumber(scaleX)) {
 +
          imageData.scaleX = scaleX;
 +
          changed = true;
 +
        }
 +
 
 +
        if (isNumber(scaleY)) {
 +
          imageData.scaleY = scaleY;
 +
          changed = true;
 +
        }
 +
 
 +
        if (changed) {
 +
          _this.renderImage();
 +
        }
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Scale the abscissa of the image
 +
    *
 +
    * @param {Number} scaleX
 +
    */
 +
    scaleX: function (scaleX) {
 +
      var _this = this;
 +
 
 +
      _this.scale(scaleX, _this.imageData.scaleY);
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    /**
 +
    * Scale the ordinate of the image
 +
    *
 +
    * @param {Number} scaleY
 +
    */
 +
    scaleY: function (scaleY) {
 +
      var _this = this;
 +
 
 +
      _this.scale(_this.imageData.scaleX, scaleY);
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Play the images
 +
    play: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var player = _this.player;
 +
      var load = proxy(_this.loadImage, _this);
 +
      var list = [];
 +
      var total = 0;
 +
      var index = 0;
 +
      var playing;
 +
 
 +
      if (!_this.isShown || _this.isPlayed) {
 +
        return _this;
 +
      }
 +
 
 +
      if (options.fullscreen) {
 +
        _this.requestFullscreen();
 +
      }
 +
 
 +
      _this.isPlayed = true;
 +
      addClass(player, CLASS_SHOW);
 +
 
 +
      each(_this.items, function (item, i) {
 +
        var img = getByTag(item, 'img')[0];
 +
        var image = document.createElement('img');
 +
 
 +
        image.src = getData(img, 'originalUrl');
 +
        image.alt = img.getAttribute('alt');
 +
        total++;
 +
 
 +
        addClass(image, CLASS_FADE);
 +
        toggleClass(image, CLASS_TRANSITION, options.transition);
 +
 
 +
        if (hasClass(item, CLASS_ACTIVE)) {
 +
          addClass(image, CLASS_IN);
 +
          index = i;
 +
        }
 +
 
 +
        list.push(image);
 +
        addListener(image, EVENT_LOAD, load, true);
 +
        appendChild(player, image);
 +
      });
 +
 
 +
      if (isNumber(options.interval) && options.interval > 0) {
 +
        playing = function () {
 +
          _this.playing = setTimeout(function () {
 +
            removeClass(list[index], CLASS_IN);
 +
            index++;
 +
            index = index < total ? index : 0;
 +
            addClass(list[index], CLASS_IN);
 +
 
 +
            playing();
 +
          }, options.interval);
 +
        };
 +
 
 +
        if (total > 1) {
 +
          playing();
 +
        }
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Stop play
 +
    stop: function () {
 +
      var _this = this;
 +
      var player = _this.player;
 +
 
 +
      if (!_this.isPlayed) {
 +
        return _this;
 +
      }
 +
 
 +
      if (_this.options.fullscreen) {
 +
        _this.exitFullscreen();
 +
      }
 +
 
 +
      _this.isPlayed = false;
 +
      clearTimeout(_this.playing);
 +
      removeClass(player, CLASS_SHOW);
 +
      empty(player);
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Enter modal mode (only available in inline mode)
 +
    full: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var viewer = _this.viewer;
 +
      var image = _this.image;
 +
      var list = _this.list;
 +
 
 +
      if (!_this.isShown || _this.isPlayed || _this.isFulled || !options.inline) {
 +
        return _this;
 +
      }
 +
 
 +
      _this.isFulled = true;
 +
      _this.open();
 +
      addClass(_this.button, CLASS_FULLSCREEN_EXIT);
 +
 
 +
      if (options.transition) {
 +
        removeClass(image, CLASS_TRANSITION);
 +
        removeClass(list, CLASS_TRANSITION);
 +
      }
 +
 
 +
      addClass(viewer, CLASS_FIXED);
 +
      viewer.setAttribute('style', '');
 +
      setStyle(viewer, {
 +
        zIndex: options.zIndex
 +
      });
 +
 
 +
      _this.initContainer();
 +
      _this.viewerData = extend({}, _this.containerData);
 +
      _this.renderList();
 +
      _this.initImage(function () {
 +
        _this.renderImage(function () {
 +
          if (options.transition) {
 +
            setTimeout(function () {
 +
              addClass(image, CLASS_TRANSITION);
 +
              addClass(list, CLASS_TRANSITION);
 +
            }, 0);
 +
          }
 +
        });
 +
      });
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Exit modal mode (only available in inline mode)
 +
    exit: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var viewer = _this.viewer;
 +
      var image = _this.image;
 +
      var list = _this.list;
 +
 
 +
      if (!_this.isFulled) {
 +
        return _this;
 +
      }
 +
 
 +
      _this.isFulled = false;
 +
      _this.close();
 +
      removeClass(_this.button, CLASS_FULLSCREEN_EXIT);
 +
 
 +
      if (options.transition) {
 +
        removeClass(image, CLASS_TRANSITION);
 +
        removeClass(list, CLASS_TRANSITION);
 +
      }
 +
 
 +
      removeClass(viewer, CLASS_FIXED);
 +
      setStyle(viewer, {
 +
        zIndex: options.zIndexInline
 +
      });
 +
 
 +
      _this.viewerData = extend({}, _this.parentData);
 +
      _this.renderViewer();
 +
      _this.renderList();
 +
      _this.initImage(function () {
 +
        _this.renderImage(function () {
 +
          if (options.transition) {
 +
            setTimeout(function () {
 +
              addClass(image, CLASS_TRANSITION);
 +
              addClass(list, CLASS_TRANSITION);
 +
            }, 0);
 +
          }
 +
        });
 +
      });
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Show the current ratio of the image with percentage
 +
    tooltip: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var tooltipBox = _this.tooltipBox;
 +
      var imageData = _this.imageData;
 +
 
 +
      if (!_this.isViewed || _this.isPlayed || !options.tooltip) {
 +
        return _this;
 +
      }
 +
 
 +
      setText(tooltipBox, round(imageData.ratio * 100) + '%');
 +
 
 +
      if (!_this.tooltiping) {
 +
        if (options.transition) {
 +
          if (_this.fading) {
 +
            dispatchEvent(tooltipBox, EVENT_TRANSITIONEND);
 +
          }
 +
 
 +
          addClass(tooltipBox, CLASS_SHOW);
 +
          addClass(tooltipBox, CLASS_FADE);
 +
          addClass(tooltipBox, CLASS_TRANSITION);
 +
          forceReflow(tooltipBox);
 +
          addClass(tooltipBox, CLASS_IN);
 +
        } else {
 +
          addClass(tooltipBox, CLASS_SHOW);
 +
        }
 +
      } else {
 +
        clearTimeout(_this.tooltiping);
 +
      }
 +
 
 +
      _this.tooltiping = setTimeout(function () {
 +
        if (options.transition) {
 +
          addListener(tooltipBox, EVENT_TRANSITIONEND, function () {
 +
            removeClass(tooltipBox, CLASS_SHOW);
 +
            removeClass(tooltipBox, CLASS_FADE);
 +
            removeClass(tooltipBox, CLASS_TRANSITION);
 +
            _this.fading = false;
 +
          }, true);
 +
 
 +
          removeClass(tooltipBox, CLASS_IN);
 +
          _this.fading = true;
 +
        } else {
 +
          removeClass(tooltipBox, CLASS_SHOW);
 +
        }
 +
 
 +
        _this.tooltiping = false;
 +
      }, 1000);
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Toggle the image size between its natural size and initial size
 +
    toggle: function () {
 +
      var _this = this;
 +
 
 +
      if (_this.imageData.ratio === 1) {
 +
        _this.zoomTo(_this.initialImageData.ratio, true);
 +
      } else {
 +
        _this.zoomTo(1, true);
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Reset the image to its initial state
 +
    reset: function () {
 +
      var _this = this;
 +
 
 +
      if (_this.isViewed && !_this.isPlayed) {
 +
        _this.imageData = extend({}, _this.initialImageData);
 +
        _this.renderImage();
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Update viewer when images changed
 +
    update: function () {
 +
      var _this = this;
 +
      var indexes = [];
 +
      var index;
 +
 
 +
      // Destroy viewer if the target image was deleted
 +
      if (_this.isImg && !_this.element.parentNode) {
 +
        return _this.destroy();
 +
      }
 +
 
 +
      _this.length = _this.images.length;
 +
 
 +
      if (_this.isBuilt) {
 +
        each(_this.items, function (item, i) {
 +
          var img = getByTag(item, 'img')[0];
 +
          var image = _this.images[i];
 +
 
 +
          if (image) {
 +
            if (image.src !== img.src) {
 +
              indexes.push(i);
 +
            }
 +
          } else {
 +
            indexes.push(i);
 +
          }
 +
        });
 +
 
 +
        setStyle(_this.list, {
 +
          width: 'auto'
 +
        });
 +
 
 +
        _this.initList();
 +
 
 +
        if (_this.isShown) {
 +
          if (_this.length) {
 +
            if (_this.isViewed) {
 +
              index = inArray(_this.index, indexes);
 +
 
 +
              if (index >= 0) {
 +
                _this.isViewed = false;
 +
                _this.view(max(_this.index - (index + 1), 0));
 +
              } else {
 +
                addClass(_this.items[_this.index], CLASS_ACTIVE);
 +
              }
 +
            }
 +
          } else {
 +
            _this.image = null;
 +
            _this.isViewed = false;
 +
            _this.index = 0;
 +
            _this.imageData = null;
 +
            empty(_this.canvas);
 +
            empty(_this.title);
 +
          }
 +
        }
 +
      }
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    // Destroy the viewer
 +
    destroy: function () {
 +
      var _this = this;
 +
      var element = _this.element;
 +
 
 +
      if (_this.options.inline) {
 +
        _this.unbind();
 +
      } else {
 +
        if (_this.isShown) {
 +
          _this.unbind();
 +
        }
 +
 
 +
        removeListener(element, EVENT_CLICK, _this._start);
 +
      }
 +
 
 +
      _this.unbuild();
 +
      removeData(element, NAMESPACE);
 +
 
 +
      return _this;
 +
    },
 +
 
 +
    open: function () {
 +
      var body = this.body;
 +
 
 +
      addClass(body, CLASS_OPEN);
 +
      body.style.paddingRight = this.scrollbarWidth + 'px';
 +
    },
 +
 
 +
    close: function () {
 +
      var body = this.body;
 +
 
 +
      removeClass(body, CLASS_OPEN);
 +
      body.style.paddingRight = 0;
 +
    },
 +
 
 +
    shown: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
 
 +
      _this.transitioning = false;
 +
      _this.isFulled = true;
 +
      _this.isShown = true;
 +
      _this.isVisible = true;
 +
      _this.render();
 +
      _this.bind();
 +
 
 +
      if (isFunction(options.shown)) {
 +
        addListener(element, EVENT_SHOWN, options.shown, true);
 +
      }
 +
 
 +
      dispatchEvent(element, EVENT_SHOWN);
 +
    },
 +
 
 +
    hidden: function () {
 +
      var _this = this;
 +
      var options = _this.options;
 +
      var element = _this.element;
 +
 
 +
      _this.transitioning = false;
 +
      _this.isViewed = false;
 +
      _this.isFulled = false;
 +
      _this.isShown = false;
 +
      _this.isVisible = false;
 +
      _this.unbind();
 +
      _this.close();
 +
      addClass(_this.viewer, CLASS_HIDE);
 +
      _this.resetList();
 +
      _this.resetImage();
 +
 
 +
      if (isFunction(options.hidden)) {
 +
        addListener(element, EVENT_HIDDEN, options.hidden, true);
 +
      }
 +
 
 +
      dispatchEvent(element, EVENT_HIDDEN);
 +
    },
 +
 
 +
    requestFullscreen: function () {
 +
      var _this = this;
 +
      var documentElement = document.documentElement;
 +
 
 +
      if (_this.isFulled && !document.fullscreenElement && !document.mozFullScreenElement &&
 +
        !document.webkitFullscreenElement && !document.msFullscreenElement) {
 +
 
 +
        if (documentElement.requestFullscreen) {
 +
          documentElement.requestFullscreen();
 +
        } else if (documentElement.msRequestFullscreen) {
 +
          documentElement.msRequestFullscreen();
 +
        } else if (documentElement.mozRequestFullScreen) {
 +
          documentElement.mozRequestFullScreen();
 +
        } else if (documentElement.webkitRequestFullscreen) {
 +
          documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
 +
        }
 +
      }
 +
    },
 +
 
 +
    exitFullscreen: function () {
 +
      var _this = this;
 +
 
 +
      if (_this.isFulled) {
 +
        if (document.exitFullscreen) {
 +
          document.exitFullscreen();
 +
        } else if (document.msExitFullscreen) {
 +
          document.msExitFullscreen();
 +
        } else if (document.mozCancelFullScreen) {
 +
          document.mozCancelFullScreen();
 +
        } else if (document.webkitExitFullscreen) {
 +
          document.webkitExitFullscreen();
 +
        }
 +
      }
 +
    },
 +
 
 +
    change: function (originalEvent) {
 +
      var _this = this;
 +
      var offsetX = _this.endX - _this.startX;
 +
      var offsetY = _this.endY - _this.startY;
 +
 
 +
      switch (_this.action) {
 +
 
 +
        // Move the current image
 +
        case 'move':
 +
          _this.move(offsetX, offsetY);
 +
          break;
 +
 
 +
        // Zoom the current image
 +
        case 'zoom':
 +
          _this.zoom(function (x1, y1, x2, y2) {
 +
            var z1 = sqrt(x1 * x1 + y1 * y1);
 +
            var z2 = sqrt(x2 * x2 + y2 * y2);
 +
 
 +
            return (z2 - z1) / z1;
 +
          }(
 +
            abs(_this.startX - _this.startX2),
 +
            abs(_this.startY - _this.startY2),
 +
            abs(_this.endX - _this.endX2),
 +
            abs(_this.endY - _this.endY2)
 +
          ), false, originalEvent);
 +
 
 +
          _this.startX2 = _this.endX2;
 +
          _this.startY2 = _this.endY2;
 +
          break;
 +
 
 +
        case 'switch':
 +
          _this.action = 'switched';
 +
 
 +
          if (abs(offsetX) > abs(offsetY)) {
 +
            if (offsetX > 1) {
 +
              _this.prev();
 +
            } else if (offsetX < -1) {
 +
              _this.next();
 +
            }
 +
          }
 +
 
 +
          break;
 +
 
 +
        // No default
 +
      }
 +
 
 +
      // Override
 +
      _this.startX = _this.endX;
 +
      _this.startY = _this.endY;
 +
    },
 +
 
 +
    isSwitchable: function () {
 +
      var _this = this;
 +
      var imageData = _this.imageData;
 +
      var viewerData = _this.viewerData;
 +
 
 +
      return imageData.left >= 0 && imageData.top >= 0 &&
 +
        imageData.width <= viewerData.width &&
 +
        imageData.height <= viewerData.height;
 +
    }
 +
  };
 +
 
 +
  Viewer.DEFAULTS = {
 +
 
 +
    // Enable inline mode
 +
    inline: false,
 +
 
 +
    // Show the button on the top-right of the viewer
 +
    button: true,
 +
 
 +
    // Show the navbar
 +
    navbar: true,
 +
 
 +
    // Show the title
 +
    title: true,
 +
 
 +
    // Show the toolbar
 +
    toolbar: true,
 +
 
 +
    // Show the tooltip with image ratio (percentage) when zoom in or zoom out
 +
    tooltip: true,
 +
 
 +
    // Enable to move the image
 +
    movable: true,
 +
 
 +
    // Enable to zoom the image
 +
    zoomable: true,
 +
 
 +
    // Enable to rotate the image
 +
    rotatable: true,
 +
 
 +
    // Enable to scale the image
 +
    scalable: true,
 +
 
 +
    // Enable CSS3 Transition for some special elements
 +
    transition: true,
 +
 
 +
    // Enable to request fullscreen when play
 +
    fullscreen: true,
 +
 
 +
    // Enable keyboard support
 +
    keyboard: true,
 +
 
 +
    // Define interval of each image when playing
 +
    interval: 5000,
 +
 
 +
    // Min width of the viewer in inline mode
 +
    minWidth: 200,
 +
 
 +
    // Min height of the viewer in inline mode
 +
    minHeight: 100,
 +
 
 +
    // Define the ratio when zoom the image by wheeling mouse
 +
    zoomRatio: 0.1,
 +
 
 +
    // Define the min ratio of the image when zoom out
 +
    minZoomRatio: 0.01,
 +
 
 +
    // Define the max ratio of the image when zoom in
 +
    maxZoomRatio: 100,
 +
 
 +
    // Define the CSS `z-index` value of viewer in modal mode.
 +
    zIndex: 2015,
 +
 
 +
    // Define the CSS `z-index` value of viewer in inline mode.
 +
    zIndexInline: 0,
 +
 
 +
    // Define where to get the original image URL for viewing
 +
    // Type: String (an image attribute) or Function (should return an image URL)
 +
    url: 'src',
 +
 
 +
    // Event shortcuts
 +
    build: null,
 +
    built: null,
 +
    show: null,
 +
    shown: null,
 +
    hide: null,
 +
    hidden: null,
 +
    view: null,
 +
    viewed: null
 +
  };
 +
 
 +
  Viewer.TEMPLATE = (
 +
    '<div class="viewer-container">' +
 +
      '<div class="viewer-canvas"></div>' +
 +
      '<div class="viewer-footer">' +
 +
        '<div class="viewer-title"></div>' +
 +
        '<ul class="viewer-toolbar">' +
 +
          '<li class="viewer-zoom-in" data-action="zoom-in"></li>' +
 +
          '<li class="viewer-zoom-out" data-action="zoom-out"></li>' +
 +
          '<li class="viewer-one-to-one" data-action="one-to-one"></li>' +
 +
          '<li class="viewer-reset" data-action="reset"></li>' +
 +
          '<li class="viewer-prev" data-action="prev"></li>' +
 +
          '<li class="viewer-play" data-action="play"></li>' +
 +
          '<li class="viewer-next" data-action="next"></li>' +
 +
          '<li class="viewer-rotate-left" data-action="rotate-left"></li>' +
 +
          '<li class="viewer-rotate-right" data-action="rotate-right"></li>' +
 +
          '<li class="viewer-flip-horizontal" data-action="flip-horizontal"></li>' +
 +
          '<li class="viewer-flip-vertical" data-action="flip-vertical"></li>' +
 +
        '</ul>' +
 +
        '<div class="viewer-navbar">' +
 +
          '<ul class="viewer-list"></ul>' +
 +
        '</div>' +
 +
      '</div>' +
 +
      '<div class="viewer-tooltip"></div>' +
 +
      '<div class="viewer-button" data-action="mix"></div>' +
 +
      '<div class="viewer-player"></div>' +
 +
    '</div>'
 +
  );
 +
 
 +
  var _Viewer = window.Viewer;
 +
 
 +
  Viewer.noConflict = function () {
 +
    window.Viewer = _Viewer;
 +
    return Viewer;
 +
  };
 +
 
 +
  Viewer.setDefaults = function (options) {
 +
    extend(Viewer.DEFAULTS, options);
 +
  };
 +
 
 +
  if (typeof define === 'function' && define.amd) {
 +
    define('viewer', [], function () {
 +
      return Viewer;
 +
    });
 +
  }
 +
 
 +
  if (!noGlobal) {
 +
    window.Viewer = Viewer;
 +
  }
 +
 
 +
  return Viewer;
 +
 
 +
});
 
</script>
 
</script>
 
<style>
 
<style>

Revision as of 20:54, 7 August 2016

In this page you can introduce your team members, instructors, and advisors.

Inspiration

You can look at what other teams did to get some inspiration!
Here are a few examples:

What should this page contain?
  • Include pictures of your teammates, don’t forget instructors and advisors!
  • You can add a small biography or a few words from each team member, to tell us what you like, and what motivated you to participate in iGEM.
  • Take team pictures! Show us your school, your lab and little bit of your city.
  • Remember that image galleries can help you showcase many pictures while saving space.
  • Picture
  • Picture 2
  • Picture 3