1/* Modernizr (Custom Build) | MIT & BSD 2 * Build: http://modernizr.com/download/#-csstransforms3d-csstransitions-touch-shiv-load-cssclasses-prefixed-teststyles-testprops-testallprops-prefixes-domprefixes-mq-respond 3 */ 4;window.Modernizr=function(e,t,n){function C(e){f.cssText=e}function k(e,t){return C(h.join(e+";")+(t||""))}function L(e,t){return typeof e===t}function A(e,t){return!!~(""+e).indexOf(t)}function O(e,t){for(var r in e){var i=e[r];if(!A(i,"-")&&f[i]!==n)return t=="pfx"?i:!0}return!1}function M(e,t,r){for(var i in e){var s=t[e[i]];if(s!==n)return r===!1?e[i]:L(s,"function")?s.bind(r||t):s}return!1}function _(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),i=(e+" "+d.join(r+" ")+r).split(" ");return L(t,"string")||L(t,"undefined")?O(i,t):(i=(e+" "+v.join(r+" ")+r).split(" "),M(i,t,n))}var r="2.8.3",i={},s=!0,o=t.documentElement,u="modernizr",a=t.createElement(u),f=a.style,l,c={}.toString,h=" -webkit- -moz- -o- -ms- ".split(" "),p="Webkit Moz O ms",d=p.split(" "),v=p.toLowerCase().split(" "),m={},g={},y={},b=[],w=b.slice,E,S=function(e,n,r,i){var s,a,f,l,c=t.createElement("div"),h=t.body,p=h||t.createElement("body");if(parseInt(r,10))while(r--)f=t.createElement("div"),f.id=i?i[r]:u+(r+1),c.appendChild(f);return s=["­",'<style id="s',u,'">',e,"</style>"].join(""),c.id=u,(h?c:p).innerHTML+=s,p.appendChild(c),h||(p.style.background="",p.style.overflow="hidden",l=o.style.overflow,o.style.overflow="hidden",o.appendChild(p)),a=n(c,e),h?c.parentNode.removeChild(c):(p.parentNode.removeChild(p),o.style.overflow=l),!!a},x=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return S("@media "+t+" { #"+u+" { position: absolute; } }",function(t){r=(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle)["position"]=="absolute"}),r},T={}.hasOwnProperty,N;!L(T,"undefined")&&!L(T.call,"undefined")?N=function(e,t){return T.call(e,t)}:N=function(e,t){return t in e&&L(e.constructor.prototype[t],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError;var r=w.call(arguments,1),i=function(){if(this instanceof i){var e=function(){};e.prototype=n.prototype;var s=new e,o=n.apply(s,r.concat(w.call(arguments)));return Object(o)===o?o:s}return n.apply(t,r.concat(w.call(arguments)))};return i}),m.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:S(["@media (",h.join("touch-enabled),("),u,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=e.offsetTop===9}),n},m.csstransforms3d=function(){var e=!!_("perspective");return e&&"webkitPerspective"in o.style&&S("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t,n){e=t.offsetLeft===9&&t.offsetHeight===3}),e},m.csstransitions=function(){return _("transition")};for(var D in m)N(m,D)&&(E=D.toLowerCase(),i[E]=m[D](),b.push((i[E]?"":"no-")+E));return i.addTest=function(e,t){if(typeof e=="object")for(var r in e)N(e,r)&&i.addTest(r,e[r]);else{e=e.toLowerCase();if(i[e]!==n)return i;t=typeof t=="function"?t():t,typeof s!="undefined"&&s&&(o.className+=" "+(t?"":"no-")+e),i[e]=t}return i},C(""),a=l=null,function(e,t){function c(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function h(){var e=y.elements;return typeof e=="string"?e.split(" "):e}function p(e){var t=f[e[u]];return t||(t={},a++,e[u]=a,f[a]=t),t}function d(e,n,r){n||(n=t);if(l)return n.createElement(e);r||(r=p(n));var o;return r.cache[e]?o=r.cache[e].cloneNode():s.test(e)?o=(r.cache[e]=r.createElem(e)).cloneNode():o=r.createElem(e),o.canHaveChildren&&!i.test(e)&&!o.tagUrn?r.frag.appendChild(o):o}function v(e,n){e||(e=t);if(l)return e.createDocumentFragment();n=n||p(e);var r=n.frag.cloneNode(),i=0,s=h(),o=s.length;for(;i<o;i++)r.createElement(s[i]);return r}function m(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?d(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function g(e){e||(e=t);var n=p(e);return y.shivCSS&&!o&&!n.hasCSS&&(n.hasCSS=!!c(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
4play:block}mark{background:#FF0;color:#000}template{display:none}")),l||m(e,n),e}var n="3.7.0",r=e.html5||{},i=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,s=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,o,u="_html5shiv",a=0,f={},l;(function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",o="hidden"in e,l=e.childNodes.length==1||function(){t.createElement("a");var e=t.createDocumentFragment();return typeof e.cloneNode=="undefined"||typeof e.createDocumentFragment=="undefined"||typeof e.createElement=="undefined"}()}catch(n){o=!0,l=!0}})();var y={elements:r.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:n,shivCSS:r.shivCSS!==!1,supportsUnknownElements:l,shivMethods:r.shivMethods!==!1,type:"default",shivDocument:g,createElement:d,createDocumentFragment:v};e.html5=y,g(t)}(this,t),i._version=r,i._prefixes=h,i._domPrefixes=v,i._cssomPrefixes=d,i.mq=x,i.testProp=function(e){return O([e])},i.testAllProps=_,i.testStyles=S,i.prefixed=function(e,t,n){return t?_(e,t,n):_(e,"pfx")},o.className=o.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(s?" js "+b.join(" "):""),i}(this,this.document),function(e,t,n){function r(e){return"[object Function]"==d.call(e)}function i(e){return"string"==typeof e}function s(){}function o(e){return!e||"loaded"==e||"complete"==e||"uninitialized"==e}function u(){var e=v.shift();m=1,e?e.t?h(function(){("c"==e.t?k.injectCss:k.injectJs)(e.s,0,e.a,e.x,e.e,1)},0):(e(),u()):m=0}function a(e,n,r,i,s,a,f){function l(t){if(!d&&o(c.readyState)&&(w.r=d=1,!m&&u(),c.onload=c.onreadystatechange=null,t)){"img"!=e&&h(function(){b.removeChild(c)},50);for(var r in T[n])T[n].hasOwnProperty(r)&&T[n][r].onload()}}var f=f||k.errorTimeout,c=t.createElement(e),d=0,g=0,w={t:r,s:n,e:s,a:a,x:f};1===T[n]&&(g=1,T[n]=[]),"object"==e?c.data=n:(c.src=n,c.type=e),c.width=c.height="0",c.onerror=c.onload=c.onreadystatechange=function(){l.call(this,g)},v.splice(i,0,w),"img"!=e&&(g||2===T[n]?(b.insertBefore(c,y?null:p),h(l,f)):T[n].push(c))}function f(e,t,n,r,s){return m=0,t=t||"j",i(e)?a("c"==t?E:w,e,t,this.i++,n,r,s):(v.splice(this.i++,0,e),1==v.length&&u()),this}function l(){var e=k;return e.loader={load:f,i:0},e}var c=t.documentElement,h=e.setTimeout,p=t.getElementsByTagName("script")[0],d={}.toString,v=[],m=0,g="MozAppearance"in c.style,y=g&&!!t.createRange().compareNode,b=y?c:p.parentNode,c=e.opera&&"[object Opera]"==d.call(e.opera),c=!!t.attachEvent&&!c,w=g?"object":c?"script":"img",E=c?"script":w,S=Array.isArray||function(e){return"[object Array]"==d.call(e)},x=[],T={},N={timeout:function(e,t){return t.length&&(e.timeout=t[0]),e}},C,k;k=function(e){function t(e){var e=e.split("!"),t=x.length,n=e.pop(),r=e.length,n={url:n,origUrl:n,prefixes:e},i,s,o;for(s=0;s<r;s++)o=e[s].split("="),(i=N[o.shift()])&&(n=i(n,o));for(s=0;s<t;s++)n=x[s](n);return n}function o(e,i,s,o,u){var a=t(e),f=a.autoCallback;a.url.split(".").pop().split("?").shift(),a.bypass||(i&&(i=r(i)?i:i[e]||i[o]||i[e.split("/").pop().split("?")[0]]),a.instead?a.instead(e,i,s,o,u):(T[a.url]?a.noexec=!0:T[a.url]=1,s.load(a.url,a.forceCSS||!a.forceJS&&"css"==a.url.split(".").pop().split("?").shift()?"c":n,a.noexec,a.attrs,a.timeout),(r(i)||r(f))&&s.load(function(){l(),i&&i(a.origUrl,u,o),f&&f(a.origUrl,u,o),T[a.url]=2})))}function u(e,t){function n(e,n){if(e){if(i(e))n||(f=function(){var e=[].slice.call(arguments);l.apply(this,e),c()}),o(e,f,t,0,u);else if(Object(e)===e)for(p in h=function(){var t=0,n;for(n in e)e.hasOwnProperty(n)&&t++;return t}(),e)e.hasOwnProperty(p)&&(!n&&!--h&&(r(f)?f=function(){var e=[].slice.call(arguments);l.apply(this,e),c()}:f[p]=function(e){return function(){var t=[].slice.call(arguments);e&&e.apply(this,t),c()}}(l[p])),o(e[p],f,t,p,u))}else!n&&c()}var u=!!e.test,a=e.load||e.both,f=e.callback||s,l=f,c=e.complete||s,h,p;n(u?e.yep:e.nope,!!a),a&&n(a)}var a,f,c=this.yepnope.loader;if(i(e))o(e,0,c,0);else if(S(e))for(a=0;a<e.length;a++)f=e[a],i(f)?o(f,0,c,0):S(f)?k(f):Object(f)===f&&u(f,c);else Object(e)===e&&u(e,c)}
4,k.addPrefix=function(e,t){N[e]=t},k.addFilter=function(e){x.push(e)},k.errorTimeout=1e4,null==t.readyState&&t.addEventListener&&(t.readyState="loading",t.addEventListener("DOMContentLoaded",C=function(){t.removeEventListener("DOMContentLoaded",C,0),t.readyState="complete"},0)),e.yepnope=l(),e.yepnope.executeStack=u,e.yepnope.injectJs=function(e,n,r,i,a,f){var l=t.createElement("script"),c,d,i=i||k.errorTimeout;l.src=e;for(d in r)l.setAttribute(d,r[d]);n=f?u:n||s,l.onreadystatechange=l.onload=function(){!c&&o(l.readyState)&&(c=1,n(),l.onload=l.onreadystatechange=null)},h(function(){c||(c=1,n(1))},i),a?l.onload():p.parentNode.insertBefore(l,p)},e.yepnope.injectCss=function(e,n,r,i,o,a){var i=t.createElement("link"),f,n=a?u:n||s;i.href=e,i.rel="stylesheet",i.type="text/css";for(f in r)i.setAttribute(f,r[f]);o||(p.parentNode.insertBefore(i,p),h(n,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))}; 5;/*})'"*/ 6;/*})'"*/ 7/* 8 * jQuery.appear 9 * https://github.com/bas2k/jquery.appear/ 10 * http://code.google.com/p/jquery-appear/ 11 * http://bas2k.ru/ 12 * 13 * Copyright (c) 2009 Michael Hixson 14 * Copyright (c) 2012-2014 Alexander Brovikov 15 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) 16 */ 17(function($) { 18 $.fn.appear = function(fn, options) { 19 20 var settings = $.extend({ 21 22 //arbitrary data to pass to fn 23 data: undefined, 24 25 //call fn only on the first appear? 26 one: true, 27 28 // X & Y accuracy 29 accX: 0, 30 accY: 0 31 32 }, options); 33 34 return this.each(function() { 35 36 var t = $(this); 37 38 //whether the element is currently visible 39 t.appeared = false; 40 41 if (!fn) { 42 43 //trigger the custom event 44 t.trigger('appear', settings.data); 45 return; 46 } 47 48 var w = $(window); 49 50 //fires the appear event when appropriate 51 var check = function() { 52 53 //is the element hidden? 54 if (!t.is(':visible')) { 55 56 //it became hidden 57 t.appeared = false; 58 return; 59 } 60 61 //is the element inside the visible window? 62 var a = w.scrollLeft(); 63 var b = w.scrollTop(); 64 var o = t.offset(); 65 var x = o.left; 66 var y = o.top; 67 68 var ax = settings.accX; 69 var ay = settings.accY; 70 var th = t.height(); 71 var wh = w.height(); 72 var tw = t.width(); 73 var ww = w.width(); 74 75 if (y + th + ay >= b && 76 y <= b + wh + ay && 77 x + tw + ax >= a && 78 x <= a + ww + ax) { 79 80 //trigger the custom event 81 if (!t.appeared) t.trigger('appear', settings.data); 82 83 } else { 84 85 //it scrolled out of view 86 t.appeared = false; 87 } 88 }; 89 90 //create a modified fn with some additional logic 91 var modifiedFn = function() { 92 93 //mark the element as visible 94 t.appeared = true; 95 96 //is this supposed to happen only once? 97 if (settings.one) { 98 99 //remove the check 100 w.unbind('scroll', check); 101 var i = $.inArray(check, $.fn.appear.checks); 102 if (i >= 0) $.fn.appear.checks.splice(i, 1); 103 } 104 105 //trigger the original fn 106 fn.apply(this, arguments); 107 }; 108 109 //bind the modified fn to the element 110 if (settings.one) t.one('appear', settings.data, modifiedFn); 111 else t.bind('appear', settings.data, modifiedFn); 112 113 //check whenever the window scrolls 114 w.scroll(check); 115 116 //check whenever the dom changes 117 $.fn.appear.checks.push(check); 118 119 //check now 120 (check)(); 121 }); 122 }; 123 124 //keep a queue of appearance checks 125 $.extend($.fn.appear, { 126 127 checks: [], 128 timeout: null, 129 130 //process the queue 131 checkAll: function() { 132 var length = $.fn.appear.checks.length; 133 if (length >
133 0) while (length--) ($.fn.appear.checks[length])(); 134 }, 135 136 //check the queue asynchronously 137 run: function() { 138 if ($.fn.appear.timeout) clearTimeout($.fn.appear.timeout); 139 $.fn.appear.timeout = setTimeout($.fn.appear.checkAll, 20); 140 } 141 }); 142 143 //run checks when these methods are called 144 $.each(['append', 'prepend', 'after', 'before', 'attr', 145 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 146 'remove', 'css', 'show', 'hide'], function(i, n) { 147 var old = $.fn[n]; 148 if (old) { 149 $.fn[n] = function() { 150 var r = old.apply(this, arguments); 151 $.fn.appear.run(); 152 return r; 153 } 154 } 155 }); 156 157})(jQuery); 158 159;/*})'"*/ 160;/*})'"*/ 161/* 162 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 163 * 164 * Uses the built in easing capabilities added In jQuery 1.1 165 * to offer multiple easing options 166 * 167 * TERMS OF USE - jQuery Easing 168 * 169 * Open source under the BSD License. 170 * 171 * Copyright © 2008 George McGinley Smith 172 * All rights reserved. 173 * 174 * Redistribution and use in source and binary forms, with or without modification, 175 * are permitted provided that the following conditions are met: 176 * 177 * Redistributions of source code must retain the above copyright notice, this list of 178 * conditions and the following disclaimer. 179 * Redistributions in binary form must reproduce the above copyright notice, this list 180 * of conditions and the following disclaimer in the documentation and/or other materials 181 * provided with the distribution. 182 * 183 * Neither the name of the author nor the names of contributors may be used to endorse 184 * or promote products derived from this software without specific prior written permission. 185 * 186 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 187 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 188 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 189 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 190 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 191 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 192 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 193 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 194 * OF THE POSSIBILITY OF SUCH DAMAGE. 195 * 196*/ 197 198// t: current time, b: begInnIng value, c: change In value, d: duration 199jQuery.easing['jswing'] = jQuery.easing['swing']; 200 201jQuery.extend( jQuery.easing, 202{ 203 def: 'easeOutQuad', 204 swing: function (x, t, b, c, d) { 205 //alert(jQuery.easing.default); 206 return jQuery.easing[jQuery.easing.def](x, t, b, c, d); 207 }, 208 easeInQuad: function (x, t, b, c, d) { 209 return c*(t/=d)*t + b; 210 }, 211 easeOutQuad: function (x, t, b, c, d) { 212 return -c *(t/=d)*(t-2) + b; 213 }, 214 easeInOutQuad: function (x, t, b, c, d) { 215 if ((t/=d/2) < 1) return c/2*t*t + b; 216 return -c/2 * ((--t)*(t-2) - 1) + b; 217 }, 218 easeInCubic: function (x, t, b, c, d) { 219 return c*(t/=d)*t*t + b; 220 }, 221 easeOutCubic: function (x, t, b, c, d) { 222 return c*((t=t/d-1)*t*t + 1) + b; 223 }, 224 easeInOutCubic: function (x, t, b, c, d) { 225 if ((t/=d/2) < 1) return c/2*t*t*t + b; 226 return c/2*((t-=2)*t*t + 2) + b; 227 }, 228 easeInQuart: function (x, t, b, c, d) { 229 return c*(t/=d)*t*t*t + b; 230 }, 231 easeOutQuart: function (x, t, b, c, d) { 232 return -c * ((t=t/d-1)*t*t*t - 1) + b; 233 }, 234 easeInOutQuart: function (x, t, b, c, d) { 235 if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 236 return -c/2 * ((t-=2)*t*t*t - 2) + b; 237 }, 238 easeInQuint: function (x, t, b, c, d) { 239 return c*(t/=d)*t*t*t*t + b; 240 }, 241 easeOutQuint: function (x, t, b, c, d) { 242 return c*((t=t/d-1)*t*t*t*t + 1) + b; 243 }, 244 easeInOutQuint: function (x, t, b, c, d) { 245 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 246 return c/2*((t-=2)*t*t*t*t + 2) + b; 247 }, 248 easeInSine: function (x, t, b, c, d) { 249 return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 250 }, 251 easeOutSine: function (x, t, b, c, d) { 252 return c * Math.sin(t/d * (Math.PI/2)) + b; 253 }, 254 easeInOutSine: function (x, t, b, c, d) {
vendor: 4,186 bytes, lines 255-358
255 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 256 }, 257 easeInExpo: function (x, t, b, c, d) { 258 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 259 }, 260 easeOutExpo: function (x, t, b, c, d) { 261 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 262 }, 263 easeInOutExpo: function (x, t, b, c, d) { 264 if (t==0) return b; 265 if (t==d) return b+c; 266 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 267 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 268 }, 269 easeInCirc: function (x, t, b, c, d) { 270 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 271 }, 272 easeOutCirc: function (x, t, b, c, d) { 273 return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 274 }, 275 easeInOutCirc: function (x, t, b, c, d) { 276 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 277 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 278 }, 279 easeInElastic: function (x, t, b, c, d) { 280 var s=1.70158;var p=0;var a=c; 281 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 282 if (a < Math.abs(c)) { a=c; var s=p/4; } 283 else var s = p/(2*Math.PI) * Math.asin (c/a); 284 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 285 }, 286 easeOutElastic: function (x, t, b, c, d) { 287 var s=1.70158;var p=0;var a=c; 288 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 289 if (a < Math.abs(c)) { a=c; var s=p/4; } 290 else var s = p/(2*Math.PI) * Math.asin (c/a); 291 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 292 }, 293 easeInOutElastic: function (x, t, b, c, d) { 294 var s=1.70158;var p=0;var a=c; 295 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 296 if (a < Math.abs(c)) { a=c; var s=p/4; } 297 else var s = p/(2*Math.PI) * Math.asin (c/a); 298 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 299 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 300 }, 301 easeInBack: function (x, t, b, c, d, s) { 302 if (s == undefined) s = 1.70158; 303 return c*(t/=d)*t*((s+1)*t - s) + b; 304 }, 305 easeOutBack: function (x, t, b, c, d, s) { 306 if (s == undefined) s = 1.70158; 307 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 308 }, 309 easeInOutBack: function (x, t, b, c, d, s) { 310 if (s == undefined) s = 1.70158; 311 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 312 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 313 }, 314 easeInBounce: function (x, t, b, c, d) { 315 return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; 316 }, 317 easeOutBounce: function (x, t, b, c, d) { 318 if ((t/=d) < (1/2.75)) { 319 return c*(7.5625*t*t) + b; 320 } else if (t < (2/2.75)) { 321 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 322 } else if (t < (2.5/2.75)) { 323 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 324 } else { 325 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 326 } 327 }, 328 easeInOutBounce: function (x, t, b, c, d) { 329 if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; 330 return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; 331 } 332}); 333 334/* 335 * 336 * TERMS OF USE - EASING EQUATIONS 337 * 338 * Open source under the BSD License. 339 * 340 * Copyright © 2001 Robert Penner 341 * All rights reserved. 342 * 343 * Redistribution and use in source and binary forms, with or without modification, 344 * are permitted provided that the following conditions are met: 345 * 346 * Redistributions of source code must retain the above copyright notice, this list of 347 * conditions and the following disclaimer. 348 * Redistributions in binary form must reproduce the above copyright notice, this list 349 * of conditions and the following disclaimer in the documentation and/or other materials 350 * provided with the distribution. 351 * 352 * Neither the name of the author nor the names of contributors may be used to endorse 353 * or promote products derived from this software without specific prior written permission. 354 * 355 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 356 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 357 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 358 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
359 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 360 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 361 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 362 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 363 * OF THE POSSIBILITY OF SUCH DAMAGE. 364 * 365 */ 366;/*})'"*/ 367;/*})'"*/ 368/*! 369 * jQuery Cookie Plugin v1.4.1 370 * https://github.com/carhartl/jquery-cookie 371 * 372 * Copyright 2013 Klaus Hartl 373 * Released under the MIT license 374 */ 375(function (factory) { 376 if (typeof define === 'function' && define.amd) { 377 // AMD 378 define(['jquery'], factory); 379 } else if (typeof exports === 'object') { 380 // CommonJS 381 factory(require('jquery')); 382 } else { 383 // Browser globals 384 factory(jQuery); 385 } 386}(function ($) { 387 388 var pluses = /\+/g; 389 390 function encode(s) { 391 return config.raw ? s : encodeURIComponent(s); 392 } 393 394 function decode(s) { 395 return config.raw ? s : decodeURIComponent(s); 396 } 397 398 function stringifyCookieValue(value) { 399 return encode(config.json ? JSON.stringify(value) : String(value)); 400 } 401 402 function parseCookieValue(s) { 403 if (s.indexOf('"') === 0) { 404 // This is a quoted cookie as according to RFC2068, unescape... 405 s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 406 } 407 408 try { 409 // Replace server-side written pluses with spaces. 410 // If we can't decode the cookie, ignore it, it's unusable. 411 // If we can't parse the cookie, ignore it, it's unusable. 412 s = decodeURIComponent(s.replace(pluses, ' ')); 413 return config.json ? JSON.parse(s) : s; 414 } catch(e) {} 415 } 416 417 function read(s, converter) { 418 var value = config.raw ? s : parseCookieValue(s); 419 return $.isFunction(converter) ? converter(value) : value; 420 } 421 422 var config = $.cookie = function (key, value, options) { 423 424 // Write 425 426 if (value !== undefined && !$.isFunction(value)) { 427 options = $.extend({}, config.defaults, options); 428 429 if (typeof options.expires === 'number') { 430 var days = options.expires, t = options.expires = new Date(); 431 t.setTime(+t + days * 864e+5); 432 } 433 434 return (document.cookie = [ 435 encode(key), '=', stringifyCookieValue(value), 436 options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 437 options.path ? '; path=' + options.path : '', 438 options.domain ? '; domain=' + options.domain : '', 439 options.secure ? '; secure' : '' 440 ].join('')); 441 } 442 443 // Read 444 445 var result = key ? undefined : {}; 446 447 // To prevent the for loop in the first place assign an empty array 448 // in case there are no cookies at all. Also prevents odd result when 449 // calling $.cookie(). 450 var cookies = document.cookie ? document.cookie.split('; ') : []; 451 452 for (var i = 0, l = cookies.length; i < l; i++) { 453 var parts = cookies[i].split('='); 454 var name = decode(parts.shift()); 455 var cookie = parts.join('='); 456 457 if (key && key === name) { 458 // If second argument (value) is a function it's a converter... 459 result = read(cookie, value); 460 break; 461 } 462 463 // Prevent storing a cookie that we couldn't decode. 464 if (!key && (cookie = read(cookie)) !== undefined) { 465 result[name] = cookie; 466 } 467 } 468 469 return result; 470 }; 471 472 config.defaults = {}; 473 474 $.removeCookie = function (key, options) { 475 if ($.cookie(key) === undefined) { 476 return false; 477 } 478 479 // Must not alter options, thus extending a fresh object... 480 $.cookie(key, '', $.extend({}, options, { expires: -1 })); 481 return !$.cookie(key); 482 }; 483 484})); 485 486;/*})'"*/ 487;/*})'"*/ 488/*! 489 * Bootstrap v3.3.5 (http://getbootstrap.com) 490 * Copyright 2011-2015 Twitter, Inc. 491 * Licensed under the MIT license 492 */ 493 494if (typeof jQuery === 'undefined') { 495 throw new Error('Bootstrap\'s JavaScript requires jQuery') 496} 497 498+function ($) { 499 'use strict'; 500 var version = $.fn.jquery.split(' ')[0].split('.') 501 if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { 502 throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') 503 } 504}(jQuery); 505 506/* ======================================================================== 507 * Bootstrap: transition.js v3.3.5 508 * http://getbootstrap.com/javascript/#transitions 509 * ======================================================================== 510 * Copyright 2011-2015 Twitter, Inc. 511 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 512 * ======================================================================== */ 513 514 515+function ($) { 516 'use strict'; 517
vendor: 66,125 bytes, lines 518-2774
518 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 519 // ============================================================ 520 521 function transitionEnd() { 522 var el = document.createElement('bootstrap') 523 524 var transEndEventNames = { 525 WebkitTransition : 'webkitTransitionEnd', 526 MozTransition : 'transitionend', 527 OTransition : 'oTransitionEnd otransitionend', 528 transition : 'transitionend' 529 } 530 531 for (var name in transEndEventNames) { 532 if (el.style[name] !== undefined) { 533 return { end: transEndEventNames[name] } 534 } 535 } 536 537 return false // explicit for ie8 ( ._.) 538 } 539 540 // http://blog.alexmaccaw.com/css-transitions 541 $.fn.emulateTransitionEnd = function (duration) { 542 var called = false 543 var $el = this 544 $(this).one('bsTransitionEnd', function () { called = true }) 545 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 546 setTimeout(callback, duration) 547 return this 548 } 549 550 $(function () { 551 $.support.transition = transitionEnd() 552 553 if (!$.support.transition) return 554 555 $.event.special.bsTransitionEnd = { 556 bindType: $.support.transition.end, 557 delegateType: $.support.transition.end, 558 handle: function (e) { 559 if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 560 } 561 } 562 }) 563 564}(jQuery); 565 566/* ======================================================================== 567 * Bootstrap: alert.js v3.3.5 568 * http://getbootstrap.com/javascript/#alerts 569 * ======================================================================== 570 * Copyright 2011-2015 Twitter, Inc. 571 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 572 * ======================================================================== */ 573 574 575+function ($) { 576 'use strict'; 577 578 // ALERT CLASS DEFINITION 579 // ====================== 580 581 var dismiss = '[data-dismiss="alert"]' 582 var Alert = function (el) { 583 $(el).on('click', dismiss, this.close) 584 } 585 586 Alert.VERSION = '3.3.5' 587 588 Alert.TRANSITION_DURATION = 150 589 590 Alert.prototype.close = function (e) { 591 var $this = $(this) 592 var selector = $this.attr('data-target') 593 594 if (!selector) { 595 selector = $this.attr('href') 596 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 597 } 598 599 var $parent = $(selector) 600 601 if (e) e.preventDefault() 602 603 if (!$parent.length) { 604 $parent = $this.closest('.alert') 605 } 606 607 $parent.trigger(e = $.Event('close.bs.alert')) 608 609 if (e.isDefaultPrevented()) return 610 611 $parent.removeClass('in') 612 613 function removeElement() { 614 // detach from parent, fire event then clean up data 615 $parent.detach().trigger('closed.bs.alert').remove() 616 } 617 618 $.support.transition && $parent.hasClass('fade') ? 619 $parent 620 .one('bsTransitionEnd', removeElement) 621 .emulateTransitionEnd(Alert.TRANSITION_DURATION) : 622 removeElement() 623 } 624 625 626 // ALERT PLUGIN DEFINITION 627 // ======================= 628 629 function Plugin(option) { 630 return this.each(function () { 631 var $this = $(this) 632 var data = $this.data('bs.alert') 633 634 if (!data) $this.data('bs.alert', (data = new Alert(this))) 635 if (typeof option == 'string') data[option].call($this) 636 }) 637 } 638 639 var old = $.fn.alert 640 641 $.fn.alert = Plugin 642 $.fn.alert.Constructor = Alert 643 644 645 // ALERT NO CONFLICT 646 // ================= 647 648 $.fn.alert.noConflict = function () { 649 $.fn.alert = old 650 return this 651 } 652 653 654 // ALERT DATA-API 655 // ============== 656 657 $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 658 659}(jQuery); 660 661/* ======================================================================== 662 * Bootstrap: button.js v3.3.5 663 * http://getbootstrap.com/javascript/#buttons 664 * ======================================================================== 665 * Copyright 2011-2015 Twitter, Inc. 666 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 667 * ======================================================================== */ 668 669 670+function ($) { 671 'use strict'; 672 673 // BUTTON PUBLIC CLASS DEFINITION 674 // ============================== 675 676 var Button = function (element, options) { 677 this.$element = $(element) 678 this.options = $.extend({}, Button.DEFAULTS, options) 679 this.isLoading = false 680 } 681 682 Button.VERSION = '3.3.5' 683 684 Button.DEFAULTS = { 685 loadingText: 'loading...' 686 } 687 688 Button.prototype.setState = function (state) { 689 var d = 'disabled' 690 var $el = this.$element 691 var val = $el.is('input') ? 'val' : 'html' 692 var data = $el.data() 693 694 state += 'Text' 695 696 if (data.resetText == null) $el.data('resetText', $el[val]()) 697 698 // push to event loop to allow forms to submit 699 setTimeout($.proxy(function () { 700 $el[val](data[state] == null ? this.options[state] : data[state]) 701 702 if (state == 'loadingText') { 703 this.isLoading = true 704 $el.addClass(d).attr(d, d) 705 } else if (this.isLoading) { 706 this.isLoading = false 707 $el.removeClass(d).removeAttr(d) 708 } 709 }, this), 0) 710 } 711 712 Button.prototype.toggle = function () { 713 var changed = true 714 var $parent = this.$element.closest('[data-toggle="buttons"]') 715 716 if ($parent.length) { 717 var $input = this.$element.find('input') 718 if ($input.prop('type') == 'radio') { 719 if ($input.prop('checked')) changed = false 720 $parent.find('.active').removeClass('active') 721 this.$element.addClass('active') 722 } else if ($input.prop('type') == 'checkbox') { 723 if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false 724 this.$element.toggleClass('active') 725 } 726 $input.prop('checked', this.$element.hasClass('active')) 727 if (changed) $input.trigger('change') 728 } else { 729 this.$element.attr('aria-pressed', !this.$element.hasClass('active')) 730 this.$element.toggleClass('active') 731 } 732 } 733 734 735 // BUTTON PLUGIN DEFINITION 736 // ======================== 737 738 function Plugin(option) { 739 return this.each(function () { 740 var $this = $(this) 741 var data = $this.data('bs.button') 742 var options = typeof option == 'object' && option 743 744 if (!data) $this.data('bs.button', (data = new Button(this, options))) 745 746 if (option == 'toggle') data.toggle() 747 else if (option) data.setState(option) 748 }) 749 } 750 751 var old = $.fn.button 752 753 $.fn.button = Plugin 754 $.fn.button.Constructor = Button 755 756 757 // BUTTON NO CONFLICT 758 // ================== 759 760 $.fn.button.noConflict = function () { 761 $.fn.button = old 762 return this 763 } 764 765 766 // BUTTON DATA-API 767 // =============== 768 769 $(document) 770 .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 771 var $btn = $(e.target) 772 if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 773 Plugin.call($btn, 'toggle') 774 if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault() 775 }) 776 .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { 777 $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) 778 }) 779 780}(jQuery); 781 782/* ======================================================================== 783 * Bootstrap: carousel.js v3.3.5 784 * http://getbootstrap.com/javascript/#carousel 785 * ======================================================================== 786 * Copyright 2011-2015 Twitter, Inc. 787 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 788 * ======================================================================== */ 789 790 791+function ($) { 792 'use strict'; 793 794 // CAROUSEL CLASS DEFINITION 795 // ========================= 796 797 var Carousel = function (element, options) { 798 this.$element = $(element) 799 this.$indicators = this.$element.find('.carousel-indicators') 800 this.options = options 801 this.paused = null 802 this.sliding = null 803 this.interval = null 804 this.$active = null 805 this.$items = null 806 807 this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) 808 809 this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element 810 .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) 811 .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) 812 } 813 814 Carousel.VERSION = '3.3.5' 815 816 Carousel.TRANSITION_DURATION = 600 817 818 Carousel.DEFAULTS = { 819 interval: 5000, 820 pause: 'hover', 821 wrap: true, 822 keyboard: true 823 } 824 825 Carousel.prototype.keydown = function (e) { 826 if (/input|textarea/i.test(e.target.tagName)) return 827 switch (e.which) { 828 case 37: this.prev(); break 829 case 39: this.next(); break 830 default: return 831 } 832 833 e.preventDefault() 834 } 835 836 Carousel.prototype.cycle = function (e) { 837 e || (this.paused = false) 838 839 this.interval && clearInterval(this.interval) 840 841 this.options.interval 842 && !this.paused 843 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 844 845 return this 846 } 847 848 Carousel.prototype.getItemIndex = function (item) { 849 this.$items = item.parent().children('.item') 850 return this.$items.index(item || this.$active) 851 } 852 853 Carousel.prototype.getItemForDirection = function (direction, active) { 854 var activeIndex = this.getItemIndex(active) 855 var willWrap = (direction == 'prev' && activeIndex === 0) 856 || (direction == 'next' && activeIndex == (this.$items.length - 1)) 857 if (willWrap && !this.options.wrap) return active 858 var delta = direction == 'prev' ? -1 : 1 859 var itemIndex = (activeIndex + delta) % this.$items.length 860 return this.$items.eq(itemIndex) 861 } 862 863 Carousel.prototype.to = function (pos) { 864 var that = this 865 var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) 866 867 if (pos > (this.$items.length - 1) || pos < 0) return 868 869 if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" 870 if (activeIndex == pos) return this.pause().cycle() 871 872 return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) 873 } 874 875 Carousel.prototype.pause = function (e) { 876 e || (this.paused = true) 877 878 if (this.$element.find('.next, .prev').length && $.support.transition) { 879 this.$element.trigger($.support.transition.end) 880 this.cycle(true) 881 } 882 883 this.interval = clearInterval(this.interval) 884 885 return this 886 } 887 888 Carousel.prototype.next = function () { 889 if (this.sliding) return 890 return this.slide('next') 891 } 892 893 Carousel.prototype.prev = function () { 894 if (this.sliding) return 895 return this.slide('prev') 896 } 897 898 Carousel.prototype.slide = function (type, next) { 899 var $active = this.$element.find('.item.active') 900 var $next = next || this.getItemForDirection(type, $active) 901 var isCycling = this.interval 902 var direction = type == 'next' ? 'left' : 'right' 903 var that = this 904 905 if ($next.hasClass('active')) return (this.sliding = false) 906 907 var relatedTarget = $next[0] 908 var slideEvent = $.Event('slide.bs.carousel', { 909 relatedTarget: relatedTarget, 910 direction: direction 911 }) 912 this.$element.trigger(slideEvent) 913 if (slideEvent.isDefaultPrevented()) return 914 915 this.sliding = true 916 917 isCycling && this.pause() 918 919 if (this.$indicators.length) { 920 this.$indicators.find('.active').removeClass('active') 921 var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) 922 $nextIndicator && $nextIndicator.addClass('active') 923 } 924 925 var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" 926 if ($.support.transition && this.$element.hasClass('slide')) { 927 $next.addClass(type) 928 $next[0].offsetWidth // force reflow 929 $active.addClass(direction) 930 $next.addClass(direction) 931 $active 932 .one('bsTransitionEnd', function () { 933 $next.removeClass([type, direction].join(' ')).addClass('active') 934 $active.removeClass(['active', direction].join(' ')) 935 that.sliding = false 936 setTimeout(function () { 937 that.$element.trigger(slidEvent) 938 }, 0) 939 }) 940 .emulateTransitionEnd(Carousel.TRANSITION_DURATION) 941 } else { 942 $active.removeClass('active') 943 $next.addClass('active') 944 this.sliding = false 945 this.$element.trigger(slidEvent) 946 } 947 948 isCycling && this.cycle() 949 950 return this 951 } 952 953 954 // CAROUSEL PLUGIN DEFINITION 955 // ========================== 956 957 function Plugin(option) { 958 return this.each(function () { 959 var $this = $(this) 960 var data = $this.data('bs.carousel') 961 var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) 962 var action = typeof option == 'string' ? option : options.slide 963 964 if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) 965 if (typeof option == 'number') data.to(option) 966 else if (action) data[action]() 967 else if (options.interval) data.pause().cycle() 968 }) 969 } 970 971 var old = $.fn.carousel 972 973 $.fn.carousel = Plugin 974 $.fn.carousel.Constructor = Carousel 975 976 977 // CAROUSEL NO CONFLICT 978 // ==================== 979 980 $.fn.carousel.noConflict = function () { 981 $.fn.carousel = old 982 return this 983 } 984 985 986 // CAROUSEL DATA-API 987 // ================= 988 989 var clickHandler = function (e) { 990 var href 991 var $this = $(this) 992 var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 993 if (!$target.hasClass('carousel')) return 994 var options = $.extend({}, $target.data(), $this.data()) 995 var slideIndex = $this.attr('data-slide-to') 996 if (slideIndex) options.interval = false 997 998 Plugin.call($target, options) 999 1000 if (slideIndex) { 1001 $target.data('bs.carousel').to(slideIndex) 1002 } 1003 1004 e.preventDefault() 1005 } 1006 1007 $(document) 1008 .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) 1009 .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) 1010 1011 $(window).on('load', function () { 1012 $('[data-ride="carousel"]').each(function () { 1013 var $carousel = $(this) 1014 Plugin.call($carousel, $carousel.data()) 1015 }) 1016 }) 1017 1018}(jQuery); 1019 1020/* ======================================================================== 1021 * Bootstrap: collapse.js v3.3.5 1022 * http://getbootstrap.com/javascript/#collapse 1023 * ======================================================================== 1024 * Copyright 2011-2015 Twitter, Inc. 1025 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1026 * ======================================================================== */ 1027 1028 1029+function ($) { 1030 'use strict'; 1031 1032 // COLLAPSE PUBLIC CLASS DEFINITION 1033 // ================================ 1034 1035 var Collapse = function (element, options) { 1036 this.$element = $(element) 1037 this.options = $.extend({}, Collapse.DEFAULTS, options) 1038 this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + 1039 '[data-toggle="collapse"][data-target="#' + element.id + '"]') 1040 this.transitioning = null 1041 1042 if (this.options.parent) { 1043 this.$parent = this.getParent() 1044 } else { 1045 this.addAriaAndCollapsedClass(this.$element, this.$trigger) 1046 } 1047 1048 if (this.options.toggle) this.toggle() 1049 } 1050 1051 Collapse.VERSION = '3.3.5' 1052 1053 Collapse.TRANSITION_DURATION = 350 1054 1055 Collapse.DEFAULTS = { 1056 toggle: true 1057 } 1058 1059 Collapse.prototype.dimension = function () { 1060 var hasWidth = this.$element.hasClass('width') 1061 return hasWidth ? 'width' : 'height' 1062 } 1063 1064 Collapse.prototype.show = function () { 1065 if (this.transitioning || this.$element.hasClass('in')) return 1066 1067 var activesData 1068 var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') 1069 1070 if (actives && actives.length) { 1071 activesData = actives.data('bs.collapse') 1072 if (activesData && activesData.transitioning) return 1073 } 1074 1075 var startEvent = $.Event('show.bs.collapse') 1076 this.$element.trigger(startEvent) 1077 if (startEvent.isDefaultPrevented()) return 1078 1079 if (actives && actives.length) { 1080 Plugin.call(actives, 'hide') 1081 activesData || actives.data('bs.collapse', null) 1082 } 1083 1084 var dimension = this.dimension() 1085 1086 this.$element 1087 .removeClass('collapse') 1088 .addClass('collapsing')[dimension](0) 1089 .attr('aria-expanded', true) 1090 1091 this.$trigger 1092 .removeClass('collapsed') 1093 .attr('aria-expanded', true) 1094 1095 this.transitioning = 1 1096 1097 var complete = function () { 1098 this.$element 1099 .removeClass('collapsing') 1100 .addClass('collapse in')[dimension]('') 1101 this.transitioning = 0 1102 this.$element 1103 .trigger('shown.bs.collapse') 1104 } 1105 1106 if (!$.support.transition) return complete.call(this) 1107 1108 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 1109 1110 this.$element 1111 .one('bsTransitionEnd', $.proxy(complete, this)) 1112 .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) 1113 } 1114 1115 Collapse.prototype.hide = function () { 1116 if (this.transitioning || !this.$element.hasClass('in')) return 1117 1118 var startEvent = $.Event('hide.bs.collapse') 1119 this.$element.trigger(startEvent) 1120 if (startEvent.isDefaultPrevented()) return 1121 1122 var dimension = this.dimension() 1123 1124 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 1125 1126 this.$element 1127 .addClass('collapsing') 1128 .removeClass('collapse in') 1129 .attr('aria-expanded', false) 1130 1131 this.$trigger 1132 .addClass('collapsed') 1133 .attr('aria-expanded', false) 1134 1135 this.transitioning = 1 1136 1137 var complete = function () { 1138 this.transitioning = 0 1139 this.$element 1140 .removeClass('collapsing') 1141 .addClass('collapse') 1142 .trigger('hidden.bs.collapse') 1143 } 1144 1145 if (!$.support.transition) return complete.call(this) 1146 1147 this.$element 1148 [dimension](0) 1149 .one('bsTransitionEnd', $.proxy(complete, this)) 1150 .emulateTransitionEnd(Collapse.TRANSITION_DURATION) 1151 } 1152 1153 Collapse.prototype.toggle = function () { 1154 this[this.$element.hasClass('in') ? 'hide' : 'show']() 1155 } 1156 1157 Collapse.prototype.getParent = function () { 1158 return $(this.options.parent) 1159 .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') 1160 .each($.proxy(function (i, element) { 1161 var $element = $(element) 1162 this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) 1163 }, this)) 1164 .end() 1165 } 1166 1167 Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { 1168 var isOpen = $element.hasClass('in') 1169 1170 $element.attr('aria-expanded', isOpen) 1171 $trigger 1172 .toggleClass('collapsed', !isOpen) 1173 .attr('aria-expanded', isOpen) 1174 } 1175 1176 function getTargetFromTrigger($trigger) { 1177 var href 1178 var target = $trigger.attr('data-target') 1179 || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 1180 1181 return $(target) 1182 } 1183 1184 1185 // COLLAPSE PLUGIN DEFINITION 1186 // ========================== 1187 1188 function Plugin(option) { 1189 return this.each(function () { 1190 var $this = $(this) 1191 var data = $this.data('bs.collapse') 1192 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 1193 1194 if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false 1195 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 1196 if (typeof option == 'string') data[option]() 1197 }) 1198 } 1199 1200 var old = $.fn.collapse 1201 1202 $.fn.collapse = Plugin 1203 $.fn.collapse.Constructor = Collapse 1204 1205 1206 // COLLAPSE NO CONFLICT 1207 // ==================== 1208 1209 $.fn.collapse.noConflict = function () { 1210 $.fn.collapse = old 1211 return this 1212 } 1213 1214 1215 // COLLAPSE DATA-API 1216 // ================= 1217 1218 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 1219 var $this = $(this) 1220 1221 if (!$this.attr('data-target')) e.preventDefault() 1222 1223 var $target = getTargetFromTrigger($this) 1224 var data = $target.data('bs.collapse') 1225 var option = data ? 'toggle' : $this.data() 1226 1227 Plugin.call($target, option) 1228 }) 1229 1230}(jQuery); 1231 1232/* ======================================================================== 1233 * Bootstrap: dropdown.js v3.3.5 1234 * http://getbootstrap.com/javascript/#dropdowns 1235 * ======================================================================== 1236 * Copyright 2011-2015 Twitter, Inc. 1237 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1238 * ======================================================================== */ 1239 1240 1241+function ($) { 1242 'use strict'; 1243 1244 // DROPDOWN CLASS DEFINITION 1245 // ========================= 1246 1247 var backdrop = '.dropdown-backdrop' 1248 var toggle = '[data-toggle="dropdown"]' 1249 var Dropdown = function (element) { 1250 $(element).on('click.bs.dropdown', this.toggle) 1251 } 1252 1253 Dropdown.VERSION = '3.3.5' 1254 1255 function getParent($this) { 1256 var selector = $this.attr('data-target') 1257 1258 if (!selector) { 1259 selector = $this.attr('href') 1260 selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 1261 } 1262 1263 var $parent = selector && $(selector) 1264 1265 return $parent && $parent.length ? $parent : $this.parent() 1266 } 1267 1268 function clearMenus(e) { 1269 if (e && e.which === 3) return 1270 $(backdrop).remove() 1271 $(toggle).each(function () { 1272 var $this = $(this) 1273 var $parent = getParent($this) 1274 var relatedTarget = { relatedTarget: this } 1275 1276 if (!$parent.hasClass('open')) return 1277 1278 if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return 1279 1280 $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) 1281 1282 if (e.isDefaultPrevented()) return 1283 1284 $this.attr('aria-expanded', 'false') 1285 $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) 1286 }) 1287 } 1288 1289 Dropdown.prototype.toggle = function (e) { 1290 var $this = $(this) 1291 1292 if ($this.is('.disabled, :disabled')) return 1293 1294 var $parent = getParent($this) 1295 var isActive = $parent.hasClass('open') 1296 1297 clearMenus() 1298 1299 if (!isActive) { 1300 if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 1301 // if mobile we use a backdrop because click events don't delegate 1302 $(document.createElement('div')) 1303 .addClass('dropdown-backdrop') 1304 .insertAfter($(this)) 1305 .on('click', clearMenus) 1306 } 1307 1308 var relatedTarget = { relatedTarget: this } 1309 $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) 1310 1311 if (e.isDefaultPrevented()) return 1312 1313 $this 1314 .trigger('focus') 1315 .attr('aria-expanded', 'true') 1316 1317 $parent 1318 .toggleClass('open') 1319 .trigger('shown.bs.dropdown', relatedTarget) 1320 } 1321 1322 return false 1323 } 1324 1325 Dropdown.prototype.keydown = function (e) { 1326 if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return 1327 1328 var $this = $(this) 1329 1330 e.preventDefault() 1331 e.stopPropagation() 1332 1333 if ($this.is('.disabled, :disabled')) return 1334 1335 var $parent = getParent($this) 1336 var isActive = $parent.hasClass('open') 1337 1338 if (!isActive && e.which != 27 || isActive && e.which == 27) { 1339 if (e.which == 27) $parent.find(toggle).trigger('focus') 1340 return $this.trigger('click') 1341 } 1342 1343 var desc = ' li:not(.disabled):visible a' 1344 var $items = $parent.find('.dropdown-menu' + desc) 1345 1346 if (!$items.length) return 1347 1348 var index = $items.index(e.target) 1349 1350 if (e.which == 38 && index > 0) index-- // up 1351 if (e.which == 40 && index < $items.length - 1) index++ // down 1352 if (!~index) index = 0 1353 1354 $items.eq(index).trigger('focus') 1355 } 1356 1357 1358 // DROPDOWN PLUGIN DEFINITION 1359 // ========================== 1360 1361 function Plugin(option) { 1362 return this.each(function () { 1363 var $this = $(this) 1364 var data = $this.data('bs.dropdown') 1365 1366 if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) 1367 if (typeof option == 'string') data[option].call($this) 1368 }) 1369 } 1370 1371 var old = $.fn.dropdown 1372 1373 $.fn.dropdown = Plugin 1374 $.fn.dropdown.Constructor = Dropdown 1375 1376 1377 // DROPDOWN NO CONFLICT 1378 // ==================== 1379 1380 $.fn.dropdown.noConflict = function () { 1381 $.fn.dropdown = old 1382 return this 1383 } 1384 1385 1386 // APPLY TO STANDARD DROPDOWN ELEMENTS 1387 // =================================== 1388 1389 $(document) 1390 .on('click.bs.dropdown.data-api', clearMenus) 1391 .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) 1392 .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) 1393 .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) 1394 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) 1395 1396}(jQuery); 1397 1398/* ======================================================================== 1399 * Bootstrap: modal.js v3.3.5 1400 * http://getbootstrap.com/javascript/#modals 1401 * ======================================================================== 1402 * Copyright 2011-2015 Twitter, Inc. 1403 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1404 * ======================================================================== */ 1405 1406 1407+function ($) { 1408 'use strict'; 1409 1410 // MODAL CLASS DEFINITION 1411 // ====================== 1412 1413 var Modal = function (element, options) { 1414 this.options = options 1415 this.$body = $(document.body) 1416 this.$element = $(element) 1417 this.$dialog = this.$element.find('.modal-dialog') 1418 this.$backdrop = null 1419 this.isShown = null 1420 this.originalBodyPad = null 1421 this.scrollbarWidth = 0 1422 this.ignoreBackdropClick = false 1423 1424 if (this.options.remote) { 1425 this.$element 1426 .find('.modal-content') 1427 .load(this.options.remote, $.proxy(function () { 1428 this.$element.trigger('loaded.bs.modal') 1429 }, this)) 1430 } 1431 } 1432 1433 Modal.VERSION = '3.3.5' 1434 1435 Modal.TRANSITION_DURATION = 300 1436 Modal.BACKDROP_TRANSITION_DURATION = 150 1437 1438 Modal.DEFAULTS = { 1439 backdrop: true, 1440 keyboard: true, 1441 show: true 1442 } 1443 1444 Modal.prototype.toggle = function (_relatedTarget) { 1445 return this.isShown ? this.hide() : this.show(_relatedTarget) 1446 } 1447 1448 Modal.prototype.show = function (_relatedTarget) { 1449 var that = this 1450 var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) 1451 1452 this.$element.trigger(e) 1453 1454 if (this.isShown || e.isDefaultPrevented()) return 1455 1456 this.isShown = true 1457 1458 this.checkScrollbar() 1459 this.setScrollbar() 1460 this.$body.addClass('modal-open') 1461 1462 this.escape() 1463 this.resize() 1464 1465 this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) 1466 1467 this.$dialog.on('mousedown.dismiss.bs.modal', function () { 1468 that.$element.one('mouseup.dismiss.bs.modal', function (e) { 1469 if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true 1470 }) 1471 }) 1472 1473 this.backdrop(function () { 1474 var transition = $.support.transition && that.$element.hasClass('fade') 1475 1476 if (!that.$element.parent().length) { 1477 that.$element.appendTo(that.$body) // don't move modals dom position 1478 } 1479 1480 that.$element 1481 .show() 1482 .scrollTop(0) 1483 1484 that.adjustDialog() 1485 1486 if (transition) { 1487 that.$element[0].offsetWidth // force reflow 1488 } 1489 1490 that.$element.addClass('in') 1491 1492 that.enforceFocus() 1493 1494 var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) 1495 1496 transition ? 1497 that.$dialog // wait for modal to slide in 1498 .one('bsTransitionEnd', function () { 1499 that.$element.trigger('focus').trigger(e) 1500 }) 1501 .emulateTransitionEnd(Modal.TRANSITION_DURATION) : 1502 that.$element.trigger('focus').trigger(e) 1503 }) 1504 } 1505 1506 Modal.prototype.hide = function (e) { 1507 if (e) e.preventDefault() 1508 1509 e = $.Event('hide.bs.modal') 1510 1511 this.$element.trigger(e) 1512 1513 if (!this.isShown || e.isDefaultPrevented()) return 1514 1515 this.isShown = false 1516 1517 this.escape() 1518 this.resize() 1519 1520 $(document).off('focusin.bs.modal') 1521 1522 this.$element 1523 .removeClass('in') 1524 .off('click.dismiss.bs.modal') 1525 .off('mouseup.dismiss.bs.modal') 1526 1527 this.$dialog.off('mousedown.dismiss.bs.modal') 1528 1529 $.support.transition && this.$element.hasClass('fade') ? 1530 this.$element 1531 .one('bsTransitionEnd', $.proxy(this.hideModal, this)) 1532 .emulateTransitionEnd(Modal.TRANSITION_DURATION) : 1533 this.hideModal() 1534 } 1535 1536 Modal.prototype.enforceFocus = function () { 1537 $(document) 1538 .off('focusin.bs.modal') // guard against infinite focus loop 1539 .on('focusin.bs.modal', $.proxy(function (e) { 1540 if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { 1541 this.$element.trigger('focus') 1542 } 1543 }, this)) 1544 } 1545 1546 Modal.prototype.escape = function () { 1547 if (this.isShown && this.options.keyboard) { 1548 this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { 1549 e.which == 27 && this.hide() 1550 }, this)) 1551 } else if (!this.isShown) { 1552 this.$element.off('keydown.dismiss.bs.modal') 1553 } 1554 } 1555 1556 Modal.prototype.resize = function () { 1557 if (this.isShown) { 1558 $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) 1559 } else { 1560 $(window).off('resize.bs.modal') 1561 } 1562 } 1563 1564 Modal.prototype.hideModal = function () { 1565 var that = this 1566 this.$element.hide() 1567 this.backdrop(function () { 1568 that.$body.removeClass('modal-open') 1569 that.resetAdjustments() 1570 that.resetScrollbar() 1571 that.$element.trigger('hidden.bs.modal') 1572 }) 1573 } 1574 1575 Modal.prototype.removeBackdrop = function () { 1576 this.$backdrop && this.$backdrop.remove() 1577 this.$backdrop = null 1578 } 1579 1580 Modal.prototype.backdrop = function (callback) { 1581 var that = this 1582 var animate = this.$element.hasClass('fade') ? 'fade' : '' 1583 1584 if (this.isShown && this.options.backdrop) { 1585 var doAnimate = $.support.transition && animate 1586 1587 this.$backdrop = $(document.createElement('div')) 1588 .addClass('modal-backdrop ' + animate) 1589 .appendTo(this.$body) 1590 1591 this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { 1592 if (this.ignoreBackdropClick) { 1593 this.ignoreBackdropClick = false 1594 return 1595 } 1596 if (e.target !== e.currentTarget) return 1597 this.options.backdrop == 'static' 1598 ? this.$element[0].focus() 1599 : this.hide() 1600 }, this)) 1601 1602 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow 1603 1604 this.$backdrop.addClass('in') 1605 1606 if (!callback) return 1607 1608 doAnimate ? 1609 this.$backdrop 1610 .one('bsTransitionEnd', callback) 1611 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : 1612 callback() 1613 1614 } else if (!this.isShown && this.$backdrop) { 1615 this.$backdrop.removeClass('in') 1616 1617 var callbackRemove = function () { 1618 that.removeBackdrop() 1619 callback && callback() 1620 } 1621 $.support.transition && this.$element.hasClass('fade') ? 1622 this.$backdrop 1623 .one('bsTransitionEnd', callbackRemove) 1624 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : 1625 callbackRemove() 1626 1627 } else if (callback) { 1628 callback() 1629 } 1630 } 1631 1632 // these following methods are used to handle overflowing modals 1633 1634 Modal.prototype.handleUpdate = function () { 1635 this.adjustDialog() 1636 } 1637 1638 Modal.prototype.adjustDialog = function () { 1639 var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight 1640 1641 this.$element.css({ 1642 paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', 1643 paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' 1644 }) 1645 } 1646 1647 Modal.prototype.resetAdjustments = function () { 1648 this.$element.css({ 1649 paddingLeft: '', 1650 paddingRight: '' 1651 }) 1652 } 1653 1654 Modal.prototype.checkScrollbar = function () { 1655 var fullWindowWidth = window.innerWidth 1656 if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 1657 var documentElementRect = document.documentElement.getBoundingClientRect() 1658 fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) 1659 } 1660 this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth 1661 this.scrollbarWidth = this.measureScrollbar() 1662 } 1663 1664 Modal.prototype.setScrollbar = function () { 1665 var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) 1666 this.originalBodyPad = document.body.style.paddingRight || '' 1667 if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) 1668 } 1669 1670 Modal.prototype.resetScrollbar = function () { 1671 this.$body.css('padding-right', this.originalBodyPad) 1672 } 1673 1674 Modal.prototype.measureScrollbar = function () { // thx walsh 1675 var scrollDiv = document.createElement('div') 1676 scrollDiv.className = 'modal-scrollbar-measure' 1677 this.$body.append(scrollDiv) 1678 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth 1679 this.$body[0].removeChild(scrollDiv) 1680 return scrollbarWidth 1681 } 1682 1683 1684 // MODAL PLUGIN DEFINITION 1685 // ======================= 1686 1687 function Plugin(option, _relatedTarget) { 1688 return this.each(function () { 1689 var $this = $(this) 1690 var data = $this.data('bs.modal') 1691 var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) 1692 1693 if (!data) $this.data('bs.modal', (data = new Modal(this, options))) 1694 if (typeof option == 'string') data[option](_relatedTarget) 1695 else if (options.show) data.show(_relatedTarget) 1696 }) 1697 } 1698 1699 var old = $.fn.modal 1700 1701 $.fn.modal = Plugin 1702 $.fn.modal.Constructor = Modal 1703 1704 1705 // MODAL NO CONFLICT 1706 // ================= 1707 1708 $.fn.modal.noConflict = function () { 1709 $.fn.modal = old 1710 return this 1711 } 1712 1713 1714 // MODAL DATA-API 1715 // ============== 1716 1717 $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { 1718 var $this = $(this) 1719 var href = $this.attr('href') 1720 var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 1721 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) 1722 1723 if ($this.is('a')) e.preventDefault() 1724 1725 $target.one('show.bs.modal', function (showEvent) { 1726 if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown 1727 $target.one('hidden.bs.modal', function () { 1728 $this.is(':visible') && $this.trigger('focus') 1729 }) 1730 }) 1731 Plugin.call($target, option, this) 1732 }) 1733 1734}(jQuery); 1735 1736/* ======================================================================== 1737 * Bootstrap: tooltip.js v3.3.5 1738 * http://getbootstrap.com/javascript/#tooltip 1739 * Inspired by the original jQuery.tipsy by Jason Frame 1740 * ======================================================================== 1741 * Copyright 2011-2015 Twitter, Inc. 1742 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1743 * ======================================================================== */ 1744 1745 1746+function ($) { 1747 'use strict'; 1748 1749 // TOOLTIP PUBLIC CLASS DEFINITION 1750 // =============================== 1751 1752 var Tooltip = function (element, options) { 1753 this.type = null 1754 this.options = null 1755 this.enabled = null 1756 this.timeout = null 1757 this.hoverState = null 1758 this.$element = null 1759 this.inState = null 1760 1761 this.init('tooltip', element, options) 1762 } 1763 1764 Tooltip.VERSION = '3.3.5' 1765 1766 Tooltip.TRANSITION_DURATION = 150 1767 1768 Tooltip.DEFAULTS = { 1769 animation: true, 1770 placement: 'top', 1771 selector: false, 1772 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 1773 trigger: 'hover focus', 1774 title: '', 1775 delay: 0, 1776 html: false, 1777 container: false, 1778 viewport: { 1779 selector: 'body', 1780 padding: 0 1781 } 1782 } 1783 1784 Tooltip.prototype.init = function (type, element, options) { 1785 this.enabled = true 1786 this.type = type 1787 this.$element = $(element) 1788 this.options = this.getOptions(options) 1789 this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) 1790 this.inState = { click: false, hover: false, focus: false } 1791 1792 if (this.$element[0] instanceof document.constructor && !this.options.selector) { 1793 throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') 1794 } 1795 1796 var triggers = this.options.trigger.split(' ') 1797 1798 for (var i = triggers.length; i--;) { 1799 var trigger = triggers[i] 1800 1801 if (trigger == 'click') { 1802 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 1803 } else if (trigger != 'manual') { 1804 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 1805 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 1806 1807 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 1808 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 1809 } 1810 } 1811 1812 this.options.selector ? 1813 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 1814 this.fixTitle() 1815 } 1816 1817 Tooltip.prototype.getDefaults = function () { 1818 return Tooltip.DEFAULTS 1819 } 1820 1821 Tooltip.prototype.getOptions = function (options) { 1822 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 1823 1824 if (options.delay && typeof options.delay == 'number') { 1825 options.delay = { 1826 show: options.delay, 1827 hide: options.delay 1828 } 1829 } 1830 1831 return options 1832 } 1833 1834 Tooltip.prototype.getDelegateOptions = function () { 1835 var options = {} 1836 var defaults = this.getDefaults() 1837 1838 this._options && $.each(this._options, function (key, value) { 1839 if (defaults[key] != value) options[key] = value 1840 }) 1841 1842 return options 1843 } 1844 1845 Tooltip.prototype.enter = function (obj) { 1846 var self = obj instanceof this.constructor ? 1847 obj : $(obj.currentTarget).data('bs.' + this.type) 1848 1849 if (!self) { 1850 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 1851 $(obj.currentTarget).data('bs.' + this.type, self) 1852 } 1853 1854 if (obj instanceof $.Event) { 1855 self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true 1856 } 1857 1858 if (self.tip().hasClass('in') || self.hoverState == 'in') { 1859 self.hoverState = 'in' 1860 return 1861 } 1862 1863 clearTimeout(self.timeout) 1864 1865 self.hoverState = 'in' 1866 1867 if (!self.options.delay || !self.options.delay.show) return self.show() 1868 1869 self.timeout = setTimeout(function () { 1870 if (self.hoverState == 'in') self.show() 1871 }, self.options.delay.show) 1872 } 1873 1874 Tooltip.prototype.isInStateTrue = function () { 1875 for (var key in this.inState) { 1876 if (this.inState[key]) return true 1877 } 1878 1879 return false 1880 } 1881 1882 Tooltip.prototype.leave = function (obj) { 1883 var self = obj instanceof this.constructor ? 1884 obj : $(obj.currentTarget).data('bs.' + this.type) 1885 1886 if (!self) { 1887 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 1888 $(obj.currentTarget).data('bs.' + this.type, self) 1889 } 1890 1891 if (obj instanceof $.Event) { 1892 self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false 1893 } 1894 1895 if (self.isInStateTrue()) return 1896 1897 clearTimeout(self.timeout) 1898 1899 self.hoverState = 'out' 1900 1901 if (!self.options.delay || !self.options.delay.hide) return self.hide() 1902 1903 self.timeout = setTimeout(function () { 1904 if (self.hoverState == 'out') self.hide() 1905 }, self.options.delay.hide) 1906 } 1907 1908 Tooltip.prototype.show = function () { 1909 var e = $.Event('show.bs.' + this.type) 1910 1911 if (this.hasContent() && this.enabled) { 1912 this.$element.trigger(e) 1913 1914 var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) 1915 if (e.isDefaultPrevented() || !inDom) return 1916 var that = this 1917 1918 var $tip = this.tip() 1919 1920 var tipId = this.getUID(this.type) 1921 1922 this.setContent() 1923 $tip.attr('id', tipId) 1924 this.$element.attr('aria-describedby', tipId) 1925 1926 if (this.options.animation) $tip.addClass('fade') 1927 1928 var placement = typeof this.options.placement == 'function' ? 1929 this.options.placement.call(this, $tip[0], this.$element[0]) : 1930 this.options.placement 1931 1932 var autoToken = /\s?auto?\s?/i 1933 var autoPlace = autoToken.test(placement) 1934 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 1935 1936 $tip 1937 .detach() 1938 .css({ top: 0, left: 0, display: 'block' }) 1939 .addClass(placement) 1940 .data('bs.' + this.type, this) 1941 1942 this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) 1943 this.$element.trigger('inserted.bs.' + this.type) 1944 1945 var pos = this.getPosition() 1946 var actualWidth = $tip[0].offsetWidth 1947 var actualHeight = $tip[0].offsetHeight 1948 1949 if (autoPlace) { 1950 var orgPlacement = placement 1951 var viewportDim = this.getPosition(this.$viewport) 1952 1953 placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : 1954 placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : 1955 placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : 1956 placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : 1957 placement 1958 1959 $tip 1960 .removeClass(orgPlacement) 1961 .addClass(placement) 1962 } 1963 1964 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 1965 1966 this.applyPlacement(calculatedOffset, placement) 1967 1968 var complete = function () { 1969 var prevHoverState = that.hoverState 1970 that.$element.trigger('shown.bs.' + that.type) 1971 that.hoverState = null 1972 1973 if (prevHoverState == 'out') that.leave(that) 1974 } 1975 1976 $.support.transition && this.$tip.hasClass('fade') ? 1977 $tip 1978 .one('bsTransitionEnd', complete) 1979 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 1980 complete() 1981 } 1982 } 1983 1984 Tooltip.prototype.applyPlacement = function (offset, placement) { 1985 var $tip = this.tip() 1986 var width = $tip[0].offsetWidth 1987 var height = $tip[0].offsetHeight 1988 1989 // manually read margins because getBoundingClientRect includes difference 1990 var marginTop = parseInt($tip.css('margin-top'), 10) 1991 var marginLeft = parseInt($tip.css('margin-left'), 10) 1992 1993 // we must check for NaN for ie 8/9 1994 if (isNaN(marginTop)) marginTop = 0 1995 if (isNaN(marginLeft)) marginLeft = 0 1996 1997 offset.top += marginTop 1998 offset.left += marginLeft 1999 2000 // $.fn.offset doesn't round pixel values 2001 // so we use setOffset directly with our own function B-0 2002 $.offset.setOffset($tip[0], $.extend({ 2003 using: function (props) { 2004 $tip.css({ 2005 top: Math.round(props.top), 2006 left: Math.round(props.left) 2007 }) 2008 } 2009 }, offset), 0) 2010 2011 $tip.addClass('in') 2012 2013 // check to see if placing tip in new offset caused the tip to resize itself 2014 var actualWidth = $tip[0].offsetWidth 2015 var actualHeight = $tip[0].offsetHeight 2016 2017 if (placement == 'top' && actualHeight != height) { 2018 offset.top = offset.top + height - actualHeight 2019 } 2020 2021 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 2022 2023 if (delta.left) offset.left += delta.left 2024 else offset.top += delta.top 2025 2026 var isVertical = /top|bottom/.test(placement) 2027 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 2028 var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' 2029 2030 $tip.offset(offset) 2031 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) 2032 } 2033 2034 Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { 2035 this.arrow() 2036 .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') 2037 .css(isVertical ? 'top' : 'left', '') 2038 } 2039 2040 Tooltip.prototype.setContent = function () { 2041 var $tip = this.tip() 2042 var title = this.getTitle() 2043 2044 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 2045 $tip.removeClass('fade in top bottom left right') 2046 } 2047 2048 Tooltip.prototype.hide = function (callback) { 2049 var that = this 2050 var $tip = $(this.$tip) 2051 var e = $.Event('hide.bs.' + this.type) 2052 2053 function complete() { 2054 if (that.hoverState != 'in') $tip.detach() 2055 that.$element 2056 .removeAttr('aria-describedby') 2057 .trigger('hidden.bs.' + that.type) 2058 callback && callback() 2059 } 2060 2061 this.$element.trigger(e) 2062 2063 if (e.isDefaultPrevented()) return 2064 2065 $tip.removeClass('in') 2066 2067 $.support.transition && $tip.hasClass('fade') ? 2068 $tip 2069 .one('bsTransitionEnd', complete) 2070 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 2071 complete() 2072 2073 this.hoverState = null 2074 2075 return this 2076 } 2077 2078 Tooltip.prototype.fixTitle = function () { 2079 var $e = this.$element 2080 if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { 2081 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 2082 } 2083 } 2084 2085 Tooltip.prototype.hasContent = function () { 2086 return this.getTitle() 2087 } 2088 2089 Tooltip.prototype.getPosition = function ($element) { 2090 $element = $element || this.$element 2091 2092 var el = $element[0] 2093 var isBody = el.tagName == 'BODY' 2094 2095 var elRect = el.getBoundingClientRect() 2096 if (elRect.width == null) { 2097 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 2098 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) 2099 } 2100 var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() 2101 var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } 2102 var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null 2103 2104 return $.extend({}, elRect, scroll, outerDims, elOffset) 2105 } 2106 2107 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 2108 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 2109 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 2110 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 2111 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 2112 2113 } 2114 2115 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 2116 var delta = { top: 0, left: 0 } 2117 if (!this.$viewport) return delta 2118 2119 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 2120 var viewportDimensions = this.getPosition(this.$viewport) 2121 2122 if (/right|left/.test(placement)) { 2123 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 2124 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 2125 if (topEdgeOffset < viewportDimensions.top) { // top overflow 2126 delta.top = viewportDimensions.top - topEdgeOffset 2127 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 2128 delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset 2129 } 2130 } else { 2131 var leftEdgeOffset = pos.left - viewportPadding 2132 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 2133 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 2134 delta.left = viewportDimensions.left - leftEdgeOffset 2135 } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow 2136 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 2137 } 2138 } 2139 2140 return delta 2141 } 2142 2143 Tooltip.prototype.getTitle = function () { 2144 var title 2145 var $e = this.$element 2146 var o = this.options 2147 2148 title = $e.attr('data-original-title') 2149 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 2150 2151 return title 2152 } 2153 2154 Tooltip.prototype.getUID = function (prefix) { 2155 do prefix += ~~(Math.random() * 1000000) 2156 while (document.getElementById(prefix)) 2157 return prefix 2158 } 2159 2160 Tooltip.prototype.tip = function () { 2161 if (!this.$tip) { 2162 this.$tip = $(this.options.template) 2163 if (this.$tip.length != 1) { 2164 throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') 2165 } 2166 } 2167 return this.$tip 2168 } 2169 2170 Tooltip.prototype.arrow = function () { 2171 return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) 2172 } 2173 2174 Tooltip.prototype.enable = function () { 2175 this.enabled = true 2176 } 2177 2178 Tooltip.prototype.disable = function () { 2179 this.enabled = false 2180 } 2181 2182 Tooltip.prototype.toggleEnabled = function () { 2183 this.enabled = !this.enabled 2184 } 2185 2186 Tooltip.prototype.toggle = function (e) { 2187 var self = this 2188 if (e) { 2189 self = $(e.currentTarget).data('bs.' + this.type) 2190 if (!self) { 2191 self = new this.constructor(e.currentTarget, this.getDelegateOptions()) 2192 $(e.currentTarget).data('bs.' + this.type, self) 2193 } 2194 } 2195 2196 if (e) { 2197 self.inState.click = !self.inState.click 2198 if (self.isInStateTrue()) self.enter(self) 2199 else self.leave(self) 2200 } else { 2201 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 2202 } 2203 } 2204 2205 Tooltip.prototype.destroy = function () { 2206 var that = this 2207 clearTimeout(this.timeout) 2208 this.hide(function () { 2209 that.$element.off('.' + that.type).removeData('bs.' + that.type) 2210 if (that.$tip) { 2211 that.$tip.detach() 2212 } 2213 that.$tip = null 2214 that.$arrow = null 2215 that.$viewport = null 2216 }) 2217 } 2218 2219 2220 // TOOLTIP PLUGIN DEFINITION 2221 // ========================= 2222 2223 function Plugin(option) { 2224 return this.each(function () { 2225 var $this = $(this) 2226 var data = $this.data('bs.tooltip') 2227 var options = typeof option == 'object' && option 2228 2229 if (!data && /destroy|hide/.test(option)) return 2230 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 2231 if (typeof option == 'string') data[option]() 2232 }) 2233 } 2234 2235 var old = $.fn.tooltip 2236 2237 $.fn.tooltip = Plugin 2238 $.fn.tooltip.Constructor = Tooltip 2239 2240 2241 // TOOLTIP NO CONFLICT 2242 // =================== 2243 2244 $.fn.tooltip.noConflict = function () { 2245 $.fn.tooltip = old 2246 return this 2247 } 2248 2249}(jQuery); 2250 2251/* ======================================================================== 2252 * Bootstrap: popover.js v3.3.5 2253 * http://getbootstrap.com/javascript/#popovers 2254 * ======================================================================== 2255 * Copyright 2011-2015 Twitter, Inc. 2256 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 2257 * ======================================================================== */ 2258 2259 2260+function ($) { 2261 'use strict'; 2262 2263 // POPOVER PUBLIC CLASS DEFINITION 2264 // =============================== 2265 2266 var Popover = function (element, options) { 2267 this.init('popover', element, options) 2268 } 2269 2270 if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') 2271 2272 Popover.VERSION = '3.3.5' 2273 2274 Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { 2275 placement: 'right', 2276 trigger: 'click', 2277 content: '', 2278 template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' 2279 }) 2280 2281 2282 // NOTE: POPOVER EXTENDS tooltip.js 2283 // ================================ 2284 2285 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) 2286 2287 Popover.prototype.constructor = Popover 2288 2289 Popover.prototype.getDefaults = function () { 2290 return Popover.DEFAULTS 2291 } 2292 2293 Popover.prototype.setContent = function () { 2294 var $tip = this.tip() 2295 var title = this.getTitle() 2296 var content = this.getContent() 2297 2298 $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) 2299 $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events 2300 this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' 2301 ](content) 2302 2303 $tip.removeClass('fade top bottom left right in') 2304 2305 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do 2306 // this manually by checking the contents. 2307 if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() 2308 } 2309 2310 Popover.prototype.hasContent = function () { 2311 return this.getTitle() || this.getContent() 2312 } 2313 2314 Popover.prototype.getContent = function () { 2315 var $e = this.$element 2316 var o = this.options 2317 2318 return $e.attr('data-content') 2319 || (typeof o.content == 'function' ? 2320 o.content.call($e[0]) : 2321 o.content) 2322 } 2323 2324 Popover.prototype.arrow = function () { 2325 return (this.$arrow = this.$arrow || this.tip().find('.arrow')) 2326 } 2327 2328 2329 // POPOVER PLUGIN DEFINITION 2330 // ========================= 2331 2332 function Plugin(option) { 2333 return this.each(function () { 2334 var $this = $(this) 2335 var data = $this.data('bs.popover') 2336 var options = typeof option == 'object' && option 2337 2338 if (!data && /destroy|hide/.test(option)) return 2339 if (!data) $this.data('bs.popover', (data = new Popover(this, options))) 2340 if (typeof option == 'string') data[option]() 2341 }) 2342 } 2343 2344 var old = $.fn.popover 2345 2346 $.fn.popover = Plugin 2347 $.fn.popover.Constructor = Popover 2348 2349 2350 // POPOVER NO CONFLICT 2351 // =================== 2352 2353 $.fn.popover.noConflict = function () { 2354 $.fn.popover = old 2355 return this 2356 } 2357 2358}(jQuery); 2359 2360/* ======================================================================== 2361 * Bootstrap: scrollspy.js v3.3.5 2362 * http://getbootstrap.com/javascript/#scrollspy 2363 * ======================================================================== 2364 * Copyright 2011-2015 Twitter, Inc. 2365 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 2366 * ======================================================================== */ 2367 2368 2369+function ($) { 2370 'use strict'; 2371 2372 // SCROLLSPY CLASS DEFINITION 2373 // ========================== 2374 2375 function ScrollSpy(element, options) { 2376 this.$body = $(document.body) 2377 this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) 2378 this.options = $.extend({}, ScrollSpy.DEFAULTS, options) 2379 this.selector = (this.options.target || '') + ' .nav li > a' 2380 this.offsets = [] 2381 this.targets = [] 2382 this.activeTarget = null 2383 this.scrollHeight = 0 2384 2385 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) 2386 this.refresh() 2387 this.process() 2388 } 2389 2390 ScrollSpy.VERSION = '3.3.5' 2391 2392 ScrollSpy.DEFAULTS = { 2393 offset: 10 2394 } 2395 2396 ScrollSpy.prototype.getScrollHeight = function () { 2397 return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) 2398 } 2399 2400 ScrollSpy.prototype.refresh = function () { 2401 var that = this 2402 var offsetMethod = 'offset' 2403 var offsetBase = 0 2404 2405 this.offsets = [] 2406 this.targets = [] 2407 this.scrollHeight = this.getScrollHeight() 2408 2409 if (!$.isWindow(this.$scrollElement[0])) { 2410 offsetMethod = 'position' 2411 offsetBase = this.$scrollElement.scrollTop() 2412 } 2413 2414 this.$body 2415 .find(this.selector) 2416 .map(function () { 2417 var $el = $(this) 2418 var href = $el.data('target') || $el.attr('href') 2419 var $href = /^#./.test(href) && $(href) 2420 2421 return ($href 2422 && $href.length 2423 && $href.is(':visible') 2424 && [[$href[offsetMethod]().top + offsetBase, href]]) || null 2425 }) 2426 .sort(function (a, b) { return a[0] - b[0] }) 2427 .each(function () { 2428 that.offsets.push(this[0]) 2429 that.targets.push(this[1]) 2430 }) 2431 } 2432 2433 ScrollSpy.prototype.process = function () { 2434 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset 2435 var scrollHeight = this.getScrollHeight() 2436 var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() 2437 var offsets = this.offsets 2438 var targets = this.targets 2439 var activeTarget = this.activeTarget 2440 var i 2441 2442 if (this.scrollHeight != scrollHeight) { 2443 this.refresh() 2444 } 2445 2446 if (scrollTop >= maxScroll) { 2447 return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) 2448 } 2449 2450 if (activeTarget && scrollTop < offsets[0]) { 2451 this.activeTarget = null 2452 return this.clear() 2453 } 2454 2455 for (i = offsets.length; i--;) { 2456 activeTarget != targets[i] 2457 && scrollTop >= offsets[i] 2458 && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) 2459 && this.activate(targets[i]) 2460 } 2461 } 2462 2463 ScrollSpy.prototype.activate = function (target) { 2464 this.activeTarget = target 2465 2466 this.clear() 2467 2468 var selector = this.selector + 2469 '[data-target="' + target + '"],' + 2470 this.selector + '[href="' + target + '"]' 2471 2472 var active = $(selector) 2473 .parents('li') 2474 .addClass('active') 2475 2476 if (active.parent('.dropdown-menu').length) { 2477 active = active 2478 .closest('li.dropdown') 2479 .addClass('active') 2480 } 2481 2482 active.trigger('activate.bs.scrollspy') 2483 } 2484 2485 ScrollSpy.prototype.clear = function () { 2486 $(this.selector) 2487 .parentsUntil(this.options.target, '.active') 2488 .removeClass('active') 2489 } 2490 2491 2492 // SCROLLSPY PLUGIN DEFINITION 2493 // =========================== 2494 2495 function Plugin(option) { 2496 return this.each(function () { 2497 var $this = $(this) 2498 var data = $this.data('bs.scrollspy') 2499 var options = typeof option == 'object' && option 2500 2501 if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) 2502 if (typeof option == 'string') data[option]() 2503 }) 2504 } 2505 2506 var old = $.fn.scrollspy 2507 2508 $.fn.scrollspy = Plugin 2509 $.fn.scrollspy.Constructor = ScrollSpy 2510 2511 2512 // SCROLLSPY NO CONFLICT 2513 // ===================== 2514 2515 $.fn.scrollspy.noConflict = function () { 2516 $.fn.scrollspy = old 2517 return this 2518 } 2519 2520 2521 // SCROLLSPY DATA-API 2522 // ================== 2523 2524 $(window).on('load.bs.scrollspy.data-api', function () { 2525 $('[data-spy="scroll"]').each(function () { 2526 var $spy = $(this) 2527 Plugin.call($spy, $spy.data()) 2528 }) 2529 }) 2530 2531}(jQuery); 2532 2533/* ======================================================================== 2534 * Bootstrap: tab.js v3.3.5 2535 * http://getbootstrap.com/javascript/#tabs 2536 * ======================================================================== 2537 * Copyright 2011-2015 Twitter, Inc. 2538 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 2539 * ======================================================================== */ 2540 2541 2542+function ($) { 2543 'use strict'; 2544 2545 // TAB CLASS DEFINITION 2546 // ==================== 2547 2548 var Tab = function (element) { 2549 // jscs:disable requireDollarBeforejQueryAssignment 2550 this.element = $(element) 2551 // jscs:enable requireDollarBeforejQueryAssignment 2552 } 2553 2554 Tab.VERSION = '3.3.5' 2555 2556 Tab.TRANSITION_DURATION = 150 2557 2558 Tab.prototype.show = function () { 2559 var $this = this.element 2560 var $ul = $this.closest('ul:not(.dropdown-menu)') 2561 var selector = $this.data('target') 2562 2563 if (!selector) { 2564 selector = $this.attr('href') 2565 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 2566 } 2567 2568 if ($this.parent('li').hasClass('active')) return 2569 2570 var $previous = $ul.find('.active:last a') 2571 var hideEvent = $.Event('hide.bs.tab', { 2572 relatedTarget: $this[0] 2573 }) 2574 var showEvent = $.Event('show.bs.tab', { 2575 relatedTarget: $previous[0] 2576 }) 2577 2578 $previous.trigger(hideEvent) 2579 $this.trigger(showEvent) 2580 2581 if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return 2582 2583 var $target = $(selector) 2584 2585 this.activate($this.closest('li'), $ul) 2586 this.activate($target, $target.parent(), function () { 2587 $previous.trigger({ 2588 type: 'hidden.bs.tab', 2589 relatedTarget: $this[0] 2590 }) 2591 $this.trigger({ 2592 type: 'shown.bs.tab', 2593 relatedTarget: $previous[0] 2594 }) 2595 }) 2596 } 2597 2598 Tab.prototype.activate = function (element, container, callback) { 2599 var $active = container.find('> .active') 2600 var transition = callback 2601 && $.support.transition 2602 && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) 2603 2604 function next() { 2605 $active 2606 .removeClass('active') 2607 .find('> .dropdown-menu > .active') 2608 .removeClass('active') 2609 .end() 2610 .find('[data-toggle="tab"]') 2611 .attr('aria-expanded', false) 2612 2613 element 2614 .addClass('active') 2615 .find('[data-toggle="tab"]') 2616 .attr('aria-expanded', true) 2617 2618 if (transition) { 2619 element[0].offsetWidth // reflow for transition 2620 element.addClass('in') 2621 } else { 2622 element.removeClass('fade') 2623 } 2624 2625 if (element.parent('.dropdown-menu').length) { 2626 element 2627 .closest('li.dropdown') 2628 .addClass('active') 2629 .end() 2630 .find('[data-toggle="tab"]') 2631 .attr('aria-expanded', true) 2632 } 2633 2634 callback && callback() 2635 } 2636 2637 $active.length && transition ? 2638 $active 2639 .one('bsTransitionEnd', next) 2640 .emulateTransitionEnd(Tab.TRANSITION_DURATION) : 2641 next() 2642 2643 $active.removeClass('in') 2644 } 2645 2646 2647 // TAB PLUGIN DEFINITION 2648 // ===================== 2649 2650 function Plugin(option) { 2651 return this.each(function () { 2652 var $this = $(this) 2653 var data = $this.data('bs.tab') 2654 2655 if (!data) $this.data('bs.tab', (data = new Tab(this))) 2656 if (typeof option == 'string') data[option]() 2657 }) 2658 } 2659 2660 var old = $.fn.tab 2661 2662 $.fn.tab = Plugin 2663 $.fn.tab.Constructor = Tab 2664 2665 2666 // TAB NO CONFLICT 2667 // =============== 2668 2669 $.fn.tab.noConflict = function () { 2670 $.fn.tab = old 2671 return this 2672 } 2673 2674 2675 // TAB DATA-API 2676 // ============ 2677 2678 var clickHandler = function (e) { 2679 e.preventDefault() 2680 Plugin.call($(this), 'show') 2681 } 2682 2683 $(document) 2684 .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) 2685 .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) 2686 2687}(jQuery); 2688 2689/* ======================================================================== 2690 * Bootstrap: affix.js v3.3.5 2691 * http://getbootstrap.com/javascript/#affix 2692 * ======================================================================== 2693 * Copyright 2011-2015 Twitter, Inc. 2694 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 2695 * ======================================================================== */ 2696 2697 2698+function ($) { 2699 'use strict'; 2700 2701 // AFFIX CLASS DEFINITION 2702 // ====================== 2703 2704 var Affix = function (element, options) { 2705 this.options = $.extend({}, Affix.DEFAULTS, options) 2706 2707 this.$target = $(this.options.target) 2708 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 2709 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) 2710 2711 this.$element = $(element) 2712 this.affixed = null 2713 this.unpin = null 2714 this.pinnedOffset = null 2715 2716 this.checkPosition() 2717 } 2718 2719 Affix.VERSION = '3.3.5' 2720 2721 Affix.RESET = 'affix affix-top affix-bottom' 2722 2723 Affix.DEFAULTS = { 2724 offset: 0, 2725 target: window 2726 } 2727 2728 Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { 2729 var scrollTop = this.$target.scrollTop() 2730 var position = this.$element.offset() 2731 var targetHeight = this.$target.height() 2732 2733 if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false 2734 2735 if (this.affixed == 'bottom') { 2736 if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' 2737 return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' 2738 } 2739 2740 var initializing = this.affixed == null 2741 var colliderTop = initializing ? scrollTop : position.top 2742 var colliderHeight = initializing ? targetHeight : height 2743 2744 if (offsetTop != null && scrollTop <= offsetTop) return 'top' 2745 if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' 2746 2747 return false 2748 } 2749 2750 Affix.prototype.getPinnedOffset = function () { 2751 if (this.pinnedOffset) return this.pinnedOffset 2752 this.$element.removeClass(Affix.RESET).addClass('affix') 2753 var scrollTop = this.$target.scrollTop() 2754 var position = this.$element.offset() 2755 return (this.pinnedOffset = position.top - scrollTop) 2756 } 2757 2758 Affix.prototype.checkPositionWithEventLoop = function () { 2759 setTimeout($.proxy(this.checkPosition, this), 1) 2760 } 2761 2762 Affix.prototype.checkPosition = function () { 2763 if (!this.$element.is(':visible')) return 2764 2765 var height = this.$element.height() 2766 var offset = this.options.offset 2767 var offsetTop = offset.top 2768 var offsetBottom = offset.bottom 2769 var scrollHeight = Math.max($(document).height(), $(document.body).height()) 2770 2771 if (typeof offset != 'object') offsetBottom = offsetTop = offset 2772 if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) 2773 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) 2774
2775 var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) 2776 2777 if (this.affixed != affix) { 2778 if (this.unpin != null) this.$element.css('top', '') 2779 2780 var affixType = 'affix' + (affix ? '-' + affix : '') 2781 var e = $.Event(affixType + '.bs.affix') 2782 2783 this.$element.trigger(e) 2784 2785 if (e.isDefaultPrevented()) return 2786 2787 this.affixed = affix 2788 this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null 2789 2790 this.$element 2791 .removeClass(Affix.RESET) 2792 .addClass(affixType) 2793 .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') 2794 } 2795 2796 if (affix == 'bottom') { 2797 this.$element.offset({ 2798 top: scrollHeight - height - offsetBottom 2799 }) 2800 } 2801 } 2802 2803 2804 // AFFIX PLUGIN DEFINITION 2805 // ======================= 2806 2807 function Plugin(option) { 2808 return this.each(function () { 2809 var $this = $(this) 2810 var data = $this.data('bs.affix') 2811 var options = typeof option == 'object' && option 2812 2813 if (!data) $this.data('bs.affix', (data = new Affix(this, options))) 2814 if (typeof option == 'string') data[option]() 2815 }) 2816 } 2817 2818 var old = $.fn.affix 2819 2820 $.fn.affix = Plugin 2821 $.fn.affix.Constructor = Affix 2822 2823 2824 // AFFIX NO CONFLICT 2825 // ================= 2826 2827 $.fn.affix.noConflict = function () { 2828 $.fn.affix = old 2829 return this 2830 } 2831 2832 2833 // AFFIX DATA-API 2834 // ============== 2835 2836 $(window).on('load', function () { 2837 $('[data-spy="affix"]').each(function () { 2838 var $spy = $(this) 2839 var data = $spy.data() 2840 2841 data.offset = data.offset || {} 2842 2843 if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom 2844 if (data.offsetTop != null) data.offset.top = data.offsetTop 2845 2846 Plugin.call($spy, data) 2847 }) 2848 }) 2849 2850}(jQuery); 2851 2852;/*})'"*/ 2853;/*})'"*/ 2854/* 2855 2856Plugin Name: BrowserSelector 2857 2858Written by: Okler Themes - (http://www.okler.net) 2859 2860Version: 4.0.0 2861 2862*/ 2863 2864 2865 2866(function($) { 2867 2868 $.extend({ 2869 2870 2871 2872 browserSelector: function() { 2873 2874 2875 2876 // jQuery.browser.mobile (http://detectmobilebrowser.com/) 2877 2878 (function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera); 2879 2880 2881 2882 // Touch 2883 2884 var hasTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints; 2885 2886 2887 2888 var u = navigator.userAgent, 2889 2890 ua = u.toLowerCase(), 2891 2892 is = function (t) { 2893 2894 return ua.indexOf(t) > -1; 2895 2896 }, 2897 2898 g = 'gecko', 2899 2900 w = 'webkit', 2901 2902 s = 'safari', 2903 2904 o = 'opera', 2905 2906 h = document.documentElement, 2907 2908 b = [(!(/opera|webtv/i.test(ua)) && /msie\s(\d)/.test(ua)) ? ('ie ie' + parseFloat(navigator.appVersion.split("MSIE")[1])) : is('firefox/2') ? g + ' ff2' : is('firefox/3.5') ? g + ' ff3 ff3_5' : is('firefox/3') ? g + ' ff3' : is('gecko/') ? g : is('opera') ? o + (/version\/(\d+)/.test(ua) ? ' ' + o + RegExp.jQuery1 : (/opera(\s|\/)(\d+)/.test(ua) ? ' ' + o + RegExp.jQuery2 : '')) : is('konqueror') ? 'konqueror' : is('chrome') ? w + ' chrome' : is('iron') ? w + ' iron' : is('applewebkit/') ? w + ' ' + s + (/version\/(\d+)/.test(ua) ? ' ' + s + RegExp.jQuery1 : '') : is('mozilla/') ? g : '', is('j2me') ? 'mobile' : is('iphone') ? 'iphone' : is('ipod') ? 'ipod' : is('mac') ? 'mac' : is('darwin') ? 'mac' : is('webtv') ? 'webtv' : is('win') ? 'win' : is('freebsd') ? 'freebsd' : (is('x11') || is('linux')) ? 'linux' : '', 'js']; 2909 2910 2911 2912 c = b.join(' '); 2913 2914 2915 2916 if ($.browser.mobile) { 2917 2918 c += ' mobile'; 2919 2920 } 2921 2922 2923 2924 if (hasTouch) { 2925 2926 c += ' touch'; 2927 2928 } 2929 2930 2931 2932 h.className += ' ' + c; 2933 2934 2935 2936 // IE11 Detect 2937 2938 var isIE11 = !(window.ActiveXObject) && "ActiveXObject" in window; 2939 2940 2941 2942 if (isIE11) { 2943 2944 $('html').removeClass('gecko').addClass('ie ie11'); 2945 2946 return; 2947 2948 } 2949 2950 2951 2952 // Dark and Boxed Compatibility 2953 2954 if($('body').hasClass('dark')) { 2955 2956 $('html').addClass('dark'); 2957 2958 } 2959 2960 2961 2962 if($('body').hasClass('boxed')) { 2963 2964 $('html').addClass('boxed'); 2965 2966 } 2967 2968 2969 2970 } 2971 2972 2973 2974 }); 2975 2976 2977 2978 $.browserSelector(); 2979 2980 2981 2982})(jQuery); 2983 2984 2985 2986/* 2987 2988Plugin Name: waitForImages 2989 2990Written by: https://github.com/alexanderdickson/waitForImages 2991 2992*/ 2993 2994 2995 2996/*! waitForImages jQuery Plugin - v2.0.2 - 2015-05-05 2997 2998* https://github.com/alexanderdickson/waitForImages 2999 3000* Copyright (c) 2015 Alex Dickson; Licensed MIT */ 3001 3002;(function (factory) { 3003 3004 if (typeof define === 'function' && define.amd) { 3005 3006 // AMD. Register as an anonymous module. 3007 3008 define(['jquery'], factory); 3009 3010 } else if (typeof exports === 'object') { 3011 3012 // CommonJS / nodejs module 3013 3014 module.exports = factory(require('jquery')); 3015 3016 } else { 3017 3018 // Browser globals 3019 3020 factory(jQuery); 3021 3022 } 3023 3024}(function ($) { 3025 3026 // Namespace all events. 3027 3028 var eventNamespace = 'waitForImages'; 3029 3030 3031 3032 // CSS properties which contain references to images. 3033 3034 $.waitForImages = { 3035 3036 hasImageProperties: [ 3037 3038 'backgroundImage', 3039 3040 'listStyleImage', 3041 3042 'borderImage', 3043 3044 'borderCornerImage', 3045 3046 'cursor' 3047 3048 ], 3049 3050 hasImageAttributes: ['srcset'] 3051 3052 }; 3053 3054 3055 3056 // Custom selector to find `img` elements that have a valid `src` 3057 3058 // attribute and have not already loaded. 3059 3060 $.expr[':'].uncached = function (obj) { 3061 3062 // Ensure we are dealing with an `img` element with a valid 3063 3064 // `src` attribute. 3065 3066 if (!$(obj).is('img[src][src!=""]')) { 3067 3068 return false;
3069 3070 } 3071 3072 3073 3074 return !obj.complete; 3075 3076 }; 3077 3078 3079 3080 $.fn.waitForImages = function () { 3081 3082 3083 3084 var allImgsLength = 0; 3085 3086 var allImgsLoaded = 0; 3087 3088 var deferred = $.Deferred(); 3089 3090 3091 3092 var finishedCallback; 3093 3094 var eachCallback; 3095 3096 var waitForAll; 3097 3098 3099 3100 // Handle options object (if passed). 3101 3102 if ($.isPlainObject(arguments[0])) { 3103 3104 3105 3106 waitForAll = arguments[0].waitForAll; 3107 3108 eachCallback = arguments[0].each; 3109 3110 finishedCallback = arguments[0].finished; 3111 3112 3113 3114 } else { 3115 3116 3117 3118 // Handle if using deferred object and only one param was passed in. 3119 3120 if (arguments.length === 1 && $.type(arguments[0]) === 'boolean') { 3121 3122 waitForAll = arguments[0]; 3123 3124 } else { 3125 3126 finishedCallback = arguments[0]; 3127 3128 eachCallback = arguments[1]; 3129 3130 waitForAll = arguments[2]; 3131 3132 } 3133 3134 3135 3136 } 3137 3138 3139 3140 // Handle missing callbacks. 3141 3142 finishedCallback = finishedCallback || $.noop; 3143 3144 eachCallback = eachCallback || $.noop; 3145 3146 3147 3148 // Convert waitForAll to Boolean 3149 3150 waitForAll = !! waitForAll; 3151 3152 3153 3154 // Ensure callbacks are functions. 3155 3156 if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) { 3157 3158 throw new TypeError('An invalid callback was supplied.'); 3159 3160 } 3161 3162 3163 3164 this.each(function () { 3165 3166 // Build a list of all imgs, dependent on what images will 3167 3168 // be considered. 3169 3170 var obj = $(this); 3171 3172 var allImgs = []; 3173 3174 // CSS properties which may contain an image. 3175 3176 var hasImgProperties = $.waitForImages.hasImageProperties || []; 3177 3178 // Element attributes which may contain an image. 3179 3180 var hasImageAttributes = $.waitForImages.hasImageAttributes || []; 3181 3182 // To match `url()` references. 3183 3184 // Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri 3185 3186 var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g; 3187 3188 3189 3190 if (waitForAll) { 3191 3192 3193 3194 // Get all elements (including the original), as any one of 3195 3196 // them could have a background image. 3197 3198 obj.find('*').addBack().each(function () { 3199 3200 var element = $(this); 3201 3202 3203 3204 // If an `img` element, add it. But keep iterating in 3205 3206 // case it has a background image too. 3207 3208 if (element.is('img:uncached')) { 3209 3210 allImgs.push({ 3211 3212 src: element.attr('src'), 3213 3214 element: element[0] 3215 3216 }); 3217 3218 } 3219 3220 3221 3222 $.each(hasImgProperties, function (i, property) { 3223 3224 var propertyValue = element.css(property); 3225 3226 var match; 3227 3228 3229 3230 // If it doesn't contain this property, skip. 3231 3232 if (!propertyValue) { 3233 3234 return true; 3235 3236 } 3237 3238 3239 3240 // Get all url() of this element. 3241 3242 while (match = matchUrl.exec(propertyValue)) { 3243 3244 allImgs.push({ 3245 3246 src: match[2], 3247 3248 element: element[0] 3249 3250 }); 3251 3252 } 3253 3254 }); 3255 3256 3257 3258 $.each(hasImageAttributes, function (i, attribute) { 3259 3260 var attributeValue = element.attr(attribute); 3261 3262 var attributeValues; 3263 3264 3265 3266 // If it doesn't contain this property, skip. 3267 3268 if (!attributeValue) { 3269 3270 return true; 3271 3272 } 3273 3274 3275 3276 // Check for multiple comma separated images 3277 3278 attributeValues = attributeValue.split(','); 3279 3280 3281 3282 $.each(attributeValues, function(i, value) { 3283 3284 // Trim value and get string before first 3285 3286 // whitespace (for use with srcset). 3287 3288 value = $.trim(value).split(' ')[0]; 3289 3290 allImgs.push({ 3291 3292 src: value, 3293 3294 element: element[0] 3295 3296 }); 3297 3298 }); 3299 3300 }); 3301 3302 }); 3303 3304 } else { 3305 3306 // For images only, the task is simpler. 3307 3308 obj.find('img:uncached') 3309 3310 .each(function () { 3311 3312 allImgs.push({ 3313 3314 src: this.src, 3315 3316 element: this 3317 3318 }); 3319 3320 }); 3321 3322 } 3323 3324 3325 3326 allImgsLength = allImgs.length; 3327 3328 allImgsLoaded = 0; 3329 3330 3331 3332 // If no images found, don't bother. 3333 3334 if (allImgsLength === 0) { 3335 3336 finishedCallback.call(obj[0]); 3337 3338 deferred.resolveWith(obj[0]); 3339 3340 } 3341 3342 3343 3344 $.each(allImgs, function (i, img) { 3345 3346 3347 3348 var image = new Image(); 3349 3350 var events = 3351 3352 'load.' + eventNamespace + ' error.' + eventNamespace; 3353 3354 3355 3356 // Handle the image loading and error with the same callback. 3357 3358 $(image).one(events, function me (event) { 3359 3360 // If an error occurred with loading the image, set the 3361 3362 // third argument accordingly. 3363 3364 var eachArguments = [ 3365 3366 allImgsLoaded, 3367 3368 allImgsLength,
3369 3370 event.type == 'load' 3371 3372 ]; 3373 3374 allImgsLoaded++; 3375 3376 3377 3378 eachCallback.apply(img.element, eachArguments); 3379 3380 deferred.notifyWith(img.element, eachArguments); 3381 3382 3383 3384 // Unbind the event listeners. I use this in addition to 3385 3386 // `one` as one of those events won't be called (either 3387 3388 // 'load' or 'error' will be called). 3389 3390 $(this).off(events, me); 3391 3392 3393 3394 if (allImgsLoaded == allImgsLength) { 3395 3396 finishedCallback.call(obj[0]); 3397 3398 deferred.resolveWith(obj[0]); 3399 3400 return false; 3401 3402 } 3403 3404 3405 3406 }); 3407 3408 3409 3410 image.src = img.src; 3411 3412 }); 3413 }); 3414 3415 3416 3417 return deferred.promise(); 3418 3419 3420 3421 }; 3422 3423})); 3424 3425 3426 3427/* 3428 3429Plugin Name: Count To 3430 3431Written by: Matt Huggins - https://github.com/mhuggins/jquery-countTo 3432 3433*/ 3434 3435 3436 3437(function ($) { 3438 3439 $.fn.countTo = function (options) { 3440 3441 options = options || {}; 3442 3443 3444 3445 return $(this).each(function () { 3446 3447 // set options for current element 3448 3449 var settings = $.extend({}, $.fn.countTo.defaults, { 3450 3451 from: $(this).data('from'), 3452 3453 to: $(this).data('to'), 3454 3455 speed: $(this).data('speed'), 3456 3457 refreshInterval: $(this).data('refresh-interval'), 3458 3459 decimals: $(this).data('decimals') 3460 3461 }, options); 3462 3463 3464 3465 // how many times to update the value, and how much to increment the value on each update 3466 3467 var loops = Math.ceil(settings.speed / settings.refreshInterval), 3468 3469 increment = (settings.to - settings.from) / loops; 3470 3471 3472 3473 // references & variables that will change with each update 3474 3475 var self = this, 3476 3477 $self = $(this), 3478 3479 loopCount = 0, 3480 3481 value = settings.from, 3482 3483 data = $self.data('countTo') || {}; 3484 3485 3486 3487 $self.data('countTo', data); 3488 3489 3490 3491 // if an existing interval can be found, clear it first 3492 3493 if (data.interval) { 3494 3495 clearInterval(data.interval); 3496 3497 } 3498 3499 data.interval = setInterval(updateTimer, settings.refreshInterval); 3500 3501 3502 3503 // initialize the element with the starting value 3504 3505 render(value); 3506 3507 3508 3509 function updateTimer() { 3510 3511 value += increment; 3512 3513 loopCount++; 3514 3515 3516 3517 render(value); 3518 3519 3520
3521 if (typeof(settings.onUpdate) == 'function') { 3522 3523 settings.onUpdate.call(self, value); 3524 3525 } 3526 3527 3528 3529 if (loopCount >= loops) { 3530 3531 // remove the interval 3532 3533 $self.removeData('countTo'); 3534 3535 clearInterval(data.interval); 3536 3537 value = settings.to; 3538 3539 3540 3541 if (typeof(settings.onComplete) == 'function') { 3542 3543 settings.onComplete.call(self, value); 3544 3545 } 3546 3547 } 3548 3549 } 3550 3551 3552 3553 function render(value) { 3554 3555 var formattedValue = settings.formatter.call(self, value, settings); 3556 3557 $self.html(formattedValue); 3558 3559 } 3560 3561 }); 3562 3563 }; 3564 3565 3566 3567 $.fn.countTo.defaults = { 3568 3569 from: 0, // the number the element should start at 3570 3571 to: 0, // the number the element should end at 3572 3573 speed: 1000, // how long it should take to count between the target numbers 3574 3575 refreshInterval: 100, // how often the element should be updated 3576 3577 decimals: 0, // the number of decimal places to show 3578 3579 formatter: formatter, // handler for formatting the value before rendering 3580 3581 onUpdate: null, // callback method for every time the element is updated 3582 3583 onComplete: null // callback method for when the element finishes updating 3584 3585 }; 3586 3587 3588 3589 function formatter(value, settings) { 3590 3591 return value.toFixed(settings.decimals); 3592 3593 } 3594 3595}(jQuery)); 3596 3597 3598 3599/* 3600 3601Plugin Name: afterResize.js 3602 3603Written by: https://github.com/mcshaman/afterResize.js 3604 3605Description: Simple jQuery plugin designed to emulate an 'after resize' event. 3606 3607*/ 3608 3609 3610 3611( function( $ ) { 3612 3613 "use strict"; 3614 3615 3616 3617 // Define default settings 3618 3619 var defaults = { 3620 3621 action: function() {}, 3622 3623 runOnLoad: false, 3624 3625 duration: 500 3626 3627 }; 3628 3629 3630 3631 // Define global variables 3632 3633 var settings = defaults, 3634 3635 running = false, 3636 3637 start; 3638 3639 3640 3641 var methods = {}; 3642 3643 3644 3645 // Initial plugin configuration 3646 3647 methods.init = function() { 3648 3649 3650 3651 // Allocate passed arguments to settings based on type 3652 3653 for( var i = 0; i <= arguments.length; i++ ) { 3654 3655 var arg = arguments[i]; 3656 3657 switch ( typeof arg ) { 3658 3659 case "function": 3660 3661 settings.action = arg; 3662 3663 break; 3664 3665 case "boolean": 3666 3667 settings.runOnLoad = arg; 3668 3669 break; 3670 3671 case "number": 3672 3673 settings.duration = arg; 3674 3675 break; 3676 3677 } 3678 3679 } 3680 3681 3682 3683 // Process each matching jQuery object 3684 3685 return this.each(function() { 3686 3687 3688 3689 if( settings.runOnLoad ) { settings.action(); } 3690 3691 3692 3693 $(this).resize( function() { 3694 3695 3696 3697 methods.timedAction.call( this ); 3698 3699 3700 3701 } ); 3702 3703 3704 3705 } ); 3706 3707 }; 3708 3709 3710 3711 methods.timedAction = function( code, millisec ) { 3712 3713 3714 3715 var doAction = function() { 3716 3717 var remaining = settings.duration; 3718 3719 3720 3721 if( running ) { 3722 3723 var elapse = new Date() - start; 3724 3725 remaining = settings.duration - elapse; 3726 3727 if( remaining <= 0 ) { 3728 3729 // Clear timeout and reset running variable 3730 3731 clearTimeout(running); 3732 3733 running = false; 3734 3735 // Perform user defined function 3736 3737 settings.action(); 3738 3739 3740 3741 return; 3742 3743 } 3744 3745 } 3746 3747 wait( remaining ); 3748 3749 }; 3750 3751 3752 3753 var wait = function( time ) { 3754 3755 running = setTimeout( doAction, time ); 3756 3757 }; 3758 3759 3760 3761 // Define new action starting time 3762 3763 start = new Date(); 3764 3765 3766 3767 // Define runtime settings if function is run directly 3768 3769 if( typeof millisec === 'number' ) { settings.duration = millisec; } 3770 3771 if( typeof code === 'function' ) { settings.action = code; } 3772 3773 3774 3775 // Only run timed loop if not already running 3776 3777 if( !running ) { doAction(); } 3778 3779 3780 3781 }; 3782 3783 3784 3785 3786 3787 $.fn.afterResize = function( method ) { 3788 3789 3790 3791 if( methods[method] ) { 3792 3793 return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) ); 3794 3795 } else { 3796 3797 return methods.init.apply( this, arguments ); 3798 3799 } 3800 3801 3802 3803 }; 3804 3805 3806 3807})(jQuery); 3808 3809 3810 3811/* 3812 3813Plugin Name: matchHeight 3814 3815Written by: Okler Themes - (http://www.okler.net) 3816 3817Version: 4.0.0 3818 3819 3820 3821Based on: 3822 3823 3824 3825 jquery.matchHeight-min.js v0.5.2 3826 3827 Licensed under the terms of the MIT license. 3828 3829 3830 3831*/ 3832 3833 3834 3835;(function($) { 3836 3837 /* 3838 3839 * internal 3840 3841 */ 3842 3843 3844 3845 var _previousResizeWidth = -1, 3846 3847 _updateTimeout = -1; 3848 3849 3850 3851 /* 3852 3853 * _rows 3854 3855 * utility function returns array of jQuery selections representing each row 3856 3857 * (as displayed after float wrapping applied by browser) 3858 3859 */ 3860 3861 3862 3863 var _rows = function(elements) { 3864 3865 var tolerance = 1, 3866 3867 $elements = $(elements), 3868 3869 lastTop = null, 3870 3871 rows = []; 3872 3873 3874 3875 // group elements by their top position 3876 3877 $elements.each(function(){ 3878 3879 var $that = $(this), 3880 3881 top = $that.offset().top - _parse($that.css('margin-top')), 3882 3883 lastRow = rows.length > 0 ? rows[rows.length - 1] : null; 3884 3885 3886 3887 if (lastRow === null) { 3888 3889 // first item on the row, so just push it 3890 3891 rows.push($that); 3892 3893 } else { 3894 3895 // if the row top is the same, add to the row group 3896 3897 if (Math.floor(Math.abs(lastTop - top)) <= tolerance) { 3898 3899 rows[rows.length - 1] = lastRow.add($that); 3900 3901 } else { 3902 3903 // otherwise start a new row group 3904 3905 rows.push($that); 3906 3907 } 3908 3909 } 3910 3911 3912 3913 // keep track of the last row top 3914 3915 lastTop = top; 3916 3917 }); 3918 3919 3920 3921 return rows; 3922 3923 }; 3924 3925 3926 3927 /* 3928 3929 * _parse 3930 3931 * value parse utility function 3932 3933 */ 3934 3935 3936 3937 var _parse = function(value) { 3938 3939 // parse value and convert NaN to 0 3940 3941 return parseFloat(value) || 0; 3942 3943 }; 3944 3945 3946 3947 /* 3948 3949 * _parseOptions 3950 3951 * handle plugin options 3952 3953 */ 3954 3955 3956 3957 var _parseOptions = function(options) { 3958 3959 var opts = { 3960 3961 byRow: true, 3962 3963 remove: false, 3964 3965 property: 'height' 3966 3967 }; 3968 3969 3970 3971 if (typeof options === 'object') { 3972 3973 return $.extend(opts, options); 3974 3975 } 3976 3977 3978 3979 if (typeof options === 'boolean') { 3980 3981 opts.byRow = options; 3982 3983 } else if (options === 'remove') { 3984 3985 opts.remove = true; 3986 3987 } 3988 3989 3990 3991 return opts; 3992 3993 }; 3994 3995 3996 3997 /* 3998 3999 * matchHeight 4000 4001 * plugin definition 4002 4003 */ 4004 4005 4006 4007 var matchHeight = $.fn.matchHeight = function(options) { 4008 4009 var opts = _parseOptions(options); 4010 4011 4012 4013 // handle remove 4014 4015 if (opts.remove) { 4016 4017 var that = this; 4018 4019 4020 4021 // remove fixed height from all selected elements 4022 4023 this.css(opts.property, ''); 4024 4025 4026 4027 // remove selected elements from all groups 4028 4029 $.each(matchHeight._groups, function(key, group) { 4030 4031 group.elements = group.elements.not(that); 4032 4033 }); 4034 4035 4036 4037 // TODO: cleanup empty groups 4038 4039 4040 4041 return this; 4042 4043 } 4044 4045 4046 4047 if (this.length <= 1) 4048 4049 return this; 4050 4051 4052 4053 // keep track of this group so we can re-apply later on load and resize events 4054 4055 matchHeight._groups.push({ 4056 4057 elements: this, 4058 4059 options: opts 4060 4061 }); 4062 4063 4064 4065 // match each element's height to the tallest element in the selection 4066 4067 matchHeight._apply(this, opts); 4068 4069 4070 4071 return this; 4072 4073 }; 4074 4075 4076 4077 /* 4078 4079 * plugin global options 4080 4081 */ 4082 4083 4084 4085 matchHeight._groups = []; 4086 4087 matchHeight._throttle = 80; 4088 4089 matchHeight._maintainScroll = false;
4090 4091 matchHeight._beforeUpdate = null; 4092 4093 matchHeight._afterUpdate = null; 4094 4095 4096 4097 /* 4098 4099 * matchHeight._apply 4100 4101 * apply matchHeight to given elements 4102 4103 */ 4104 4105 4106 4107 matchHeight._apply = function(elements, options) { 4108 4109 var opts = _parseOptions(options), 4110 4111 $elements = $(elements), 4112 4113 rows = [$elements]; 4114 4115 4116 4117 // take note of scroll position 4118 4119 var scrollTop = $(window).scrollTop(), 4120 4121 htmlHeight = $('html').outerHeight(true); 4122 4123 4124 4125 // get hidden parents 4126 4127 var $hiddenParents = $elements.parents().filter(':hidden'); 4128 4129 4130 4131 // cache the original inline style 4132 4133 $hiddenParents.each(function() { 4134 4135 var $that = $(this); 4136 4137 $that.data('style-cache', $that.attr('style')); 4138 4139 }); 4140 4141 4142 4143 // temporarily must force hidden parents visible 4144 4145 $hiddenParents.css('display', 'block'); 4146 4147 4148 4149 // get rows if using byRow, otherwise assume one row 4150 4151 if (opts.byRow) { 4152 4153 4154 4155 // must first force an arbitrary equal height so floating elements break evenly 4156 4157 $elements.each(function() { 4158 4159 var $that = $(this), 4160 4161 display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block'; 4162 4163 4164 4165 // cache the original inline style 4166 4167 $that.data('style-cache', $that.attr('style')); 4168 4169 4170 4171 $that.css({ 4172 4173 'display': display, 4174 4175 'padding-top': '0', 4176 4177 'padding-bottom': '0', 4178 4179 'margin-top': '0', 4180 4181 'margin-bottom': '0', 4182 4183 'border-top-width': '0', 4184 4185 'border-bottom-width': '0', 4186 4187 'height': '100px' 4188 4189 }); 4190 4191 }); 4192 4193 4194 4195 // get the array of rows (based on element top position) 4196 4197 rows = _rows($elements); 4198 4199 4200 4201 // revert original inline styles 4202 4203 $elements.each(function() { 4204 4205 var $that = $(this); 4206 4207 $that.attr('style', $that.data('style-cache') || ''); 4208 4209 }); 4210 4211 } 4212 4213 4214 4215 $.each(rows, function(key, row) { 4216 4217 var $row = $(row), 4218 4219 maxHeight = 0; 4220 4221 4222 4223 // skip apply to rows with only one item 4224 4225 if (opts.byRow && $row.length <= 1) { 4226 4227 $row.css(opts.property, ''); 4228 4229 return; 4230 4231 } 4232 4233 4234 4235 // iterate the row and find the max height 4236 4237 $row.each(function(){ 4238 4239 var $that = $(this), 4240 4241 display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block'; 4242 4243 4244 4245 // ensure we get the correct actual height (and not a previously set height value) 4246 4247 var css = { 'display': display }; 4248 4249 css[opts.property] = ''; 4250 4251 $that.css(css); 4252 4253 4254 4255 // find the max height (including padding, but not margin) 4256 4257 if ($that.outerHeight(false) > maxHeight) 4258 4259 maxHeight = $that.outerHeight(false); 4260 4261 4262 4263 // revert display block 4264 4265 $that.css('display', ''); 4266 4267 }); 4268 4269 4270 4271 // iterate the row and apply the height to all elements 4272 4273 $row.each(function(){ 4274 4275 var $that = $(this), 4276 4277 verticalPadding = 0; 4278 4279 4280 4281 // handle padding and border correctly (required when not using border-box) 4282 4283 if ($that.css('box-sizing') !== 'border-box') { 4284 4285 verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width')); 4286 4287 verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom')); 4288 4289 } 4290 4291 4292 4293 // set the height (accounting for padding and border) 4294 4295 $that.css(opts.property, maxHeight - verticalPadding); 4296 4297 }); 4298 4299 }); 4300 4301 4302 4303 // revert hidden parents 4304 4305 $hiddenParents.each(function() { 4306 4307 var $that = $(this); 4308 4309 $that.attr('style', $that.data('style-cache') || null); 4310 4311 }); 4312 4313 4314 4315 // restore scroll position if enabled 4316 4317 if (matchHeight._maintainScroll) 4318 4319 $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true)); 4320 4321 4322 4323 return this; 4324 4325 }; 4326 4327 4328 4329 /* 4330 4331 * matchHeight._applyDataApi 4332 4333 * applies matchHeight to all elements with a data-match-height attribute 4334 4335 */ 4336 4337 4338 4339 matchHeight._applyDataApi = function() { 4340 4341 var groups = {}; 4342 4343 4344 4345 // generate groups by their groupId set by elements using data-match-height 4346 4347 $('[data-match-height], [data-mh]').each(function() { 4348 4349 var $this = $(this), 4350 4351 groupId = $this.attr('data-match-height') || $this.attr('data-mh'); 4352 4353 if (groupId in groups) { 4354 4355 groups[groupId] = groups[groupId].add($this); 4356 4357 } else { 4358 4359 groups[groupId] = $this; 4360 4361 } 4362 4363 }); 4364 4365 4366 4367 // apply matchHeight to each group 4368 4369 $.each(groups, function() { 4370 4371 this.matchHeight(true); 4372 4373 }); 4374 4375 }; 4376 4377 4378 4379 /* 4380 4381 * matchHeight._update 4382 4383 * updates matchHeight on all current groups with their correct options 4384 4385 */ 4386 4387 4388 4389 var _update = function(event) { 4390 4391 if (matchHeight._beforeUpdate) 4392 4393 matchHeight._beforeUpdate(event, matchHeight._groups); 4394 4395 4396 4397 $.each(matchHeight._groups, function() { 4398 4399 matchHeight._apply(this.elements, this.options); 4400 4401 }); 4402 4403 4404 4405 if (matchHeight._afterUpdate) 4406 4407 matchHeight._afterUpdate(event, matchHeight._groups); 4408 4409 }; 4410 4411 4412 4413 matchHeight._update = function(throttle, event) { 4414 4415 // prevent update if fired from a resize event 4416 4417 // where the viewport width hasn't actually changed 4418 4419 // fixes an event looping bug in IE8 4420 4421 if (event && event.type === 'resize') { 4422 4423 var windowWidth = $(window).width(); 4424 4425 if (windowWidth === _previousResizeWidth) 4426 4427 return; 4428 4429 _previousResizeWidth = windowWidth; 4430 4431 } 4432 4433 4434 4435 // throttle updates 4436 4437 if (!throttle) { 4438 4439 _update(event); 4440 4441 } else if (_updateTimeout === -1) { 4442 4443 _updateTimeout = setTimeout(function() { 4444 4445 _update(event); 4446 4447 _updateTimeout = -1; 4448 4449 }, matchHeight._throttle); 4450 4451 } 4452 4453 }; 4454 4455 4456 4457 /* 4458 4459 * bind events 4460 4461 */ 4462 4463 4464 4465 // apply on DOM ready event 4466 4467 $(matchHeight._applyDataApi); 4468 4469 4470 4471 // update heights on load and resize events 4472 4473 $(window).bind('load', function(event) { 4474 4475 matchHeight._update(false, event); 4476 4477 }); 4478 4479 4480 4481 // throttled update heights on resize events 4482 4483 $(window).bind('resize orientationchange', function(event) { 4484 4485 matchHeight._update(true, event); 4486 4487 }); 4488 4489 4490 4491})(jQuery); 4492 4493 4494 4495/* 4496 4497Plugin Name: jQuery.pin 4498 4499Written by: Okler Themes - (http://www.okler.net) 4500 4501Version: 4.0.0 4502 4503 4504 4505Based on: 4506 4507 4508 4509 https://github.com/webpop/jquery.pin 4510 4511 Licensed under the terms of the MIT license. 4512 4513 4514 4515*/ 4516 4517(function ($) { 4518 4519 "use strict"; 4520 4521 $.fn.pin = function (options) { 4522 4523 var scrollY = 0, elements = [], disabled = false, $window = $(window); 4524 4525 4526 4527 options = options || {}; 4528 4529 4530 4531 var recalculateLimits = function () { 4532 4533 for (var i=0, len=elements.length; i<len; i++) { 4534 4535 var $this = elements[i]; 4536 4537 4538 4539 if (options.minWidth && $window.width() <= options.minWidth) { 4540 4541 if ($this.parent().is(".pin-wrapper")) { $this.unwrap(); } 4542 4543 $this.css({width: "", left: "", top: "", position: ""}); 4544 4545 if (options.activeClass) { $this.removeClass(options.activeClass); } 4546 4547 disabled = true; 4548 4549 continue; 4550 4551 } else { 4552 4553 disabled = false;
4554 4555 } 4556 4557 4558 4559 var $container = options.containerSelector ? $this.closest(options.containerSelector) : $(document.body); 4560 4561 var offset = $this.offset(); 4562 4563 var containerOffset = $container.offset(); 4564 4565 var parentOffset = $this.parent().offset(); 4566 4567 4568 4569 if (!$this.parent().is(".pin-wrapper")) { 4570 4571 $this.wrap("<div class='pin-wrapper'>"); 4572 4573 } 4574 4575 4576 4577 var pad = $.extend({ 4578 4579 top: 0, 4580 4581 bottom: 0 4582 4583 }, options.padding || {}); 4584 4585 4586 4587 $this.data("pin", { 4588 4589 pad: pad, 4590 4591 from: (options.containerSelector ? containerOffset.top : offset.top) - pad.top, 4592 4593 to: containerOffset.top + $container.height() - $this.outerHeight() - pad.bottom, 4594 4595 end: containerOffset.top + $container.height(), 4596 4597 parentTop: parentOffset.top 4598 4599 }); 4600 4601 4602 4603 $this.css({width: $this.outerWidth()}); 4604 4605 $this.parent().css("height", $this.outerHeight()); 4606 4607 } 4608 4609 }; 4610 4611 4612 4613 var onScroll = function () { 4614 4615 if (disabled) { return; } 4616 4617 4618 4619 scrollY = $window.scrollTop(); 4620 4621 4622 4623 var elmts = []; 4624 4625 for (var i=0, len=elements.length; i<len; i++) { 4626 4627 var $this = $(elements[i]), 4628 4629 data = $this.data("pin"); 4630 4631 4632 4633 if (!data) { // Removed element 4634 4635 continue; 4636 4637 } 4638 4639 4640 4641 elmts.push($this); 4642 4643 4644 4645 var from = data.from - data.pad.bottom, 4646 4647 to = data.to - data.pad.top; 4648 4649 4650 4651 if (from + $this.outerHeight() > data.end) { 4652 4653 $this.css('position', ''); 4654 4655 continue; 4656 4657 } 4658 4659 4660 4661 if (from < scrollY && to > scrollY) { 4662 4663 !($this.css("position") == "fixed") && $this.css({ 4664 4665 left: $this.offset().left, 4666 4667 top: data.pad.top 4668 4669 }).css("position", "fixed"); 4670 4671 if (options.activeClass) { $this.addClass(options.activeClass); } 4672 4673 } else if (scrollY >= to) { 4674 4675 $this.css({ 4676 4677 left: "", 4678 4679 top: to - data.parentTop + data.pad.top 4680 4681 }).css("position", "absolute"); 4682 4683 if (options.activeClass) { $this.addClass(options.activeClass); } 4684 4685 } else { 4686 4687 $this.css({position: "", top: "", left: ""}); 4688 4689 if (options.activeClass) { $this.removeClass(options.activeClass); } 4690 4691 } 4692 4693 } 4694 4695 elements = elmts; 4696 4697 }; 4698 4699 4700 4701 var update = function () { recalculateLimits(); onScroll(); }; 4702 4703 4704 4705 this.each(function () { 4706 4707 var $this = $(this), 4708 4709 data = $(this).data('pin') || {}; 4710 4711 4712 4713 if (data && data.update) { return; } 4714 4715 elements.push($this); 4716 4717 $("img", this).one("load", recalculateLimits); 4718 4719 data.update = update; 4720 4721 $(this).data('pin', data); 4722 4723 }); 4724 4725 4726 4727 $window.scroll(onScroll); 4728 4729 $window.resize(function () { recalculateLimits(); }); 4730 4731 recalculateLimits(); 4732 4733 4734 4735 $window.load(update); 4736 4737 4738 4739 return this; 4740 4741 }; 4742 4743})(jQuery); 4744 4745 4746 4747/* 4748 4749Plugin Name: smoothScroll for jQuery. 4750 4751Written by: Okler Themes - (http://www.okler.net) 4752 4753Version: 4.0.0 4754 4755 4756 4757Based on: 4758 4759 4760 4761 SmoothScroll v1.2.1 4762 4763 Licensed under the terms of the MIT license. 4764 4765 4766 4767 People involved 4768 4769 - Balazs Galambosi (maintainer) 4770 4771 - Patrick Brunner (original idea) 4772 4773 - Michael Herf (Pulse Algorithm) 4774 4775 4776 4777*/ 4778 4779 4780 4781(function($) { 4782 4783 $.extend({ 4784 4785 4786 4787 smoothScroll: function() { 4788 4789 4790 4791 // Scroll Variables (tweakable) 4792 4793 var defaults = { 4794 4795 4796 4797 // Scrolling Core 4798 4799 frameRate : 60, // [Hz] 4800 4801 animationTime : 700, // [px] 4802 4803 stepSize : 120, // [px] 4804 4805 4806 4807 // Pulse (less tweakable) 4808 4809 // ratio of "tail" to "acceleration" 4810 4811 pulseAlgorithm : true, 4812 4813 pulseScale : 10, 4814 4815 pulseNormalize : 1, 4816 4817 4818 4819 // Acceleration 4820 4821 accelerationDelta : 20, // 20 4822 4823 accelerationMax : 1, // 1 4824 4825 4826 4827 // Keyboard Settings 4828 4829 keyboardSupport : true, // option 4830 4831 arrowScroll : 50, // [px] 4832 4833 4834 4835 // Other 4836 4837 touchpadSupport : true, 4838
4839 fixedBackground : true, 4840 4841 excluded : "" 4842 4843 }; 4844 4845 4846 4847 var options = defaults; 4848 4849 4850 4851 // Other Variables 4852 4853 var isExcluded = false; 4854 4855 var isFrame = false; 4856 4857 var direction = { x: 0, y: 0 }; 4858 4859 var initDone = false; 4860 4861 var root = document.documentElement; 4862 4863 var activeElement; 4864 4865 var observer; 4866 4867 var deltaBuffer = [ 120, 120, 120 ]; 4868 4869 4870 4871 var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, 4872 4873 pageup: 33, pagedown: 34, end: 35, home: 36 }; 4874 4875 4876 4877 4878 4879 /*********************************************** 4880 4881 * INITIALIZE 4882 4883 ***********************************************/ 4884 4885 4886 4887 /** 4888 4889 * Tests if smooth scrolling is allowed. Shuts down everything if not. 4890 4891 */ 4892 4893 function initTest() { 4894 4895 4896 4897 var disableKeyboard = false; 4898 4899 4900 4901 // disable keys for google reader (spacebar conflict) 4902 4903 if (document.URL.indexOf("google.com/reader/view") > -1) { 4904 4905 disableKeyboard = true; 4906 4907 } 4908 4909 4910 4911 // disable everything if the page is blacklisted 4912 4913 if (options.excluded) { 4914 4915 var domains = options.excluded.split(/[,\n] ?/); 4916 4917 domains.push("mail.google.com"); // exclude Gmail for now 4918 4919 for (var i = domains.length; i--;) { 4920 4921 if (document.URL.indexOf(domains[i]) > -1) { 4922 4923 observer && observer.disconnect(); 4924 4925 removeEvent("mousewheel", wheel); 4926 4927 disableKeyboard = true; 4928 4929 isExcluded = true; 4930 4931 break; 4932 4933 } 4934 4935 } 4936 4937 } 4938 4939 4940 4941 // disable keyboard support if anything above requested it 4942 4943 if (disableKeyboard) { 4944 4945 removeEvent("keydown", keydown); 4946 4947 } 4948 4949 4950 4951 if (options.keyboardSupport && !disableKeyboard) { 4952 4953 addEvent("keydown", keydown); 4954 4955 } 4956 4957 } 4958 4959 4960 4961 /** 4962 4963 * Sets up scrolls array, determines if frames are involved. 4964 4965 */ 4966 4967 function init() { 4968 4969 4970 4971 if (!document.body) return; 4972 4973 4974 4975 var body = document.body; 4976 4977 var html = document.documentElement; 4978 4979 var windowHeight = window.innerHeight; 4980 4981 var scrollHeight = body.scrollHeight; 4982 4983 4984 4985 // check compat mode for root element 4986 4987 root = (document.compatMode.indexOf('CSS') >= 0) ? html : body; 4988 4989 activeElement = body; 4990 4991 4992 4993 initTest(); 4994 4995 initDone = true; 4996 4997 4998 4999 // Checks if this script is running in a frame 5000 5001 if (top != self) { 5002 5003 isFrame = true; 5004 5005 } 5006 5007 5008 5009 /** 5010 5011 * This fixes a bug where the areas left and right to 5012 5013 * the content does not trigger the onmousewheel event 5014 5015 * on some pages. e.g.: html, body { height: 100% } 5016 5017 */ 5018 5019 else if (scrollHeight > windowHeight && 5020 5021 (body.offsetHeight <= windowHeight || 5022 5023 html.offsetHeight <= windowHeight)) { 5024 5025 5026 5027 // DOMChange (throttle): fix height 5028 5029 var pending = false; 5030 5031 var refresh = function () { 5032 if (!pending && html.scrollHeight != document.height) { 5033 5034 pending = true; // add a new pending action 5035 5036 setTimeout(function () { 5037 5038 html.style.height = document.height + 'px'; 5039 5040 pending = false; 5041 5042 }, 500); // act rarely to stay fast 5043 5044 } 5045 5046 }; 5047 5048 html.style.height = 'auto'; 5049 5050 setTimeout(refresh, 10); 5051 5052 5053 5054 var config = { 5055 5056 attributes: true, 5057 5058 childList: true, 5059 5060 characterData: false 5061 5062 }; 5063 5064 5065 5066 observer = new MutationObserver(refresh); 5067 5068 observer.observe(body, config); 5069 5070 5071 5072 // clearfix 5073 5074 if (root.offsetHeight <= windowHeight) { 5075 5076 var underlay = document.createElement("div"); 5077 5078 underlay.style.clear = "both"; 5079 5080 body.appendChild(underlay); 5081 5082 } 5083 5084 } 5085 5086 5087 5088 // gmail performance fix 5089 5090 if (document.URL.indexOf("mail.google.com") > -1) { 5091 5092 var s = document.createElement("style"); 5093 5094 s.innerHTML = ".iu { visibility: hidden }"; 5095 5096 (document.getElementsByTagName("head")[0] || html).appendChild(s); 5097 5098 } 5099 5100 // facebook better home timeline performance 5101 5102 // all the HTML resized images make rendering CPU intensive 5103 5104 else if (document.URL.indexOf("www.facebook.com") > -1) { 5105 5106 var home_stream = document.getElementById("home_stream"); 5107 5108 home_stream && (home_stream.style.webkitTransform = "translateZ(0)"); 5109 5110 } 5111 5112 // disable fixed background 5113
5114 if (!options.fixedBackground && !isExcluded) { 5115 5116 body.style.backgroundAttachment = "scroll"; 5117 5118 html.style.backgroundAttachment = "scroll"; 5119 5120 } 5121 5122 } 5123 5124 5125 5126 5127 5128 /************************************************ 5129 5130 * SCROLLING 5131 5132 ************************************************/ 5133 5134 5135 5136 var que = []; 5137 5138 var pending = false; 5139 5140 var lastScroll = +new Date; 5141 5142 5143 5144 /** 5145 5146 * Pushes scroll actions to the scrolling queue. 5147 5148 */ 5149 5150 function scrollArray(elem, left, top, delay) { 5151 5152 5153 5154 delay || (delay = 1000); 5155 5156 directionCheck(left, top); 5157 5158 5159 5160 if (options.accelerationMax != 1) { 5161 5162 var now = +new Date; 5163 5164 var elapsed = now - lastScroll; 5165 5166 if (elapsed < options.accelerationDelta) { 5167 5168 var factor = (1 + (30 / elapsed)) / 2; 5169 5170 if (factor > 1) { 5171 5172 factor = Math.min(factor, options.accelerationMax); 5173 5174 left *= factor; 5175 5176 top *= factor; 5177 5178 } 5179 5180 } 5181 5182 lastScroll = +new Date; 5183 5184 } 5185 5186 5187 5188 // push a scroll command 5189 5190 que.push({ 5191 5192 x: left, 5193 5194 y: top, 5195 5196 lastX: (left < 0) ? 0.99 : -0.99, 5197 5198 lastY: (top < 0) ? 0.99 : -0.99, 5199 5200 start: +new Date 5201 5202 }); 5203 5204 5205 5206 // don't act if there's a pending queue 5207 5208 if (pending) { 5209 5210 return; 5211 5212 } 5213 5214 5215 5216 var scrollWindow = (elem === document.body); 5217 5218 5219 5220 var step = function (time) { 5221 5222 5223 5224 var now = +new Date; 5225 5226 var scrollX = 0; 5227 5228 var scrollY = 0; 5229 5230 5231 5232 for (var i = 0; i < que.length; i++) { 5233 5234 5235 5236 var item = que[i]; 5237 5238 var elapsed = now - item.start; 5239 5240 var finished = (elapsed >= options.animationTime); 5241 5242 5243 5244 // scroll position: [0, 1] 5245 5246 var position = (finished) ? 1 : elapsed / options.animationTime; 5247 5248 5249 5250 // easing [optional] 5251 5252 if (options.pulseAlgorithm) { 5253 5254 position = pulse(position); 5255 5256 } 5257 5258 5259 5260 // only need the difference 5261 5262 var x = (item.x * position - item.lastX) >> 0; 5263 5264 var y = (item.y * position - item.lastY) >> 0; 5265 5266 5267 5268 // add this to the total scrolling 5269 5270 scrollX += x; 5271 5272 scrollY += y; 5273 5274 5275 5276 // update last values 5277 5278 item.lastX += x; 5279 5280 item.lastY += y; 5281 5282 5283 5284 // delete and step back if it's over 5285 5286 if (finished) { 5287 5288 que.splice(i, 1); i--; 5289 5290 } 5291 5292 } 5293 5294 5295 5296 // scroll left and top 5297 5298 if (scrollWindow) { 5299 5300 window.scrollBy(scrollX, scrollY); 5301 5302 } 5303 5304 else { 5305 5306 if (scrollX) elem.scrollLeft += scrollX; 5307 5308 if (scrollY) elem.scrollTop += scrollY; 5309 5310 } 5311 5312 5313 5314 // clean up if there's nothing left to do 5315 5316 if (!left && !top) { 5317 5318 que = []; 5319 5320 } 5321 5322 5323 5324 if (que.length) { 5325 5326 requestFrame(step, elem, (delay / options.frameRate + 1)); 5327 5328 } else { 5329 5330 pending = false; 5331 5332 } 5333 5334 }; 5335 5336 5337 5338 // start a new queue of actions 5339 5340 requestFrame(step, elem, 0); 5341 5342 pending = true; 5343 5344 } 5345 5346 5347 5348 5349 5350 /*********************************************** 5351 5352 * EVENTS 5353 5354 ***********************************************/ 5355 5356 5357 5358 /** 5359 5360 * Mouse wheel handler. 5361 5362 * @param {Object} event 5363 5364 */ 5365 5366 function wheel(event) { 5367 5368 5369 5370 if (!initDone) { 5371 5372 init(); 5373 5374 } 5375 5376 5377 5378 var target = event.target; 5379 5380 var overflowing = overflowingAncestor(target); 5381 5382 5383 5384 // use default if there's no overflowing 5385 5386 // element or default action is prevented 5387 5388 if (!overflowing || event.defaultPrevented || 5389 5390 isNodeName(activeElement, "embed") || 5391 5392 (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) { 5393 5394 return true; 5395 5396 } 5397 5398 5399 5400 var deltaX = event.wheelDeltaX || 0; 5401 5402 var deltaY = event.wheelDeltaY || 0; 5403 5404 5405 5406 // use wheelDelta if deltaX/Y is not available 5407 5408 if (!deltaX && !deltaY) { 5409 5410 deltaY = event.wheelDelta || 0; 5411 5412 } 5413 5414 5415 5416 // check if it's a touchpad scroll that should be ignored 5417 5418 if (!options.touchpadSupport && isTouchpad(deltaY)) { 5419 5420 return true; 5421 5422 } 5423 5424 5425 5426 // scale by step size 5427 5428 // delta is 120 most of the time 5429 5430 // synaptics seems to send 1 sometimes 5431 5432 if (Math.abs(deltaX) > 1.2) { 5433 5434 deltaX *= options.stepSize / 120; 5435 5436 } 5437 5438 if (Math.abs(deltaY) > 1.2) { 5439 5440 deltaY *= options.stepSize / 120; 5441 5442 } 5443 5444 5445 5446 scrollArray(overflowing, -deltaX, -deltaY); 5447 5448 if (typeof event.cancelable !== 'boolean' || event.cancelable) { 5449 // The event can be canceled, so we do so. 5450 event.preventDefault(); 5451 } 5452 5453 } 5454 5455 5456 5457 /** 5458 5459 * Keydown event handler. 5460 5461 * @param {Object} event 5462 5463 */ 5464 5465 function keydown(event) { 5466 5467 5468 5469 var target = event.target; 5470 5471 var modifier = event.ctrlKey || event.altKey || event.metaKey || 5472 5473 (event.shiftKey && event.keyCode !== key.spacebar); 5474 5475 5476 5477 // do nothing if user is editing text 5478 5479 // or using a modifier key (except shift) 5480 5481 // or in a dropdown 5482
5483 if ( /input|textarea|select|embed/i.test(target.nodeName) || 5484 5485 target.isContentEditable || 5486 5487 event.defaultPrevented || 5488 5489 modifier ) { 5490 5491 return true; 5492 5493 } 5494 5495 // spacebar should trigger button press 5496 5497 if (isNodeName(target, "button") && 5498 5499 event.keyCode === key.spacebar) { 5500 5501 return true; 5502 5503 } 5504 5505 5506 5507 var shift, x = 0, y = 0; 5508 5509 var elem = overflowingAncestor(activeElement); 5510 5511 var clientHeight = elem.clientHeight; 5512 5513 5514 5515 if (elem == document.body) { 5516 5517 clientHeight = window.innerHeight; 5518 5519 } 5520 5521 5522 5523 switch (event.keyCode) { 5524 5525 case key.up: 5526 5527 y = -options.arrowScroll; 5528 5529 break; 5530 5531 case key.down: 5532 5533 y = options.arrowScroll; 5534 5535 break; 5536 5537 case key.spacebar: // (+ shift) 5538 5539 shift = event.shiftKey ? 1 : -1; 5540 5541 y = -shift * clientHeight * 0.9; 5542 5543 break; 5544 5545 case key.pageup: 5546 5547 y = -clientHeight * 0.9; 5548 5549 break; 5550 5551 case key.pagedown: 5552 5553 y = clientHeight * 0.9; 5554 5555 break; 5556 5557 case key.home: 5558 5559 y = -elem.scrollTop; 5560 5561 break; 5562 5563 case key.end: 5564 5565 var damt = elem.scrollHeight - elem.scrollTop - clientHeight; 5566 5567 y = (damt > 0) ? damt+10 : 0; 5568 5569 break; 5570 5571 case key.left: 5572 5573 x = -options.arrowScroll; 5574 5575 break; 5576 5577 case key.right: 5578 5579 x = options.arrowScroll; 5580 5581 break; 5582 5583 default: 5584 5585 return true; // a key we don't care about 5586 5587 } 5588 5589 5590 5591 scrollArray(elem, x, y); 5592 5593 event.preventDefault(); 5594 5595 } 5596 5597 5598 5599 /** 5600 5601 * Mousedown event only for updating activeElement 5602 5603 */ 5604 5605 function mousedown(event) { 5606 5607 activeElement = event.target; 5608 5609 } 5610 5611 5612 5613 5614 5615 /*********************************************** 5616 5617 * OVERFLOW 5618 5619 ***********************************************/ 5620 5621 5622 5623 var cache = {}; // cleared out every once in while 5624 5625 setInterval(function () { cache = {}; }, 10 * 1000); 5626 5627 5628 5629 var uniqueID = (function () { 5630 5631 var i = 0; 5632 5633 return function (el) { 5634 5635 return el.uniqueID || (el.uniqueID = i++); 5636 5637 }; 5638 5639 })(); 5640 5641 5642 5643 function setCache(elems, overflowing) { 5644 5645 for (var i = elems.length; i--;) 5646 5647 cache[uniqueID(elems[i])] = overflowing; 5648 5649 return overflowing; 5650 5651 } 5652 5653 5654 5655 function overflowingAncestor(el) { 5656 5657 var elems = []; 5658 5659 var rootScrollHeight = root.scrollHeight; 5660 5661 do { 5662 5663 var cached = cache[uniqueID(el)]; 5664 5665 if (cached) { 5666 5667 return setCache(elems, cached); 5668 5669 } 5670 5671 elems.push(el); 5672 5673 if (rootScrollHeight === el.scrollHeight) { 5674 5675 if (!isFrame || root.clientHeight + 10 < rootScrollHeight) { 5676 5677 return setCache(elems, document.body); // scrolling root in WebKit 5678 5679 } 5680 5681 } else if (el.clientHeight + 10 < el.scrollHeight) { 5682 5683 overflow = getComputedStyle(el, "").getPropertyValue("overflow-y"); 5684 5685 if (overflow === "scroll" || overflow === "auto") { 5686 5687 return setCache(elems, el); 5688 5689 } 5690 5691 } 5692 5693 } while (el = el.parentNode); 5694 5695 } 5696 5697 5698 5699 5700 5701 /*********************************************** 5702 5703 * HELPERS 5704 5705 ***********************************************/ 5706 5707 5708 5709 function addEvent(type, fn, bubble) { 5710 5711 window.addEventListener(type, fn, (bubble||false)); 5712 5713 } 5714 5715 5716 5717 function removeEvent(type, fn, bubble) { 5718 5719 window.removeEventListener(type, fn, (bubble||false)); 5720 5721 } 5722 5723 5724 5725 function isNodeName(el, tag) { 5726 5727 return (el.nodeName||"").toLowerCase() === tag.toLowerCase(); 5728 5729 } 5730 5731 5732 5733 function directionCheck(x, y) { 5734 5735 x = (x > 0) ? 1 : -1; 5736 5737 y = (y > 0) ? 1 : -1; 5738 5739 if (direction.x !== x || direction.y !== y) { 5740 5741 direction.x = x; 5742 5743 direction.y = y; 5744 5745 que = []; 5746 5747 lastScroll = 0; 5748 5749 } 5750 5751 } 5752 5753 5754 5755 var deltaBufferTimer; 5756 5757 5758 5759 function isTouchpad(deltaY) { 5760 5761 if (!deltaY) return; 5762 5763 deltaY = Math.abs(deltaY) 5764 5765 deltaBuffer.push(deltaY); 5766 5767 deltaBuffer.shift(); 5768 5769 clearTimeout(deltaBufferTimer); 5770 5771 var allEquals = (deltaBuffer[0] == deltaBuffer[1] && 5772 5773 deltaBuffer[1] == deltaBuffer[2]); 5774 5775 var allDivisable = (isDivisible(deltaBuffer[0], 120) && 5776 5777 isDivisible(deltaBuffer[1], 120) && 5778 5779 isDivisible(deltaBuffer[2], 120)); 5780 5781 return !(allEquals || allDivisable); 5782 5783 } 5784 5785 5786 5787 function isDivisible(n, divisor) { 5788 5789 return (Math.floor(n / divisor) == n / divisor); 5790 5791 } 5792 5793 5794 5795 var requestFrame = (function () { 5796 5797 return window.requestAnimationFrame || 5798 5799 window.webkitRequestAnimationFrame || 5800 5801 function (callback, element, delay) { 5802 5803 window.setTimeout(callback, delay || (1000/60)); 5804 5805 }; 5806 5807 })(); 5808 5809 5810 5811 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; 5812 5813 5814 5815 5816 5817 /*********************************************** 5818 5819 * PULSE 5820 5821 ***********************************************/ 5822 5823 5824 5825 /** 5826 5827 * Viscous fluid with a pulse for part and decay for the rest. 5828 5829 * - Applies a fixed force over an interval (a damped acceleration), and 5830 5831 * - Lets the exponential bleed away the velocity over a longer interval 5832 5833 * - Michael Herf, http://stereopsis.com/stopping/ 5834 5835 */ 5836 5837 function pulse_(x) { 5838 5839 var val, start, expx; 5840 5841 // test 5842 5843 x = x * options.pulseScale; 5844 5845 if (x < 1) { // acceleartion 5846 5847 val = x - (1 - Math.exp(-x)); 5848 5849 } else { // tail 5850 5851 // the previous animation ended here: 5852 5853 start = Math.exp(-1); 5854 5855 // simple viscous drag 5856 5857 x -= 1; 5858 5859 expx = 1 - Math.exp(-x); 5860 5861 val = start + (expx * (1 - start)); 5862 5863 } 5864
5865 return val * options.pulseNormalize; 5866 5867 } 5868 5869 5870 5871 function pulse(x) { 5872 5873 if (x >= 1) return 1; 5874 5875 if (x <= 0) return 0; 5876 5877 5878 5879 if (options.pulseNormalize == 1) { 5880 5881 options.pulseNormalize /= pulse_(1); 5882 5883 } 5884 5885 return pulse_(x); 5886 5887 } 5888 5889 5890 5891 addEvent("mousedown", mousedown); 5892 5893 addEvent("mousewheel", wheel); 5894 5895 addEvent("load", init); 5896 5897 5898 5899 } 5900 5901 5902 5903 }); 5904 5905 5906 5907 if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { 5908 5909 $.smoothScroll(); 5910 5911 } 5912 5913})(jQuery); 5914;/*})'"*/ 5915;/*})'"*/ 5916/*! 5917 * jQuery Validation Plugin v1.13.1 5918 * 5919 * http://jqueryvalidation.org/ 5920 * 5921 * Copyright (c) 2014 Jörn Zaefferer 5922 * Released under the MIT license 5923 */ 5924(function( factory ) { 5925 if ( typeof define === "function" && define.amd ) { 5926 define( ["jquery"], factory ); 5927 } else { 5928 factory( jQuery ); 5929 } 5930}(function( $ ) { 5931 5932$.extend($.fn, { 5933 // http://jqueryvalidation.org/validate/ 5934 validate: function( options ) { 5935 5936 // if nothing is selected, return nothing; can't chain anyway 5937 if ( !this.length ) { 5938 if ( options && options.debug && window.console ) { 5939 console.warn( "Nothing selected, can't validate, returning nothing." ); 5940 } 5941 return; 5942 } 5943 5944 // check if a validator for this form was already created 5945 var validator = $.data( this[ 0 ], "validator" ); 5946 if ( validator ) { 5947 return validator; 5948 } 5949 5950 // Add novalidate tag if HTML5. 5951 this.attr( "novalidate", "novalidate" ); 5952 5953 validator = new $.validator( options, this[ 0 ] ); 5954 $.data( this[ 0 ], "validator", validator ); 5955 5956 if ( validator.settings.onsubmit ) { 5957 5958 this.validateDelegate( ":submit", "click", function( event ) { 5959 if ( validator.settings.submitHandler ) { 5960 validator.submitButton = event.target; 5961 } 5962 // allow suppressing validation by adding a cancel class to the submit button 5963 if ( $( event.target ).hasClass( "cancel" ) ) { 5964 validator.cancelSubmit = true; 5965 } 5966 5967 // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 5968 if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) { 5969 validator.cancelSubmit = true; 5970 } 5971 }); 5972 5973 // validate the form on submit 5974 this.submit( function( event ) { 5975 if ( validator.settings.debug ) { 5976 // prevent form submit to be able to see console output 5977 event.preventDefault(); 5978 } 5979 function handle() { 5980 var hidden, result; 5981 if ( validator.settings.submitHandler ) { 5982 if ( validator.submitButton ) { 5983 // insert a hidden input as a replacement for the missing submit button 5984 hidden = $( "<input type='hidden'/>" ) 5985 .attr( "name", validator.submitButton.name ) 5986 .val( $( validator.submitButton ).val() ) 5987 .appendTo( validator.currentForm ); 5988 } 5989 result = validator.settings.submitHandler.call( validator, validator.currentForm, event ); 5990 if ( validator.submitButton ) { 5991 // and clean up afterwards; thanks to no-block-scope, hidden can be referenced 5992 hidden.remove(); 5993 } 5994 if ( result !== undefined ) { 5995 return result; 5996 } 5997 return false; 5998 } 5999 return true; 6000 } 6001 6002 // prevent submit for invalid forms or custom submit handlers 6003 if ( validator.cancelSubmit ) { 6004 validator.cancelSubmit = false; 6005 return handle(); 6006 } 6007 if ( validator.form() ) { 6008 if ( validator.pendingRequest ) { 6009 validator.formSubmitted = true; 6010 return false; 6011 } 6012 return handle(); 6013 } else { 6014 validator.focusInvalid(); 6015 return false; 6016 } 6017 }); 6018 } 6019 6020 return validator; 6021 }, 6022 // http://jqueryvalidation.org/valid/ 6023 valid: function() { 6024 var valid, validator; 6025 6026 if ( $( this[ 0 ] ).is( "form" ) ) { 6027 valid = this.validate().form(); 6028 } else { 6029 valid = true; 6030 validator = $( this[ 0 ].form ).validate(); 6031 this.each( function() { 6032 valid = validator.element( this ) && valid; 6033 }); 6034 } 6035 return valid; 6036 }, 6037 // attributes: space separated list of attributes to retrieve and remove 6038 removeAttrs: function( attributes ) { 6039 var result = {}, 6040 $element = this; 6041 $.each( attributes.split( /\s/ ), function( index, value ) { 6042 result[ value ] = $element.attr( value ); 6043 $element.removeAttr( value ); 6044 }); 6045 return result; 6046 }, 6047 // http://jqueryvalidation.org/rules/ 6048 rules: function( command, argument ) { 6049 var element = this[ 0 ], 6050 settings, staticRules, existingRules, data, param, filtered; 6051 6052 if ( command ) { 6053 settings = $.data( element.form, "validator" ).settings; 6054 staticRules = settings.rules; 6055 existingRules = $.validator.staticRules( element ); 6056 switch ( command ) { 6057 case "add": 6058 $.extend( existingRules, $.validator.normalizeRule( argument ) ); 6059 // remove messages from rules, but allow them to be set separately 6060 delete existingRules.messages; 6061 staticRules[ element.name ] = existingRules; 6062 if ( argument.messages ) { 6063 settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages ); 6064 } 6065 break; 6066 case "remove": 6067 if ( !argument ) { 6068 delete staticRules[ element.name ]; 6069 return existingRules; 6070 } 6071 filtered = {}; 6072 $.each( argument.split( /\s/ ), function( index, method ) { 6073 filtered[ method ] = existingRules[ method ]; 6074 delete existingRules[ method ]; 6075 if ( method === "required" ) { 6076 $( element ).removeAttr( "aria-required" ); 6077 } 6078 }); 6079 return filtered; 6080 } 6081 } 6082 6083 data = $.validator.normalizeRules( 6084 $.extend( 6085 {}, 6086 $.validator.classRules( element ), 6087 $.validator.attributeRules( element ), 6088 $.validator.dataRules( element ), 6089 $.validator.staticRules( element ) 6090 ), element ); 6091 6092 // make sure required is at front 6093 if ( data.required ) { 6094 param = data.required; 6095 delete data.required; 6096 data = $.extend( { required: param }, data ); 6097 $( element ).attr( "aria-required", "true" ); 6098 } 6099 6100 // make sure remote is at back 6101 if ( data.remote ) { 6102 param = data.remote; 6103 delete data.remote; 6104 data = $.extend( data, { remote: param }); 6105 } 6106 6107 return data; 6108 } 6109}); 6110 6111// Custom selectors 6112$.extend( $.expr[ ":" ], { 6113 // http://jqueryvalidation.org/blank-selector/ 6114 blank: function( a ) { 6115 return !$.trim( "" + $( a ).val() ); 6116 }, 6117 // http://jqueryvalidation.org/filled-selector/ 6118 filled: function( a ) { 6119 return !!$.trim( "" + $( a ).val() ); 6120 }, 6121 // http://jqueryvalidation.org/unchecked-selector/ 6122 unchecked: function( a ) { 6123 return !$( a ).prop( "checked" ); 6124 } 6125}); 6126 6127// constructor for validator 6128$.validator = function( options, form ) { 6129 this.settings = $.extend( true, {}, $.validator.defaults, options ); 6130 this.currentForm = form; 6131 this.init(); 6132}; 6133 6134// http://jqueryvalidation.org/jQuery.validator.format/ 6135$.validator.format = function( source, params ) { 6136 if ( arguments.length === 1 ) { 6137 return function() { 6138 var args = $.makeArray( arguments ); 6139 args.unshift( source ); 6140 return $.validator.format.apply( this, args ); 6141 }; 6142 } 6143 if ( arguments.length > 2 && params.constructor !== Array ) { 6144 params = $.makeArray( arguments ).slice( 1 ); 6145 } 6146 if ( params.constructor !== Array ) { 6147 params = [ params ]; 6148 } 6149 $.each( params, function( i, n ) { 6150 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() { 6151 return n; 6152 }); 6153 }); 6154 return source; 6155}; 6156 6157$.extend( $.validator, { 6158 6159 defaults: { 6160 messages: {}, 6161 groups: {}, 6162 rules: {}, 6163 errorClass: "error", 6164 validClass: "valid", 6165 errorElement: "label", 6166 focusCleanup: false, 6167 focusInvalid: true, 6168 errorContainer: $( [] ), 6169 errorLabelContainer: $( [] ), 6170 onsubmit: true, 6171 ignore: ":hidden", 6172 ignoreTitle: false, 6173 onfocusin: function( element ) { 6174 this.lastActive = element; 6175 6176 // Hide error label and remove error class on focus if enabled 6177 if ( this.settings.focusCleanup ) { 6178 if ( this.settings.unhighlight ) { 6179 this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.val
6179idClass ); 6180 } 6181 this.hideThese( this.errorsFor( element ) ); 6182 } 6183 }, 6184 onfocusout: function( element ) { 6185 if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) { 6186 this.element( element ); 6187 } 6188 }, 6189 onkeyup: function( element, event ) { 6190 if ( event.which === 9 && this.elementValue( element ) === "" ) { 6191 return; 6192 } else if ( element.name in this.submitted || element === this.lastElement ) { 6193 this.element( element ); 6194 } 6195 }, 6196 onclick: function( element ) { 6197 // click on selects, radiobuttons and checkboxes 6198 if ( element.name in this.submitted ) { 6199 this.element( element ); 6200 6201 // or option elements, check parent select in that case 6202 } else if ( element.parentNode.name in this.submitted ) { 6203 this.element( element.parentNode ); 6204 } 6205 }, 6206 highlight: function( element, errorClass, validClass ) { 6207 if ( element.type === "radio" ) { 6208 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); 6209 } else { 6210 $( element ).addClass( errorClass ).removeClass( validClass ); 6211 } 6212 }, 6213 unhighlight: function( element, errorClass, validClass ) { 6214 if ( element.type === "radio" ) { 6215 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); 6216 } else { 6217 $( element ).removeClass( errorClass ).addClass( validClass ); 6218 } 6219 } 6220 }, 6221 6222 // http://jqueryvalidation.org/jQuery.validator.setDefaults/ 6223 setDefaults: function( settings ) { 6224 $.extend( $.validator.defaults, settings ); 6225 }, 6226 6227 messages: { 6228 required: "This field is required.", 6229 remote: "Please fix this field.", 6230 email: "Please enter a valid email address.", 6231 url: "Please enter a valid URL.", 6232 date: "Please enter a valid date.", 6233 dateISO: "Please enter a valid date ( ISO ).", 6234 number: "Please enter a valid number.", 6235 digits: "Please enter only digits.", 6236 creditcard: "Please enter a valid credit card number.", 6237 equalTo: "Please enter the same value again.", 6238 maxlength: $.validator.format( "Please enter no more than {0} characters." ), 6239 minlength: $.validator.format( "Please enter at least {0} characters." ), 6240 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), 6241 range: $.validator.format( "Please enter a value between {0} and {1}." ), 6242 max: $.validator.format( "Please enter a value less than or equal to {0}." ), 6243 min: $.validator.format( "Please enter a value greater than or equal to {0}." ) 6244 }, 6245 6246 autoCreateRanges: false, 6247 6248 prototype: { 6249 6250 init: function() { 6251 this.labelContainer = $( this.settings.errorLabelContainer ); 6252 this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm ); 6253 this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer ); 6254 this.submitted = {}; 6255 this.valueCache = {}; 6256 this.pendingRequest = 0; 6257 this.pending = {}; 6258 this.invalid = {}; 6259 this.reset(); 6260 6261 var groups = ( this.groups = {} ), 6262 rules; 6263 $.each( this.settings.groups, function( key, value ) { 6264 if ( typeof value === "string" ) { 6265 value = value.split( /\s/ ); 6266 } 6267 $.each( value, function( index, name ) { 6268 groups[ name ] = key; 6269 }); 6270 }); 6271 rules = this.settings.rules; 6272 $.each( rules, function( key, value ) { 6273 rules[ key ] = $.validator.normalizeRule( value ); 6274 }); 6275 6276 function delegate( event ) { 6277 var validator = $.data( this[ 0 ].form, "validator" ), 6278 eventType = "on" + event.type.replace( /^validate/, "" ), 6279 settings = validator.settings; 6280 if ( settings[ eventType ] && !this.is( settings.ignore ) ) { 6281 settings[ eventType ].call( validator, this[ 0 ], event ); 6282 } 6283 } 6284 $( this.currentForm ) 6285 .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " + 6286 "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + 6287 "[type='email'], [type='datetime'], [type='date'], [type='month'], " + 6288 "[type='week'], [type='time'], [type='datetime-local'], " + 6289 "[type='range'], [type='color'], [type='radio'], [type='checkbox']", 6290 "focusin focusout keyup", delegate)
6291 // Support: Chrome, oldIE 6292 // "select" is provided as event.target when clicking a option 6293 .validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate); 6294 6295 if ( this.settings.invalidHandler ) { 6296 $( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler ); 6297 } 6298 6299 // Add aria-required to any Static/Data/Class required fields before first validation 6300 // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html 6301 $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" ); 6302 }, 6303 6304 // http://jqueryvalidation.org/Validator.form/ 6305 form: function() { 6306 this.checkForm(); 6307 $.extend( this.submitted, this.errorMap ); 6308 this.invalid = $.extend({}, this.errorMap ); 6309 if ( !this.valid() ) { 6310 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); 6311 } 6312 this.showErrors(); 6313 return this.valid(); 6314 }, 6315 6316 checkForm: function() { 6317 this.prepareForm(); 6318 for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { 6319 this.check( elements[ i ] ); 6320 } 6321 return this.valid(); 6322 }, 6323 6324 // http://jqueryvalidation.org/Validator.element/ 6325 element: function( element ) { 6326 var cleanElement = this.clean( element ), 6327 checkElement = this.validationTargetFor( cleanElement ), 6328 result = true; 6329 6330 this.lastElement = checkElement; 6331 6332 if ( checkElement === undefined ) { 6333 delete this.invalid[ cleanElement.name ]; 6334 } else { 6335 this.prepareElement( checkElement ); 6336 this.currentElements = $( checkElement ); 6337 6338 result = this.check( checkElement ) !== false; 6339 if ( result ) { 6340 delete this.invalid[ checkElement.name ]; 6341 } else { 6342 this.invalid[ checkElement.name ] = true; 6343 } 6344 } 6345 // Add aria-invalid status for screen readers 6346 $( element ).attr( "aria-invalid", !result ); 6347 6348 if ( !this.numberOfInvalids() ) { 6349 // Hide error containers on last error 6350 this.toHide = this.toHide.add( this.containers ); 6351 } 6352 this.showErrors(); 6353 return result; 6354 }, 6355 6356 // http://jqueryvalidation.org/Validator.showErrors/ 6357 showErrors: function( errors ) { 6358 if ( errors ) { 6359 // add items to error list and map 6360 $.extend( this.errorMap, errors ); 6361 this.errorList = []; 6362 for ( var name in errors ) { 6363 this.errorList.push({ 6364 message: errors[ name ], 6365 element: this.findByName( name )[ 0 ] 6366 }); 6367 } 6368 // remove items from success list 6369 this.successList = $.grep( this.successList, function( element ) { 6370 return !( element.name in errors ); 6371 }); 6372 } 6373 if ( this.settings.showErrors ) { 6374 this.settings.showErrors.call( this, this.errorMap, this.errorList ); 6375 } else { 6376 this.defaultShowErrors(); 6377 } 6378 }, 6379 6380 // http://jqueryvalidation.org/Validator.resetForm/ 6381 resetForm: function() { 6382 if ( $.fn.resetForm ) { 6383 $( this.currentForm ).resetForm(); 6384 } 6385 this.submitted = {}; 6386 this.lastElement = null; 6387 this.prepareForm(); 6388 this.hideErrors(); 6389 this.elements() 6390 .removeClass( this.settings.errorClass ) 6391 .removeData( "previousValue" ) 6392 .removeAttr( "aria-invalid" ); 6393 }, 6394 6395 numberOfInvalids: function() { 6396 return this.objectLength( this.invalid ); 6397 }, 6398 6399 objectLength: function( obj ) { 6400 /* jshint unused: false */ 6401 var count = 0, 6402 i; 6403 for ( i in obj ) { 6404 count++; 6405 } 6406 return count; 6407 }, 6408 6409 hideErrors: function() { 6410 this.hideThese( this.toHide ); 6411 }, 6412 6413 hideThese: function( errors ) { 6414 errors.not( this.containers ).text( "" ); 6415 this.addWrapper( errors ).hide(); 6416 }, 6417 6418 valid: function() { 6419 return this.size() === 0; 6420 }, 6421 6422 size: function() { 6423 return this.errorList.length; 6424 }, 6425 6426 focusInvalid: function() { 6427 if ( this.settings.focusInvalid ) { 6428 try { 6429 $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || []) 6430 .filter( ":visible" ) 6431 .focus() 6432 // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 6433 .trigger( "focusin" ); 6434 } catch ( e ) {
6435 // ignore IE throwing errors when focusing hidden elements 6436 } 6437 } 6438 }, 6439 6440 findLastActive: function() { 6441 var lastActive = this.lastActive; 6442 return lastActive && $.grep( this.errorList, function( n ) { 6443 return n.element.name === lastActive.name; 6444 }).length === 1 && lastActive; 6445 }, 6446 6447 elements: function() { 6448 var validator = this, 6449 rulesCache = {}; 6450 6451 // select all valid inputs inside the form (no submit or reset buttons) 6452 return $( this.currentForm ) 6453 .find( "input, select, textarea" ) 6454 .not( ":submit, :reset, :image, [disabled], [readonly]" ) 6455 .not( this.settings.ignore ) 6456 .filter( function() { 6457 if ( !this.name && validator.settings.debug && window.console ) { 6458 console.error( "%o has no name assigned", this ); 6459 } 6460 6461 // select only the first element for each name, and only those with rules specified 6462 if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { 6463 return false; 6464 } 6465 6466 rulesCache[ this.name ] = true; 6467 return true; 6468 }); 6469 }, 6470 6471 clean: function( selector ) { 6472 return $( selector )[ 0 ]; 6473 }, 6474 6475 errors: function() { 6476 var errorClass = this.settings.errorClass.split( " " ).join( "." ); 6477 return $( this.settings.errorElement + "." + errorClass, this.errorContext ); 6478 }, 6479 6480 reset: function() { 6481 this.successList = []; 6482 this.errorList = []; 6483 this.errorMap = {}; 6484 this.toShow = $( [] ); 6485 this.toHide = $( [] ); 6486 this.currentElements = $( [] ); 6487 }, 6488 6489 prepareForm: function() { 6490 this.reset(); 6491 this.toHide = this.errors().add( this.containers ); 6492 }, 6493 6494 prepareElement: function( element ) { 6495 this.reset(); 6496 this.toHide = this.errorsFor( element ); 6497 }, 6498 6499 elementValue: function( element ) { 6500 var val, 6501 $element = $( element ), 6502 type = element.type; 6503 6504 if ( type === "radio" || type === "checkbox" ) { 6505 return $( "input[name='" + element.name + "']:checked" ).val(); 6506 } else if ( type === "number" && typeof element.validity !== "undefined" ) { 6507 return element.validity.badInput ? false : $element.val(); 6508 } 6509 6510 val = $element.val(); 6511 if ( typeof val === "string" ) { 6512 return val.replace(/\r/g, "" ); 6513 } 6514 return val; 6515 }, 6516 6517 check: function( element ) { 6518 element = this.validationTargetFor( this.clean( element ) ); 6519 6520 var rules = $( element ).rules(), 6521 rulesCount = $.map( rules, function( n, i ) { 6522 return i; 6523 }).length, 6524 dependencyMismatch = false, 6525 val = this.elementValue( element ), 6526 result, method, rule; 6527 6528 for ( method in rules ) { 6529 rule = { method: method, parameters: rules[ method ] }; 6530 try { 6531 6532 result = $.validator.methods[ method ].call( this, val, element, rule.parameters ); 6533 6534 // if a method indicates that the field is optional and therefore valid, 6535 // don't mark it as valid when there are no other rules 6536 if ( result === "dependency-mismatch" && rulesCount === 1 ) { 6537 dependencyMismatch = true; 6538 continue; 6539 } 6540 dependencyMismatch = false; 6541 6542 if ( result === "pending" ) { 6543 this.toHide = this.toHide.not( this.errorsFor( element ) ); 6544 return; 6545 } 6546 6547 if ( !result ) { 6548 this.formatAndAdd( element, rule ); 6549 return false; 6550 } 6551 } catch ( e ) { 6552 if ( this.settings.debug && window.console ) { 6553 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); 6554 } 6555 throw e; 6556 } 6557 } 6558 if ( dependencyMismatch ) { 6559 return; 6560 } 6561 if ( this.objectLength( rules ) ) { 6562 this.successList.push( element ); 6563 } 6564 return true; 6565 }, 6566 6567 // return the custom message for the given element and validation method 6568 // specified in the element's HTML5 data attribute 6569 // return the generic message if present and no method specific message is present 6570 customDataMessage: function( element, method ) { 6571 return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() + 6572 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" ); 6573 }, 6574 6575 // return the custom message for the given element name and validation method 6576 customMessage: function( name, method ) { 6577 var m = this.settings.messages[ name ]; 6578 return m && ( m.constructor === String ? m : m[ method ]); 6579 }, 6580 6581 // return the first defined argument, allowing empty strings 6582 findDefined: function() { 6583 for ( var i = 0; i < arguments.length; i++) { 6584 if ( arguments[ i ] !== undefined ) { 6585 return arguments[ i ]; 6586 } 6587 } 6588 return undefined; 6589 }, 6590 6591 defaultMessage: function( element, method ) { 6592 return this.findDefined( 6593 this.customMessage( element.name, method ), 6594 this.customDataMessage( element, method ), 6595 // title is never undefined, so handle empty string as undefined 6596 !this.settings.ignoreTitle && element.title || undefined, 6597 $.validator.messages[ method ], 6598 "<strong>Warning: No message defined for " + element.name + "</strong>" 6599 ); 6600 }, 6601 6602 formatAndAdd: function( element, rule ) { 6603 var message = this.defaultMessage( element, rule.method ), 6604 theregex = /\$?\{(\d+)\}/g; 6605 if ( typeof message === "function" ) { 6606 message = message.call( this, rule.parameters, element ); 6607 } else if ( theregex.test( message ) ) { 6608 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters ); 6609 } 6610 this.errorList.push({ 6611 message: message, 6612 element: element, 6613 method: rule.method 6614 }); 6615 6616 this.errorMap[ element.name ] = message; 6617 this.submitted[ element.name ] = message; 6618 }, 6619 6620 addWrapper: function( toToggle ) { 6621 if ( this.settings.wrapper ) { 6622 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 6623 } 6624 return toToggle; 6625 }, 6626 6627 defaultShowErrors: function() { 6628 var i, elements, error; 6629 for ( i = 0; this.errorList[ i ]; i++ ) { 6630 error = this.errorList[ i ]; 6631 if ( this.settings.highlight ) { 6632 this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.val
6632idClass ); 6633 } 6634 this.showLabel( error.element, error.message ); 6635 } 6636 if ( this.errorList.length ) { 6637 this.toShow = this.toShow.add( this.containers ); 6638 } 6639 if ( this.settings.success ) { 6640 for ( i = 0; this.successList[ i ]; i++ ) { 6641 this.showLabel( this.successList[ i ] ); 6642 } 6643 } 6644 if ( this.settings.unhighlight ) { 6645 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) { 6646 this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass ); 6647 } 6648 } 6649 this.toHide = this.toHide.not( this.toShow ); 6650 this.hideErrors(); 6651 this.addWrapper( this.toShow ).show(); 6652 }, 6653 6654 validElements: function() { 6655 return this.currentElements.not( this.invalidElements() ); 6656 }, 6657 6658 invalidElements: function() { 6659 return $( this.errorList ).map(function() { 6660 return this.element; 6661 }); 6662 }, 6663 6664 showLabel: function( element, message ) { 6665 var place, group, errorID, 6666 error = this.errorsFor( element ), 6667 elementID = this.idOrName( element ), 6668 describedBy = $( element ).attr( "aria-describedby" ); 6669 if ( error.length ) { 6670 // refresh error/success class 6671 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); 6672 // replace message on existing label 6673 error.html( message ); 6674 } else { 6675 // create error element 6676 error = $( "<" + this.settings.errorElement + ">" ) 6677 .attr( "id", elementID + "-error" ) 6678 .addClass( this.settings.errorClass ) 6679 .html( message || "" ); 6680 6681 // Maintain reference to the element to be placed into the DOM 6682 place = error; 6683 if ( this.settings.wrapper ) { 6684 // make sure the element is visible, even in IE 6685 // actually showing the wrapped element is handled elsewhere 6686 place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent(); 6687 } 6688 if ( this.labelContainer.length ) { 6689 this.labelContainer.append( place ); 6690 } else if ( this.settings.errorPlacement ) { 6691 this.settings.errorPlacement( place, $( element ) ); 6692 } else { 6693 place.insertAfter( element ); 6694 } 6695 6696 // Link error back to the element 6697 if ( error.is( "label" ) ) { 6698 // If the error is a label, then associate using 'for' 6699 error.attr( "for", elementID ); 6700 } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) { 6701 // If the element is not a child of an associated label, then it's necessary 6702 // to explicitly apply aria-describedby 6703 6704 errorID = error.attr( "id" ).replace( /(:|\.|\[|\])/g, "\\$1"); 6705 // Respect existing non-error aria-describedby 6706 if ( !describedBy ) { 6707 describedBy = errorID; 6708 } else if ( !describedBy.match( new RegExp( "\\b" + errorID + "\\b" ) ) ) { 6709 // Add to end of list if not already present 6710 describedBy += " " + errorID; 6711 } 6712 $( element ).attr( "aria-describedby", describedBy ); 6713 6714 // If this element is grouped, then assign to all elements in the same group 6715 group = this.groups[ element.name ]; 6716 if ( group ) { 6717 $.each( this.groups, function( name, testgroup ) { 6718 if ( testgroup === group ) { 6719 $( "[name='" + name + "']", this.currentForm ) 6720 .attr( "aria-describedby", error.attr( "id" ) ); 6721 } 6722 }); 6723 } 6724 } 6725 } 6726 if ( !message && this.settings.success ) { 6727 error.text( "" ); 6728 if ( typeof this.settings.success === "string" ) { 6729 error.addClass( this.settings.success ); 6730 } else { 6731 this.settings.success( error, element ); 6732 } 6733 } 6734 this.toShow = this.toShow.add( error ); 6735 }, 6736 6737 errorsFor: function( element ) { 6738 var name = this.idOrName( element ), 6739 describer = $( element ).attr( "aria-describedby" ), 6740 selector = "label[for='" + name + "'], label[for='" + name + "'] *"; 6741 6742 // aria-describedby should directly reference the error element 6743 if ( describer ) { 6744 selector = selector + ", #" + describer.replace( /\s+/g, ", #" ); 6745 } 6746 return this 6747 .errors() 6748 .filter( selector ); 6749 }, 6750 6751 idOrName: function( element ) { 6752 return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.i
vendor: 11,336 bytes, lines 6752-7089
6752d || element.name ); 6753 }, 6754 6755 validationTargetFor: function( element ) { 6756 6757 // If radio/checkbox, validate first element in group instead 6758 if ( this.checkable( element ) ) { 6759 element = this.findByName( element.name ); 6760 } 6761 6762 // Always apply ignore filter 6763 return $( element ).not( this.settings.ignore )[ 0 ]; 6764 }, 6765 6766 checkable: function( element ) { 6767 return ( /radio|checkbox/i ).test( element.type ); 6768 }, 6769 6770 findByName: function( name ) { 6771 return $( this.currentForm ).find( "[name='" + name + "']" ); 6772 }, 6773 6774 getLength: function( value, element ) { 6775 switch ( element.nodeName.toLowerCase() ) { 6776 case "select": 6777 return $( "option:selected", element ).length; 6778 case "input": 6779 if ( this.checkable( element ) ) { 6780 return this.findByName( element.name ).filter( ":checked" ).length; 6781 } 6782 } 6783 return value.length; 6784 }, 6785 6786 depend: function( param, element ) { 6787 return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true; 6788 }, 6789 6790 dependTypes: { 6791 "boolean": function( param ) { 6792 return param; 6793 }, 6794 "string": function( param, element ) { 6795 return !!$( param, element.form ).length; 6796 }, 6797 "function": function( param, element ) { 6798 return param( element ); 6799 } 6800 }, 6801 6802 optional: function( element ) { 6803 var val = this.elementValue( element ); 6804 return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch"; 6805 }, 6806 6807 startRequest: function( element ) { 6808 if ( !this.pending[ element.name ] ) { 6809 this.pendingRequest++; 6810 this.pending[ element.name ] = true; 6811 } 6812 }, 6813 6814 stopRequest: function( element, valid ) { 6815 this.pendingRequest--; 6816 // sometimes synchronization fails, make sure pendingRequest is never < 0 6817 if ( this.pendingRequest < 0 ) { 6818 this.pendingRequest = 0; 6819 } 6820 delete this.pending[ element.name ]; 6821 if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { 6822 $( this.currentForm ).submit(); 6823 this.formSubmitted = false; 6824 } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) { 6825 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); 6826 this.formSubmitted = false; 6827 } 6828 }, 6829 6830 previousValue: function( element ) { 6831 return $.data( element, "previousValue" ) || $.data( element, "previousValue", { 6832 old: null, 6833 valid: true, 6834 message: this.defaultMessage( element, "remote" ) 6835 }); 6836 } 6837 6838 }, 6839 6840 classRuleSettings: { 6841 required: { required: true }, 6842 email: { email: true }, 6843 url: { url: true }, 6844 date: { date: true }, 6845 dateISO: { dateISO: true }, 6846 number: { number: true }, 6847 digits: { digits: true }, 6848 creditcard: { creditcard: true } 6849 }, 6850 6851 addClassRules: function( className, rules ) { 6852 if ( className.constructor === String ) { 6853 this.classRuleSettings[ className ] = rules; 6854 } else { 6855 $.extend( this.classRuleSettings, className ); 6856 } 6857 }, 6858 6859 classRules: function( element ) { 6860 var rules = {}, 6861 classes = $( element ).attr( "class" ); 6862 6863 if ( classes ) { 6864 $.each( classes.split( " " ), function() { 6865 if ( this in $.validator.classRuleSettings ) { 6866 $.extend( rules, $.validator.classRuleSettings[ this ]); 6867 } 6868 }); 6869 } 6870 return rules; 6871 }, 6872 6873 attributeRules: function( element ) { 6874 var rules = {}, 6875 $element = $( element ), 6876 type = element.getAttribute( "type" ), 6877 method, value; 6878 6879 for ( method in $.validator.methods ) { 6880 6881 // support for <input required> in both html5 and older browsers 6882 if ( method === "required" ) { 6883 value = element.getAttribute( method ); 6884 // Some browsers return an empty string for the required attribute 6885 // and non-HTML5 browsers might have required="" markup 6886 if ( value === "" ) { 6887 value = true; 6888 } 6889 // force non-HTML5 browsers to return bool 6890 value = !!value; 6891 } else { 6892 value = $element.attr( method ); 6893 } 6894 6895 // convert the value to a number for number inputs, and for text for backwards compability 6896 // allows type="date" and others to be compared as strings 6897 if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { 6898 value = Number( value ); 6899 } 6900 6901 if ( value || value === 0 ) { 6902 rules[ method ] = value; 6903 } else if ( type === method && type !== "range" ) { 6904 // exception: the jquery validate 'range' method 6905 // does not test for the html5 'range' type 6906 rules[ method ] = true; 6907 } 6908 } 6909 6910 // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs 6911 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) { 6912 delete rules.maxlength; 6913 } 6914 6915 return rules; 6916 }, 6917 6918 dataRules: function( element ) { 6919 var method, value, 6920 rules = {}, $element = $( element ); 6921 for ( method in $.validator.methods ) { 6922 value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() ); 6923 if ( value !== undefined ) { 6924 rules[ method ] = value; 6925 } 6926 } 6927 return rules; 6928 }, 6929 6930 staticRules: function( element ) { 6931 var rules = {}, 6932 validator = $.data( element.form, "validator" ); 6933 6934 if ( validator.settings.rules ) { 6935 rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {}; 6936 } 6937 return rules; 6938 }, 6939 6940 normalizeRules: function( rules, element ) { 6941 // handle dependency check 6942 $.each( rules, function( prop, val ) { 6943 // ignore rule when param is explicitly false, eg. required:false 6944 if ( val === false ) { 6945 delete rules[ prop ]; 6946 return; 6947 } 6948 if ( val.param || val.depends ) { 6949 var keepRule = true; 6950 switch ( typeof val.depends ) { 6951 case "string": 6952 keepRule = !!$( val.depends, element.form ).length; 6953 break; 6954 case "function": 6955 keepRule = val.depends.call( element, element ); 6956 break; 6957 } 6958 if ( keepRule ) { 6959 rules[ prop ] = val.param !== undefined ? val.param : true; 6960 } else { 6961 delete rules[ prop ]; 6962 } 6963 } 6964 }); 6965 6966 // evaluate parameters 6967 $.each( rules, function( rule, parameter ) { 6968 rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter; 6969 }); 6970 6971 // clean number parameters 6972 $.each([ "minlength", "maxlength" ], function() { 6973 if ( rules[ this ] ) { 6974 rules[ this ] = Number( rules[ this ] ); 6975 } 6976 }); 6977 $.each([ "rangelength", "range" ], function() { 6978 var parts; 6979 if ( rules[ this ] ) { 6980 if ( $.isArray( rules[ this ] ) ) { 6981 rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ]; 6982 } else if ( typeof rules[ this ] === "string" ) { 6983 parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ ); 6984 rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ]; 6985 } 6986 } 6987 }); 6988 6989 if ( $.validator.autoCreateRanges ) { 6990 // auto-create ranges 6991 if ( rules.min != null && rules.max != null ) { 6992 rules.range = [ rules.min, rules.max ]; 6993 delete rules.min; 6994 delete rules.max; 6995 } 6996 if ( rules.minlength != null && rules.maxlength != null ) { 6997 rules.rangelength = [ rules.minlength, rules.maxlength ]; 6998 delete rules.minlength; 6999 delete rules.maxlength; 7000 } 7001 } 7002 7003 return rules; 7004 }, 7005 7006 // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 7007 normalizeRule: function( data ) { 7008 if ( typeof data === "string" ) { 7009 var transformed = {}; 7010 $.each( data.split( /\s/ ), function() { 7011 transformed[ this ] = true; 7012 }); 7013 data = transformed; 7014 } 7015 return data; 7016 }, 7017 7018 // http://jqueryvalidation.org/jQuery.validator.addMethod/ 7019 addMethod: function( name, method, message ) { 7020 $.validator.methods[ name ] = method; 7021 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ]; 7022 if ( method.length < 3 ) { 7023 $.validator.addClassRules( name, $.validator.normalizeRule( name ) ); 7024 } 7025 }, 7026 7027 methods: { 7028 7029 // http://jqueryvalidation.org/required-method/ 7030 required: function( value, element, param ) { 7031 // check if dependency is met 7032 if ( !this.depend( param, element ) ) { 7033 return "dependency-mismatch"; 7034 } 7035 if ( element.nodeName.toLowerCase() === "select" ) { 7036 // could be an array for select-multiple or a string, both are fine this way 7037 var val = $( element ).val(); 7038 return val && val.length > 0; 7039 } 7040 if ( this.checkable( element ) ) { 7041 return this.getLength( value, element ) > 0; 7042 } 7043 return $.trim( value ).length > 0; 7044 }, 7045 7046 // http://jqueryvalidation.org/email-method/ 7047 email: function( value, element ) { 7048 // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29 7049 // Retrieved 2014-01-14 7050 // If you have a problem with this implementation, report a bug against the above spec 7051 // Or use custom methods to implement your own email validation 7052 return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value ); 7053 }, 7054 7055 // http://jqueryvalidation.org/url-method/ 7056 url: function( value, element ) { 7057 // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ 7058 return this.optional( element ) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value ); 7059 }, 7060 7061 // http://jqueryvalidation.org/date-method/ 7062 date: function( value, element ) { 7063 return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); 7064 }, 7065 7066 // http://jqueryvalidation.org/dateISO-method/ 7067 dateISO: function( value, element ) { 7068 return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value ); 7069 }, 7070 7071 // http://jqueryvalidation.org/number-method/ 7072 number: function( value, element ) { 7073 return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value ); 7074 }, 7075 7076 // http://jqueryvalidation.org/digits-method/ 7077 digits: function( value, element ) { 7078 return this.optional( element ) || /^\d+$/.test( value ); 7079 }, 7080 7081 // http://jqueryvalidation.org/creditcard-method/ 7082 // based on http://en.wikipedia.org/wiki/Luhn/ 7083 creditcard: function( value, element ) { 7084 if ( this.optional( element ) ) { 7085 return "dependency-mismatch"; 7086 } 7087 // accept only spaces, digits and dashes 7088 if ( /[^0-9 \-]+/.test( value ) ) { 7089 return false;
7090 } 7091 var nCheck = 0, 7092 nDigit = 0, 7093 bEven = false, 7094 n, cDigit; 7095 7096 value = value.replace( /\D/g, "" ); 7097 7098 // Basing min and max length on 7099 // http://developer.ean.com/general_info/Valid_Credit_Card_Types 7100 if ( value.length < 13 || value.length > 19 ) { 7101 return false; 7102 } 7103 7104 for ( n = value.length - 1; n >= 0; n--) { 7105 cDigit = value.charAt( n ); 7106 nDigit = parseInt( cDigit, 10 ); 7107 if ( bEven ) { 7108 if ( ( nDigit *= 2 ) > 9 ) { 7109 nDigit -= 9; 7110 } 7111 } 7112 nCheck += nDigit; 7113 bEven = !bEven; 7114 } 7115 7116 return ( nCheck % 10 ) === 0; 7117 }, 7118 7119 // http://jqueryvalidation.org/minlength-method/ 7120 minlength: function( value, element, param ) { 7121 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 7122 return this.optional( element ) || length >= param; 7123 }, 7124 7125 // http://jqueryvalidation.org/maxlength-method/ 7126 maxlength: function( value, element, param ) { 7127 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 7128 return this.optional( element ) || length <= param; 7129 }, 7130 7131 // http://jqueryvalidation.org/rangelength-method/ 7132 rangelength: function( value, element, param ) { 7133 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 7134 return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] ); 7135 }, 7136 7137 // http://jqueryvalidation.org/min-method/ 7138 min: function( value, element, param ) { 7139 return this.optional( element ) || value >= param; 7140 }, 7141 7142 // http://jqueryvalidation.org/max-method/ 7143 max: function( value, element, param ) { 7144 return this.optional( element ) || value <= param; 7145 }, 7146 7147 // http://jqueryvalidation.org/range-method/ 7148 range: function( value, element, param ) { 7149 return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); 7150 }, 7151 7152 // http://jqueryvalidation.org/equalTo-method/ 7153 equalTo: function( value, element, param ) {
7154 // bind to the blur event of the target in order to revalidate whenever the target field is updated 7155 // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 7156 var target = $( param ); 7157 if ( this.settings.onfocusout ) { 7158 target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() { 7159 $( element ).valid(); 7160 }); 7161 } 7162 return value === target.val(); 7163 }, 7164 7165 // http://jqueryvalidation.org/remote-method/ 7166 remote: function( value, element, param ) { 7167 if ( this.optional( element ) ) { 7168 return "dependency-mismatch"; 7169 } 7170 7171 var previous = this.previousValue( element ), 7172 validator, data; 7173 7174 if (!this.settings.messages[ element.name ] ) { 7175 this.settings.messages[ element.name ] = {}; 7176 } 7177 previous.originalMessage = this.settings.messages[ element.name ].remote; 7178 this.settings.messages[ element.name ].remote = previous.message; 7179 7180 param = typeof param === "string" && { url: param } || param; 7181 7182 if ( previous.old === value ) { 7183 return previous.valid; 7184 } 7185 7186 previous.old = value; 7187 validator = this; 7188 this.startRequest( element ); 7189 data = {}; 7190 data[ element.name ] = value; 7191 $.ajax( $.extend( true, { 7192 url: param, 7193 mode: "abort", 7194 port: "validate" + element.name, 7195 dataType: "json", 7196 data: data, 7197 context: validator.currentForm, 7198 success: function( response ) { 7199 var valid = response === true || response === "true", 7200 errors, message, submitted; 7201 7202 validator.settings.messages[ element.name ].remote = previous.originalMessage; 7203 if ( valid ) { 7204 submitted = validator.formSubmitted; 7205 validator.prepareElement( element ); 7206 validator.formSubmitted = submitted; 7207 validator.successList.push( element ); 7208 delete validator.invalid[ element.name ]; 7209 validator.showErrors(); 7210 } else { 7211 errors = {}; 7212 message = response || validator.defaultMessage( element, "remote" ); 7213 errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message; 7214 validator.invalid[ element.name ] = true; 7215 validator.showErrors( errors ); 7216 } 7217 previous.valid = valid; 7218 validator.stopRequest( element, valid ); 7219 } 7220 }, param ) ); 7221 return "pending"; 7222 } 7223 7224 } 7225 7226}); 7227 7228$.format = function deprecated() { 7229 throw "$.format has been deprecated. Please use $.validator.format instead."; 7230}; 7231 7232// ajax mode: abort 7233// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 7234// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 7235 7236var pendingRequests = {}, 7237 ajax; 7238// Use a prefilter if available (1.5+) 7239if ( $.ajaxPrefilter ) { 7240 $.ajaxPrefilter(function( settings, _, xhr ) { 7241 var port = settings.port; 7242 if ( settings.mode === "abort" ) { 7243 if ( pendingRequests[port] ) { 7244 pendingRequests[port].abort(); 7245 } 7246 pendingRequests[port] = xhr; 7247 } 7248 }); 7249} else { 7250 // Proxy ajax 7251 ajax = $.ajax; 7252 $.ajax = function( settings ) { 7253 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 7254 port = ( "port" in settings ? settings : $.ajaxSettings ).port; 7255 if ( mode === "abort" ) { 7256 if ( pendingRequests[port] ) { 7257 pendingRequests[port].abort(); 7258 } 7259 pendingRequests[port] = ajax.apply(this, arguments); 7260 return pendingRequests[port]; 7261 } 7262 return ajax.apply(this, arguments); 7263 }; 7264} 7265 7266// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation 7267// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target 7268 7269$.extend($.fn, { 7270 validateDelegate: function( delegate, type, handler ) { 7271 return this.bind(type, function( event ) { 7272 var target = $(event.target); 7273 if ( target.is(delegate) ) { 7274 return handler.apply(target, arguments); 7275 } 7276 }); 7277 } 7278}); 7279 7280})); 7281;/*})'"*/ 7282;/*})'"*/ 7283/*! 7284 * Stellar.js v0.6.2 7285 * http://markdalgleish.com/projects/stellar.js 7286 * 7287 * Copyright 2013, Mark Dalgleish 7288 * This content is released under the MIT license 7289 * http://markdalgleish.mit-license.org 7290 */ 7291 7292;(function($, window, document, undefined) { 7293 7294 var pluginName = 'stellar', 7295 defaults = { 7296 scrollProperty: 'scroll', 7297 positionProperty: 'position', 7298 horizontalScrolling: true, 7299 verticalScrolling: true, 7300 horizontalOffset: 0, 7301 verticalOffset: 0, 7302 responsive: false,
7303 parallaxBackgrounds: true, 7304 parallaxElements: true, 7305 hideDistantElements: true, 7306 hideElement: function($elem) { $elem.hide(); }, 7307 showElement: function($elem) { $elem.show(); } 7308 }, 7309 7310 scrollProperty = { 7311 scroll: { 7312 getLeft: function($elem) { return $elem.scrollLeft(); }, 7313 setLeft: function($elem, val) { $elem.scrollLeft(val); }, 7314 7315 getTop: function($elem) { return $elem.scrollTop(); }, 7316 setTop: function($elem, val) { $elem.scrollTop(val); } 7317 }, 7318 position: { 7319 getLeft: function($elem) { return parseInt($elem.css('left'), 10) * -1; }, 7320 getTop: function($elem) { return parseInt($elem.css('top'), 10) * -1; } 7321 }, 7322 margin: { 7323 getLeft: function($elem) { return parseInt($elem.css('margin-left'), 10) * -1; }, 7324 getTop: function($elem) { return parseInt($elem.css('margin-top'), 10) * -1; } 7325 }, 7326 transform: { 7327 getLeft: function($elem) { 7328 var computedTransform = getComputedStyle($elem[0])[prefixedTransform]; 7329 return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[4], 10) * -1 : 0); 7330 }, 7331 getTop: function($elem) { 7332 var computedTransform = getComputedStyle($elem[0])[prefixedTransform]; 7333 return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[5], 10) * -1 : 0); 7334 } 7335 } 7336 }, 7337 7338 positionProperty = { 7339 position: { 7340 setLeft: function($elem, left) { $elem.css('left', left); }, 7341 setTop: function($elem, top) { $elem.css('top', top); } 7342 }, 7343 transform: { 7344 setPosition: function($elem, left, startingLeft, top, startingTop) { 7345 $elem[0].style[prefixedTransform] = 'translate3d(' + (left - startingLeft) + 'px, ' + (top - startingTop) + 'px, 0)'; 7346 } 7347 } 7348 }, 7349 7350 // Returns a function which adds a vendor prefix to any CSS property name 7351 vendorPrefix = (function() { 7352 var prefixes = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/, 7353 style = $('script')[0].style, 7354 prefix = '', 7355 prop; 7356 7357 for (prop in style) { 7358 if (prefixes.test(prop)) { 7359 prefix = prop.match(prefixes)[0]; 7360 break; 7361 } 7362 } 7363 7364 if ('WebkitOpacity' in style) { prefix = 'Webkit'; } 7365 if ('KhtmlOpacity' in style) { prefix = 'Khtml'; } 7366 7367 return function(property) { 7368 return prefix + (prefix.length > 0 ? property.charAt(0).toUpperCase() + property.slice(1) : property); 7369 }; 7370 }()), 7371 7372 prefixedTransform = vendorPrefix('transform'), 7373 7374 supportsBackgroundPositionXY = $('<div />', { style: 'background:#fff' }).css('background-position-x') !== undefined, 7375 7376 setBackgroundPosition = (supportsBackgroundPositionXY ? 7377 function($elem, x, y) { 7378 $elem.css({ 7379 'background-position-x': x, 7380 'background-position-y': y 7381 }); 7382 } : 7383 function($elem, x, y) { 7384 $elem.css('background-position', x + ' ' + y); 7385 } 7386 ), 7387 7388 getBackgroundPosition = (supportsBackgroundPositionXY ? 7389 function($elem) { 7390 return [ 7391 $elem.css('background-position-x'), 7392 $elem.css('background-position-y') 7393 ]; 7394 } : 7395 function($elem) { 7396 return $elem.css('background-position').split(' '); 7397 } 7398 ), 7399 7400 requestAnimFrame = ( 7401 window.requestAnimationFrame || 7402 window.webkitRequestAnimationFrame || 7403 window.mozRequestAnimationFrame || 7404 window.oRequestAnimationFrame || 7405 window.msRequestAnimationFrame || 7406 function(callback) { 7407 setTimeout(callback, 1000 / 60); 7408 } 7409 ); 7410 7411 function Plugin(element, options) { 7412 this.element = element; 7413 this.options = $.extend({}, defaults, options); 7414 7415 this._defaults = defaults; 7416 this._name = pluginName; 7417 7418 this.init(); 7419 } 7420 7421 Plugin.prototype = { 7422 init: function() { 7423 this.options.name = pluginName + '_' + Math.floor(Math.random() * 1e9); 7424 7425 this._defineElements(); 7426 this._defineGetters(); 7427 this._defineSetters(); 7428 this._handleWindowLoadAndResize(); 7429 this._detectViewport(); 7430 7431 this.refresh({ firstLoad: true }); 7432 7433 if (this.options.scrollProperty === 'scroll') { 7434 this._handleScrollEvent(); 7435 } else { 7436 this._startAnimationLoop(); 7437 } 7438 }, 7439 _defineElements: function() { 7440 if (this.element === document.body) this.element = window; 7441 this.$scrollElement = $(this.element); 7442 this.$element = (this.element === window ? $('body') : this.$scrollElement); 7443 this.$viewportElement = (this.options.viewportElement !== undefined ? $(this.options.viewportElement) : (this.$scrollElement[0] === window || this.options.scrollProperty === 'scroll' ? this.$scrollElement : this.$scrollElement.parent()) ); 7444 }, 7445 _defineGetters: function() { 7446 var self = this, 7447 scrollPropertyAdapter = scrollProperty[self.options.scrollProperty]; 7448 7449 this._getScrollLeft = function() { 7450 return scrollPropertyAdapter.getLeft(self.$scrollElement); 7451 }; 7452 7453 this._getScrollTop = function() { 7454 return scrollPropertyAdapter.getTop(self.$scrollElement); 7455 }; 7456 }, 7457 _defineSetters: function() { 7458 var self = this, 7459 scrollPropertyAdapter = scrollProperty[self.options.scrollProperty], 7460 positionPropertyAdapter = positionProperty[self.options.positionProperty], 7461 setScrollLeft = scrollPropertyAdapter.setLeft, 7462 setScrollTop = scrollPropertyAdapter.setTop; 7463 7464 this._setScrollLeft = (typeof setScrollLeft === 'function' ? function(val) { 7465 setScrollLeft(self.$scrollElement, val); 7466 } : $.noop); 7467 7468 this._setScrollTop = (typeof setScrollTop === 'function' ? function(val) { 7469 setScrollTop(self.$scrollElement, val); 7470 } : $.noop); 7471 7472 this._setPosition = positionPropertyAdapter.setPosition || 7473 function($elem, left, startingLeft, top, startingTop) { 7474 if (self.options.horizontalScrolling) { 7475 positionPropertyAdapter.setLeft($elem, left, startingLeft); 7476 } 7477 7478 if (self.options.verticalScrolling) { 7479 positionPropertyAdapter.setTop($elem, top, startingTop); 7480 } 7481 }; 7482 },
7483 _handleWindowLoadAndResize: function() { 7484 var self = this, 7485 $window = $(window); 7486 7487 if (self.options.responsive) { 7488 $window.bind('load.' + this.name, function() { 7489 self.refresh(); 7490 }); 7491 } 7492 7493 $window.bind('resize.' + this.name, function() { 7494 self._detectViewport(); 7495 7496 if (self.options.responsive) { 7497 self.refresh(); 7498 } 7499 }); 7500 }, 7501 refresh: function(options) { 7502 var self = this, 7503 oldLeft = self._getScrollLeft(), 7504 oldTop = self._getScrollTop(); 7505 7506 if (!options || !options.firstLoad) { 7507 this._reset(); 7508 } 7509 7510 this._setScrollLeft(0); 7511 this._setScrollTop(0); 7512 7513 this._setOffsets(); 7514 this._findParticles(); 7515 this._findBackgrounds(); 7516 7517 // Fix for WebKit background rendering bug 7518 if (options && options.firstLoad && /WebKit/.test(navigator.userAgent)) { 7519 $(window).load(function() { 7520 var oldLeft = self._getScrollLeft(), 7521 oldTop = self._getScrollTop(); 7522 7523 self._setScrollLeft(oldLeft + 1); 7524 self._setScrollTop(oldTop + 1); 7525 7526 self._setScrollLeft(oldLeft); 7527 self._setScrollTop(oldTop); 7528 }); 7529 } 7530 7531 this._setScrollLeft(oldLeft); 7532 this._setScrollTop(oldTop); 7533 }, 7534 _detectViewport: function() { 7535 var viewportOffsets = this.$viewportElement.offset(), 7536 hasOffsets = viewportOffsets !== null && viewportOffsets !== undefined; 7537 7538 this.viewportWidth = this.$viewportElement.width(); 7539 this.viewportHeight = this.$viewportElement.height(); 7540 7541 this.viewportOffsetTop = (hasOffsets ? viewportOffsets.top : 0); 7542 this.viewportOffsetLeft = (hasOffsets ? viewportOffsets.left : 0); 7543 }, 7544 _findParticles: function() { 7545 var self = this, 7546 scrollLeft = this._getScrollLeft(), 7547 scrollTop = this._getScrollTop(); 7548 7549 if (this.particles !== undefined) { 7550 for (var i = this.particles.length - 1; i >= 0; i--) { 7551 this.particles[i].$element.data('stellar-elementIsActive', undefined); 7552 } 7553 } 7554 7555 this.particles = []; 7556 7557 if (!this.options.parallaxElements) return; 7558 7559 this.$element.find('[data-stellar-ratio]').each(function(i) { 7560 var $this = $(this), 7561 horizontalOffset, 7562 verticalOffset, 7563 positionLeft, 7564 positionTop, 7565 marginLeft, 7566 marginTop, 7567 $offsetParent, 7568 offsetLeft, 7569 offsetTop, 7570 parentOffsetLeft = 0, 7571 parentOffsetTop = 0, 7572 tempParentOffsetLeft = 0, 7573 tempParentOffsetTop = 0; 7574 7575 // Ensure this element isn't already part of another scrolling element 7576 if (!$this.data('stellar-elementIsActive')) { 7577 $this.data('stellar-elementIsActive', this); 7578 } else if ($this.data('stellar-elementIsActive') !== this) { 7579 return; 7580 } 7581 7582 self.options.showElement($this); 7583 7584 // Save/restore the original top and left CSS values in case we refresh the particles or destroy the instance 7585 if (!$this.data('stellar-startingLeft')) { 7586 $this.data('stellar-startingLeft', $this.css('left')); 7587 $this.data('stellar-startingTop', $this.css('top')); 7588 } else { 7589 $this.css('left', $this.data('stellar-startingLeft')); 7590 $this.css('top', $this.data('stellar-startingTop')); 7591 } 7592 7593 positionLeft = $this.position().left; 7594 positionTop = $this.position().top; 7595 7596 // Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8) 7597 marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), 10); 7598 marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), 10); 7599 7600 offsetLeft = $this.offset().left - marginLeft; 7601 offsetTop = $this.offset().top - marginTop; 7602 7603 // Calculate the offset parent 7604 $this.parents().each(function() { 7605 var $this = $(this); 7606 7607 if ($this.data('stellar-offset-parent') === true) { 7608 parentOffsetLeft = tempParentOffsetLeft; 7609 parentOffsetTop = tempParentOffsetTop; 7610 $offsetParent = $this; 7611 7612 return false; 7613 } else { 7614 tempParentOffsetLeft += $this.position().left; 7615 tempParentOffsetTop += $this.position().top; 7616 } 7617 }); 7618 7619 // Detect the offsets 7620 horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset)); 7621 verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset)); 7622 7623 // Add our object to the particles collection 7624 self.particles.push({ 7625 $element: $this, 7626 $offsetParent: $offsetParent, 7627 isFixed: $this.css('position') === 'fixed', 7628 horizontalOffset: horizontalOffset, 7629 verticalOffset: verticalOffset, 7630 startingPositionLeft: positionLeft, 7631 startingPositionTop: positionTop, 7632 startingOffsetLeft: offsetLeft, 7633 startingOffsetTop: offsetTop, 7634 parentOffsetLeft: parentOffsetLeft, 7635 parentOffsetTop: parentOffsetTop, 7636 stellarRatio: ($this.data('stellar-ratio') !== undefined ? $this.data('stellar-ratio') : 1), 7637 width: $this.outerWidth(true), 7638 height: $this.outerHeight(true), 7639 isHidden: false 7640 }); 7641 }); 7642 },
7643 _findBackgrounds: function() { 7644 var self = this, 7645 scrollLeft = this._getScrollLeft(), 7646 scrollTop = this._getScrollTop(), 7647 $backgroundElements; 7648 7649 this.backgrounds = []; 7650 7651 if (!this.options.parallaxBackgrounds) return; 7652 7653 $backgroundElements = this.$element.find('[data-stellar-background-ratio]'); 7654 7655 if (this.$element.data('stellar-background-ratio')) { 7656 $backgroundElements = $backgroundElements.add(this.$element); 7657 } 7658 7659 $backgroundElements.each(function() { 7660 var $this = $(this), 7661 backgroundPosition = getBackgroundPosition($this), 7662 horizontalOffset, 7663 verticalOffset, 7664 positionLeft, 7665 positionTop, 7666 marginLeft, 7667 marginTop, 7668 offsetLeft, 7669 offsetTop, 7670 $offsetParent, 7671 parentOffsetLeft = 0, 7672 parentOffsetTop = 0, 7673 tempParentOffsetLeft = 0, 7674 tempParentOffsetTop = 0; 7675 7676 // Ensure this element isn't already part of another scrolling element 7677 if (!$this.data('stellar-backgroundIsActive')) { 7678 $this.data('stellar-backgroundIsActive', this); 7679 } else if ($this.data('stellar-backgroundIsActive') !== this) { 7680 return; 7681 } 7682 7683 // Save/restore the original top and left CSS values in case we destroy the instance 7684 if (!$this.data('stellar-backgroundStartingLeft')) { 7685 $this.data('stellar-backgroundStartingLeft', backgroundPosition[0]); 7686 $this.data('stellar-backgroundStartingTop', backgroundPosition[1]); 7687 } else { 7688 setBackgroundPosition($this, $this.data('stellar-backgroundStartingLeft'), $this.data('stellar-backgroundStartingTop')); 7689 } 7690 7691 // Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8) 7692 marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), 10); 7693 marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), 10); 7694 7695 offsetLeft = $this.offset().left - marginLeft - scrollLeft; 7696 offsetTop = $this.offset().top - marginTop - scrollTop; 7697 7698 // Calculate the offset parent 7699 $this.parents().each(function() { 7700 var $this = $(this); 7701 7702 if ($this.data('stellar-offset-parent') === true) { 7703 parentOffsetLeft = tempParentOffsetLeft; 7704 parentOffsetTop = tempParentOffsetTop; 7705 $offsetParent = $this; 7706 7707 return false; 7708 } else { 7709 tempParentOffsetLeft += $this.position().left; 7710 tempParentOffsetTop += $this.position().top; 7711 } 7712 }); 7713 7714 // Detect the offsets 7715 horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset)); 7716 verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset)); 7717 7718 self.backgrounds.push({ 7719 $element: $this, 7720 $offsetParent: $offsetParent, 7721 isFixed: $this.css('background-attachment') === 'fixed', 7722 horizontalOffset: horizontalOffset, 7723 verticalOffset: verticalOffset, 7724 startingValueLeft: backgroundPosition[0], 7725 startingValueTop: backgroundPosition[1],
7726 startingBackgroundPositionLeft: (isNaN(parseInt(backgroundPosition[0], 10)) ? 0 : parseInt(backgroundPosition[0], 10)), 7727 startingBackgroundPositionTop: (isNaN(parseInt(backgroundPosition[1], 10)) ? 0 : parseInt(backgroundPosition[1], 10)), 7728 startingPositionLeft: $this.position().left, 7729 startingPositionTop: $this.position().top, 7730 startingOffsetLeft: offsetLeft, 7731 startingOffsetTop: offsetTop, 7732 parentOffsetLeft: parentOffsetLeft, 7733 parentOffsetTop: parentOffsetTop, 7734 stellarRatio: ($this.data('stellar-background-ratio') === undefined ? 1 : $this.data('stellar-background-ratio')) 7735 }); 7736 }); 7737 }, 7738 _reset: function() { 7739 var particle, 7740 startingPositionLeft, 7741 startingPositionTop, 7742 background, 7743 i; 7744 7745 for (i = this.particles.length - 1; i >= 0; i--) { 7746 particle = this.particles[i]; 7747 startingPositionLeft = particle.$element.data('stellar-startingLeft'); 7748 startingPositionTop = particle.$element.data('stellar-startingTop'); 7749 7750 this._setPosition(particle.$element, startingPositionLeft, startingPositionLeft, startingPositionTop, startingPositionTop); 7751 7752 this.options.showElement(particle.$element); 7753 7754 particle.$element.data('stellar-startingLeft', null).data('stellar-elementIsActive', null).data('stellar-backgroundIsActive', null); 7755 } 7756 7757 for (i = this.backgrounds.length - 1; i >= 0; i--) { 7758 background = this.backgrounds[i]; 7759 7760 background.$element.data('stellar-backgroundStartingLeft', null).data('stellar-backgroundStartingTop', null); 7761 7762 setBackgroundPosition(background.$element, background.startingValueLeft, background.startingValueTop); 7763 } 7764 }, 7765 destroy: function() { 7766 this._reset(); 7767 7768 this.$scrollElement.unbind('resize.' + this.name).unbind('scroll.' + this.name); 7769 this._animationLoop = $.noop; 7770 7771 $(window).unbind('load.' + this.name).unbind('resize.' + this.name); 7772 }, 7773 _setOffsets: function() { 7774 var self = this, 7775 $window = $(window); 7776 7777 $window.unbind('resize.horizontal-' + this.name).unbind('resize.vertical-' + this.name); 7778 7779 if (typeof this.options.horizontalOffset === 'function') { 7780 this.horizontalOffset = this.options.horizontalOffset(); 7781 $window.bind('resize.horizontal-' + this.name, function() { 7782 self.horizontalOffset = self.options.horizontalOffset(); 7783 }); 7784 } else { 7785 this.horizontalOffset = this.options.horizontalOffset; 7786 } 7787 7788 if (typeof this.options.verticalOffset === 'function') { 7789 this.verticalOffset = this.options.verticalOffset(); 7790 $window.bind('resize.vertical-' + this.name, function() { 7791 self.verticalOffset = self.options.verticalOffset(); 7792 }); 7793 } else { 7794 this.verticalOffset = this.options.verticalOffset; 7795 } 7796 }, 7797 _repositionElements: function() { 7798 var scrollLeft = this._getScrollLeft(), 7799 scrollTop = this._getScrollTop(), 7800 horizontalOffset, 7801 verticalOffset, 7802 particle, 7803 fixedRatioOffset, 7804 background, 7805 bgLeft, 7806 bgTop, 7807 isVisibleVertical = true, 7808 isVisibleHorizontal = true, 7809 newPositionLeft, 7810 newPositionTop, 7811 newOffsetLeft, 7812 newOffsetTop, 7813 i; 7814 7815 // First check that the scroll position or container size has changed 7816 if (this.currentScrollLeft === scrollLeft && this.currentScrollTop === scrollTop && this.currentWidth === this.viewportWidth && this.currentHeight === this.viewportHeight) { 7817 return; 7818 } else { 7819 this.currentScrollLeft = scrollLeft; 7820 this.currentScrollTop = scrollTop; 7821 this.currentWidth = this.viewportWidth; 7822 this.currentHeight = this.viewportHeight; 7823 } 7824 7825 // Reposition elements 7826 for (i = this.particles.length - 1; i >= 0; i--) { 7827 particle = this.particles[i]; 7828 7829 fixedRatioOffset = (particle.isFixed ? 1 : 0); 7830 7831 // Calculate position, then calculate what the particle's new offset will be (for visibility check) 7832 if (this.options.horizontalScrolling) { 7833 newPositionLeft = (scrollLeft + particle.horizontalOffset + this.viewportOffsetLeft + particle.startingPositionLeft - particle.startingOffsetLeft + particle.parentOffsetLeft) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionLeft; 7834 newOffsetLeft = newPositionLeft - particle.startingPositionLeft + particle.startingOffsetLeft; 7835 } else { 7836 newPositionLeft = particle.startingPositionLeft; 7837 newOffsetLeft = particle.startingOffsetLeft; 7838 } 7839 7840 if (this.options.verticalScrolling) { 7841 newPositionTop = (scrollTop + particle.verticalOffset + this.viewportOffsetTop + particle.startingPositionTop - particle.startingOffsetTop + particle.parentOffsetTop) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionTop; 7842 newOffsetTop = newPositionTop - particle.startingPositionTop + particle.startingOffsetTop; 7843 } else { 7844 newPositionTop = particle.startingPositionTop; 7845 newOffsetTop = particle.startingOffsetTop; 7846 } 7847 7848 // Check visibility 7849 if (this.options.hideDistantElements) { 7850 isVisibleHorizontal = !this.options.horizontalScrolling || newOffsetLeft + particle.width >
7850 (particle.isFixed ? 0 : scrollLeft) && newOffsetLeft < (particle.isFixed ? 0 : scrollLeft) + this.viewportWidth + this.viewportOffsetLeft; 7851 isVisibleVertical = !this.options.verticalScrolling || newOffsetTop + particle.height > (particle.isFixed ? 0 : scrollTop) && newOffsetTop < (particle.isFixed ? 0 : scrollTop) + this.viewportHeight + this.viewportOffsetTop; 7852 } 7853 7854 if (isVisibleHorizontal && isVisibleVertical) { 7855 if (particle.isHidden) { 7856 this.options.showElement(particle.$element); 7857 particle.isHidden = false; 7858 } 7859 7860 this._setPosition(particle.$element, newPositionLeft, particle.startingPositionLeft, newPositionTop, particle.startingPositionTop); 7861 } else { 7862 if (!particle.isHidden) { 7863 this.options.hideElement(particle.$element); 7864 particle.isHidden = true; 7865 } 7866 } 7867 } 7868 7869 // Reposition backgrounds 7870 for (i = this.backgrounds.length - 1; i >= 0; i--) { 7871 background = this.backgrounds[i]; 7872 7873 fixedRatioOffset = (background.isFixed ? 0 : 1); 7874 bgLeft = (this.options.horizontalScrolling ? (scrollLeft + background.horizontalOffset - this.viewportOffsetLeft - background.startingOffsetLeft + background.parentOffsetLeft - background.startingBackgroun
7874dPositionLeft) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueLeft); 7875 bgTop = (this.options.verticalScrolling ? (scrollTop + background.verticalOffset - this.viewportOffsetTop - background.startingOffsetTop + background.parentOffsetTop - background.startingBackgroundPositionTop) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueTop); 7876 7877 setBackgroundPosition(background.$element, bgLeft, bgTop); 7878 } 7879 }, 7880 _handleScrollEvent: function() { 7881 var self = this, 7882 ticking = false; 7883 7884 var update = function() { 7885 self._repositionElements(); 7886 ticking = false; 7887 }; 7888 7889 var requestTick = function() { 7890 if (!ticking) { 7891 requestAnimFrame(update); 7892 ticking = true; 7893 } 7894 }; 7895 7896 this.$scrollElement.bind('scroll.' + this.name, requestTick); 7897 requestTick(); 7898 }, 7899 _startAnimationLoop: function() { 7900 var self = this; 7901 7902 this._animationLoop = function() { 7903 requestAnimFrame(self._animationLoop); 7904 self._repositionElements(); 7905 }; 7906 this._animationLoop(); 7907 } 7908 }; 7909 7910 $.fn[pluginName] = function (options) { 7911 var args = arguments; 7912 if (options === undefined || typeof options === 'object') { 7913 return this.each(function () { 7914 if (!$.data(this, 'plugin_' + pluginName)) { 7915 $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); 7916 } 7917 }); 7918 } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { 7919 return this.each(function () { 7920 var instance = $.data(this, 'plugin_' + pluginName); 7921 if (instance instanceof Plugin && typeof instance[options] === 'function') { 7922 instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 7923 } 7924 if (options === 'destroy') { 7925 $.data(this, 'plugin_' + pluginName, null); 7926 } 7927 }); 7928 } 7929 }; 7930 7931 $[pluginName] = function(options) { 7932 var $window = $(window); 7933 return $window.stellar.apply($window, Array.prototype.slice.call(arguments, 0)); 7934 }; 7935 7936 // Expose the scroll and position property function hashes so they can be extended 7937 $[pluginName].scrollProperty = scrollProperty; 7938 $[pluginName].positionProperty = positionProperty; 7939 7940 // Expose the plugin class so it can be modified 7941 window.Stellar = Plugin; 7942}(jQuery, this, document)); 7943;/*})'"*/ 7944;/*})'"*/ 7945/**! 7946 * easyPieChart 7947 * Lightweight plugin to render simple, animated and retina optimized pie charts 7948 * 7949 * @license 7950 * @author Robert Fleischmann <[email protected]> (http://robert-fleischmann.de) 7951 * @version 2.1.6 7952 **/ 7953 7954(function(root, factory) { 7955 if(typeof exports === 'object') { 7956 module.exports = factory(require('jquery')); 7957 } 7958 else if(typeof define === 'function' && define.amd) { 7959 define(['jquery'], factory); 7960 } 7961 else { 7962 factory(root.jQuery); 7963 } 7964}(this, function($) { 7965 7966/** 7967 * Renderer to render the chart on a canvas object 7968 * @param {DOMElement} el DOM element to host the canvas (root of the plugin) 7969 * @param {object} options options object of the plugin 7970 */ 7971var CanvasRenderer = function(el, options) { 7972 var cachedBackground; 7973 var canvas = document.createElement('canvas'); 7974 7975 el.appendChild(canvas); 7976 7977 if (typeof(G_vmlCanvasManager) !== 'undefined') { 7978 G_vmlCanvasManager.initElement(canvas); 7979 } 7980 7981 var ctx = canvas.getContext('2d'); 7982 7983 canvas.width = canvas.height = options.size; 7984 7985 // canvas on retina devices 7986 var scaleBy = 1; 7987 if (window.devicePixelRatio > 1) { 7988 scaleBy = window.devicePixelRatio; 7989 canvas.style.width = canvas.style.height = [options.size, 'px'].join(''); 7990 canvas.width = canvas.height = options.size * scaleBy; 7991 ctx.scale(scaleBy, scaleBy); 7992 } 7993 7994 // move 0,0 coordinates to the center 7995 ctx.translate(options.size / 2, options.size / 2); 7996 7997 // rotate canvas -90deg 7998 ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); 7999 8000 var radius = (options.size - options.lineWidth) / 2; 8001 if (options.scaleColor && options.scaleLength) { 8002 radius -= options.scaleLength + 2; // 2 is the distance between scale and bar 8003 } 8004 8005 // IE polyfill for Date 8006 Date.now = Date.now || function() { 8007 return +(new Date()); 8008 }; 8009 8010 /** 8011 * Draw a circle around the center of the canvas 8012 * @param {strong} color Valid CSS color string 8013 * @param {number} lineWidth Width of the line in px 8014 * @param {number} percent Percentage to draw (float between -1 and 1) 8015 */ 8016 var drawCircle = function(color, lineWidth, percent) { 8017 percent = Math.min(Math.max(-1, percent || 0), 1); 8018 var isNegative = percent <= 0 ? true : false;
8019 8020 ctx.beginPath(); 8021 ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative); 8022 8023 ctx.strokeStyle = color; 8024 ctx.lineWidth = lineWidth; 8025 8026 ctx.stroke(); 8027 }; 8028 8029 /** 8030 * Draw the scale of the chart 8031 */ 8032 var drawScale = function() { 8033 var offset; 8034 var length; 8035 8036 ctx.lineWidth = 1; 8037 ctx.fillStyle = options.scaleColor; 8038 8039 ctx.save(); 8040 for (var i = 24; i > 0; --i) { 8041 if (i % 6 === 0) { 8042 length = options.scaleLength; 8043 offset = 0; 8044 } else { 8045 length = options.scaleLength * 0.6; 8046 offset = options.scaleLength - length; 8047 } 8048 ctx.fillRect(-options.size/2 + offset, 0, length, 1); 8049 ctx.rotate(Math.PI / 12); 8050 } 8051 ctx.restore(); 8052 }; 8053 8054 /** 8055 * Request animation frame wrapper with polyfill 8056 * @return {function} Request animation frame method or timeout fallback 8057 */ 8058 var reqAnimationFrame = (function() { 8059 return window.requestAnimationFrame || 8060 window.webkitRequestAnimationFrame || 8061 window.mozRequestAnimationFrame || 8062 function(callback) { 8063 window.setTimeout(callback, 1000 / 60); 8064 }; 8065 }()); 8066 8067 /** 8068 * Draw the background of the plugin including the scale and the track 8069 */ 8070 var drawBackground = function() { 8071 if(options.scaleColor) drawScale(); 8072 if(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1); 8073 }; 8074 8075 /** 8076 * Canvas accessor 8077 */ 8078 this.getCanvas = function() { 8079 return canvas; 8080 }; 8081 8082 /** 8083 * Canvas 2D context 'ctx' accessor 8084 */ 8085 this.getCtx = function() { 8086 return ctx; 8087 }; 8088 8089 /** 8090 * Clear the complete canvas 8091 */ 8092 this.clear = function() { 8093 ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size); 8094 }; 8095 8096 /** 8097 * Draw the complete chart 8098 * @param {number} percent Percent shown by the chart between -100 and 100 8099 */ 8100 this.draw = function(percent) { 8101 // do we need to render a background 8102 if (!!options.scaleColor || !!options.trackColor) { 8103 // getImageData and putImageData are supported 8104 if (ctx.getImageData && ctx.putImageData) { 8105 if (!cachedBackground) { 8106 drawBackground(); 8107 cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy); 8108 } else { 8109 ctx.putImageData(cachedBackground, 0, 0); 8110 } 8111 } else { 8112 this.clear(); 8113 drawBackground(); 8114 } 8115 } else { 8116 this.clear(); 8117 } 8118 8119 ctx.lineCap = options.lineCap; 8120 8121 // if barcolor is a function execute it and pass the percent as a value 8122 var color; 8123 if (typeof(options.barColor) === 'function') { 8124 color = options.barColor(percent); 8125 } else { 8126 color = options.barColor; 8127 } 8128 8129 // draw bar 8130 drawCircle(color, options.lineWidth, percent / 100); 8131 }.bind(this); 8132 8133 /** 8134 * Animate from some percent to some other percentage 8135 * @param {number} from Starting percentage 8136 * @param {number} to Final percentage 8137 */ 8138 this.animate = function(from, to) { 8139 var startTime = Date.now(); 8140 options.onStart(from, to); 8141 var animation = function() { 8142 var process = Math.min(Date.now() - startTime, options.animate.duration); 8143 var currentValue = options.easing(this, process, from, to - from, options.animate.duration); 8144 this.draw(currentValue); 8145 options.onStep(from, to, currentValue); 8146 if (process >= options.animate.duration) { 8147 options.onStop(from, to); 8148 } else { 8149 reqAnimationFrame(animation); 8150 } 8151 }.bind(this); 8152 8153 reqAnimationFrame(animation); 8154 }.bind(this); 8155}; 8156 8157var EasyPieChart = function(el, opts) { 8158 var defaultOptions = { 8159 barColor: '#ef1e25', 8160 trackColor: '#f9f9f9', 8161 scaleColor: '#dfe0e0', 8162 scaleLength: 5, 8163 lineCap: 'round', 8164 lineWidth: 3, 8165 trackWidth: undefined, 8166 size: 110, 8167 rotate: 0, 8168 animate: { 8169 duration: 1000, 8170 enabled: true 8171 }, 8172 easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/ 8173 t = t / (d/2); 8174 if (t < 1) { 8175 return c / 2 * t * t + b; 8176 } 8177 return -c/2 * ((--t)*(t-2) - 1) + b; 8178 }, 8179 onStart: function(from, to) { 8180 return; 8181 }, 8182 onStep: function(from, to, currentValue) { 8183 return; 8184 }, 8185 onStop: function(from, to) { 8186 return; 8187 } 8188 }; 8189 8190 // detect present renderer 8191 if (typeof(CanvasRenderer) !== 'undefined') { 8192 defaultOptions.renderer = CanvasRenderer; 8193 } else if (typeof(SVGRenderer) !== 'undefined') { 8194 defaultOptions.renderer = SVGRenderer; 8195 } else { 8196 throw new Error('Please load either the SVG- or the CanvasRenderer'); 8197 } 8198 8199 var options = {}; 8200 var currentValue = 0; 8201 8202 /** 8203 * Initialize the plugin by creating the options object and initialize rendering 8204 */ 8205 var init = function() { 8206 this.el = el; 8207 this.options = options; 8208 8209 // merge user options into default options 8210 for (var i in defaultOptions) { 8211 if (defaultOptions.hasOwnProperty(i)) { 8212 options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i]; 8213 if (typeof(options[i]) === 'function') { 8214 options[i] = options[i].bind(this); 8215 } 8216 } 8217 } 8218 8219 // check for jQuery easing 8220 if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) { 8221 options.easing = jQuery.easing[options.easing]; 8222 } else { 8223 options.easing = defaultOptions.easing; 8224 } 8225 8226 // process earlier animate option to avoid bc breaks 8227 if (typeof(options.animate) === 'number') { 8228 options.animate = { 8229 duration: options.animate, 8230 enabled: true 8231 }; 8232 } 8233 8234 if (typeof(options.animate) === 'boolean' && !options.animate) { 8235 options.animate = { 8236 duration: 1000, 8237 enabled: options.animate 8238 }; 8239 } 8240 8241 // create renderer 8242 this.renderer = new options.renderer(el, options); 8243 8244 // initial draw 8245 this.renderer.draw(currentValue); 8246 8247 // initial update 8248 if (el.dataset && el.dataset.percent) { 8249 this.update(parseFloat(el.dataset.percent)); 8250 } else if (el.getAttribute && el.getAttribute('data-percent')) { 8251 this.update(parseFloat(el.getAttribute('data-percent'))); 8252 } 8253 }.bind(this); 8254 8255 /** 8256 * Update the value of the chart 8257 * @param {number} newValue Number between 0 and 100 8258 * @return {object} Instance of the plugin for method chaining 8259 */ 8260 this.update = function(newValue) { 8261 newValue = parseFloat(newValue); 8262 if (options.animate.enabled) { 8263 this.renderer.animate(currentValue, newValue); 8264 } else { 8265 this.renderer.draw(newValue); 8266 } 8267 currentValue = newValue; 8268 return this; 8269 }.bind(this); 8270 8271 /** 8272 * Disable animation 8273 * @return {object} Instance of the plugin for method chaining 8274 */ 8275 this.disableAnimation = function() { 8276 options.animate.enabled = false;
8277 return this; 8278 }; 8279 8280 /** 8281 * Enable animation 8282 * @return {object} Instance of the plugin for method chaining 8283 */ 8284 this.enableAnimation = function() { 8285 options.animate.enabled = true; 8286 return this; 8287 }; 8288 8289 init(); 8290}; 8291 8292$.fn.easyPieChart = function(options) { 8293 return this.each(function() { 8294 var instanceOptions; 8295 8296 if (!$.data(this, 'easyPieChart')) { 8297 instanceOptions = $.extend({}, options, $(this).data()); 8298 $.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions)); 8299 } 8300 }); 8301}; 8302 8303 8304})); 8305 8306;/*})'"*/ 8307;/*})'"*/ 8308/** 8309 * jQuery gMap - Google Maps API V3 8310 * 8311 * @license MIT License; http://www.opensource.org/licenses/mit-license.php 8312 * @url http://github.com/marioestrada/jQuery-gMap 8313 * @author Mario Estrada <[email protected]> based on original plugin by Cedric Kastner <[email protected]> 8314 * @version 2.1.5 8315 */ 8316/* global google */ 8317(function($) 8318{ 8319 // Main plugin function 8320 $.fn.gMap = function(options, methods_options) 8321 { 8322 // Optional methods 8323 switch(options) 8324 { 8325 case 'addMarker': 8326 return $(this).trigger( 8327 'gMap.addMarker', 8328 [methods_options.latitude, methods_options.longitude, methods_options.content, methods_options.icon, methods_options.popup] 8329 ); 8330 case 'centerAt': 8331 return $(this).trigger('gMap.centerAt', [methods_options.latitude, methods_options.longitude, methods_options.zoom]); 8332 case 'clearMarkers': 8333 return $(this).trigger('gMap.clearMarkers'); 8334 } 8335 8336 // Build main options before element iteration 8337 var opts = $.extend({}, $.fn.gMap.defaults, options); 8338 8339 // Iterate through each element 8340 return this.each(function() 8341 { 8342 // Create map and set initial options 8343 var $gmap = new google.maps.Map(this); 8344 8345 $(this).data('gMap.reference', $gmap); 8346 8347 // Create new object to geocode addresses 8348 var $geocoder = new google.maps.Geocoder(); 8349 8350 // Check for address to center on 8351 if (opts.address) 8352 { 8353 // Get coordinates for given address and center the map 8354 $geocoder.geocode( 8355 { 8356 address: opts.address 8357 }, function(gresult, status) 8358 { 8359 if(gresult && gresult.length) { 8360 $gmap.setCenter(gresult[0].geometry.location); 8361 } 8362 } 8363 ); 8364 }else{
8365 // Check for coordinates to center on 8366 if (opts.latitude && opts.longitude) 8367 { 8368 // Center map to coordinates given by option 8369 $gmap.setCenter(new google.maps.LatLng(opts.latitude, opts.longitude)); 8370 } 8371 else 8372 { 8373 // Check for a marker to center on (if no coordinates given) 8374 if ($.isArray(opts.markers) && opts.markers.length > 0) 8375 { 8376 // Check if the marker has an address 8377 if (opts.markers[0].address) 8378 { 8379 // Get the coordinates for given marker address and center 8380 $geocoder.geocode( 8381 { 8382 address: opts.markers[0].address 8383 }, function(gresult, status) 8384 { 8385 if(gresult && gresult.length > 0) { 8386 $gmap.setCenter(gresult[0].geometry.location); 8387 } 8388 } 8389 ); 8390 }else{ 8391 // Center the map to coordinates given by marker 8392 $gmap.setCenter(new google.maps.LatLng(opts.markers[0].latitude, opts.markers[0].longitude)); 8393 } 8394 }else{ 8395 // Revert back to world view 8396 $gmap.setCenter(new google.maps.LatLng(34.885931, 9.84375)); 8397 } 8398 } 8399 } 8400 $gmap.setZoom(opts.zoom); 8401 8402 // Set the preferred map type 8403 $gmap.setMapTypeId(google.maps.MapTypeId[opts.maptype]); 8404 8405 // Set scrollwheel option 8406 var map_options = { scrollwheel: opts.scrollwheel, disableDoubleClickZoom: !opts.doubleclickzoom }; 8407 // Check for map controls 8408 if(opts.controls === false){ 8409 $.extend(map_options, { disableDefaultUI: true }); 8410 }else if (opts.controls.length !== 0){ 8411 $.extend(map_options, opts.controls, { disableDefaultUI: true }); 8412 } 8413 8414 $gmap.setOptions(map_options); 8415 8416 // Create new icon 8417 var gicon = new google.maps.Marker(); 8418 var marker_icon; 8419 var marker_shadow; 8420 8421 // Set icon properties from global options 8422 marker_icon = new google.maps.MarkerImage(opts.icon.image); 8423 marker_icon.size = new google.maps.Size(opts.icon.iconsize[0], opts.icon.iconsize[1]);
8424 marker_icon.anchor = new google.maps.Point(opts.icon.iconanchor[0], opts.icon.iconanchor[1]); 8425 gicon.setIcon(marker_icon); 8426 8427 if(opts.icon.shadow) 8428 { 8429 marker_shadow = new google.maps.MarkerImage(opts.icon.shadow); 8430 marker_shadow.size = new google.maps.Size(opts.icon.shadowsize[0], opts.icon.shadowsize[1]); 8431 marker_shadow.anchor = new google.maps.Point(opts.icon.shadowanchor[0], opts.icon.shadowanchor[1]); 8432 gicon.setShadow(marker_shadow); 8433 } 8434 8435 // Bind actions 8436 $(this).bind('gMap.centerAt', function(e, latitude, longitude, zoom) 8437 { 8438 if(zoom) { 8439 $gmap.setZoom(zoom); 8440 } 8441 8442 $gmap.panTo(new google.maps.LatLng(parseFloat(latitude), parseFloat(longitude))); 8443 }); 8444 8445 // Clear Markers 8446 var overlays = []; 8447 $(this).bind('gMap.clearMarkers', function() 8448 { 8449 while(overlays[0]){ 8450 overlays.pop().setMap(null); 8451 } 8452 }); 8453 8454 var last_infowindow; 8455 $(this).bind('gMap.addMarker', function(e, latitude, longitude, content, icon, popup) 8456 { 8457 var marker_icon; 8458 var marker_shadow; 8459 var glatlng = new google.maps.LatLng(parseFloat(latitude), parseFloat(longitude)); 8460 8461 var gmarker = new google.maps.Marker({ 8462 position: glatlng 8463 }); 8464 8465 if(icon) 8466 { 8467 marker_icon = new google.maps.MarkerImage(icon.image); 8468 marker_icon.size = new google.maps.Size(icon.iconsize[0], icon.iconsize[1]);
8469 marker_icon.anchor = new google.maps.Point(icon.iconanchor[0], icon.iconanchor[1]); 8470 gmarker.setIcon(marker_icon); 8471 8472 if(icon.shadow) 8473 { 8474 marker_shadow = new google.maps.MarkerImage(icon.shadow); 8475 marker_shadow.size = new google.maps.Size(icon.shadowsize[0], icon.shadowsize[1]); 8476 marker_shadow.anchor = new google.maps.Point(icon.shadowanchor[0], icon.shadowanchor[1]); 8477 gicon.setShadow(marker_shadow); 8478 } 8479 }else{ 8480 gmarker.setIcon(gicon.getIcon()); 8481 gmarker.setShadow(gicon.getShadow()); 8482 } 8483 8484 if(content) 8485 { 8486 if(content === '_latlng') { 8487 content = latitude + ', ' + longitude; 8488 } 8489 8490 var infowindow = new google.maps.InfoWindow({ 8491 content: opts.html_prepend + content + opts.html_append 8492 }); 8493 8494 google.maps.event.addListener(gmarker, 'click', function() 8495 { 8496 if (last_infowindow) { 8497 last_infowindow.close(); 8498 } 8499 infowindow.open($gmap, gmarker); 8500 last_infowindow = infowindow; 8501 }); 8502 8503 if(popup) 8504 { 8505 google.maps.event.addListenerOnce($gmap, 'tilesloaded', function() 8506 { 8507 infowindow.open($gmap, gmarker); 8508 }); 8509 } 8510 } 8511 gmarker.setMap($gmap); 8512 overlays.push(gmarker); 8513 }); 8514 8515 var marker; 8516 var self = this; 8517 var geocode_callback = function(marker) { 8518 return function(gresult, status) { 8519 // Create marker 8520 if(gresult && gresult.length > 0) 8521 { 8522 $(self).trigger( 8523 'gMap.addMarker', 8524 [gresult[0].geometry.location.lat(), gresult[0].geometry.location.lng(), marker.html, marker.icon, marker.popup] 8525 ); 8526 } 8527 }; 8528 }; 8529 8530 // Loop through marker array 8531 for (var j = 0; j < opts.markers.length; j++) 8532 { 8533 // Get the options from current marker 8534 marker = opts.markers[j]; 8535 8536 // Check if address is available 8537 if (marker.address) 8538 { 8539 // Check for reference to the marker's address 8540 if (marker.html === '_address') { 8541 marker.html = marker.address; 8542 } 8543 8544 // Get the point for given address 8545 $geocoder.geocode({ 8546 address: marker.address 8547 }, geocode_callback(marker)); 8548 }else{ 8549 $(this).trigger('gMap.addMarker', [marker.latitude, marker.longitude, marker.html, marker.icon, marker.popup]); 8550 } 8551 } 8552 }); 8553 8554 }; 8555 8556 // Default settings 8557 $.fn.gMap.defaults = { 8558 address: '', 8559 latitude: 0, 8560 longitude: 0, 8561 zoom: 1, 8562 markers: [], 8563 controls: [], 8564 scrollwheel: false, 8565 doubleclickzoom: true, 8566 maptype: 'ROADMAP', 8567 html_prepend: '<div class="gmap_marker">', 8568 html_append: '</div>', 8569 icon: { 8570 image: "http://www.google.com/mapfiles/marker.png", 8571 shadow: "http://www.google.com/mapfiles/shadow50.png", 8572 iconsize: [20, 34], 8573 shadowsize: [37, 34], 8574 iconanchor: [9, 34], 8575 shadowanchor: [6, 34] 8576 } 8577 }; 8578 8579})(jQuery); 8580 8581;/*})'"*/ 8582;/*})'"*/ 8583/* 8584 * Lazy Load - jQuery plugin for lazy loading images 8585 * 8586 * Copyright (c) 2007-2015 Mika Tuupola 8587 * 8588 * Licensed under the MIT license: 8589 * http://www.opensource.org/licenses/mit-license.php 8590 * 8591 * Project home: 8592 * http://www.appelsiini.net/projects/lazyload 8593 * 8594 * Version: 1.9.5 8595 * 8596 */ 8597 8598(function($, window, document, undefined) { 8599 var $window = $(window); 8600 8601 $.fn.lazyload = function(options) { 8602 var elements = this; 8603 var $container; 8604 var settings = { 8605 threshold : 0, 8606 failure_limit : 0, 8607 event : "scroll", 8608 effect : "show", 8609 container : window, 8610 data_attribute : "original", 8611 skip_invisible : false, 8612 appear : null, 8613 load : null, 8614 placeholder : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" 8615 }; 8616
vendor: 5,182 bytes, lines 8617-8753
8617 function update() { 8618 var counter = 0; 8619 8620 elements.each(function() { 8621 var $this = $(this); 8622 if (settings.skip_invisible && !$this.is(":visible")) { 8623 return; 8624 } 8625 if ($.abovethetop(this, settings) || 8626 $.leftofbegin(this, settings)) { 8627 /* Nothing. */ 8628 } else if (!$.belowthefold(this, settings) && 8629 !$.rightoffold(this, settings)) { 8630 $this.trigger("appear"); 8631 /* if we found an image we'll load, reset the counter */ 8632 counter = 0; 8633 } else { 8634 if (++counter > settings.failure_limit) { 8635 return false; 8636 } 8637 } 8638 }); 8639 8640 } 8641 8642 if(options) { 8643 /* Maintain BC for a couple of versions. */ 8644 if (undefined !== options.failurelimit) { 8645 options.failure_limit = options.failurelimit; 8646 delete options.failurelimit; 8647 } 8648 if (undefined !== options.effectspeed) { 8649 options.effect_speed = options.effectspeed; 8650 delete options.effectspeed; 8651 } 8652 8653 $.extend(settings, options); 8654 } 8655 8656 /* Cache container as jQuery as object. */ 8657 $container = (settings.container === undefined || 8658 settings.container === window) ? $window : $(settings.container); 8659 8660 /* Fire one scroll event per scroll. Not one scroll event per image. */ 8661 if (0 === settings.event.indexOf("scroll")) { 8662 $container.bind(settings.event, function() { 8663 return update(); 8664 }); 8665 } 8666 8667 this.each(function() { 8668 var self = this; 8669 var $self = $(self); 8670 8671 self.loaded = false; 8672 8673 /* If no src attribute given use data:uri. */ 8674 if ($self.attr("src") === undefined || $self.attr("src") === false) { 8675 if ($self.is("img")) { 8676 $self.attr("src", settings.placeholder); 8677 } 8678 } 8679 8680 /* When appear is triggered load original image. */ 8681 $self.one("appear", function() { 8682 if (!this.loaded) { 8683 if (settings.appear) { 8684 var elements_left = elements.length; 8685 settings.appear.call(self, elements_left, settings); 8686 } 8687 $("<img />") 8688 .bind("load", function() { 8689 8690 var original = $self.attr("data-" + settings.data_attribute); 8691 $self.hide(); 8692 if ($self.is("img")) { 8693 $self.attr("src", original); 8694 } else { 8695 $self.css("background-image", "url('" + original + "')"); 8696 } 8697 $self[settings.effect](settings.effect_speed); 8698 8699 self.loaded = true; 8700 8701 /* Remove image from array so it is not looped next time. */ 8702 var temp = $.grep(elements, function(element) { 8703 return !element.loaded; 8704 }); 8705 elements = $(temp); 8706 8707 if (settings.load) { 8708 var elements_left = elements.length; 8709 settings.load.call(self, elements_left, settings); 8710 } 8711 }) 8712 .attr("src", $self.attr("data-" + settings.data_attribute)); 8713 } 8714 }); 8715 8716 /* When wanted event is triggered load original image */ 8717 /* by triggering appear. */ 8718 if (0 !== settings.event.indexOf("scroll")) { 8719 $self.bind(settings.event, function() { 8720 if (!self.loaded) { 8721 $self.trigger("appear"); 8722 } 8723 }); 8724 } 8725 }); 8726 8727 /* Check if something appears when window is resized. */ 8728 $window.bind("resize", function() { 8729 update(); 8730 }); 8731 8732 /* With IOS5 force loading images when navigating with back button. */ 8733 /* Non optimal workaround. */ 8734 if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) { 8735 $window.bind("pageshow", function(event) { 8736 if (event.originalEvent && event.originalEvent.persisted) { 8737 elements.each(function() { 8738 $(this).trigger("appear"); 8739 }); 8740 } 8741 }); 8742 } 8743 8744 /* Force initial check if images should appear. */ 8745 $(document).ready(function() { 8746 update(); 8747 }); 8748 8749 return this; 8750 }; 8751 8752 /* Convenience methods in jQuery namespace. */ 8753 /* Use as $.belowthefold(element, {threshold : 100, container : window}
8753) */ 8754 8755 $.belowthefold = function(element, settings) { 8756 var fold; 8757 8758 if (settings.container === undefined || settings.container === window) { 8759 fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop(); 8760 } else { 8761 fold = $(settings.container).offset().top + $(settings.container).height(); 8762 } 8763 8764 return fold <= $(element).offset().top - settings.threshold; 8765 }; 8766 8767 $.rightoffold = function(element, settings) { 8768 var fold; 8769 8770 if (settings.container === undefined || settings.container === window) { 8771 fold = $window.width() + $window.scrollLeft(); 8772 } else { 8773 fold = $(settings.container).offset().left + $(settings.container).width(); 8774 } 8775 8776 return fold <= $(element).offset().left - settings.threshold; 8777 }; 8778 8779 $.abovethetop = function(element, settings) { 8780 var fold; 8781 8782 if (settings.container === undefined || settings.container === window) { 8783 fold = $window.scrollTop(); 8784 } else { 8785 fold = $(settings.container).offset().top; 8786 } 8787 8788 return fold >= $(element).offset().top + settings.threshold + $(element).height(); 8789 }; 8790 8791 $.leftofbegin = function(element, settings) { 8792 var fold; 8793 8794 if (settings.container === undefined || settings.container === window) { 8795 fold = $window.scrollLeft(); 8796 } else { 8797 fold = $(settings.container).offset().left; 8798 } 8799 8800 return fold >= $(element).offset().left + settings.threshold + $(element).width(); 8801 }; 8802 8803 $.inviewport = function(element, settings) { 8804 return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) && 8805 !$.belowthefold(element, settings) && !$.abovethetop(element, settings); 8806 }; 8807 8808 /* Custom selectors for your convenience. */ 8809 /* Use as $("img:below-the-fold").something() or */ 8810 /* $("img").filter(":below-the-fold").something() which is faster */ 8811 8812 $.extend($.expr[":"], { 8813 "below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); }, 8814 "above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); }, 8815 "right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); }, 8816 "left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); }, 8817 "in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); }, 8818 /* Maintain BC for couple of versions. */ 8819 "above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); }, 8820 "right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); }, 8821 "left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); } 8822 }); 8823 8824})(jQuery, window, document); 8825 8826;/*})'"*/ 8827;/*})'"*/ 8828/*! 8829 * Isotope PACKAGED v2.2.0 8830 * 8831 * Licensed GPLv3 for open source use 8832 * or Isotope Commercial License for commercial use 8833 * 8834 * http://isotope.metafizzy.co 8835 * Copyright 2015 Metafizzy 8836 */ 8837 8838(function(t){function e(){}function i(t){function i(e){e.prototype.option||(e.prototype.option=function(e){t.isPlainObject(e)&&(this.options=t.extend(!0,this.options,e))})}function n(e,i){t.fn[e]=function(n){if("string"==typeof n){for(var s=o.call(arguments,1),a=0,u=this.length;u>a;a++){var p=this[a],h=t.data(p,e);if(h)if(t.isFunction(h[n])&&"_"!==n.charAt(0)){var f=h[n].apply(h,s);if(void 0!==f)return f}else r("no such method '"+n+"' for "+e+" instance");else r("cannot call methods on "+e+" prior to initialization; "+"attempted to call '"+n+"'")}return this}return this.each(function(){var o=t.data(this,e);o?(o.option(n),o._init()):(o=new i(this,n),t.data(this,e,o))})}}if(t){var r="undefined"==typeof console?e:function(t){console.error(t)};return t.bridget=function(t,e){i(e),n(t,e)},t.bridget}}var o=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],i):"object"==typeof exports?i(require("jquery")):i(t.jQuery)})(window),function(t){function e(e){var i=t.event;return i.target=i.target||i.srcElement||e,i}var i=document.documentElement,o=function(){};
8838i.addEventListener?o=function(t,e,i){t.addEventListener(e,i,!1)}:i.attachEvent&&(o=function(t,i,o){t[i+o]=o.handleEvent?function(){var i=e(t);o.handleEvent.call(o,i)}:function(){var i=e(t);o.call(t,i)},t.attachEvent("on"+i,t[i+o])});var n=function(){};i.removeEventListener?n=function(t,e,i){t.removeEventListener(e,i,!1)}:i.detachEvent&&(n=function(t,e,i){t.detachEvent("on"+e,t[e+i]);try{delete t[e+i]}catch(o){t[e+i]=void 0}});var r={bind:o,unbind:n};"function"==typeof define&&define.amd?define("eventie/eventie",r):"object"==typeof exports?module.exports=r:t.eventie=r}(window),function(){function t(){}function e(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function i(t){return function(){return this[t].apply(this,arguments)}}var o=t.prototype,n=this,r=n.EventEmitter;o.getListeners=function(t){var e,i,o=this._getEvents();if(t instanceof RegExp){e={};for(i in o)o.hasOwnProperty(i)&&t.test(i)&&(e[i]=o[i])}else e=o[t]||(o[t]=[]);return e},o.flattenListeners=function(t){var e,i=[];for(e=0;t.length>e;e+=1)i.push(t[e].listener);return i},o.getListenersAsObject=function(t){var e,i=this.getListeners(t);return i instanceof Array&&(e={},e[t]=i),e||i},o.addListener=function(t,i){var o,n=this.getListenersAsObject(t),r="object"==typeof i;for(o in n)n.hasOwnProperty(o)&&-1===e(n[o],i)&&n[o].push(r?i:{listener:i,once:!1});return this},o.on=i("addListener"),o.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},o.once=i("addOnceListener"),o.defineEvent=function(t){return this.getListeners(t),this},o.defineEvents=function(t){for(var e=0;t.length>e;e+=1)this.defineEvent(t[e]);return this},o.removeListener=function(t,i){var o,n,r=this.getListenersAsObject(t);for(n in r)r.hasOwnProperty(n)&&(o=e(r[n],i),-1!==o&&r[n].splice(o,1));return this},o.off=i("removeListener"),o.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},o.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},o.manipulateListeners=function(t,e,i){var o,n,r=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(o=i.length;o--;)r.call(this,e,i[o]);else for(o in e)e.hasOwnProperty(o)&&(n=e[o])&&("function"==typeof n?r.call(this,o,n):s.call(this,o,n));return this},o.removeEvent=function(t){var e,i=typeof t,o=this._getEvents();if("string"===i)delete o[t];else if(t instanceof RegExp)for(e in o)o.hasOwnProperty(e)&&t.test(e)&&delete o[e];else delete this._events;return this},o.removeAllListeners=i("removeEvent"),o.emitEvent=function(t,e){var i,o,n,r,s=this.getListenersAsObject(t);for(n in s)if(s.hasOwnProperty(n))for(o=s[n].length;o--;)i=s[n][o],i.once===!0&&this.removeListener(t,i.listener),r=i.listener.apply(this,e||[]),r===this._getOnceReturnValue()&&this.removeListener(t,i.listener);return this},o.trigger=i("emitEvent"),o.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},o.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},o._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},o._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return n.EventEmitter=r,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.EventEmitter=t}.call(this),function(t){function e(t){if(t){if("string"==typeof o[t])return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e,n=0,r=i.length;r>n;n++)if(e=i[n]+t,"string"==typeof o[e])return e}}var i="Webkit Moz ms Ms O".split(" "),o=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return e}):"object"==typeof exports?module.exports=e:t.getStyleProperty=e}(window),function(t){function e(t){var e=parseFloat(t),i=-1===t.indexOf("%")&&!isNaN(e);return i&&e}function i(){}function o(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0,i=s.length;i>e;e++){var o=s[e];t[o]=0}return t}function n(i){function n(){if(!d){d=!0;var o=t.getComputedStyle;if(p=function(){var t=o?function(t){return o(t,null)}:function(t){return t.currentStyle};return function(e){var i=t(e);return i||r("Style returned "+i+". Are you running this code in a hidden iframe on Firefox? "+"See http://bit.ly/getsizebug1"),i}}(),h=i("boxSizing")){var n=document.createElement("div");n.style.width="200px",n.style.padding="1px 2px 3px 4px",n.style.borderStyle="solid",n.style.borderWidth="1px 2px 3px 4px",n.style[h]="border-box";var s=document.body||document.documentElement;s.appendChild(n);var a=p(n);f=200===e(a.width),s.removeChild(n)}}}function a(t){if(n(),"string"==typeof t&&(t=document.querySelector(t)),t&&"object"==typeof t&&t.nodeType){var i=p(t);if("none"===i.display)return o();var r={};r.width=t.offsetWidth,r.height=t.offsetHeight;for(var a=r.isBorderBox=!(!h||!i[h]||"border-box"!==i[h]),d=0,l=s.length;l>d;d++){var c=s[d],m=i[c];m=u(t,m);var y=parseFloat(m);r[c]=isNaN(y)?0:y}var g=r.paddingLeft+r.paddingRight,v=r.paddingTop+r.paddingBottom,_=r.marginLeft+r.marginRight,I=r.marginTop+r.marginBottom,z=r.borderLeftWidth+r.borderRightWidth,L=r.borderTopWidth+r.borderBottomWidth,x=a&&f,E=e(i.width);E!==!1&&(r.width=E+(x?0:g+z));var b=e(i.height);return b!==!1&&(r.height=b+(x?0:v+L)),r.innerWidth=r.width-(g+z),r.innerHe
8838ight=r.height-(v+L),r.outerWidth=r.width+_,r.outerHeight=r.height+I,r}}function u(e,i){if(t.getComputedStyle||-1===i.indexOf("%"))return i;var o=e.style,n=o.left,r=e.runtimeStyle,s=r&&r.left;return s&&(r.left=e.currentStyle.left),o.left=i,i=o.pixelLeft,o.left=n,s&&(r.left=s),i}var p,h,f,d=!1;return a}var r="undefined"==typeof console?i:function(t){console.error(t)},s=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],n):"object"==typeof exports?module.exports=n(require("desandro-get-style-property")):t.getSize=n(t.getStyleProperty)}(window),function(t){function e(t){"function"==typeof t&&(e.isReady?t():s.push(t))}function i(t){var i="readystatechange"===t.type&&"complete"!==r.readyState;e.isReady||i||o()}function o(){e.isReady=!0;for(var t=0,i=s.length;i>t;t++){var o=s[t];o()}}function n(n){return"complete"===r.readyState?o():(n.bind(r,"DOMContentLoaded",i),n.bind(r,"readystatechange",i),n.bind(t,"load",i)),e}var r=t.document,s=[];e.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],n):"object"==typeof exports?module.exports=n(require("eventie")):t.docReady=n(t.eventie)}(window),function(t){function e(t,e){return t[s](e)}function i(t){if(!t.parentNode){var e=document.createDocumentFragment();e.appendChild(t)}}function o(t,e){i(t);for(var o=t.parentNode.querySelectorAll(e),n=0,r=o.length;r>n;n++)if(o[n]===t)return!0;return!1}function n(t,o){return i(t),e(t,o)}var r,s=function(){if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0,o=e.length;o>i;i++){var n=e[i],r=n+"MatchesSelector";if(t[r])return r}}();if(s){var a=document.createElement("div"),u=e(a,"div");r=u?e:n}else r=o;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return r}):"object"==typeof exports?module.exports=r:window.matchesSelector=r}(Element.prototype),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["doc-ready/doc-ready","matches-selector/matches-selector"],function(i,o){return e(t,i,o)}):"object"==typeof exports?module.exports=e(t,require("doc-ready"),require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.docReady,t.matchesSelector)}(window,function(t,e,i){var o={};o.extend=function(t,e){for(var i in e)t[i]=e[i];return t},o.modulo=function(t,e){return(t%e+e)%e};var n=Object.prototype.toString;o.isArray=function(t){return"[object Array]"==n.call(t)},o.makeArray=function(t){var e=[];if(o.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0,n=t.length;n>i;i++)e.push(t[i]);else e.push(t);return e},o.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++)if(t[i]===e)return i;return-1},o.removeFrom=function(t,e){var i=o.indexOf(t,e);-1!=i&&t.splice(i,1)},o.isElement="function"==typeof HTMLElement||"object"==typeof HTMLElement?function(t){return t instanceof HTMLElement}:function(t){return t&&"object"==typeof t&&1==t.nodeType&&"string"==typeof t.nodeName},o.setText=function(){function t(t,i){e=e||(void 0!==document.documentElement.textContent?"textContent":"innerText"),t[e]=i}var e;return t}(),o.getParent=function(t,e){for(;t!=document.body;)if(t=t.parentNode,i(t,e))return t},o.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},o.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},o.filterFindElements=function(t,e){t=o.makeArray(t);for(var n=[],r=0,s=t.length;s>r;r++){var a=t[r];if(o.isElement(a))if(e){i(a,e)&&n.push(a);for(var u=a.querySelectorAll(e),p=0,h=u.length;h>p;p++)n.push(u[p])}else n.push(a)}return n},o.debounceMethod=function(t,e,i){var o=t.prototype[e],n=e+"Timeout";t.prototype[e]=function(){var t=this[n];t&&clearTimeout(t);var e=arguments,r=this;this[n]=setTimeout(function(){o.apply(r,e),delete r[n]},i||100)}},o.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,
8838i){return e+"-"+i}).toLowerCase()};var r=t.console;return o.htmlInit=function(i,n){e(function(){for(var e=o.toDashed(n),s=document.querySelectorAll(".js-"+e),a="data-"+e+"-options",u=0,p=s.length;p>u;u++){var h,f=s[u],d=f.getAttribute(a);try{h=d&&JSON.parse(d)}catch(l){r&&r.error("Error parsing "+a+" on "+f.nodeName.toLowerCase()+(f.id?"#"+f.id:"")+": "+l);continue}var c=new i(f,h),m=t.jQuery;m&&m.data(f,n,c)}})},o}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property","fizzy-ui-utils/utils"],function(i,o,n,r){return e(t,i,o,n,r)}):"object"==typeof exports?module.exports=e(t,require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property"),require("fizzy-ui-utils")):(t.Outlayer={},t.Outlayer.Item=e(t,t.EventEmitter,t.getSize,t.getStyleProperty,t.fizzyUIUtils))}(window,function(t,e,i,o,n){function r(t){for(var e in t)return!1;return e=null,!0}function s(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}var a=t.getComputedStyle,u=a?function(t){return a(t,null)}:function(t){return t.currentStyle},p=o("transition"),h=o("transform"),f=p&&h,d=!!o("perspective"),l={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[p],c=["transform","transition","transitionDuration","transitionProperty"],m=function(){for(var t={},e=0,i=c.length;i>e;e++){var n=c[e],r=o(n);r&&r!==n&&(t[n]=r)}return t}();n.extend(s.prototype,e.prototype),s.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},s.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},s.prototype.getSize=function(){this.size=i(this.element)},s.prototype.css=function(t){var e=this.element.style;for(var i in t){var o=m[i]||i;e[o]=t[i]}},s.prototype.getPosition=function(){var t=u(this.element),e=this.layout.options,i=e.isOriginLeft,o=e.isOriginTop,n=parseInt(t[i?"left":"right"],10),r=parseInt(t[o?"top":"bottom"],10);n=isNaN(n)?0:n,r=isNaN(r)?0:r;var s=this.layout.size;n-=i?s.paddingLeft:s.paddingRight,r-=o?s.paddingTop:s.paddingBottom,this.position.x=n,this.position.y=r},s.prototype.layoutPosition=function(){var t=this.layout.size,e=this.layout.options,i={},o=e.isOriginLeft?"paddingLeft":"paddingRight",n=e.isOriginLeft?"left":"right",r=e.isOriginLeft?"right":"left",s=this.position.x+t[o];s=e.percentPosition&&!e.isHorizontal?100*(s/t.width)+"%":s+"px",i[n]=s,i[r]="";var a=e.isOriginTop?"paddingTop":"paddingBottom",u=e.isOriginTop?"top":"bottom",p=e.isOriginTop?"bottom":"top",h=this.position.y+t[a];h=e.percentPosition&&e.isHorizontal?100*(h/t.height)+"%":h+"px",i[u]=h,i[p]="",this.css(i),this.emitEvent("layout",[this])};var y=d?function(t,e){return"translate3d("+t+"px, "+e+"px, 0)"}:function(t,e){return"translate("+t+"px, "+e+"px)"};s.prototype._transitionTo=function(t,e){this.getPosition();var i=this.position.x,o=this.position.y,n=parseInt(t,10),r=parseInt(e,10),s=n===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return this.layoutPosition(),void 0;var a=t-i,u=e-o,p={},h=this.layout.options;a=h.isOriginLeft?a:-a,u=h.isOriginTop?u:-u,p.transform=y(a,u),this.transition({to:p,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},s.prototype.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},s.prototype.moveTo=f?s.prototype._transitionTo:s.prototype.goTo,s.prototype.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},s.prototype._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},s.prototype._transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return this._nonTransition(t),void 0;var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var o=this.element.offsetHeight;o=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var g=h&&n.toDashed(h)+",opacity";s.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:g,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(l,this,!1))},s.prototype.transition=s.prototype[p?"_transition":"_nonTransition"],s.prototype.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},s.prototype.onotransitionend=function(t){this.ontransitionend(t)};var v={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};s.prototype.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,i=v[t.propertyName]||t.propertyName;if(delete e.ingProperties[i],r(e.ingProperties)&&this.disableTransition(),i in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[i]),i in e.onEnd){var o=e.onEnd[i];o.call(this),delete e.onEnd[i]}this.emitEvent("transitionEnd",[this])}},s.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(l,this,!1),this.isTransitioning=!1},s.prototype._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var _={transitionProperty:"",transitionDuration:""};return s.prototype.removeTransitionStyles=function(){this.css(_)},s.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},s.prototype.remove=function(){if(!p||!parseFloat(this.layout.options.transitionDuration))return this.removeElem(),void 0;var t=this;this.once("transitionEnd",function(){t.removeElem()}),this.hide()},s.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},s.prototype.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},s.prototype.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},s.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},s.prototype.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},s.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},s}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","eventEmitter/EventEmitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,o,n,r,s){return e(t,i,o,n,r,s)}):"object"==typeof exports?module.exports=e(t,require("eventie"),require("wolfy87-eventemitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.eventie,t.EventEmitter,t.getSize,t.f
8838izzyUIUtils,t.Outlayer.Item)}(window,function(t,e,i,o,n,r){function s(t,e){var i=n.getQueryElement(t);if(!i)return a&&a.error("Bad element for "+this.constructor.namespace+": "+(i||t)),void 0;this.element=i,u&&(this.$element=u(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++h;this.element.outlayerGUID=o,f[o]=this,this._create(),this.options.isInitLayout&&this.layout()}var a=t.console,u=t.jQuery,p=function(){},h=0,f={};return s.namespace="outlayer",s.Item=r,s.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},n.extend(s.prototype,i.prototype),s.prototype.option=function(t){n.extend(this.options,t)},s.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},s.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},s.prototype._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,o=[],n=0,r=e.length;r>n;n++){var s=e[n],a=new i(s,this);o.push(a)}return o},s.prototype._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},s.prototype.getItemElements=function(){for(var t=[],e=0,i=this.items.length;i>e;e++)t.push(this.items[e].element);return t},s.prototype.layout=function(){this._resetLayout(),this._manageStamps();var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,t),this._isLayoutInited=!0},s.prototype._init=s.prototype.layout,s.prototype._resetLayout=function(){this.getSize()},s.prototype.getSize=function(){this.size=o(this.element)},s.prototype._getMeasurement=function(t,e){var i,r=this.options[t];r?("string"==typeof r?i=this.element.querySelector(r):n.isElement(r)&&(i=r),this[t]=i?o(i)[e]:r):this[t]=0},s.prototype.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},s.prototype._getItemsForLayout=function(t){for(var e=[],i=0,o=t.length;o>i;i++){var n=t[i];n.isIgnored||e.push(n)}return e},s.prototype._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){for(var i=[],o=0,n=t.length;n>o;o++){var r=t[o],s=this._getItemLayoutPosition(r);s.item=r,s.isInstant=e||r.isLayoutInstant,i.push(s)}this._processLayoutQueue(i)}},s.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},s.prototype._processLayoutQueue=function(t){for(var e=0,i=t.length;i>e;e++){var o=t[e];this._positionItem(o.item,o.x,o.y,o.isInstant)}},s.prototype._positionItem=function(t,e,i,o){o?t.goTo(e,i):t.moveTo(e,i)},s.prototype._postLayout=function(){this.resizeContainer()},s.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var t=this._getContainerSize();t&&(this._setContainerMeasure(t.width,!0),this._setContainerMeasure(t.height,!1))}},s.prototype._getContainerSize=p,s.prototype._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},s.prototype._emitCompleteOnItems=function(t,e){function i(){n.emitEvent(t+"Complete",[e])}function o(){s++,s===r&&i()}var n=this,r=e.length;if(!e||!r)return i(),void 0;for(var s=0,a=0,u=e.length;u>a;a++){var p=e[a];p.once(t,o)}},s.prototype.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},s.prototype.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},s.prototype.stamp=function(t){if(t=this._find(t)){this.stamps=this.stamps.concat(t);for(var e=0,i=t.length;i>e;e++){var o=t[e];this.ignore(o)}}},s.prototype.unstamp=function(t){if(t=this._find(t))for(var e=0,i=t.length;i>e;e++){var o=t[e];n.removeFrom(this.stamps,o),this.unignore(o)}},s.prototype._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},s.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect
8838();for(var t=0,e=this.stamps.length;e>t;t++){var i=this.stamps[t];this._manageStamp(i)}}},s.prototype._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},s.prototype._manageStamp=p,s.prototype._getElementOffset=function(t){var e=t.getBoundingClientRect(),i=this._boundingRect,n=o(t),r={left:e.left-i.left-n.marginLeft,top:e.top-i.top-n.marginTop,right:i.right-e.right-n.marginRight,bottom:i.bottom-e.bottom-n.marginBottom};return r},s.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},s.prototype.bindResize=function(){this.isResizeBound||(e.bind(t,"resize",this),this.isResizeBound=!0)},s.prototype.unbindResize=function(){this.isResizeBound&&e.unbind(t,"resize",this),this.isResizeBound=!1},s.prototype.onresize=function(){function t(){e.resize(),delete e.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var e=this;this.resizeTimeout=setTimeout(t,100)},s.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},s.prototype.needsResizeLayout=function(){var t=o(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},s.prototype.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},s.prototype.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},s.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},s.prototype.reveal=function(t){this._emitCompleteOnItems("reveal",t);for(var e=t&&t.length,i=0;e&&e>i;i++){var o=t[i];o.reveal()}},s.prototype.hide=function(t){this._emitCompleteOnItems("hide",t);for(var e=t&&t.length,i=0;e&&e>i;i++){var o=t[i];o.hide()}},s.prototype.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},s.prototype.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},s.prototype.getItem=function(t){for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];if(o.element===t)return o}},s.prototype.getItems=function(t){t=n.makeArray(t);for(var e=[],i=0,o=t.length;o>i;i++){var r=t[i],s=this.getItem(r);s&&e.push(s)}return e},s.prototype.remove=function(t){var e=this.getItems(t);if(this._emitCompleteOnItems("remove",e),e&&e.length)for(var i=0,o=e.length;o>i;i++){var r=e[i];r.remove(),n.removeFrom(this.items,r)}},s.prototype.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="";for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];o.destroy()}this.unbindResize();var n=this.element.outlayerGUID;delete f[n],delete this.element.outlayerGUID,u&&u.removeData(this.element,this.constructor.namespace)},s.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&f[e]},s.create=function(t,e){function i(){s.apply(this,arguments)}return Object.create?i.prototype=Object.create(s.prototype):n.extend(i.prototype,s.prototype),i.prototype.constructor=i,i.defaults=n.extend({},s.defaults),n.extend(i.defaults,e),i.prototype.settings={},i.namespace=t,i.data=s.data,i.Item=function(){r.apply(this,arguments)},i.Item.prototype=new r,n.htmlInit(i,t),u&&u.bridget&&u.bridget(t,i),i},s.Item=r,s}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/item",["outlayer/outlayer"],e):"object"==typeof exports?module.exports=e(require("outlayer")):(t.Isotope=t.Isotope||{},t.Isotope.Item=e(t.Outlayer))}(window,function(t){function e(){t.Item.apply(this,arguments)}e.prototype=new t.Item,e.prototype._create=function(){this.id=this.layout.itemGUID++,t.Item.prototype._create.call(this),this.sortData={}},e.prototype.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var o=e[i];this.sortData[i]=o(this.element,this)}}};var i=e.prototype.destroy;return e.prototype.destroy=function(){i.apply(this,arguments),this.css({display:""})},e}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-mode",["get-size/get-size","outlayer/outlayer"],e):"object"==typeof exports?module.exports=e(require("get-size"),require("outlayer")):(t.Isotope=t.Isotope||{},t.Isotope.LayoutMode=e(t.getSize,t.Outlayer))}(window,function(t,e){function i(t){this.isotope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}return function(){function t(t){return function(){return e.prototype[t].apply(this.isotope,arguments)}}for(var o=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout"],n=0,r=o.length;r>n;n++){var s=o[n];i.prototype[s]=t(s)}}(),i.prototype.needsVerticalResizeLayout=function(){var e=t(this.isotope.element),i=this.isotope.size&&e;
8838return i&&e.innerHeight!=this.isotope.size.innerHeight},i.prototype._getMeasurement=function(){this.isotope._getMeasurement.apply(this,arguments)},i.prototype.getColumnWidth=function(){this.getSegmentSize("column","Width")},i.prototype.getRowHeight=function(){this.getSegmentSize("row","Height")},i.prototype.getSegmentSize=function(t,e){var i=t+e,o="outer"+e;if(this._getMeasurement(i,o),!this[i]){var n=this.getFirstItemSize();this[i]=n&&n[o]||this.isotope.size["inner"+e]}},i.prototype.getFirstItemSize=function(){var e=this.isotope.filteredItems[0];return e&&e.element&&t(e.element)},i.prototype.layout=function(){this.isotope.layout.apply(this.isotope,arguments)},i.prototype.getSize=function(){this.isotope.getSize(),this.size=this.isotope.size},i.modes={},i.create=function(t,e){function o(){i.apply(this,arguments)}return o.prototype=new i,e&&(o.options=e),o.prototype.namespace=t,i.modes[t]=o,o},i}),function(t,e){"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size","fizzy-ui-utils/utils"],e):"object"==typeof exports?module.exports=e(require("outlayer"),require("get-size"),require("fizzy-ui-utils")):t.Masonry=e(t.Outlayer,t.getSize,t.fizzyUIUtils)}(window,function(t,e,i){var o=t.create("masonry");return o.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var t=this.cols;for(this.colYs=[];t--;)this.colYs.push(0);this.maxY=0},o.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var o=this.columnWidth+=this.gutter,n=this.containerWidth+this.gutter,r=n/o,s=o-n%o,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},o.prototype.getContainerWidth=function(){var t=this.options.isFitWidth?this.element.parentNode:this.element,i=e(t);this.containerWidth=i&&i.innerWidth},o.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,o=e&&1>e?"round":"ceil",n=Math[o](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var r=this._getColGroup(n),s=Math.min.apply(Math,r),a=i.indexOf(r,s),u={x:this.columnWidth*a,y:s},p=s+t.size.outerHeight,h=this.cols+1-r.length,f=0;h>f;f++)this.colYs[a+f]=p;return u},o.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,o=0;i>o;o++){var n=this.colYs.slice(o,o+t);e[o]=Math.max.apply(Math,n)}return e},o.prototype._manageStamp=function(t){var i=e(t),o=this._getElementOffset(t),n=this.options.isOriginLeft?o.left:o.right,r=n+i.outerWidth,s=Math.floor(n/this.columnWidth);s=Math.max(0,s);var a=Math.floor(r/this.columnWidth);a-=r%this.columnWidth?0:1,a=Math.min(this.cols-1,a);for(var u=(this.options.isOriginTop?o.top:o.bottom)+i.outerHeight,p=s;a>=p;p++)this.colYs[p]=Math.max(u,this.colYs[p])},o.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this.options.isFitWidth&&(t.width=this._getContainerFitWidth()),t},o.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},o.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!==this.containerWidth},o}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-modes/masonry",["../layout-mode","masonry/masonry"],e):"object"==typeof exports?module.exports=e(require("../layout-mode"),require("masonry-layout")):e(t.Isotope.LayoutMode,t.Masonry)}(window,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}var o=t.create("masonry"),n=o.prototype._getElementOffset,r=o.prototype.layout,s=o.prototype._getMeasurement;i(o.prototype,e.prototype),o.prototype._getElementOffset=n,o.prototype.layout=r,o.prototype._getMeasurement=s;var a=o.prototype.measureColumns;o.prototype.measureColumns=function(){this.items=this.isotope.filteredItems,a.call(this)};var u=o.prototype._manageStamp;return o.prototype._manageStamp=function(){this.options.isOriginLeft=this.isotope.options.isOriginLeft,this.options.isOriginTop=this.isotope.options.isOriginTop,u.apply(this,arguments)},o}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-modes/fit-rows",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Isotope.LayoutMode)}(window,function(t){var e=t.create("fitRows");return e.prototype._resetLayout=function(){this.x=0,this.y=0,this.maxY=0,this._getMeasurement("gutter","outerWidth") 8839},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth+this.gutter,i=this.isotope.size.innerWidth+this.gutter;0!==this.x&&e+this.x>i&&(this.x=0,this.y=this.maxY);var o={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=e,o},e.prototype._getContainerSize=function(){return{height:this.maxY}},e}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-modes/vertical",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Isotope.LayoutMode)}(window,function(t){var e=t.create("vertical",{horizontalAlignment:0});return e.prototype._resetLayout=function(){this.y=0},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=(this.isotope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},e.prototype._getContainerSize=function(){return{height:this.y}},e}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","matches-selector/matches-selector","fizzy-ui-utils/utils","isotope/js/item","isotope/js/layout-mode","isotope/js/layout-modes/masonry","isotope/js/layout-modes/fit-rows","isotope/js/layout-modes/vertical"],function(i,o,n,r,s,a){return e(t,i,o,n,r,s,a)}):"object"==typeof exports?module.exports=e(t,require("outlayer"),require("get-size"),require("desandro-matches-selector"),require("fizzy-ui-utils"),require("./item"),require("./layout-mode"),require("./layout-modes/masonry"),require("./layout-modes/fit-rows"),require("./layout-modes/vertical")):t.Isotope=e(t,t.Outlayer,t.getSize,t.matchesSelector,t.fizzyUIUtils,t.Isotope.Item,t.Isotope.LayoutMode)}
8839(window,function(t,e,i,o,n,r,s){function a(t,e){return function(i,o){for(var n=0,r=t.length;r>n;n++){var s=t[n],a=i.sortData[s],u=o.sortData[s];if(a>u||u>a){var p=void 0!==e[s]?e[s]:e,h=p?1:-1;return(a>u?1:-1)*h}}return 0}}var u=t.jQuery,p=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},h=document.documentElement,f=h.textContent?function(t){return t.textContent}:function(t){return t.innerText},d=e.create("isotope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});d.Item=r,d.LayoutMode=s,d.prototype._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),e.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var t in s.modes)this._initLayoutMode(t)},d.prototype.reloadItems=function(){this.itemGUID=0,e.prototype.reloadItems.call(this)},d.prototype._itemize=function(){for(var t=e.prototype._itemize.apply(this,arguments),i=0,o=t.length;o>i;i++){var n=t[i];n.id=this.itemGUID++}return this._updateItemsSortData(t),t},d.prototype._initLayoutMode=function(t){var e=s.modes[t],i=this.options[t]||{};this.options[t]=e.options?n.extend(e.options,i):i,this.modes[t]=new e(this)},d.prototype.layout=function(){return!this._isLayoutInited&&this.options.isInitLayout?(this.arrange(),void 0):(this._layout(),void 0)},d.prototype._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},d.prototype.arrange=function(t){function e(){o.reveal(i.needReveal),o.hide(i.needHide)}this.option(t),this._getIsInstant();var i=this._filter(this.items);this.filteredItems=i.matches;var o=this;this._bindArrangeComplete(),this._isInstant?this._noTransition(e):e(),this._sort(),this._layout()},d.prototype._init=d.prototype.arrange,d.prototype._getIsInstant=function(){var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;return this._isInstant=t,t},d.prototype._bindArrangeComplete=function(){function t(){e&&i&&o&&n.emitEvent("arrangeComplete",[n.filteredItems])}var e,i,o,n=this;this.once("layoutComplete",function(){e=!0,t()}),this.once("hideComplete",function(){i=!0,t()}),this.once("revealComplete",function(){o=!0,t()})},d.prototype._filter=function(t){var e=this.options.filter;e=e||"*";for(var i=[],o=[],n=[],r=this._getFilterTest(e),s=0,a=t.length;a>s;s++){var u=t[s];if(!u.isIgnored){var p=r(u);
8839p&&i.push(u),p&&u.isHidden?o.push(u):p||u.isHidden||n.push(u)}}return{matches:i,needReveal:o,needHide:n}},d.prototype._getFilterTest=function(t){return u&&this.options.isJQueryFiltering?function(e){return u(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return o(e.element,t)}},d.prototype.updateSortData=function(t){var e;t?(t=n.makeArray(t),e=this.getItems(t)):e=this.items,this._getSorters(),this._updateItemsSortData(e)},d.prototype._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=l(i)}},d.prototype._updateItemsSortData=function(t){for(var e=t&&t.length,i=0;e&&e>i;i++){var o=t[i];o.updateSortData()}};var l=function(){function t(t){if("string"!=typeof t)return t;var i=p(t).split(" "),o=i[0],n=o.match(/^\[(.+)\]$/),r=n&&n[1],s=e(r,o),a=d.sortDataParsers[i[1]];return t=a?function(t){return t&&a(s(t))}:function(t){return t&&s(t)}}function e(t,e){var i;return i=t?function(e){return e.getAttribute(t)}:function(t){var i=t.querySelector(e);return i&&f(i)}}return t}();d.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},d.prototype._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=a(e,this.options.sortAscending);this.filteredItems.sort(i),t!=this.sortHistory[0]&&this.sortHistory.unshift(t)}},d.prototype._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw Error("No layout mode: "+t);return e.options=this.options[t],e},d.prototype._resetLayout=function(){e.prototype._resetLayout.call(this),this._mode()._resetLayout()},d.prototype._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},d.prototype._manageStamp=function(t){this._mode()._manageStamp(t)},d.prototype._getContainerSize=function(){return this._mode()._getContainerSize()},d.prototype.needsResizeLayout=function(){return this._mode().needsResizeLayout()},d.prototype.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},d.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){this._resetLayout(),this._manageStamps();var i=this._filterRevealAdded(e);this.layoutItems(this.filteredItems),this.filteredItems=i.concat(this.filteredItems),this.items=e.concat(this.items)}},d.prototype._filterRevealAdded=function(t){var e=this._filter(t);return this.hide(e.needHide),this.reveal(e.matches),this.layoutItems(e.matches,!0),e.matches},d.prototype.insert=function(t){var e=this.addItems(t);if(e.length){var i,o,n=e.length;for(i=0;n>i;i++)o=e[i],this.element.appendChild(o.element);var r=this._filter(e).matches;for(i=0;n>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;n>i;i++)delete e[i].isLayoutInstant;this.reveal(r)}};var c=d.prototype.remove;return d.prototype.remove=function(t){t=n.makeArray(t);var e=this.getItems(t);c.call(this,t);var i=e&&e.length;if(i)for(var o=0;i>o;o++){var r=e[o];n.removeFrom(this.filteredItems,r)}},d.prototype.shuffle=function(){for(var t=0,e=this.items.length;e>t;t++){var i=this.items[t];i.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},d.prototype._noTransition=function(t){var e=this.options.transitionDuration;this.options.transitionDuration=0;var i=t.call(this);return this.options.transitionDuration=e,i},d.prototype.getFilteredItemElements=function(){for(var t=[],e=0,i=this.filteredItems.length;i>e;e++)t.push(this.filteredItems[e].element);return t},d}); 8840;/*})'"*/ 8841;/*})'"*/ 8842/** 8843 * Owl carousel 8844 * @version 2.0.0 8845 * @author Bartosz Wojciechowski 8846 * @license The MIT License (MIT) 8847 * @todo Lazy Load Icon 8848 * @todo prevent animationend bubling 8849 * @todo itemsScaleUp 8850 * @todo Test Zepto 8851 * @todo stagePadding calculate wrong active classes 8852 */ 8853;(function($, window, document, undefined) { 8854 8855 var item, dom, width, num, pos, drag, speed, state, e; 8856 8857 /** 8858 * Template for the data of each item respectively its DOM element. 8859 * @private 8860 */ 8861 item = { 8862 index: false, 8863 indexAbs: false, 8864 posLeft: false, 8865 clone: false, 8866 active: false, 8867 loaded: false, 8868 lazyLoad: false, 8869 current: false, 8870 width: false, 8871 center: false, 8872 page: false, 8873 hasVideo: false, 8874 playVideo: false 8875 }; 8876 8877 /** 8878 * Template for the references to DOM elements, those with `$` sign are `jQuery` objects. 8879 * @private 8880 */ 8881 dom = { 8882 el: null, // main element 8883 $el: null, // jQuery main element 8884 stage: null, // stage 8885 $stage: null, // jQuery stage 8886 oStage: null, // outer stage 8887 $oStage: null, // $ outer stage 8888 $items: null, // all items, clones and originals included 8889 $oItems: null, // original items 8890 $cItems: null, // cloned items only 8891 $content: null 8892 }; 8893 8894 /** 8895 * Template for the widths of some elements. 8896 * @private 8897 */ 8898 width = { 8899 el: 0, 8900 stage: 0, 8901 item: 0, 8902 prevWindow: 0, 8903 cloneLast: 0 8904 }; 8905 8906 /** 8907 * Template for counting to some properties. 8908 * @private 8909 */ 8910 num = { 8911 items: 0, 8912 oItems: 0, 8913 cItems: 0, 8914 active: 0, 8915 merged: [] 8916 }; 8917 8918 /** 8919 * Template for status information about drag and touch events. 8920 * @private 8921 */ 8922 drag = { 8923 start: 0, 8924 startX: 0, 8925 startY: 0, 8926 current: 0, 8927 currentX: 0, 8928 currentY: 0, 8929 offsetX: 0, 8930 offsetY: 0, 8931 distance: null, 8932 startTime: 0, 8933 endTime: 0, 8934 updatedX: 0, 8935 targetEl: null 8936 }; 8937 8938 /** 8939 * Template for some status informations. 8940 * @private 8941 */ 8942 state = { 8943 isTouch: false, 8944 isScrolling: false, 8945 isSwiping: false, 8946 direction: false, 8947 inMotion: false 8948 }; 8949 8950 /** 8951 * Event functions references. 8952 * @private 8953 */ 8954 e = { 8955 _onDragStart: null, 8956 _onDragMove: null, 8957 _onDragEnd: null, 8958 _transitionEnd: null, 8959 _resizer: null, 8960 _responsiveCall: null, 8961 _goToLoop: null, 8962 _checkVisibile: null 8963 }; 8964 8965 /** 8966 * Creates a carousel. 8967 * @class The Owl Carousel. 8968 * @public 8969 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 8970 * @param {Object} [options] - The options 8971 */ 8972 function Owl(element, options) { 8973 8974 // add basic Owl information to dom element 8975 element.owlCarousel = { 8976 'name': 'Owl Carousel', 8977 'author': 'Bartosz Wojciechowski', 8978 'version': '2.0.0-beta.2.1' 8979 }; 8980 8981 /** 8982 * Current settings for the carousel. 8983 * @protected 8984 */ 8985 this.settings = null; 8986 8987 /** 8988 * 8989 * @protected 8990 * @todo Must be dosumented. 8991 */ 8992 this.options = $.extend({}, Owl.Defaults, options); 8993 8994 /** 8995 * Template for the data of each item. 8996 * @protected 8997 */ 8998 this.itemData = $.extend({}, item); 8999 9000 /** 9001 * Contains references to DOM elements, those with `$` sign are `jQuery` objects. 9002 * @protected 9003 */ 9004 this.dom = $.extend({}, dom); 9005 9006 /** 9007 * Caches the widths of some elements. 9008 * @protected 9009 */ 9010 this.width = $.extend({}, width); 9011 9012 /** 9013 * Caches some count informations. 9014 * @protected 9015 */ 9016 this.num = $.extend({}, num); 9017 9018 /** 9019 * Caches informations about drag and touch events. 9020 */ 9021 this.drag = $.extend({}, drag); 9022 9023 /** 9024 * Caches some status informations. 9025 * @protected 9026 */ 9027 this.state = $.extend({}, state); 9028 9029 /** 9030 * @protected 9031 * @todo Must be documented 9032 */ 9033 this.e = $.extend({}, e); 9034 9035 /** 9036 * References to the running plugins of this carousel. 9037 * @protected 9038 */ 9039 this.plugins = {}; 9040 9041 /** 9042 * Currently suppressed events to prevent them from beeing retriggered. 9043 * @protected 9044 */ 9045 this._supress = {}; 9046 9047 /** 9048 * The absolute current position. 9049 * @protected 9050 */ 9051 this._current = null; 9052 9053 /** 9054 * The animation speed in milliseconds. 9055 * @protected 9056 */ 9057 this._speed = null; 9058 9059 /** 9060 * The coordinates of all items in pixel. 9061 */ 9062 this._coordinates = null; 9063 9064 this.dom.el = element; 9065 this.dom.$el = $(element); 9066 9067 for (var plugin in Owl.Plugins) { 9068 this.plugins[plugin[0].toLowerCase() + plugin.slice(1)] 9069 = new Owl.Plugins[plugin](this); 9070 } 9071 9072 this.init(); 9073 } 9074 9075 /** 9076 * Default options for the carousel. 9077 * @public 9078 */ 9079 Owl.Defaults = { 9080 items: 3, 9081 loop: false, 9082 center: false, 9083
9084 mouseDrag: true, 9085 touchDrag: true, 9086 pullDrag: true, 9087 freeDrag: false, 9088 9089 margin: 0, 9090 stagePadding: 0, 9091 9092 merge: false, 9093 mergeFit: true, 9094 autoWidth: false, 9095 9096 startPosition: 0, 9097 9098 smartSpeed: 250, 9099 fluidSpeed: false, 9100 dragEndSpeed: false, 9101 9102 responsive: {}, 9103 responsiveRefreshRate: 200, 9104 responsiveBaseElement: window, 9105 responsiveClass: false, 9106 9107 fallbackEasing: 'swing', 9108 9109 info: false, 9110 9111 nestedItemSelector: false, 9112 itemElement: 'div', 9113 stageElement: 'div', 9114 9115 // Classes and Names 9116 themeClass: 'owl-theme', 9117 baseClass: 'owl-carousel', 9118 itemClass: 'owl-item', 9119 centerClass: 'center', 9120 activeClass: 'active' 9121 }; 9122 9123 /** 9124 * Contains all registered plugins. 9125 * @public 9126 */ 9127 Owl.Plugins = {}; 9128 9129 /** 9130 * Initializes the carousel. 9131 * @protected 9132 */ 9133 Owl.prototype.init = function() { 9134 9135 // Update options.items on given size 9136 this.setResponsiveOptions(); 9137 9138 this.trigger('initialize'); 9139 9140 // Add base class 9141 if (!this.dom.$el.hasClass(this.settings.baseClass)) { 9142 this.dom.$el.addClass(this.settings.baseClass); 9143 } 9144 9145 // Add theme class 9146 if (!this.dom.$el.hasClass(this.settings.themeClass)) { 9147 this.dom.$el.addClass(this.settings.themeClass); 9148 } 9149 9150 // Add theme class 9151 if (this.settings.rtl) { 9152 this.dom.$el.addClass('owl-rtl'); 9153 } 9154 9155 // Check support 9156 this.browserSupport(); 9157 9158 if (this.settings.autoWidth && this.state.imagesLoaded !== true) { 9159 var imgs, nestedSelector, width; 9160 imgs = this.dom.$el.find('img'); 9161 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 9162 width = this.dom.$el.children(nestedSelector).width(); 9163 9164 if (imgs.length && width <= 0) { 9165 this.preloadAutoWidthImages(imgs); 9166 return false; 9167 } 9168 } 9169 9170 // Get and store window width 9171 // iOS safari likes to trigger unnecessary resize event 9172 this.width.prevWindow = this.viewport(); 9173 9174 // create stage object 9175 this.createStage(); 9176 9177 // Append local content 9178 this.fetchContent(); 9179 9180 // attach generic events 9181 this.eventsCall(); 9182 9183 // attach generic events 9184 this.internalEvents(); 9185 9186 this.dom.$el.addClass('owl-loading'); 9187 this.refresh(true); 9188 this.dom.$el.removeClass('owl-loading').addClass('owl-loaded'); 9189 9190 this.trigger('initialized'); 9191 9192 // attach custom control events 9193 this.addTriggerableEvents(); 9194 }; 9195 9196 /** 9197 * Sets responsive options. 9198 * @protected 9199 */ 9200 Owl.prototype.setResponsiveOptions = function() { 9201 if (!this.options.responsive) { 9202 this.settings = $.extend({}, this.options); 9203 } else { 9204 var viewport = this.viewport(), 9205 overwrites = this.options.responsive, 9206 match = -1; 9207 9208 $.each(overwrites, function(breakpoint) { 9209 if (breakpoint <= viewport && breakpoint > match) { 9210 match = Number(breakpoint); 9211 } 9212 }); 9213 9214 this.settings = $.extend({}, this.options, overwrites[match]); 9215 delete this.settings.responsive; 9216 9217 // Responsive Class 9218 if (this.settings.responsiveClass) { 9219 this.dom.$el.attr('class', function(i, c) { 9220 return c.replace(/\b owl-responsive-\S+/g, ''); 9221 }).addClass('owl-responsive-' + match); 9222 } 9223 } 9224 }; 9225 9226 /** 9227 * Updates option logic if necessery. 9228 * @protected 9229 */ 9230 Owl.prototype.optionsLogic = function() { 9231 // Toggle Center class 9232 this.dom.$el.toggleClass('owl-center', this.settings.center); 9233 9234 // if items number is less than in body 9235 if (this.settings.loop && this.num.oItems < this.settings.items) { 9236 this.settings.loop = false; 9237 } 9238 9239 if (this.settings.autoWidth) { 9240 this.settings.stagePadding = false; 9241 this.settings.merge = false; 9242 } 9243 }; 9244 9245 /** 9246 * Creates stage and outer-stage elements. 9247 * @protected 9248 */ 9249 Owl.prototype.createStage = function() { 9250 var oStage = document.createElement('div'), 9251 stage = document.createElement(this.settings.stageElement); 9252 9253 oStage.className = 'owl-stage-outer'; 9254 stage.className = 'owl-stage'; 9255 9256 oStage.appendChild(stage); 9257 this.dom.el.appendChild(oStage); 9258 9259 this.dom.oStage = oStage; 9260 this.dom.$oStage = $(oStage); 9261 this.dom.stage = stage; 9262 this.dom.$stage = $(stage); 9263 9264 oStage = null; 9265 stage = null; 9266 }; 9267 9268 /** 9269 * Creates an item container. 9270 * @protected 9271 * @returns {jQuery} - The item container. 9272 */ 9273 Owl.prototype.createItemContainer = function() { 9274 var item = document.createElement(this.settings.itemElement); 9275 item.className = this.settings.itemClass; 9276 return $(item); 9277 }; 9278 9279 /** 9280 * Fetches the content. 9281 * @protected 9282 */ 9283 Owl.prototype.fetchContent = function(extContent) { 9284 if (extContent) { 9285 this.dom.$content = (extContent instanceof jQuery) ? extContent : $(extContent); 9286 } else if (this.settings.nestedItemSelector) { 9287 this.dom.$content = this.dom.$el.find('.' + this.settings.nestedItemSelector).not('.owl-stage-outer'); 9288 } else { 9289 this.dom.$content = this.dom.$el.children().not('.owl-stage-outer'); 9290 } 9291 // content length 9292 this.num.oItems = this.dom.$content.length; 9293 9294 // init Structure 9295 if (this.num.oItems !== 0) { 9296 this.initStructure(); 9297 } 9298 }; 9299 9300 /** 9301 * Initializes the content struture. 9302 * @protected 9303 */ 9304 Owl.prototype.initStructure = function() { 9305 this.createNormalStructure(); 9306 }; 9307 9308 /** 9309 * Creates small/mid weight content structure. 9310 * @protected 9311 * @todo This results in a poor performance, 9312 * but this is due to the approach of completely 9313 * rebuild the existing DOM tree from scratch, 9314 * rather to use them. The effort to implement 9315 * this with a good performance, while maintaining 9316 * the original approach is disproportionate. 9317 */ 9318 Owl.prototype.createNormalStructure = function() { 9319 var i, $item; 9320 for (i = 0; i < this.num.oItems; i++) { 9321 $item = this.createItemContainer(); 9322 this.initializeItemContainer($item, this.dom.$content[i]); 9323 this.dom.$stage.append($item); 9324 } 9325 this.dom.$content = null; 9326 }; 9327 9328 /** 9329 * Creates custom content structure. 9330 * @protected 9331 */ 9332 Owl.prototype.createCustomStructure = function(howManyItems) { 9333 var i, $item; 9334 for (i = 0; i < howManyItems; i++) { 9335 $item = this.createItemContainer(); 9336 this.createItemContainerData($item); 9337 this.dom.$stage.append($item); 9338 } 9339 }; 9340 9341 /** 9342 * Initializes item container with provided content. 9343 * @protected 9344 * @param {jQuery} item - The item that has to be filled. 9345 * @param {HTMLElement|jQuery|string} content - The content that fills the item. 9346 */ 9347 Owl.prototype.initializeItemContainer = function(item, content) { 9348 this.trigger('change', { property: { name: 'item', value: item } }); 9349 9350 this.createItemContainerData(item); 9351 item.append(content); 9352 9353 this.trigger('changed', { property: { name: 'item', value: item } }); 9354 }; 9355 9356 /** 9357 * Creates item container data. 9358 * @protected 9359 * @param {jQuery} item - The item for which the data are to be set. 9360 * @param {jQuery} [source] - The item whose data are to be copied. 9361 */ 9362 Owl.prototype.createItemContainerData = function(item, source) { 9363 var data = $.extend({}, this.itemData); 9364 9365 if (source) { 9366 $.extend(data, source.data('owl-item')); 9367 } 9368 9369 item.data('owl-item', data); 9370 }; 9371 9372 /** 9373 * Clones an item container. 9374 * @protected 9375 * @param {jQuery} item - The item to clone.
9376 * @returns {jQuery} - The cloned item. 9377 */ 9378 Owl.prototype.cloneItemContainer = function(item) { 9379 var $clone = item.clone(true, true).addClass('cloned'); 9380 // somehow data references the same object 9381 this.createItemContainerData($clone, $clone); 9382 $clone.data('owl-item').clone = true; 9383 return $clone; 9384 }; 9385 9386 /** 9387 * Updates original items index data. 9388 * @protected 9389 */ 9390 Owl.prototype.updateLocalContent = function() { 9391 9392 var k, item; 9393 9394 this.dom.$oItems = this.dom.$stage.find('.' + this.settings.itemClass).filter(function() { 9395 return $(this).data('owl-item').clone === false; 9396 }); 9397 9398 this.num.oItems = this.dom.$oItems.length; 9399 // update index on original items 9400 9401 for (k = 0; k < this.num.oItems; k++) { 9402 item = this.dom.$oItems.eq(k); 9403 item.data('owl-item').index = k; 9404 } 9405 }; 9406 9407 /** 9408 * Creates clones for infinity loop. 9409 * @protected 9410 */ 9411 Owl.prototype.loopClone = function() { 9412 if (!this.settings.loop || this.num.oItems < this.settings.items) { 9413 return false; 9414 } 9415 9416 var append, prepend, i, 9417 items = this.settings.items, 9418 last = this.num.oItems - 1; 9419 9420 // if neighbour margin then add one more duplicat 9421 if (this.settings.stagePadding && this.settings.items === 1) { 9422 items += 1; 9423 } 9424 this.num.cItems = items * 2; 9425 9426 for (i = 0; i < items; i++) { 9427 append = this.cloneItemContainer(this.dom.$oItems.eq(i)); 9428 prepend = this.cloneItemContainer(this.dom.$oItems.eq(last - i)); 9429 9430 this.dom.$stage.append(append); 9431 this.dom.$stage.prepend(prepend); 9432 } 9433 9434 this.dom.$cItems = this.dom.$stage.find('.' + this.settings.itemClass).filter(function() { 9435 return $(this).data('owl-item').clone === true; 9436 }); 9437 }; 9438 9439 /** 9440 * Update cloned elements. 9441 * @protected 9442 */ 9443 Owl.prototype.reClone = function() { 9444 // remove cloned items 9445 if (this.dom.$cItems !== null) { // && (this.num.oItems !== 0 && 9446 // this.num.oItems <= 9447 // this.settings.items)){ 9448 this.dom.$cItems.remove(); 9449 this.dom.$cItems = null; 9450 this.num.cItems = 0; 9451 } 9452 9453 if (!this.settings.loop) { 9454 return; 9455 } 9456 // generete new elements 9457 this.loopClone(); 9458 }; 9459 9460 /** 9461 * Updates all items index data. 9462 * @protected 9463 */ 9464 Owl.prototype.calculate = function() { 9465 9466 var i, j, elMinusMargin, dist, allItems, iWidth, mergeNumber, posLeft = 0, fullWidth = 0; 9467 9468 // element width minus neighbour 9469 this.width.el = this.dom.$el.width() - (this.settings.stagePadding * 2); 9470 9471 // to check 9472 this.width.view = this.dom.$el.width(); 9473 9474 // calculate width minus addition margins 9475 elMinusMargin = this.width.el - (this.settings.margin * (this.settings.items === 1 ? 0 : this.settings.items - 1)); 9476 9477 // calculate element width and item width 9478 this.width.el = this.width.el + this.settings.margin; 9479 this.width.item = ((elMinusMargin / this.settings.items) + this.settings.margin).toFixed(3); 9480 9481 this.dom.$items = this.dom.$stage.find('.owl-item'); 9482 this.num.items = this.dom.$items.length; 9483 9484 // change to autoWidths 9485 if (this.settings.autoWidth) { 9486 this.dom.$items.css('width', ''); 9487 } 9488 9489 // Set grid array 9490 this._coordinates = []; 9491 this.num.merged = []; 9492 9493 // item distances 9494 if (this.settings.rtl) { 9495 dist = this.settings.center ? -((this.width.el) / 2) : 0; 9496 } else { 9497 dist = this.settings.center ? (this.width.el) / 2 : 0; 9498 } 9499 9500 this.width.mergeStage = 0; 9501 9502 // Calculate items positions 9503 for (i = 0; i < this.num.items; i++) { 9504 9505 // check merged items 9506 9507 if (this.settings.merge) { 9508 mergeNumber = this.dom.$items.eq(i).find('[data-merge]').attr('data-merge') || 1; 9509 if (this.settings.mergeFit && mergeNumber > this.settings.items) { 9510 mergeNumber = this.settings.items; 9511 } 9512 this.num.merged.push(parseInt(mergeNumber)); 9513 this.width.mergeStage += this.width.item * this.num.merged[i]; 9514 } else { 9515 this.num.merged.push(1); 9516 } 9517 9518 iWidth = this.width.item * this.num.merged[i]; 9519 9520 // autoWidth item size 9521 if (this.settings.autoWidth) { 9522 iWidth = this.dom.$items.eq(i).width() + this.settings.margin; 9523 if (this.settings.rtl) { 9524 this.dom.$items[i].style.marginLeft = this.settings.margin + 'px'; 9525 } else { 9526 this.dom.$items[i].style.marginRight = this.settings.margin + 'px'; 9527 } 9528 9529 } 9530 // push item position into array 9531 this._coordinates.push(dist); 9532 9533 // update item data 9534 this.dom.$items.eq(i).data('owl-item').posLeft = posLeft; 9535 this.dom.$items.eq(i).data('owl-item').width = iWidth; 9536 9537 // dist starts from middle of stage if center 9538 // posLeft always starts from 0 9539 if (this.settings.rtl) { 9540 dist += iWidth; 9541 posLeft += iWidth; 9542 } else { 9543 dist -= iWidth; 9544 posLeft -= iWidth; 9545 } 9546 9547 fullWidth -= Math.abs(iWidth); 9548 9549 // update position if center 9550 if (this.settings.center) { 9551 this._coordinates[i] = !this.settings.rtl ? this._coordinates[i] - (iWidth / 2) : this._coordinates[i] 9552 + (iWidth / 2); 9553 } 9554 } 9555 9556 if (this.settings.autoWidth) { 9557 this.width.stage = this.settings.center ? Math.abs(fullWidth) : Math.abs(dist); 9558 } else { 9559 this.width.stage = Math.abs(fullWidth);
9560 } 9561 9562 // update indexAbs on all items 9563 allItems = this.num.oItems + this.num.cItems; 9564 9565 for (j = 0; j < allItems; j++) { 9566 this.dom.$items.eq(j).data('owl-item').indexAbs = j; 9567 } 9568 9569 // Recalculate grid 9570 this.setSizes(); 9571 }; 9572 9573 /** 9574 * Set sizes on elements from `collectData`. 9575 * @protected 9576 * @todo CRAZY FIX!!! Doublecheck this! 9577 */ 9578 Owl.prototype.setSizes = function() { 9579 9580 // show neighbours 9581 if (this.settings.stagePadding !== false) { 9582 this.dom.oStage.style.paddingLeft = this.settings.stagePadding + 'px'; 9583 this.dom.oStage.style.paddingRight = this.settings.stagePadding + 'px'; 9584 } 9585 9586 // if(this.width.stagePrev > this.width.stage){ 9587 if (this.settings.rtl) { 9588 window.setTimeout($.proxy(function() { 9589 this.dom.stage.style.width = this.width.stage + 'px'; 9590 }, this), 0); 9591 } else { 9592 this.dom.stage.style.width = this.width.stage + 'px'; 9593 } 9594 9595 for (var i = 0; i < this.num.items; i++) { 9596 9597 // Set items width 9598 if (!this.settings.autoWidth) { 9599 this.dom.$items[i].style.width = this.width.item - (this.settings.margin) + 'px'; 9600 } 9601 // add margin 9602 if (this.settings.rtl) { 9603 this.dom.$items[i].style.marginLeft = this.settings.margin + 'px'; 9604 } else { 9605 this.dom.$items[i].style.marginRight = this.settings.margin + 'px'; 9606 } 9607 9608 if (this.num.merged[i] !== 1 && !this.settings.autoWidth) { 9609 this.dom.$items[i].style.width = (this.width.item * this.num.merged[i]) - (this.settings.margin) + 'px'; 9610 } 9611 } 9612 9613 // save prev stage size 9614 this.width.stagePrev = this.width.stage; 9615 }; 9616 9617 /** 9618 * Updates all data by calling `refresh`. 9619 * @protected 9620 */ 9621 Owl.prototype.responsive = function() { 9622 9623 if (!this.num.oItems) { 9624 return false; 9625 } 9626 // If El width hasnt change then stop responsive 9627 var elChanged = this.isElWidthChanged(); 9628 if (!elChanged) { 9629 return false; 9630 } 9631 9632 if (this.trigger('resize').isDefaultPrevented()) { 9633 return false; 9634 } 9635 9636 this.state.responsive = true; 9637 this.refresh(); 9638 this.state.responsive = false; 9639 9640 this.trigger('resized'); 9641 }; 9642 9643 /** 9644 * Refreshes the carousel primarily for adaptive purposes. 9645 * @public 9646 */ 9647 Owl.prototype.refresh = function() { 9648 var current = this.dom.$oItems && this.dom.$oItems.eq(this.normalize(this.current(), true)); 9649 9650 this.trigger('refresh'); 9651 9652 // Update Options for given width 9653 this.setResponsiveOptions(); 9654 9655 // update info about local content 9656 this.updateLocalContent(); 9657 9658 // udpate options 9659 this.optionsLogic(); 9660 9661 // if no items then stop 9662 if (this.num.oItems === 0) { 9663 return false; 9664 } 9665 9666 // Hide and Show methods helps here to set a proper widths. 9667 // This prevents Scrollbar to be calculated in stage width 9668 this.dom.$stage.addClass('owl-refresh'); 9669 9670 // Remove clones and generate new ones 9671 this.reClone(); 9672 9673 // calculate 9674 this.calculate(); 9675 9676 // aaaand show. 9677 this.dom.$stage.removeClass('owl-refresh'); 9678 9679 if (!current) { 9680 this.dom.oStage.scrollLeft = 0; 9681 this.reset(this.dom.$oItems.eq(0).data('owl-item').indexAbs); 9682 } else { 9683 this.reset(current.data('owl-item').indexAbs); // fix that 9684 } 9685 9686 this.state.orientation = window.orientation; 9687 9688 this.watchVisibility(); 9689 9690 this.trigger('refreshed'); 9691 }; 9692 9693 /** 9694 * Updates information about current state of items (visibile, hidden, active, etc.). 9695 * @protected 9696 */ 9697 Owl.prototype.updateActiveItems = function() { 9698 this.trigger('change', { property: { name: 'items', value: this.dom.$items } }); 9699 9700 var i, j, item, ipos, iwidth, outsideView; 9701 9702 // clear states 9703 for (i = 0; i < this.num.items; i++) { 9704 this.dom.$items.eq(i).data('owl-item').active = false; 9705 this.dom.$items.eq(i).data('owl-item').current = false; 9706 this.dom.$items.eq(i).removeClass(this.settings.activeClass).removeClass(this.settings.centerClass); 9707 } 9708 9709 this.num.active = 0; 9710 padding = this.settings.stagePadding * 2; 9711 stageX = this.coordinates(this.current()) + padding; 9712 view = this.settings.rtl ? this.width.view : -this.width.view; 9713 9714 for (j = 0; j < this.num.items; j++) { 9715 9716 item = this.dom.$items.eq(j); 9717 ipos = item.data('owl-item').posLeft; 9718 iwidth = item.data('owl-item').width; 9719 outsideView = this.settings.rtl ? ipos - iwidth - padding : ipos - iwidth + padding; 9720 9721 if ((this.op(ipos, '<=', stageX) && (this.op(ipos, '>', stageX + view))) 9722 || (this.op(outsideView, '<', stageX) && this.op(outsideView, '>', stageX + view))) { 9723 9724 this.num.active++; 9725 9726 item.data('owl-item').active = true; 9727 item.data('owl-item').current = true; 9728 item.addClass(this.settings.activeClass); 9729 9730 if (!this.settings.lazyLoad) { 9731 item.data('owl-item').loaded = true; 9732 } 9733 if (this.settings.loop) { 9734 this.updateClonedItemsState(item.data('owl-item').index); 9735 } 9736 } 9737 } 9738 9739 if (this.settings.center) { 9740 this.dom.$items.eq(this.current()).addClass(this.settings.centerClass).data('owl-item').center = true; 9741 } 9742 this.trigger('changed', { property: { name: 'items', value: this.dom.$items } }); 9743 }; 9744 9745 /** 9746 * Sets current state on sibilings items for center.
9747 * @protected 9748 */ 9749 Owl.prototype.updateClonedItemsState = function(activeIndex) { 9750 9751 // find cloned center 9752 var center, $el, i; 9753 if (this.settings.center) { 9754 center = this.dom.$items.eq(this.current()).data('owl-item').index; 9755 } 9756 9757 for (i = 0; i < this.num.items; i++) { 9758 $el = this.dom.$items.eq(i); 9759 if ($el.data('owl-item').index === activeIndex) { 9760 $el.data('owl-item').current = true; 9761 if ($el.data('owl-item').index === center) { 9762 $el.addClass(this.settings.centerClass); 9763 } 9764 } 9765 } 9766 }; 9767 9768 /** 9769 * Save internal event references and add event based functions. 9770 * @protected 9771 */ 9772 Owl.prototype.eventsCall = function() { 9773 // Save events references 9774 this.e._onDragStart = $.proxy(function(e) { 9775 this.onDragStart(e); 9776 }, this); 9777 this.e._onDragMove = $.proxy(function(e) { 9778 this.onDragMove(e); 9779 }, this); 9780 this.e._onDragEnd = $.proxy(function(e) { 9781 this.onDragEnd(e); 9782 }, this); 9783 this.e._transitionEnd = $.proxy(function(e) { 9784 this.transitionEnd(e); 9785 }, this); 9786 this.e._resizer = $.proxy(function() { 9787 this.responsiveTimer(); 9788 }, this); 9789 this.e._responsiveCall = $.proxy(function() { 9790 this.responsive(); 9791 }, this); 9792 this.e._preventClick = $.proxy(function(e) { 9793 this.preventClick(e); 9794 }, this); 9795 }; 9796 9797 /** 9798 * Checks window `resize` event. 9799 * @protected 9800 */ 9801 Owl.prototype.responsiveTimer = function() { 9802 if (this.viewport() === this.width.prevWindow) { 9803 return false; 9804 } 9805 window.clearTimeout(this.resizeTimer); 9806 9807 this.resizeTimer = window.setTimeout(this.e._responsiveCall, this.settings.responsiveRefreshRate); 9808 this.width.prevWindow = this.viewport(); 9809 }; 9810 9811 /** 9812 * Checks for touch/mouse drag options and add necessery event handlers. 9813 * @protected 9814 */ 9815 Owl.prototype.internalEvents = function() { 9816 var isTouch = isTouchSupport(), 9817 isTouchIE = isTouchSupportIE(); 9818 9819 if (isTouch && !isTouchIE) { 9820 this.dragType = [ 'touchstart', 'touchmove', 'touchend', 'touchcancel' ]; 9821 } else if (isTouch && isTouchIE) { 9822 this.dragType = [ 'MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel' ]; 9823 } else { 9824 this.dragType = [ 'mousedown', 'mousemove', 'mouseup' ]; 9825 } 9826 9827 if ((isTouch || isTouchIE) && this.settings.touchDrag) { 9828 // touch cancel event 9829 this.on(document, this.dragType[3], this.e._onDragEnd); 9830 9831 } else { 9832 // firefox startdrag fix - addeventlistener doesnt work here :/ 9833 this.dom.$stage.on('dragstart', function() { 9834 return false; 9835 }); 9836 9837 if (this.settings.mouseDrag) { 9838 // disable text select 9839 this.dom.stage.onselectstart = function() { 9840 return false; 9841 }; 9842 } else { 9843 // enable text select 9844 this.dom.$el.addClass('owl-text-select-on'); 9845 } 9846 } 9847 9848 // Catch transitionEnd event 9849 if (this.transitionEndVendor) { 9850 this.on(this.dom.stage, this.transitionEndVendor, this.e._transitionEnd, false); 9851 } 9852 9853 // Responsive 9854 if (this.settings.responsive !== false) { 9855 this.on(window, 'resize', this.e._resizer, false); 9856 } 9857 9858 this.dragEvents(); 9859 }; 9860 9861 /** 9862 * Triggers event handlers for drag events. 9863 * @protected 9864 */ 9865 Owl.prototype.dragEvents = function() { 9866 9867 if (this.settings.touchDrag && (this.dragType[0] === 'touchstart' || this.dragType[0] === 'MSPointerDown')) { 9868 this.on(this.dom.stage, this.dragType[0], this.e._onDragStart, false); 9869 } else if (this.settings.mouseDrag && this.dragType[0] === 'mousedown') { 9870 this.on(this.dom.stage, this.dragType[0], this.e._onDragStart, false); 9871 } else { 9872 this.off(this.dom.stage, this.dragType[0], this.e._onDragStart); 9873 } 9874 }; 9875 9876 /** 9877 * Handles touchstart/mousedown event. 9878 * @protected 9879 * @param {Event} event - The event arguments. 9880 */ 9881 Owl.prototype.onDragStart = function(event) { 9882 var ev, isTouchEvent, pageX, pageY, animatedPos; 9883 9884 ev = event.originalEvent || event || window.event; 9885 9886 // prevent right click 9887 if (ev.which === 3) { 9888 return false; 9889 } 9890 9891 if (this.dragType[0] === 'mousedown') { 9892 this.dom.$stage.addClass('owl-grab'); 9893 } 9894 9895 this.trigger('drag'); 9896 this.drag.startTime = new Date().getTime(); 9897 this.speed(0); 9898 this.state.isTouch = true; 9899 this.state.isScrolling = false; 9900 this.state.isSwiping = false; 9901 this.drag.distance = 0; 9902 9903 // if is 'touchstart' 9904 isTouchEvent = ev.type === 'touchstart'; 9905 pageX = isTouchEvent ? event.targetTouches[0].pageX : (ev.pageX || ev.clientX); 9906 pageY = isTouchEvent ? event.targetTouches[0].pageY : (ev.pageY || ev.clientY); 9907 9908 // get stage position left 9909 this.drag.offsetX = this.dom.$stage.position().left - this.settings.stagePadding; 9910 this.drag.offsetY = this.dom.$stage.position().top; 9911 9912 if (this.settings.rtl) { 9913 this.drag.offsetX = this.dom.$stage.position().left + this.width.stage - this.width.el 9914 + this.settings.margin; 9915 } 9916 9917 // catch position // ie to fix 9918 if (this.state.inMotion && this.support3d) { 9919 animatedPos = this.getTransformProperty(); 9920 this.drag.offsetX = animatedPos; 9921 this.animate(animatedPos);
9922 this.state.inMotion = true; 9923 } else if (this.state.inMotion && !this.support3d) { 9924 this.state.inMotion = false; 9925 return false; 9926 } 9927 9928 this.drag.startX = pageX - this.drag.offsetX; 9929 this.drag.startY = pageY - this.drag.offsetY; 9930 9931 this.drag.start = pageX - this.drag.startX; 9932 this.drag.targetEl = ev.target || ev.srcElement; 9933 this.drag.updatedX = this.drag.start; 9934 9935 // to do/check 9936 // prevent links and images dragging; 9937 if (this.drag.targetEl.tagName === "IMG" || this.drag.targetEl.tagName === "A") { 9938 this.drag.targetEl.draggable = false; 9939 } 9940 9941 this.on(document, this.dragType[1], this.e._onDragMove, false); 9942 this.on(document, this.dragType[2], this.e._onDragEnd, false); 9943 }; 9944 9945 /** 9946 * Handles the touchmove/mousemove events. 9947 * @todo Simplify 9948 * @protected 9949 * @param {Event} event - The event arguments. 9950 */ 9951 Owl.prototype.onDragMove = function(event) { 9952 var ev, isTouchEvent, pageX, pageY, minValue, maxValue, pull; 9953 9954 if (!this.state.isTouch) { 9955 return; 9956 } 9957 9958 if (this.state.isScrolling) { 9959 return; 9960 } 9961 9962 ev = event.originalEvent || event || window.event; 9963 9964 // if is 'touchstart' 9965 isTouchEvent = ev.type == 'touchmove'; 9966 pageX = isTouchEvent ? ev.targetTouches[0].pageX : (ev.pageX || ev.clientX); 9967 pageY = isTouchEvent ? ev.targetTouches[0].pageY : (ev.pageY || ev.clientY); 9968 9969 // Drag Direction 9970 this.drag.currentX = pageX - this.drag.startX; 9971 this.drag.currentY = pageY - this.drag.startY; 9972 this.drag.distance = this.drag.currentX - this.drag.offsetX; 9973 9974 // Check move direction 9975 if (this.drag.distance < 0) { 9976 this.state.direction = this.settings.rtl ? 'right' : 'left'; 9977 } else if (this.drag.distance > 0) { 9978 this.state.direction = this.settings.rtl ? 'left' : 'right'; 9979 } 9980 // Loop 9981 if (this.settings.loop) { 9982 if (this.op(this.drag.currentX, '>', this.coordinates(this.minimum())) && this.state.direction === 'right') { 9983 this.drag.currentX -= (this.settings.center && this.coordinates(0)) - this.coordinates(this.num.oItems); 9984 } else if (this.op(this.drag.currentX, '<', this.coordinates(this.maximum())) && this.state.direction === 'left') { 9985 this.drag.currentX += (this.settings.center && this.coordinates(0)) - this.coordinates(this.num.oItems); 9986 } 9987 } else { 9988 // pull 9989 minValue = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 9990 maxValue = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 9991 pull = this.settings.pullDrag ? this.drag.distance / 5 : 0; 9992 this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull); 9993 } 9994 9995 // Lock browser if swiping horizontal 9996 9997 if ((this.drag.distance > 8 || this.drag.distance < -8)) { 9998 if (ev.preventDefault !== undefined) { 9999 ev.preventDefault(); 10000 } else { 10001 ev.returnValue = false; 10002 } 10003 this.state.isSwiping = true; 10004 } 10005 10006 this.drag.updatedX = this.drag.currentX; 10007 10008 // Lock Owl if scrolling 10009 if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) { 10010 this.state.isScrolling = true; 10011 this.drag.updatedX = this.drag.start; 10012 } 10013 10014 this.animate(this.drag.updatedX); 10015 }; 10016 10017 /** 10018 * Handles the touchend/mouseup events. 10019 * @protected 10020 */ 10021 Owl.prototype.onDragEnd = function() { 10022 var compareTimes, distanceAbs, closest; 10023 10024 if (!this.state.isTouch) { 10025 return; 10026 } 10027 if (this.dragType[0] === 'mousedown') { 10028 this.dom.$stage.removeClass('owl-grab'); 10029 } 10030 10031 this.trigger('dragged'); 10032 10033 // prevent links and images dragging; 10034 this.drag.targetEl.removeAttribute("draggable"); 10035 10036 // remove drag event listeners 10037 10038 this.state.isTouch = false; 10039 this.state.isScrolling = false; 10040 this.state.isSwiping = false; 10041 10042 // to check 10043 if (this.drag.distance === 0 && this.state.inMotion !== true) { 10044 this.state.inMotion = false; 10045 return false; 10046 } 10047 10048 // prevent clicks while scrolling 10049 10050 this.drag.endTime = new Date().getTime(); 10051 compareTimes = this.drag.endTime - this.drag.startTime; 10052 distanceAbs = Math.abs(this.drag.distance); 10053 10054 // to test 10055 if (distanceAbs > 3 || compareTimes > 300) { 10056 this.removeClick(this.drag.targetEl); 10057 } 10058 10059 closest = this.closest(this.drag.updatedX); 10060 10061 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 10062 this.current(closest); 10063 10064 // if pullDrag is off then fire transitionEnd event manually when stick 10065 // to border 10066 if (!this.settings.pullDrag && this.drag.updatedX === this.coordinates(closest)) { 10067 this.transitionEnd(); 10068 } 10069 10070 this.drag.distance = 0; 10071 10072 this.off(document, this.dragType[1], this.e._onDragMove); 10073 this.off(document, this.dragType[2], this.e._onDragEnd); 10074 }; 10075 10076 /** 10077 * Attaches `preventClick` to disable link while swipping. 10078 * @protected 10079 * @param {HTMLElement} [target] - The target of the `click` event. 10080 */ 10081 Owl.prototype.removeClick = function(target) { 10082 this.drag.targetEl = target; 10083 $(target).on('click.preventClick', this.e._preventClick); 10084 // to make sure click is removed: 10085 window.setTimeout(function() { 10086 $(target).off('click.preventClick'); 10087 }, 300); 10088 }; 10089 10090 /** 10091 * Suppresses click event. 10092 * @protected 10093 * @param {Event} ev - The event arguments. 10094 */ 10095 Owl.prototype.preventClick = function(ev) { 10096 if (ev.preventDefault) { 10097 ev.preventDefault(); 10098 } else { 10099 ev.returnValue = false; 10100 } 10101 if (ev.stopPropagation) { 10102 ev.stopPropagation(); 10103 } 10104 $(ev.target).off('click.preventClick'); 10105 }; 10106 10107 /** 10108 * Catches stage position while animate (only CSS3). 10109 * @protected 10110 * @returns 10111 */ 10112 Owl.prototype.getTransformProperty = function() { 10113 var transform, matrix3d; 10114 10115 transform = window.getComputedStyle(this.dom.stage, null).getPropertyValue(this.vendorName + 'transform'); 10116 // var transform = this.dom.$stage.css(this.vendorName + 'transform') 10117 transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(','); 10118 matrix3d = transform.length === 16; 10119 10120 return matrix3d !== true ? transform[4] : transform[12]; 10121 }; 10122 10123 /** 10124 * Gets absolute position of the closest item for a coordinate. 10125 * @protected 10126 * @param {Number} coordinate - The coordinate in pixel. 10127 * @return {Number} - The absolute position of the closest item. 10128 */ 10129 Owl.prototype.closest = function(coordinate) { 10130 var position = 0, pull = 30; 10131 10132 if (!this.settings.freeDrag) { 10133 // check closest item 10134 $.each(this.coordinates(), $.proxy(function(index, value) { 10135 if (coordinate > value - pull && coordinate < value + pull) { 10136 position = index; 10137 } else if (this.op(coordinate, '<', value) 10138 && this.op(coordinate, '>', this.coordinates(index + 1) || value - this.width.el)) { 10139 position = this.state.direction === 'left' ? index + 1 : index; 10140 } 10141 }, this)); 10142 } 10143 10144 if (!this.settings.loop) { 10145 // non loop boundries 10146 if (this.op(coordinate, '>', this.coordinates(this.minimum()))) { 10147 position = coordinate = this.minimum(); 10148 } else if (this.op(coordinate, '<', this.coordinates(this.maximum()))) { 10149 position = coordinate = this.maximum(); 10150 } 10151 } 10152 10153 return position; 10154 }; 10155 10156 /** 10157 * Animates the stage. 10158 * @public 10159 * @param {Number} coordinate - The coordinate in pixels. 10160 */ 10161 Owl.prototype.animate = function(coordinate) { 10162 this.trigger('translate'); 10163 this.state.inMotion = this.speed() > 0; 10164 10165 if (this.support3d) { 10166 this.dom.$stage.css({ 10167 transform: 'translate3d(' + coordinate + 'px' + ',0px, 0px)', 10168 transition: (this.speed() / 1000) + 's' 10169 }); 10170 } else if (this.state.isTouch) { 10171 this.dom.$stage.css({ 10172 left: coordinate + 'px' 10173 }); 10174 } else { 10175 this.dom.$stage.animate({ 10176 left: coordinate 10177 }, this.speed() / 1000, this.settings.fallbackEasing, $.proxy(function() { 10178 if (this.state.inMotion) { 10179 this.transitionEnd(); 10180 } 10181 }, this)); 10182 } 10183 }; 10184 10185 /** 10186 * Sets the absolute position of the current item. 10187 * @public 10188 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 10189 * @returns {Number} - The absolute position of the current item. 10190 */ 10191 Owl.prototype.current = function(position) { 10192 if (position === undefined) { 10193 return this._current; 10194 } 10195 10196 if (this.num.oItems === 0) { 10197 return undefined; 10198 } 10199 10200 position = this.normalize(position); 10201 10202 if (this._current === position) { 10203 this.animate(this.coordinates(this._current)); 10204 } else { 10205 var event = this.trigger('change', { property: { name: 'position', value: position } }); 10206 10207 if (event.data !== undefined) { 10208 position = this.normalize(event.data); 10209 } 10210 10211 this._current = position; 10212 10213 this.animate(this.coordinates(this._current)); 10214 10215 this.updateActiveItems();
10216 10217 this.trigger('changed', { property: { name: 'position', value: this._current } }); 10218 } 10219 10220 return this._current; 10221 }; 10222 10223 /** 10224 * Resets the absolute position of the current item. 10225 * @public 10226 * @param {Number} position - The absolute position of the new item. 10227 */ 10228 Owl.prototype.reset = function(position) { 10229 this.suppress([ 'change', 'changed' ]); 10230 this.speed(0); 10231 this.current(position); 10232 this.release([ 'change', 'changed' ]); 10233 }; 10234 10235 /** 10236 * Normalizes an absolute position for an item. 10237 * @public 10238 * @param {Number} position - The absolute position to normalize. 10239 * @param {Boolean} [relative=false] - Whether to return a relative position or not. 10240 * @return {Number} - The normalized position. 10241 */ 10242 Owl.prototype.normalize = function(position, relative) { 10243 if (position === undefined || !this.dom.$items) { 10244 return undefined; 10245 } 10246 10247 if (this.settings.loop) { 10248 var n = this.dom.$items.length; 10249 position = ((position % n) + n) % n; 10250 } else { 10251 position = Math.max(this.minimum(), Math.min(this.maximum(), position)); 10252 } 10253 10254 return relative ? this.dom.$items.eq(position).data('owl-item').index : position; 10255 }; 10256 10257 /** 10258 * Gets the absolute maximum position for an item. 10259 * @public 10260 * @returns {Number} 10261 */ 10262 Owl.prototype.maximum = function() { 10263 var maximum, width, 10264 settings = this.settings; 10265 10266 if (!settings.loop && settings.center) { 10267 maximum = this.num.oItems - 1; 10268 } else if (!settings.loop && !settings.center) { 10269 maximum = this.num.oItems - settings.items; 10270 } else if (settings.loop || settings.center) { 10271 maximum = this.num.oItems + settings.items; 10272 } else if (settings.autoWidth || settings.merge) { 10273 revert = settings.rtl ? 1 : -1; 10274 width = this.dom.$stage.width() - this.$el.width(); 10275 $.each(this.coordinates(), function(index, coordinate) { 10276 if (coordinate * revert >= width) { 10277 return false; 10278 } 10279 maximum = index + 1; 10280 }); 10281 } else { 10282 throw 'Can not detect maximum absolute position.' 10283 } 10284 10285 return maximum; 10286 }; 10287 10288 /** 10289 * Gets the absolute minimum position for an item. 10290 * @public 10291 * @returns {Number} 10292 */ 10293 Owl.prototype.minimum = function() { 10294 return this.dom.$oItems.eq(0).data('owl-item').indexAbs; 10295 }; 10296 10297 /** 10298 * Sets the current animation speed. 10299 * @public 10300 * @param {Number} [speed] - The animation speed in millisecondsor nothing to leave it unchanged. 10301 * @returns {Number} - The current animation speed in milliseconds. 10302 */ 10303 Owl.prototype.speed = function(speed) { 10304 if (speed !== undefined) { 10305 this._speed = speed; 10306 } 10307 10308 return this._speed; 10309 }; 10310 10311 /** 10312 * Gets the coordinate for an item. 10313 * @public 10314 * @param {Number} [position] - The absolute position of the item. 10315 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 10316 */ 10317 Owl.prototype.coordinates = function(position) { 10318 return position !== undefined ? this._coordinates[position] : this._coordinates; 10319 }; 10320 10321 /** 10322 * Calculates the speed for a translation. 10323 * @protected 10324 * @param {Number} from - The absolute position of the start item. 10325 * @param {Number} to - The absolute position of the target item. 10326 * @param {Number} [factor=undefined] - The time factor in milliseconds. 10327 * @returns {Number} - The time in milliseconds for the translation. 10328 */ 10329 Owl.prototype.duration = function(from, to, factor) { 10330 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 10331 }; 10332 10333 /** 10334 * Slides to the specified item. 10335 * @public 10336 * @param {Number} position - The position of the item. 10337 * @param {Number} [speed] - The time in milliseconds for the transition. 10338 */ 10339 Owl.prototype.to = function(position, speed) { 10340 if (this.settings.loop) { 10341 var distance = position - this.normalize(this.current(), true), 10342 revert = this.current(), 10343 before = this.current(), 10344 after = this.current() + distance, 10345 direction = before - after < 0 ? true : false; 10346 10347 if (after < this.settings.items && direction === false) { 10348 revert = this.num.items - (this.settings.items - before) - this.settings.items; 10349 this.reset(revert); 10350 } else if (after >= this.num.items - this.settings.items && direction === true) { 10351 revert = before - this.num.oItems; 10352 this.reset(revert); 10353 } 10354 window.clearTimeout(this.e._goToLoop); 10355 this.e._goToLoop = window.setTimeout($.proxy(function() { 10356 this.speed(this.duration(this.current(), revert + distance, speed)); 10357 this.current(revert + distance); 10358 }, this), 30); 10359 } else { 10360 this.speed(this.duration(this.current(), position, speed)); 10361 this.current(position); 10362 } 10363 }; 10364 10365 /** 10366 * Slides to the next item. 10367 * @public 10368 * @param {Number}
10368 [speed] - The time in milliseconds for the transition. 10369 */ 10370 Owl.prototype.next = function(speed) { 10371 speed = speed || false; 10372 this.to(this.normalize(this.current(), true) + 1, speed); 10373 }; 10374 10375 /** 10376 * Slides to the previous item. 10377 * @public 10378 * @param {Number} [speed] - The time in milliseconds for the transition. 10379 */ 10380 Owl.prototype.prev = function(speed) { 10381 speed = speed || false; 10382 this.to(this.normalize(this.current(), true) - 1, speed); 10383 }; 10384 10385 /** 10386 * Handles the end of an animation. 10387 * @protected 10388 * @param {Event} event - The event arguments. 10389 */ 10390 Owl.prototype.transitionEnd = function(event) { 10391 10392 // if css2 animation then event object is undefined 10393 if (event !== undefined) { 10394 event.stopPropagation(); 10395 10396 // Catch only owl-stage transitionEnd event 10397 var eventTarget = event.target || event.srcElement || event.originalTarget; 10398 if (eventTarget !== this.dom.stage) { 10399 return false; 10400 } 10401 } 10402 10403 this.state.inMotion = false; 10404 this.trigger('translated'); 10405 }; 10406 10407 /** 10408 * Checks if element width has changed 10409 * @protected 10410 * @returns {Booelan} 10411 */ 10412 Owl.prototype.isElWidthChanged = function() { 10413 var newElWidth = this.dom.$el.width() - this.settings.stagePadding, // to 10414 // check 10415 prevElWidth = this.width.el + this.settings.margin; 10416 return newElWidth !== prevElWidth; 10417 }; 10418 10419 /** 10420 * Gets viewport width. 10421 * @protected 10422 * @return {Number} - The width in pixel. 10423 */ 10424 Owl.prototype.viewport = function() { 10425 var width; 10426 if (this.options.responsiveBaseElement !== window) { 10427 width = $(this.options.responsiveBaseElement).width(); 10428 } else if (window.innerWidth) { 10429 width = window.innerWidth; 10430 } else if (document.documentElement && document.documentElement.clientWidth) { 10431 width = document.documentElement.clientWidth; 10432 } else { 10433 throw 'Can not detect viewport width.'; 10434 } 10435 return width; 10436 }; 10437 10438 /** 10439 * Replaces the current content. 10440 * @public 10441 * @param {HTMLElement|jQuery|String} content - The new content. 10442 */ 10443 Owl.prototype.insertContent = function(content) { 10444 this.dom.$stage.empty(); 10445 this.fetchContent(content); 10446 this.refresh(); 10447 }; 10448 10449 /** 10450 * Adds an item. 10451 * @public 10452 * @param {HTMLElement|jQuery|String} content - The item content to add. 10453 * @param {Number} [position=0] - The position at which to insert the item. 10454 */ 10455 Owl.prototype.addItem = function(content, position) { 10456 var $item = this.createItemContainer(); 10457 10458 position = position || 0; 10459 // wrap content 10460 this.initializeItemContainer($item, content); 10461 // if carousel is empty then append item 10462 if (this.dom.$oItems.length === 0) { 10463 this.dom.$stage.append($item); 10464 } else { 10465 // append item 10466 if (pos !== -1) { 10467 this.dom.$oItems.eq(position).before($item); 10468 } else { 10469 this.dom.$oItems.eq(position).after($item); 10470 } 10471 } 10472 // update and calculate carousel 10473 this.refresh(); 10474 }; 10475 10476 /** 10477 * Removes an item. 10478 * @public 10479 * @param {Number} pos - The position of the item. 10480 */ 10481 Owl.prototype.removeItem = function(pos) { 10482 this.dom.$oItems.eq(pos).remove(); 10483 this.refresh(); 10484 }; 10485 10486 /** 10487 * Adds triggerable events. 10488 * @protected 10489 */ 10490 Owl.prototype.addTriggerableEvents = function() { 10491 var handler = $.proxy(function(callback, event) { 10492 return $.proxy(function(e) { 10493 if (e.relatedTarget !== this) { 10494 this.suppress([ event ]); 10495 callback.apply(this, [].slice.call(arguments, 1)); 10496 this.release([ event ]); 10497 } 10498 }, this); 10499 }, this); 10500 10501 $.each({ 10502 'next': this.next, 10503 'prev': this.prev, 10504 'to': this.to, 10505 'destroy': this.destroy, 10506 'refresh': this.refresh, 10507 'replace': this.insertContent, 10508 'add': this.addItem, 10509 'remove': this.removeItem 10510 }, $.proxy(function(event, callback) { 10511 this.dom.$el.on(event + '.owl.carousel', handler(callback, event + '.owl.carousel')); 10512 }, this)); 10513 10514 }; 10515 10516 /** 10517 * Watches the visibility of the carousel element. 10518 * @protected 10519 */ 10520 Owl.prototype.watchVisibility = function() { 10521 10522 // test on zepto 10523 if (!isElVisible(this.dom.el)) { 10524 this.dom.$el.addClass('owl-hidden'); 10525 window.clearInterval(this.e._checkVisibile); 10526 this.e._checkVisibile = window.setInterval($.proxy(checkVisible, this), 500); 10527 } 10528 10529 function isElVisible(el) { 10530 return el.offsetWidth > 0 && el.offsetHeight > 0; 10531 } 10532 10533 function checkVisible() { 10534 if (isElVisible(this.dom.el)) { 10535 this.dom.$el.removeClass('owl-hidden'); 10536 this.refresh();
10537 window.clearInterval(this.e._checkVisibile); 10538 } 10539 } 10540 }; 10541 10542 /** 10543 * Preloads images with auto width. 10544 * @protected 10545 * @todo Still to test 10546 */ 10547 Owl.prototype.preloadAutoWidthImages = function(imgs) { 10548 var loaded, that, $el, img; 10549 10550 loaded = 0; 10551 that = this; 10552 imgs.each(function(i, el) { 10553 $el = $(el); 10554 img = new Image(); 10555 10556 img.onload = function() { 10557 loaded++; 10558 $el.attr('src', img.src); 10559 $el.css('opacity', 1); 10560 if (loaded >= imgs.length) { 10561 that.state.imagesLoaded = true; 10562 that.init(); 10563 } 10564 }; 10565 10566 img.src = $el.attr('src') || $el.attr('data-src') || $el.attr('data-src-retina'); 10567 }); 10568 }; 10569 10570 /** 10571 * Destroys the carousel. 10572 * @public 10573 */ 10574 Owl.prototype.destroy = function() { 10575 10576 if (this.dom.$el.hasClass(this.settings.themeClass)) { 10577 this.dom.$el.removeClass(this.settings.themeClass); 10578 } 10579 10580 if (this.settings.responsive !== false) { 10581 this.off(window, 'resize', this.e._resizer); 10582 } 10583 10584 if (this.transitionEndVendor) { 10585 this.off(this.dom.stage, this.transitionEndVendor, this.e._transitionEnd); 10586 } 10587 10588 for ( var i in this.plugins) { 10589 this.plugins[i].destroy(); 10590 } 10591 10592 if (this.settings.mouseDrag || this.settings.touchDrag) { 10593 this.off(this.dom.stage, this.dragType[0], this.e._onDragStart); 10594 if (this.settings.mouseDrag) { 10595 this.off(document, this.dragType[3], this.e._onDragStart); 10596 } 10597 if (this.settings.mouseDrag) { 10598 this.dom.$stage.off('dragstart', function() { 10599 return false; 10600 }); 10601 this.dom.stage.onselectstart = function() { 10602 }; 10603 } 10604 } 10605 10606 // Remove event handlers in the ".owl.carousel" namespace 10607 this.dom.$el.off('.owl'); 10608 10609 if (this.dom.$cItems !== null) { 10610 this.dom.$cItems.remove(); 10611 } 10612 this.e = null; 10613 this.dom.$el.data('owlCarousel', null); 10614 delete this.dom.el.owlCarousel; 10615 10616 this.dom.$stage.unwrap(); 10617 this.dom.$items.unwrap(); 10618 this.dom.$items.contents().unwrap(); 10619 this.dom = null; 10620 }; 10621 10622 /** 10623 * Operators to calculate right-to-left and left-to-right. 10624 * @protected 10625 * @param {Number} [a] - The left side operand. 10626 * @param {String} [o] - The operator. 10627 * @param {Number} [b] - The right side operand. 10628 */ 10629 Owl.prototype.op = function(a, o, b) { 10630 var rtl = this.settings.rtl; 10631 switch (o) { 10632 case '<': 10633 return rtl ? a > b : a < b; 10634 case '>': 10635 return rtl ? a < b : a > b; 10636 case '>=': 10637 return rtl ? a <= b : a >= b; 10638 case '<=': 10639 return rtl ? a >= b : a <= b; 10640 default: 10641 break; 10642 } 10643 }; 10644 10645 /** 10646 * Attaches to an internal event. 10647 * @protected 10648 * @param {HTMLElement} element - The event source. 10649 * @param {String} event - The event name. 10650 * @param {Function} listener - The event handler to attach. 10651 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 10652 */ 10653 Owl.prototype.on = function(element, event, listener, capture) { 10654 if (element.addEventListener) { 10655 element.addEventListener(event, listener, capture); 10656 } else if (element.attachEvent) { 10657 element.attachEvent('on' + event, listener); 10658 } 10659 }; 10660 10661 /** 10662 * Detaches from an internal event. 10663 * @protected 10664 * @param {HTMLElement} element - The event source. 10665 * @param {String} event - The event name. 10666 * @param {Function} listener - The attached event handler to detach. 10667 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 10668 */ 10669 Owl.prototype.off = function(element, event, listener, capture) { 10670 if (element.removeEventListener) { 10671 element.removeEventListener(event, listener, capture); 10672 } else if (element.detachEvent) { 10673 element.detachEvent('on' + event, listener); 10674 } 10675 }; 10676 10677 /** 10678 * Triggers an public event. 10679 * @protected 10680 * @param {String} name - The event name. 10681 * @param {*} [data=null] - The event data. 10682 * @param {String} [namespace=.owl.carousel] - The event namespace. 10683 * @returns {Event} - The event arguments. 10684 */ 10685 Owl.prototype.trigger = function(name, data, namespace) { 10686 var status = { 10687 item: { count: this.num.oItems, index: this.current() } 10688 }, handler = $.camelCase( 10689 $.grep([ 'on', name, namespace ], function(v) { return v }) 10690 .join('-').toLowerCase() 10691 ), event = $.Event( 10692 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 10693 $.extend({ relatedTarget: this }, status, data) 10694 ); 10695 10696 if (!this._supress[event.type]) { 10697 $.each(this.plugins, function(name, plugin) { 10698 if (plugin.onTrigger) { 10699 plugin.onTrigger(event); 10700 } 10701 }); 10702 10703 this.dom.$el.trigger(event); 10704 10705 if (typeof this.settings[handler] === 'function') { 10706 this.settings[handler].apply(this, event); 10707 } 10708 } 10709 10710 return event; 10711 }; 10712 10713 /** 10714 * Suppresses events. 10715 * @protected 10716 * @param {Array.<String>} events - The events to suppress. 10717 */ 10718 Owl.prototype.suppress = function(events) { 10719 $.each(events, $.proxy(function(index, event) { 10720 this._supress[event] = true; 10721 }, this)); 10722 } 10723 10724 /** 10725 * Releases suppressed events. 10726 * @protected 10727 * @param {Array.<String>} events - The events to release. 10728 */ 10729 Owl.prototype.release = function(events) { 10730 $.each(events, $.proxy(function(index, event) { 10731 delete this._supress[event]; 10732 }, this)); 10733 } 10734 10735 /** 10736 * Checks the availability of some browser features. 10737 * @protected 10738 */ 10739 Owl.prototype.browserSupport = function() { 10740 this.support3d = isPerspective(); 10741 10742 if (this.support3d) { 10743 this.transformVendor = isTransform(); 10744 10745 // take transitionend event name by detecting transition 10746 var endVendors = [ 'transitionend', 'webkitTransitionEnd', 'transitionend', 'oTransitionEnd' ]; 10747 this.transitionEndVendor = endVendors[isTransition()]; 10748 10749 // take vendor name from transform name 10750 this.vendorName = this.transformVendor.replace(/Transform/i, ''); 10751 this.vendorName = this.vendorName !== '' ? '-' + this.vendorName.toLowerCase() + '-' : ''; 10752 } 10753 10754 this.state.orientation = window.orientation; 10755 }; 10756 10757 /** 10758 * Checks for CSS support. 10759 * @private 10760 * @param {Array} array - The CSS properties to check for. 10761 * @returns {Array} - Contains the supported CSS property name and its index or `false`. 10762 */ 10763 function isStyleSupported(array) { 10764 var p, s, fake = document.createElement('div'), list = array; 10765 for (p in list) { 10766 s = list[p]; 10767 if (typeof fake.style[s] !== 'undefined') { 10768 fake = null; 10769 return [ s, p ]; 10770 } 10771 } 10772 return [ false ]; 10773 } 10774 10775 /** 10776 * Checks for CSS transition support. 10777 * @private 10778 * @todo Realy bad design 10779 * @returns {Number} 10780 */ 10781 function isTransition() { 10782 return isStyleSupported([ 'transition', 'WebkitTransition', 'MozTransition', 'OTransition' ])[1]; 10783 } 10784 10785 /** 10786 * Checks for CSS transform support. 10787 * @private 10788 * @returns {String} The supported property name or false. 10789 */ 10790 function isTransform() { 10791 return isStyleSupported([ 'transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ])[0]; 10792 } 10793 10794 /** 10795 * Checks for CSS perspective support. 10796 * @private 10797 * @returns {String} The supported property name or false. 10798 */ 10799 function isPerspective() { 10800 return isStyleSupported([ 'perspective', 'webkitPerspective', 'MozPerspective', 'OPerspective', 'MsPerspective' ])[0]; 10801 } 10802 10803 /** 10804 * Checks wether touch is supported or not. 10805 * @private 10806 * @returns {Boolean} 10807 */ 10808 function isTouchSupport() { 10809 return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints); 10810 } 10811 10812 /** 10813 * Checks wether touch is supported or not for IE. 10814 * @private 10815 * @returns {Boolean} 10816 */ 10817 function isTouchSupportIE() { 10818 return window.navigator.msPointerEnabled; 10819 } 10820 10821 /** 10822 * The jQuery Plugin for the Owl Carousel 10823 * @public 10824 */ 10825 $.fn.owlCarousel = function(options) { 10826 return this.each(function() { 10827 if (!$(this).data('owlCarousel')) { 10828 $(this).data('owlCarousel', new Owl(this, options)); 10829 } 10830 }); 10831 }; 10832 10833 /** 10834 * The constructor for the jQuery Plugin 10835 * @public 10836 */ 10837 $.fn.owlCarousel.Constructor = Owl; 10838 10839})(window.Zepto || window.jQuery, window, document); 10840 10841/** 10842 * LazyLoad Plugin 10843 * @version 2.0.0 10844 * @author Bartosz Wojciechowski 10845 * @license The MIT License (MIT) 10846 */ 10847;(function($, window, document, undefined) { 10848 10849 /** 10850 * Creates the lazy load plugin. 10851 * @class The Lazy Load Plugin 10852 * @param {Owl} scope - The Owl Carousel 10853 */ 10854 LazyLoad = function(scope) { 10855 this.owl = scope; 10856 this.owl.options = $.extend({}, LazyLoad.Defaults, this.owl.options); 10857 10858 this.handlers = { 10859 'changed.owl.carousel': $.proxy(function(e) { 10860 if (e.property.name == 'items' && e.property.value && !e.property.value.is(':empty')) { 10861 this.check(); 10862 } 10863 }, this) 10864 }; 10865 10866 this.owl.dom.$el.on(this.handlers); 10867 }; 10868 10869 /** 10870 * Default options. 10871 * @public 10872 */ 10873 LazyLoad.Defaults = { 10874 lazyLoad: false 10875 }; 10876 10877 /** 10878 * Checks all items and if necessary, calls `preload`. 10879 * @protected 10880 */
10881 LazyLoad.prototype.check = function() { 10882 var attr = window.devicePixelRatio > 1 ? 'data-src-retina' : 'data-src', 10883 src, img, i, $item; 10884 10885 for (i = 0; i < this.owl.num.items; i++) { 10886 $item = this.owl.dom.$items.eq(i); 10887 10888 if ($item.data('owl-item').current === true && $item.data('owl-item').loaded === false) { 10889 img = $item.find('.owl-lazy'); 10890 src = img.attr(attr); 10891 src = src || img.attr('data-src'); 10892 if (src) { 10893 img.css('opacity', '0'); 10894 this.preload(img, $item); 10895 } 10896 } 10897 } 10898 }; 10899 10900 /** 10901 * Preloads the images of an item. 10902 * @protected 10903 * @param {jQuery} images - The images to load. 10904 * @param {jQuery} $item - The item for which the images are loaded. 10905 */ 10906 LazyLoad.prototype.preload = function(images, $item) { 10907 var $el, img, srcType; 10908 10909 images.each($.proxy(function(i, el) { 10910 10911 this.owl.trigger('load', null, 'lazy'); 10912 10913 $el = $(el); 10914 img = new Image(); 10915 srcType = window.devicePixelRatio > 1 ? $el.attr('data-src-retina') : $el.attr('data-src'); 10916 srcType = srcType || $el.attr('data-src'); 10917 10918 img.onload = $.proxy(function() { 10919 $item.data('owl-item').loaded = true; 10920 if ($el.is('img')) { 10921 $el.attr('src', img.src); 10922 } else { 10923 $el.css('background-image', 'url(' + img.src + ')'); 10924 } 10925 10926 $el.css('opacity', 1); 10927 this.owl.trigger('loaded', null, 'lazy'); 10928 }, this); 10929 img.src = srcType; 10930 }, this)); 10931 }; 10932 10933 /** 10934 * Destroys the plugin. 10935 * @public 10936 */ 10937 LazyLoad.prototype.destroy = function() { 10938 var handler, property; 10939 10940 for (handler in this.handlers) { 10941 this.owl.dom.$el.off(handler, this.handlers[handler]); 10942 } 10943 for (property in Object.getOwnPropertyNames(this)) { 10944 typeof this[property] != 'function' && (this[property] = null); 10945 } 10946 }; 10947 10948 $.fn.owlCarousel.Constructor.Plugins.lazyLoad = LazyLoad; 10949 10950})(window.Zepto || window.jQuery, window, document); 10951 10952/** 10953 * AutoHeight Plugin 10954 * @version 2.0.0 10955 * @author Bartosz Wojciechowski 10956 * @license The MIT License (MIT) 10957 */ 10958;(function($, window, document, undefined) { 10959 10960 /** 10961 * Creates the auto height plugin. 10962 * @class The Auto Height Plugin 10963 * @param {Owl} scope - The Owl Carousel 10964 */ 10965 AutoHeight = function(scope) { 10966 this.owl = scope; 10967 this.owl.options = $.extend({}, AutoHeight.Defaults, this.owl.options); 10968 10969 this.handlers = { 10970 'changed.owl.carousel': $.proxy(function(e) { 10971 if (e.property.name == 'position' && this.owl.settings.autoHeight){ 10972 this.setHeight(); 10973 } 10974 }, this) 10975 }; 10976 10977 this.owl.dom.$el.on(this.handlers); 10978 }; 10979 10980 /** 10981 * Default options. 10982 * @public 10983 */ 10984 AutoHeight.Defaults = { 10985 autoHeight: false, 10986 autoHeightClass: 'owl-height' 10987 }; 10988 10989 /** 10990 * 10991 * @param {Boolean} callback - Whether 10992 * @returns {Boolean} 10993 */ 10994 AutoHeight.prototype.setHeight = function() { 10995 var loaded = this.owl.dom.$items.eq(this.owl.current()), 10996 stage = this.owl.dom.$oStage, 10997 iterations = 0, 10998 isLoaded; 10999 11000 if (!this.owl.dom.$oStage.hasClass(this.owl.settings.autoHeightClass)) { 11001 this.owl.dom.$oStage.addClass(this.owl.settings.autoHeightClass); 11002 } 11003 11004 isLoaded = window.setInterval(function() { 11005 iterations += 1; 11006 if (loaded.data('owl-item').loaded) { 11007 stage.height(loaded.height() + 'px'); 11008 clearInterval(isLoaded); 11009 } else if (iterations === 500) { 11010 clearInterval(isLoaded); 11011 } 11012 }, 100); 11013 11014 }; 11015 11016 AutoHeight.prototype.destroy = function() { 11017 var handler, property; 11018 11019 for (handler in this.handlers) { 11020 this.owl.dom.$el.off(handler, this.handlers[handler]); 11021 } 11022 for (property in Object.getOwnPropertyNames(this)) { 11023 typeof this[property] != 'function' && (this[property] = null); 11024 } 11025 }; 11026 11027 $.fn.owlCarousel.Constructor.Plugins.autoHeight = AutoHeight; 11028 11029})(window.Zepto || window.jQuery, window, document); 11030 11031/** 11032 * Video Plugin 11033 * @version 2.0.0 11034 * @author Bartosz Wojciechowski 11035 * @license The MIT License (MIT) 11036 */ 11037;(function($, window, document, undefined) { 11038 11039 /** 11040 * Creates the video plugin. 11041 * @class The Video Plugin 11042 * @param {Owl} scope - The Owl Carousel 11043 */ 11044 Video = function(scope) { 11045 this.owl = scope; 11046 this.owl.options = $.extend({}, Video.Defaults, this.owl.options); 11047 11048 this.handlers = { 11049 'resize.owl.carousel': $.proxy(function(e) { 11050 if (this.owl.settings.video && !this.isInFullScreen()) { 11051 e.preventDefault(); 11052 } 11053 }, this), 11054 'refresh.owl.carousel changed.owl.carousel': $.proxy(function(e) { 11055 if (this.owl.state.videoPlay) { 11056 this.stopVideo(); 11057 } 11058 }, this), 11059 'refresh.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 11060 if (!this.owl.settings.video) { 11061 return false; 11062 } 11063 this.refreshing = e.type == 'refresh'; 11064 }, this), 11065 'changed.owl.carousel': $.proxy(function(e) { 11066 if (this.refreshing && e.property.name == 'items' && e.property.value && !e.property.value.is(':empty')) { 11067 this.checkVideoLinks(); 11068 } 11069 }, this) 11070 }; 11071 11072 this.owl.dom.$el.on(this.handlers); 11073 11074 this.owl.dom.$el.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 11075 this.playVideo(e); 11076 }, this)); 11077 }; 11078 11079 /** 11080 * Default options. 11081 * @public 11082 */ 11083 Video.Defaults = { 11084 video: false, 11085 videoHeight: false, 11086 videoWidth: false 11087 }; 11088 11089 /** 11090 * Checks if for any videos links exists. 11091 * @protected 11092 */ 11093 Video.prototype.checkVideoLinks = function() { 11094 var videoEl, item, i; 11095 11096 for (i = 0; i < this.owl.num.items; i++) { 11097 11098 item = this.owl.dom.$items.eq(i); 11099 if (item.data('owl-item').hasVideo) { 11100 continue; 11101 } 11102 11103 videoEl = item.find('.owl-video'); 11104 if (videoEl.length) { 11105 this.owl.state.hasVideos = true; 11106 this.owl.dom.$items.eq(i).data('owl-item').hasVideo = true; 11107 videoEl.css('display', 'none'); 11108 this.getVideoInfo(videoEl, item); 11109 } 11110 } 11111 }; 11112 11113 /** 11114 * Gets the video ID and the type (YouTube/Vimeo only). 11115 * @protected 11116 * @param {jQuery} videoEl - The element containing the video data. 11117 * @param {jQuery} item - The item containing the video. 11118 */ 11119 Video.prototype.getVideoInfo = function(videoEl, item) { 11120 11121 var info, type, id, dimensions, 11122 vimeoId = videoEl.data('vimeo-id'), 11123 youTubeId = videoEl.data('youtube-id'), 11124 width = videoEl.data('width') || this.owl.settings.videoWidth, 11125 height = videoEl.data('height') || this.owl.settings.videoHeight, 11126 url = videoEl.attr('href'); 11127 11128 if (vimeoId) { 11129 type = 'vimeo'; 11130 id = vimeoId; 11131 } else if (youTubeId) { 11132 type = 'youtube'; 11133 id = youTubeId; 11134 } else if (url) { 11135 id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/); 11136 11137 if (id[3].indexOf('youtu') > -1) { 11138 type = 'youtube'; 11139 } else if (id[3].indexOf('vimeo') > -1) { 11140 type = 'vimeo'; 11141 } 11142 id = id[6]; 11143 } else { 11144 throw new Error('Missing video link.'); 11145 } 11146 11147 item.data('owl-item').videoType = type; 11148 item.data('owl-item').videoId = id; 11149 item.data('owl-item').videoWidth = width; 11150 item.data('owl-item').videoHeight = height; 11151 11152 info = { 11153 type: type, 11154 id: id 11155 }; 11156 11157 // Check dimensions 11158 dimensions = width && height ? 'style="width:' + width + 'px;height:' + height + 'px;"' : ''; 11159 11160 // wrap video content into owl-video-wrapper div 11161 videoEl.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 11162 11163 this.createVideoTn(videoEl, info); 11164 }; 11165 11166 /** 11167 * Creates video thumbnail. 11168 * @protected 11169 * @param {jQuery} videoEl - The element containing the video data. 11170 * @param {Object} info - The video info object. 11171 * @see `getVideoInfo` 11172 */ 11173 Video.prototype.createVideoTn = function(videoEl, info) { 11174 11175 var tnLink, icon, path, 11176 customTn = videoEl.find('img'), 11177 srcType = 'src', 11178 lazyClass = '', 11179 that = this.owl; 11180 11181 if (this.owl.settings.lazyLoad) { 11182 srcType = 'data-src'; 11183 lazyClass = 'owl-lazy'; 11184 } 11185 11186 // Custom thumbnail 11187 11188 if (customTn.length) { 11189 addThumbnail(customTn.attr(srcType)); 11190 customTn.remove(); 11191 return false; 11192 } 11193 11194 function addThumbnail(tnPath) { 11195 icon = '<div class="owl-video-play-icon"></div>'; 11196 11197 if (that.settings.lazyLoad) { 11198 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + tnPath + '"></div>'; 11199 } else { 11200 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + tnPath + ')"></div>'; 11201 } 11202 videoEl.after(tnLink); 11203 videoEl.after(icon); 11204 } 11205 11206 if (info.type === 'youtube') { 11207 path = "http://img.youtube.com/vi/" + info.id + "/hqdefault.jpg"; 11208 addThumbnail(path); 11209 } else if (info.type === 'vimeo') { 11210 $.ajax({
11211 type: 'GET', 11212 url: 'http://vimeo.com/api/v2/video/' + info.id + '.json', 11213 jsonp: 'callback', 11214 dataType: 'jsonp', 11215 success: function(data) { 11216 path = data[0].thumbnail_large; 11217 addThumbnail(path); 11218 if (that.settings.loop) { 11219 that.updateActiveItems(); 11220 } 11221 } 11222 }); 11223 } 11224 }; 11225 11226 /** 11227 * Stops the current video. 11228 * @public 11229 */ 11230 Video.prototype.stopVideo = function() { 11231 this.owl.trigger('stop', null, 'video'); 11232 var item = this.owl.dom.$items.eq(this.owl.state.videoPlayIndex); 11233 item.find('.owl-video-frame').remove(); 11234 item.removeClass('owl-video-playing'); 11235 this.owl.state.videoPlay = false; 11236 }; 11237 11238 /** 11239 * Starts the current video. 11240 * @public 11241 * @param {Event} ev - The event arguments. 11242 */ 11243 Video.prototype.playVideo = function(ev) { 11244 this.owl.trigger('play', null, 'video'); 11245 11246 if (this.owl.state.videoPlay) { 11247 this.stopVideo(); 11248 } 11249 var videoLink, videoWrap, videoType, 11250 target = $(ev.target || ev.srcElement), 11251 item = target.closest('.' + this.owl.settings.itemClass); 11252 11253 videoType = item.data('owl-item').videoType, id = item.data('owl-item').videoId, width = item 11254 .data('owl-item').videoWidth 11255 || Math.floor(item.data('owl-item').width - this.owl.settings.margin), height = item.data('owl-item').videoHeight 11256 || this.owl.dom.$stage.height(); 11257 11258 if (videoType === 'youtube') { 11259 videoLink = "<iframe width=\"" + width + "\" height=\"" + height + "\" src=\"http://www.youtube.com/embed/" 11260 + id + "?autoplay=1&v=" + id + "\" frameborder=\"0\" allowfullscreen></iframe>"; 11261 } else if (videoType === 'vimeo') { 11262 videoLink = '<iframe src="http://player.vimeo.com/video/' + id + '?autoplay=1" width="' + width 11263 + '" height="' + height 11264 + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 11265 } 11266 11267 item.addClass('owl-video-playing'); 11268 this.owl.state.videoPlay = true; 11269 this.owl.state.videoPlayIndex = item.data('owl-item').indexAbs; 11270 11271 videoWrap = $('<div style="height:' + height + 'px; width:' + width + 'px" class="owl-video-frame">' 11272 + videoLink + '</div>'); 11273 target.after(videoWrap); 11274 }; 11275 11276 /** 11277 * Checks whether an video is currently in full screen mode or not. 11278 * @protected 11279 * @returns {Boolean} 11280 */ 11281 Video.prototype.isInFullScreen = function() { 11282 11283 // if Vimeo Fullscreen mode 11284 var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement 11285 || document.webkitFullscreenElement; 11286 if (fullscreenElement) { 11287 if ($(fullscreenElement.parentNode).hasClass('owl-video-frame')) { 11288 this.owl.speed(0); 11289 this.owl.state.isFullScreen = true; 11290 } 11291 } 11292 11293 if (fullscreenElement && this.owl.state.isFullScreen && this.owl.state.videoPlay) { 11294 return false; 11295 } 11296 11297 // Comming back from fullscreen 11298 if (this.owl.state.isFullScreen) { 11299 this.owl.state.isFullScreen = false; 11300 return false; 11301 } 11302 11303 // check full screen mode and window orientation 11304 if (this.owl.state.videoPlay) { 11305 if (this.owl.state.orientation !== window.orientation) { 11306 this.owl.state.orientation = window.orientation; 11307 return false; 11308 } 11309 } 11310 return true; 11311 }; 11312 11313 /** 11314 * Destroys the plugin. 11315 */ 11316 Video.prototype.destroy = function() { 11317 var handler, property; 11318 11319 this.owl.dom.$el.off('click.owl.video'); 11320 11321 for (handler in this.handlers) { 11322 this.owl.dom.$el.off(handler, this.handlers[handler]); 11323 } 11324 for (property in Object.getOwnPropertyNames(this)) { 11325 typeof this[property] != 'function' && (this[property] = null); 11326 } 11327 }; 11328 11329 $.fn.owlCarousel.Constructor.Plugins.video = Video; 11330 11331})(window.Zepto || window.jQuery, window, document); 11332 11333/** 11334 * Animate Plugin 11335 * @version 2.0.0 11336 * @author Bartosz Wojciechowski 11337 * @license The MIT License (MIT) 11338 */ 11339;(function($, window, document, undefined) { 11340 11341 /** 11342 * Creates the animate plugin. 11343 * @class The Navigation Plugin 11344 * @param {Owl} scope - The Owl Carousel 11345 */ 11346 Animate = function(scope) { 11347 this.core = scope; 11348 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 11349 this.swapping = true; 11350 this.previous = undefined; 11351 this.next = undefined; 11352 11353 this.handlers = { 11354 'change.owl.carousel': $.proxy(function(e) { 11355 if (e.property.name == 'position') { 11356 this.previous = this.core.current(); 11357 this.next = e.property.value; 11358 } 11359 }, this), 11360 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 11361 this.swapping = e.type == 'translated'; 11362 }, this), 11363 'translate.owl.carousel': $.proxy(function(e) { 11364 if (this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 11365 this.swap();
11366 } 11367 }, this) 11368 }; 11369 11370 this.core.dom.$el.on(this.handlers); 11371 }; 11372 11373 /** 11374 * Default options. 11375 * @public 11376 */ 11377 Animate.Defaults = { 11378 animateOut: false, 11379 animateIn: false 11380 }; 11381 11382 /** 11383 * Toggles the animation classes whenever an translations starts. 11384 * @protected 11385 * @returns {Boolean|undefined} 11386 */ 11387 Animate.prototype.swap = function() { 11388 11389 if (this.core.settings.items !== 1 || !this.core.support3d) { 11390 return; 11391 } 11392 11393 this.core.speed(0); 11394 11395 var left, 11396 clear = $.proxy(this.clear, this), 11397 previous = this.core.dom.$items.eq(this.previous), 11398 next = this.core.dom.$items.eq(this.next), 11399 incoming = this.core.settings.animateIn, 11400 outgoing = this.core.settings.animateOut; 11401 11402 if (this.core.current() === this.previous) { 11403 return; 11404 } 11405 11406 if (outgoing) { 11407 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 11408 previous.css( { 'left': left + 'px' } ) 11409 .addClass('animated owl-animated-out') 11410 .addClass(outgoing) 11411 .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); 11412 } 11413 11414 if (incoming) { 11415 next.addClass('animated owl-animated-in') 11416 .addClass(incoming) 11417 .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); 11418 } 11419 }; 11420 11421 Animate.prototype.clear = function(e) { 11422 $(e.target).css( { 'left': '' } ) 11423 .removeClass('animated owl-animated-out owl-animated-in') 11424 .removeClass(this.core.settings.animateIn) 11425 .removeClass(this.core.settings.animateOut); 11426 this.core.transitionEnd(); 11427 } 11428 11429 /** 11430 * Destroys the plugin. 11431 * @public 11432 */ 11433 Animate.prototype.destroy = function() { 11434 var handler, property; 11435 11436 for (handler in this.handlers) { 11437 this.core.dom.$el.off(handler, this.handlers[handler]); 11438 } 11439 for (property in Object.getOwnPropertyNames(this)) { 11440 typeof this[property] != 'function' && (this[property] = null); 11441 } 11442 }; 11443 11444 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 11445 11446})(window.Zepto || window.jQuery, window, document); 11447 11448/** 11449 * Autoplay Plugin 11450 * @version 2.0.0 11451 * @author Bartosz Wojciechowski 11452 * @license The MIT License (MIT) 11453 */ 11454;(function($, window, document, undefined) { 11455 11456 /** 11457 * Creates the autoplay plugin. 11458 * @class The Autoplay Plugin 11459 * @param {Owl} scope - The Owl Carousel 11460 */ 11461 Autoplay = function(scope) { 11462 this.core = scope; 11463 this.core.options = $.extend({}, Autoplay.Defaults, this.core.options); 11464 11465 this.handlers = { 11466 'translated.owl.carousel refreshed.owl.carousel': $.proxy(function() { 11467 this.autoplay(); 11468 }, this), 11469 'play.owl.autoplay': $.proxy(function(e, t, s) { 11470 this.play(t, s); 11471 }, this), 11472 'stop.owl.autoplay': $.proxy(function() { 11473 this.stop(); 11474 }, this), 11475 'mouseover.owl.autoplay': $.proxy(function() { 11476 if (this.core.settings.autoplayHoverPause) { 11477 this.pause(); 11478 } 11479 }, this), 11480 'mouseleave.owl.autoplay': $.proxy(function() { 11481 if (this.core.settings.autoplayHoverPause) { 11482 this.autoplay(); 11483 } 11484 }, this) 11485 }; 11486 11487 this.core.dom.$el.on(this.handlers); 11488 }; 11489 11490 /** 11491 * Default options. 11492 * @public 11493 */ 11494 Autoplay.Defaults = { 11495 autoplay: false, 11496 autoplayTimeout: 5000, 11497 autoplayHoverPause: false, 11498 autoplaySpeed: false 11499 }; 11500 11501 /** 11502 * @protected 11503 * @todo Must be documented. 11504 */ 11505 Autoplay.prototype.autoplay = function() { 11506 if (this.core.settings.autoplay && !this.core.state.videoPlay) { 11507 window.clearInterval(this.interval); 11508 11509 this.interval = window.setInterval($.proxy(function() { 11510 this.play(); 11511 }, this), this.core.settings.autoplayTimeout); 11512 } else { 11513 window.clearInterval(this.interval); 11514 } 11515 }; 11516 11517 /** 11518 * Starts the autoplay. 11519 * @public 11520 * @param {Number} [timeout] - ... 11521 * @param {Number} [speed] - ... 11522 * @returns {Boolean|undefined} - ... 11523 * @todo Must be documented. 11524 */ 11525 Autoplay.prototype.play = function(timeout, speed) { 11526 // if tab is inactive - doesnt work in <IE10 11527 if (document.hidden === true) { 11528 return; 11529 } 11530 11531 if (this.core.state.isTouch || this.core.state.isScrolling 11532 || this.core.state.isSwiping || this.core.state.inMotion) { 11533 return; 11534 } 11535 11536 if (this.core.settings.autoplay === false) { 11537 window.clearInterval(this.interval); 11538 return; 11539 } 11540 11541 this.core.next(this.core.settings.autoplaySpeed); 11542 }; 11543 11544 /** 11545 * Stops the autoplay. 11546 * @public 11547 */ 11548 Autoplay.prototype.stop = function() { 11549 window.clearInterval(this.interval); 11550 }; 11551 11552 /** 11553 * Pauses the autoplay. 11554 * @public 11555 */ 11556 Autoplay.prototype.pause = function() { 11557 window.clearInterval(this.interval); 11558 }; 11559 11560 /** 11561 * Destroys the plugin. 11562 */ 11563 Autoplay.prototype.destroy = function() { 11564 var handler, property; 11565 11566 window.clearInterval(this.interval); 11567 11568 for (handler in this.handlers) { 11569 this.core.dom.$el.off(handler, this.handlers[handler]); 11570 } 11571 for (property in Object.getOwnPropertyNames(this)) { 11572 typeof this[property] != 'function' && (this[property] = null); 11573 } 11574 }; 11575 11576 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 11577 11578})(window.Zepto || window.jQuery, window, document); 11579 11580/** 11581 * Navigation Plugin 11582 * @version 2.0.0 11583 * @author Artus Kolanowski 11584 * @license The MIT License (MIT) 11585 */ 11586;(function($, window, document, undefined) { 11587 'use strict'; 11588 11589 /** 11590 * Creates the navigation plugin. 11591 * @class The Navigation Plugin 11592 * @param {Owl} carousel - The Owl Carousel. 11593 */ 11594 var Navigation = function(carousel) { 11595 /** 11596 * Reference to the core. 11597 * @type {Owl} 11598 */ 11599 this.core = carousel; 11600 11601 /** 11602 * Indicates whether the plugin is initialized or not. 11603 * @type {Boolean} 11604 */ 11605 this.initialized = false; 11606 11607 /** 11608 * The current paging indexes. 11609 * @type {Array} 11610 */ 11611 this.pages = []; 11612 11613 /** 11614 * All DOM elements of the user interface. 11615 * @type {Object} 11616 */ 11617 this.controls = {}; 11618 11619 /** 11620 * Markup for an indicator. 11621 * @type {String} 11622 */ 11623 this.template = null; 11624 11625 /** 11626 * The carousel element. 11627 * @type {jQuery} 11628 */ 11629 this.$element = this.core.dom.$el; 11630 11631 /** 11632 * Overridden methods of the carousel. 11633 * @type {Object} 11634 */ 11635 this.overrides = { 11636 next: this.core.next, 11637 prev: this.core.prev, 11638 to: this.core.to 11639 }; 11640 11641 /** 11642 * All event handlers. 11643 * @type {Object} 11644 */ 11645 this.handlers = { 11646 'changed.owl.carousel': $.proxy(function(e) { 11647 if (e.property.name == 'items') { 11648 if (!this.initialized) { 11649 this.initialize(); 11650 this.initialized = true; 11651 } 11652 this.update(); 11653 this.draw(); 11654 } 11655 if (this.filling) { 11656 e.property.value.data('owl-item').dot = $(':first-child', e.property.value) 11657 .find('[data-dot]').andSelf().data('dot'); 11658 } 11659 }, this), 11660 'change.owl.carousel': $.proxy(function(e) { 11661 if (e.property.name == 'position' && !this.core.state.revert 11662 && !this.core.settings.loop && this.core.settings.navRewind) { 11663 var current = this.core.current(), 11664 maximum = this.core.maximum(), 11665 minimum = this.core.minimum(); 11666 e.data = e.property.value > maximum 11667 ? current >= maximum ? minimum : maximum 11668 : e.property.value < minimum ? maximum : e.property.value; 11669 } 11670 this.filling = this.core.settings.dotsData && e.property.name == 'item' 11671 && e.property.value && e.property.value.is(':empty'); 11672 }, this), 11673 'refreshed.owl.carousel': $.proxy(function() { 11674 if (this.initialized) { 11675 this.update(); 11676 this.draw(); 11677 } 11678 }, this) 11679 }; 11680 11681 // set default options 11682 this.core.options = $.extend({}, Navigation.Defaults, this.core.options); 11683 11684 // register event handlers 11685 this.$element.on(this.handlers); 11686 } 11687 11688 /** 11689 * Default options. 11690 * @public 11691 * @todo Rename `slideBy` to `navBy` 11692 */ 11693 Navigation.Defaults = { 11694 nav: false, 11695 navRewind: true, 11696 navText: [ 'prev', 'next' ], 11697 navSpeed: false, 11698 navElement: 'div', 11699 navContainer: false, 11700 navContainerClass: 'owl-nav', 11701 navClass: [ 'owl-prev', 'owl-next' ], 11702 slideBy: 1, 11703 dotClass: 'owl-dot', 11704 dotsClass: 'owl-dots', 11705 dots: true, 11706 dotsEach: false, 11707 dotData: false, 11708 dotsSpeed: false, 11709 dotsContainer: false,
11710 controlsClass: 'owl-controls' 11711 } 11712 11713 /** 11714 * Initializes the layout of the plugin and extends the carousel. 11715 * @protected 11716 */ 11717 Navigation.prototype.initialize = function() { 11718 var $container, override, 11719 options = this.core.settings; 11720 11721 // create the indicator template 11722 if (!options.dotsData) { 11723 this.template = $('<div>') 11724 .addClass(options.dotClass) 11725 .append($('<span>')) 11726 .prop('outerHTML'); 11727 } 11728 11729 // create controls container if needed 11730 if (!options.navContainer || !options.dotsContainer) { 11731 this.controls.$container = $('<div>') 11732 .addClass(options.controlsClass) 11733 .appendTo(this.$element); 11734 } 11735 11736 // create DOM structure for absolute navigation 11737 this.controls.$indicators = options.dotsContainer ? $(options.dotsContainer) 11738 : $('<div>').hide().addClass(options.dotsClass).appendTo(this.controls.$container); 11739 11740 this.controls.$indicators.on(this.core.dragType[2], 'div', $.proxy(function(e) { 11741 var index = $(e.target).parent().is(this.controls.$indicators) 11742 ? $(e.target).index() : $(e.target).parent().index(); 11743 11744 e.preventDefault(); 11745 11746 this.to(index, options.dotsSpeed); 11747 }, this)); 11748 11749 // create DOM structure for relative navigation 11750 $container = options.navContainer ? $(options.navContainer) 11751 : $('<div>').addClass(options.navContainerClass).prependTo(this.controls.$container); 11752 11753 this.controls.$next = $('<' + options.navElement + '>'); 11754 this.controls.$previous = this.controls.$next.clone(); 11755 11756 this.controls.$previous 11757 .addClass(options.navClass[0]) 11758 .html(options.navText[0]) 11759 .hide() 11760 .prependTo($container) 11761 .on(this.core.dragType[2], $.proxy(function(e) { 11762 this.prev(); 11763 }, this)); 11764 this.controls.$next 11765 .addClass(options.navClass[1]) 11766 .html(options.navText[1]) 11767 .hide() 11768 .appendTo($container) 11769 .on(this.core.dragType[2], $.proxy(function(e) { 11770 this.next(); 11771 }, this)); 11772 11773 // override public methods of the carousel 11774 for (override in this.overrides) { 11775 this.core[override] = $.proxy(this[override], this); 11776 } 11777 } 11778 11779 /** 11780 * Destroys the plugin. 11781 * @protected 11782 */ 11783 Navigation.prototype.destroy = function() { 11784 var handler, control, property, override; 11785 11786 for (handler in this.handlers) { 11787 this.$element.off(handler, this.handlers[handler]); 11788 } 11789 for (control in this.controls) { 11790 this.controls[control].remove(); 11791 } 11792 for (override in this.overides) { 11793 this.core[override] = this.overrides[override]; 11794 } 11795 for (property in Object.getOwnPropertyNames(this)) { 11796 typeof this[property] != 'function' && (this[property] = null); 11797 } 11798 } 11799 11800 /** 11801 * Updates the internal state. 11802 * @protected 11803 */ 11804 Navigation.prototype.update = function() { 11805 var i, j, k, 11806 options = this.core.settings, 11807 lower = this.core.num.cItems / 2, 11808 upper = this.core.num.items - lower, 11809 size = options.center || options.autoWidth || options.dotData 11810 ? 1 : options.dotsEach || options.items; 11811 11812 if (options.slideBy !== 'page') { 11813 options.slideBy = Math.min(options.slideBy, options.items); 11814 } 11815 11816 if (options.dots) { 11817 this.pages = []; 11818 11819 for (i = lower, j = 0, k = 0; i < upper; i++) { 11820 if (j >= size || j === 0) { 11821 this.pages.push({ 11822 start: i - lower, 11823 end: i - lower + size - 1 11824 }); 11825 j = 0, ++k; 11826 } 11827 j += this.core.num.merged[i]; 11828 } 11829 } 11830 } 11831 11832 /** 11833 * Draws the user interface. 11834 * @protected 11835 */ 11836 Navigation.prototype.draw = function() { 11837 var difference, i, html = '', 11838 options = this.core.settings, 11839 $items = this.core.dom.$oItems, 11840 index = this.core.normalize(this.core.current(), true); 11841 11842 if (options.nav && !options.loop && !options.navRewind) { 11843 this.controls.$previous.toggleClass('disabled', index <= 0); 11844 this.controls.$next.toggleClass('disabled', index >= this.core.maximum()); 11845 } 11846 11847 this.controls.$previous.toggle(options.nav); 11848 this.controls.$next.toggle(options.nav); 11849 11850 if (options.dots) { 11851 difference = this.pages.length - this.controls.$indicators.children().length; 11852 11853 if (difference > 0) { 11854 for (i = 0; i < Math.abs(difference); i++) { 11855 html += options.dotData ? $items.eq(i).data('owl-item').dot : this.template; 11856 } 11857 this.controls.$indicators.append(html); 11858 } else if (difference < 0) { 11859 this.controls.$indicators.children().slice(difference).remove(); 11860 } 11861 11862 this.controls.$indicators.find('.active').removeClass('active'); 11863 this.controls.$indicators.children().eq($.inArray(this.current(), this.pages)).addClass('active'); 11864 } 11865 11866 this.controls.$indicators.toggle(options.dots); 11867 } 11868 11869 /** 11870 * Extends event data. 11871 * @protected 11872 * @param {Event} event - The event object which gets thrown. 11873 */ 11874 Navigation.prototype.onTrigger = function(event) { 11875 var options = this.core.settings; 11876 11877 event.page = { 11878 index: $.inArray(this.current(), this.pages), 11879 count: this.pages.length, 11880 size: options.center || options.autoWidth || options.dotData 11881 ? 1 : options.dotsEach || options.items 11882 }; 11883 } 11884 11885 /** 11886 * Gets the current page position of the carousel. 11887 * @protected 11888 * @returns {Number} 11889 */ 11890 Navigation.prototype.current = function() { 11891 var index = this.core.normalize(this.core.current(), true); 11892 return $.grep(this.pages, function(o) { 11893 return o.start <= index && o.end >= index; 11894 }).pop(); 11895 } 11896 11897 /** 11898 * Gets the current succesor/predecessor position. 11899 * @protected 11900 * @returns {Number} 11901 */ 11902 Navigation.prototype.getPosition = function(successor) { 11903 var position, length, 11904 options = this.core.settings; 11905 11906 if (options.slideBy == 'page') { 11907 position = $.inArray(this.current(), this.pages); 11908 length = this.pages.length; 11909 successor ? ++position : --position;
11910 position = this.pages[((position % length) + length) % length].start; 11911 } else { 11912 position = this.core.normalize(this.core.current(), true); 11913 length = this.core.num.oItems; 11914 successor ? position += options.slideBy : position -= options.slideBy; 11915 } 11916 return position; 11917 } 11918 11919 /** 11920 * Slides to the next item or page. 11921 * @public 11922 * @param {Number} [speed=false] - The time in milliseconds for the transition. 11923 */ 11924 Navigation.prototype.next = function(speed) { 11925 $.proxy(this.overrides.to, this.core)(this.getPosition(true), speed); 11926 } 11927 11928 /** 11929 * Slides to the previous item or page. 11930 * @public 11931 * @param {Number} [speed=false] - The time in milliseconds for the transition. 11932 */ 11933 Navigation.prototype.prev = function(speed) { 11934 $.proxy(this.overrides.to, this.core)(this.getPosition(false), speed); 11935 } 11936 11937 /** 11938 * Slides to the specified item or page. 11939 * @public 11940 * @param {Number} position - The position of the item or page. 11941 * @param {Number} [speed] - The time in milliseconds for the transition. 11942 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 11943 */ 11944 Navigation.prototype.to = function(position, speed, standard) { 11945 var length; 11946 11947 if (!standard) { 11948 length = this.pages.length; 11949 $.proxy(this.overrides.to, this.core)(this.pages[((position % length) + length) % length].start, speed); 11950 } else { 11951 $.proxy(this.overrides.to, this.core)(position, speed); 11952 } 11953 } 11954 11955 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 11956 11957})(window.Zepto || window.jQuery, window, document); 11958 11959/** 11960 * Hash Plugin 11961 * @version 2.0.0 11962 * @author Artus Kolanowski 11963 * @license The MIT License (MIT) 11964 */ 11965;(function($, window, document, undefined) { 11966 'use strict'; 11967 11968 /** 11969 * Creates the hash plugin. 11970 * @class The Hash Plugin 11971 * @param {Owl} carousel - The Owl Carousel 11972 */ 11973 var Hash = function(carousel) { 11974 /** 11975 * Reference to the core. 11976 * @type {Owl} 11977 */ 11978 this.core = carousel; 11979 11980 /** 11981 * Hash table for the hashes. 11982 * @type {Object} 11983 */ 11984 this.hashes = {}; 11985 11986 /** 11987 * The carousel element. 11988 * @type {jQuery} 11989 */ 11990 this.$element = this.core.dom.$el; 11991 11992 /** 11993 * All event handlers. 11994 * @type {Object} 11995 */ 11996 this.handlers = { 11997 'initialized.owl.carousel': $.proxy(function() { 11998 if (window.location.hash.substring(1)) { 11999 $(window).trigger('hashchange.owl.navigation'); 12000 } 12001 }, this), 12002 'changed.owl.carousel': $.proxy(function(e) { 12003 if (this.filling) { 12004 e.property.value.data('owl-item').hash 12005 = $(':first-child', e.property.value).find('[data-hash]').andSelf().data('hash'); 12006 this.hashes[e.property.value.data('owl-item').hash] = e.property.value; 12007 } 12008 }, this), 12009 'change.owl.carousel': $.proxy(function(e) { 12010 if (e.property.name == 'position' && this.core.current() === undefined 12011 && this.core.settings.startPosition == 'URLHash') { 12012 e.data = this.hashes[window.location.hash.substring(1)]; 12013 } 12014 this.filling = e.property.name == 'item' && e.property.value && e.property.value.is(':empty'); 12015 }, this), 12016 }; 12017 12018 // set default options 12019 this.core.options = $.extend({}, Hash.Defaults, this.core.options); 12020 12021 // register the event handlers 12022 this.$element.on(this.handlers); 12023 12024 // register event listener for hash navigation 12025 $(window).on('hashchange.owl.navigation', $.proxy(function() { 12026 var hash = window.location.hash.substring(1), 12027 items = this.core.dom.$oItems, 12028 position = this.hashes[hash] && items.index(this.hashes[hash]) || 0; 12029 12030 if (!hash) { 12031 return false; 12032 } 12033 12034 this.core.dom.oStage.scrollLeft = 0; 12035 this.core.to(position, false, true); 12036 }, this)); 12037 } 12038 12039 /** 12040 * Default options. 12041 * @public 12042 */ 12043 Hash.Defaults = { 12044 URLhashListener: false 12045 } 12046 12047 /** 12048 * Destroys the plugin. 12049 * @public 12050 */ 12051 Hash.prototype.destroy = function() { 12052 var handler, property; 12053 12054 $(window).off('hashchange.owl.navigation'); 12055 12056 for (handler in this.handlers) { 12057 this.owl.dom.$el.off(handler, this.handlers[handler]); 12058 } 12059 for (property in Object.getOwnPropertyNames(this)) { 12060 typeof this[property] != 'function' && (this[property] = null); 12061 } 12062 } 12063 12064 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 12065 12066})(window.Zepto || window.jQuery, window, document); 12067 12068;/*})'"*/ 12069;/*})'"*/ 12070/* 12071* Copyright (C) 2009 Joel Sutherland 12072* Licenced under the MIT license 12073* http://www.newmediacampaigns.com/page/jquery-flickr-plugin 12074* 12075* Available tags for templates: 12076* title, link, date_taken, description, published, author, author_id, tags, image* 12077*/ 12078(function($) {
12079 $.fn.jflickrfeed = function(settings, callback) { 12080 settings = $.extend(true, { 12081 flickrbase: 'http://api.flickr.com/services/feeds/', 12082 feedapi: 'photos_public.gne', 12083 limit: 20, 12084 qstrings: { 12085 lang: 'en-us', 12086 format: 'json', 12087 jsoncallback: '?' 12088 }, 12089 cleanDescription: true, 12090 useTemplate: true, 12091 itemTemplate: '<li><a href="{{image_b}}" title="{{title}}"><span class="thumbnail"><img src="{{image_s}}" /></span></a></li>', 12092 itemCallback: function(){} 12093 }, settings); 12094 12095 var url = settings.flickrbase + settings.feedapi + '?'; 12096 var first = true; 12097 12098 for(var key in settings.qstrings){ 12099 if(!first) 12100 url += '&'; 12101 url += key + '=' + settings.qstrings[key]; 12102 first = false; 12103 } 12104 12105 return $(this).each(function(){ 12106 var $container = $(this); 12107 var container = this; 12108 12109 $.getJSON(url, function(data){ 12110 12111 $.each(data.items, function(i,item){ 12112 if(i < settings.limit){ 12113 // Clean out the Flickr Description 12114 if(settings.cleanDescription){ 12115 var regex = /<p>(.*?)<\/p>/g; 12116 var input = item.description; 12117 if(regex.test(input)) { 12118 item.description = input.match(regex)[2] 12119 if(item.description!=undefined) 12120 item.description = item.description.replace('<p>','').replace('</p>',''); 12121 } 12122 } 12123 12124 // Add Image Sizes 12125 // http://www.flickr.com/services/api/misc.urls.html 12126 item['image_s'] = item.media.m.replace('_m', '_s'); 12127 item['image_t'] = item.media.m.replace('_m', '_t'); 12128 item['image_m'] = item.media.m.replace('_m', '_m'); 12129 item['image'] = item.media.m.replace('_m', ''); 12130 item['image_b'] = item.media.m.replace('_m', '_b'); 12131 delete item.media; 12132 12133 // Use Template 12134 if(settings.useTemplate){ 12135 var template = settings.itemTemplate; 12136 for(var key in item){ 12137 template = template.replace('{{' + key + '}}', item[key]); 12138 } 12139 12140 $container.append(template) 12141 } 12142 12143 //itemCallback 12144 settings.itemCallback.call(container, item); 12145 } 12146 }); 12147 if($.isFunction(callback)){ 12148 callback.call(container, data); 12149 } 12150 }); 12151 }); 12152 } 12153})(jQuery); 12154;/*})'"*/ 12155;/*})'"*/ 12156/*! Magnific Popup - v1.0.0 - 2014-12-12 12157* http://dimsemenov.com/plugins/magnific-popup/ 12158* Copyright (c) 2014 Dmitry Semenov; */ 12159;(function (factory) { 12160if (typeof define === 'function' && define.amd) { 12161 // AMD. Register as an anonymous module. 12162 define(['jquery'], factory); 12163 } else if (typeof exports === 'object') { 12164 // Node/CommonJS 12165 factory(require('jquery')); 12166 } else { 12167 // Browser globals 12168 factory(window.jQuery || window.Zepto); 12169 } 12170 }(function($) { 12171 12172/*>>core*/ 12173/** 12174 * 12175 * Magnific Popup Core JS file 12176 * 12177 */ 12178 12179 12180/** 12181 * Private static constants 12182 */ 12183var CLOSE_EVENT = 'Close', 12184 BEFORE_CLOSE_EVENT = 'BeforeClose', 12185 AFTER_CLOSE_EVENT = 'AfterClose', 12186 BEFORE_APPEND_EVENT = 'BeforeAppend', 12187 MARKUP_PARSE_EVENT = 'MarkupParse', 12188 OPEN_EVENT = 'Open', 12189 CHANGE_EVENT = 'Change', 12190 NS = 'mfp', 12191 EVENT_NS = '.' + NS, 12192 READY_CLASS = 'mfp-ready', 12193 REMOVING_CLASS = 'mfp-removing', 12194 PREVENT_CLOSE_CLASS = 'mfp-prevent-close'; 12195 12196 12197/** 12198 * Private vars 12199 */ 12200var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this' 12201 MagnificPopup = function(){}, 12202 _isJQ = !!(window.jQuery), 12203 _prevStatus, 12204 _window = $(window), 12205 _body, 12206 _document, 12207 _prevContentType, 12208 _wrapClasses, 12209 _currPopupType; 12210 12211 12212/** 12213 * Private functions 12214 */ 12215var _mfpOn = function(name, f) { 12216 mfp.ev.on(NS + name + EVENT_NS, f); 12217 }, 12218 _getEl = function(className, appendTo, html, raw) { 12219 var el = document.createElement('div'); 12220 el.className = 'mfp-'+className; 12221 if(html) { 12222 el.innerHTML = html; 12223 } 12224 if(!raw) { 12225 el = $(el); 12226 if(appendTo) { 12227 el.appendTo(appendTo); 12228 } 12229 } else if(appendTo) { 12230 appendTo.appendChild(el); 12231 } 12232 return el; 12233 }, 12234 _mfpTrigger = function(e, data) { 12235 mfp.ev.triggerHandler(NS + e, data); 12236 12237 if(mfp.st.callbacks) { 12238 // converts "mfpEventName" to "eventName" callback and triggers it if it's present 12239 e = e.charAt(0).toLowerCase() + e.slice(1); 12240 if(mfp.st.callbacks[e]) { 12241 mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]); 12242 } 12243 } 12244 }, 12245 _getCloseBtn = function(type) { 12246 if(type !== _currPopupType || !mfp.currTemplate.closeBtn) { 12247 mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) ); 12248 _currPopupType = type; 12249 } 12250 return mfp.currTemplate.closeBtn; 12251 }, 12252 // Initialize Magnific Popup only when called at least once 12253 _checkInstance = function() { 12254 if(!$.magnificPopup.instance) { 12255 mfp = new MagnificPopup(); 12256 mfp.init(); 12257 $.magnificPopup.instance = mfp; 12258 } 12259 }, 12260 // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr 12261 supportsTransitions = function() { 12262 var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist 12263 v = ['ms','O','Moz','Webkit']; // 'v' for vendor 12264 12265 if( s['transition'] !== undefined ) { 12266 return true; 12267 } 12268 12269 while( v.length ) { 12270 if( v.pop() + 'Transition' in s ) { 12271 return true; 12272 } 12273 } 12274 12275 return false;
vendor: 35,181 bytes, lines 12276-13888
12276 }; 12277 12278 12279 12280/** 12281 * Public functions 12282 */ 12283MagnificPopup.prototype = { 12284 12285 constructor: MagnificPopup, 12286 12287 /** 12288 * Initializes Magnific Popup plugin. 12289 * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed 12290 */ 12291 init: function() { 12292 var appVersion = navigator.appVersion; 12293 mfp.isIE7 = appVersion.indexOf("MSIE 7.") !== -1; 12294 mfp.isIE8 = appVersion.indexOf("MSIE 8.") !== -1; 12295 mfp.isLowIE = mfp.isIE7 || mfp.isIE8; 12296 mfp.isAndroid = (/android/gi).test(appVersion); 12297 mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion); 12298 mfp.supportsTransition = supportsTransitions(); 12299 12300 // We disable fixed positioned lightbox on devices that don't handle it nicely. 12301 // If you know a better way of detecting this - let me know. 12302 mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) ); 12303 _document = $(document); 12304 12305 mfp.popupsCache = {}; 12306 }, 12307 12308 /** 12309 * Opens popup 12310 * @param data [description] 12311 */ 12312 open: function(data) { 12313 12314 if(!_body) { 12315 _body = $(document.body); 12316 } 12317 12318 var i; 12319 12320 if(data.isObj === false) { 12321 // convert jQuery collection to array to avoid conflicts later 12322 mfp.items = data.items.toArray(); 12323 12324 mfp.index = 0; 12325 var items = data.items, 12326 item; 12327 for(i = 0; i < items.length; i++) { 12328 item = items[i]; 12329 if(item.parsed) { 12330 item = item.el[0]; 12331 } 12332 if(item === data.el[0]) { 12333 mfp.index = i; 12334 break; 12335 } 12336 } 12337 } else { 12338 mfp.items = $.isArray(data.items) ? data.items : [data.items]; 12339 mfp.index = data.index || 0; 12340 } 12341 12342 // if popup is already opened - we just update the content 12343 if(mfp.isOpen) { 12344 mfp.updateItemHTML(); 12345 return; 12346 } 12347 12348 mfp.types = []; 12349 _wrapClasses = ''; 12350 if(data.mainEl && data.mainEl.length) { 12351 mfp.ev = data.mainEl.eq(0); 12352 } else { 12353 mfp.ev = _document; 12354 } 12355 12356 if(data.key) { 12357 if(!mfp.popupsCache[data.key]) { 12358 mfp.popupsCache[data.key] = {}; 12359 } 12360 mfp.currTemplate = mfp.popupsCache[data.key]; 12361 } else { 12362 mfp.currTemplate = {}; 12363 } 12364 12365 12366 12367 mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); 12368 mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos; 12369 12370 if(mfp.st.modal) { 12371 mfp.st.closeOnContentClick = false; 12372 mfp.st.closeOnBgClick = false; 12373 mfp.st.showCloseBtn = false; 12374 mfp.st.enableEscapeKey = false; 12375 } 12376 12377 12378 // Building markup 12379 // main containers are created only once 12380 if(!mfp.bgOverlay) { 12381 12382 // Dark overlay 12383 mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() { 12384 mfp.close(); 12385 }); 12386 12387 mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) { 12388 if(mfp._checkIfClose(e.target)) { 12389 mfp.close(); 12390 } 12391 }); 12392 12393 mfp.container = _getEl('container', mfp.wrap); 12394 } 12395 12396 mfp.contentContainer = _getEl('content'); 12397 if(mfp.st.preloader) { 12398 mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading); 12399 } 12400 12401 12402 // Initializing modules 12403 var modules = $.magnificPopup.modules; 12404 for(i = 0; i < modules.length; i++) { 12405 var n = modules[i]; 12406 n = n.charAt(0).toUpperCase() + n.slice(1); 12407 mfp['init'+n].call(mfp); 12408 } 12409 _mfpTrigger('BeforeOpen'); 12410 12411 12412 if(mfp.st.showCloseBtn) { 12413 // Close button 12414 if(!mfp.st.closeBtnInside) { 12415 mfp.wrap.append( _getCloseBtn() ); 12416 } else { 12417 _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) { 12418 values.close_replaceWith = _getCloseBtn(item.type); 12419 }); 12420 _wrapClasses += ' mfp-close-btn-in'; 12421 } 12422 } 12423 12424 if(mfp.st.alignTop) { 12425 _wrapClasses += ' mfp-align-top'; 12426 } 12427 12428 12429 12430 if(mfp.fixedContentPos) { 12431 mfp.wrap.css({ 12432 overflow: mfp.st.overflowY, 12433 overflowX: 'hidden', 12434 overflowY: mfp.st.overflowY 12435 }); 12436 } else { 12437 mfp.wrap.css({ 12438 top: _window.scrollTop(), 12439 position: 'absolute' 12440 }); 12441 } 12442 if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) { 12443 mfp.bgOverlay.css({ 12444 height: _document.height(), 12445 position: 'absolute' 12446 }); 12447 } 12448 12449 12450 12451 if(mfp.st.enableEscapeKey) { 12452 // Close on ESC key 12453 _document.on('keyup' + EVENT_NS, function(e) { 12454 if(e.keyCode === 27) { 12455 mfp.close(); 12456 } 12457 }); 12458 } 12459 12460 _window.on('resize' + EVENT_NS, function() { 12461 mfp.updateSize(); 12462 }); 12463 12464 12465 if(!mfp.st.closeOnContentClick) { 12466 _wrapClasses += ' mfp-auto-cursor'; 12467 } 12468 12469 if(_wrapClasses) 12470 mfp.wrap.addClass(_wrapClasses); 12471 12472 12473 // this triggers recalculation of layout, so we get it once to not to trigger twice 12474 var windowHeight = mfp.wH = _window.height(); 12475 12476 12477 var windowStyles = {}; 12478 12479 if( mfp.fixedContentPos ) { 12480 if(mfp._hasScrollBar(windowHeight)){ 12481 var s = mfp._getScrollbarSize(); 12482 if(s) { 12483 windowStyles.marginRight = s; 12484 } 12485 } 12486 } 12487 12488 if(mfp.fixedContentPos) { 12489 if(!mfp.isIE7) { 12490 windowStyles.overflow = 'hidden'; 12491 } else { 12492 // ie7 double-scroll bug 12493 $('body, html').css('overflow', 'hidden'); 12494 } 12495 } 12496 12497 12498 12499 var classesToadd = mfp.st.mainClass; 12500 if(mfp.isIE7) { 12501 classesToadd += ' mfp-ie7'; 12502 } 12503 if(classesToadd) { 12504 mfp._addClassToMFP( classesToadd ); 12505 } 12506 12507 // add content 12508 mfp.updateItemHTML(); 12509 12510 _mfpTrigger('BuildControls'); 12511 12512 // remove scrollbar, add margin e.t.c 12513 $('html').css(windowStyles); 12514 12515 // add everything to DOM 12516 mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || _body ); 12517 12518 // Save last focused element 12519 mfp._lastFocusedEl = document.activeElement; 12520 12521 // Wait for next cycle to allow CSS transition 12522 setTimeout(function() { 12523 12524 if(mfp.content) { 12525 mfp._addClassToMFP(READY_CLASS); 12526 mfp._setFocus(); 12527 } else { 12528 // if content is not defined (not loaded e.t.c) we add class only for BG 12529 mfp.bgOverlay.addClass(READY_CLASS); 12530 } 12531 12532 // Trap the focus in popup 12533 _document.on('focusin' + EVENT_NS, mfp._onFocusIn); 12534 12535 }, 16); 12536 12537 mfp.isOpen = true; 12538 mfp.updateSize(windowHeight); 12539 _mfpTrigger(OPEN_EVENT); 12540 12541 return data; 12542 }, 12543 12544 /** 12545 * Closes the popup 12546 */ 12547 close: function() { 12548 if(!mfp.isOpen) return; 12549 _mfpTrigger(BEFORE_CLOSE_EVENT); 12550 12551 mfp.isOpen = false; 12552 // for CSS3 animation 12553 if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) { 12554 mfp._addClassToMFP(REMOVING_CLASS); 12555 setTimeout(function() { 12556 mfp._close(); 12557 }, mfp.st.removalDelay); 12558 } else { 12559 mfp._close(); 12560 } 12561 }, 12562 12563 /** 12564 * Helper for close() function 12565 */ 12566 _close: function() { 12567 _mfpTrigger(CLOSE_EVENT); 12568 12569 var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' '; 12570 12571 mfp.bgOverlay.detach(); 12572 mfp.wrap.detach(); 12573 mfp.container.empty(); 12574 12575 if(mfp.st.mainClass) { 12576 classesToRemove += mfp.st.mainClass + ' '; 12577 } 12578 12579 mfp._removeClassFromMFP(classesToRemove); 12580 12581 if(mfp.fixedContentPos) { 12582 var windowStyles = {marginRight: ''}; 12583 if(mfp.isIE7) { 12584 $('body, html').css('overflow', ''); 12585 } else { 12586 windowStyles.overflow = ''; 12587 } 12588 $('html').css(windowStyles); 12589 } 12590 12591 _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS); 12592 mfp.ev.off(EVENT_NS); 12593 12594 // clean up DOM elements that aren't removed 12595 mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style'); 12596 mfp.bgOverlay.attr('class', 'mfp-bg'); 12597 mfp.container.attr('class', 'mfp-container'); 12598 12599 // remove close button from target element 12600 if(mfp.st.showCloseBtn && 12601 (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) { 12602 if(mfp.currTemplate.closeBtn) 12603 mfp.currTemplate.closeBtn.detach(); 12604 } 12605 12606 12607 if(mfp._lastFocusedEl) { 12608 $(mfp._lastFocusedEl).focus(); // put tab focus back 12609 } 12610 mfp.currItem = null; 12611 mfp.content = null; 12612 mfp.currTemplate = null; 12613 mfp.prevHeight = 0; 12614 12615 _mfpTrigger(AFTER_CLOSE_EVENT); 12616 }, 12617 12618 updateSize: function(winHeight) { 12619 12620 if(mfp.isIOS) { 12621 // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2 12622 var zoomLevel = document.documentElement.clientWidth / window.innerWidth; 12623 var height = window.innerHeight * zoomLevel; 12624 mfp.wrap.css('height', height); 12625 mfp.wH = height; 12626 } else { 12627 mfp.wH = winHeight || _window.height(); 12628 } 12629 // Fixes #84: popup incorrectly positioned with position:relative on body 12630 if(!mfp.fixedContentPos) { 12631 mfp.wrap.css('height', mfp.wH); 12632 } 12633 12634 _mfpTrigger('Resize'); 12635 12636 }, 12637 12638 /** 12639 * Set content of popup based on current index 12640 */ 12641 updateItemHTML: function() { 12642 var item = mfp.items[mfp.index]; 12643 12644 // Detach and perform modifications 12645 mfp.contentContainer.detach(); 12646 12647 if(mfp.content) 12648 mfp.content.detach(); 12649 12650 if(!item.parsed) { 12651 item = mfp.parseEl( mfp.index ); 12652 } 12653 12654 var type = item.type; 12655 12656 _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]); 12657 // BeforeChange event works like so: 12658 // _mfpOn('BeforeChange', function(e, prevType, newType) { }); 12659 12660 mfp.currItem = item; 12661 12662 12663 12664 12665 12666 if(!mfp.currTemplate[type]) { 12667 var markup = mfp.st[type] ? mfp.st[type].markup : false; 12668 12669 // allows to modify markup 12670 _mfpTrigger('FirstMarkupParse', markup); 12671 12672 if(markup) { 12673 mfp.currTemplate[type] = $(markup); 12674 } else { 12675 // if there is no markup found we just define that template is parsed 12676 mfp.currTemplate[type] = true; 12677 } 12678 } 12679 12680 if(_prevContentType && _prevContentType !== item.type) { 12681 mfp.container.removeClass('mfp-'+_prevContentType+'-holder'); 12682 } 12683 12684 var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]); 12685 mfp.appendContent(newContent, type); 12686 12687 item.preloaded = true; 12688 12689 _mfpTrigger(CHANGE_EVENT, item); 12690 _prevContentType = item.type; 12691 12692 // Append container back after its content changed 12693 mfp.container.prepend(mfp.contentContainer); 12694 12695 _mfpTrigger('AfterChange'); 12696 }, 12697 12698 12699 /** 12700 * Set HTML content of popup 12701 */ 12702 appendContent: function(newContent, type) { 12703 mfp.content = newContent; 12704 12705 if(newContent) { 12706 if(mfp.st.showCloseBtn && mfp.st.closeBtnInside && 12707 mfp.currTemplate[type] === true) { 12708 // if there is no markup, we just append close button element inside 12709 if(!mfp.content.find('.mfp-close').length) { 12710 mfp.content.append(_getCloseBtn()); 12711 } 12712 } else { 12713 mfp.content = newContent; 12714 } 12715 } else { 12716 mfp.content = ''; 12717 } 12718 12719 _mfpTrigger(BEFORE_APPEND_EVENT); 12720 mfp.container.addClass('mfp-'+type+'-holder'); 12721 12722 mfp.contentContainer.append(mfp.content); 12723 }, 12724 12725 12726 12727 12728 /** 12729 * Creates Magnific Popup data object based on given data 12730 * @param {int} index Index of item to parse 12731 */ 12732 parseEl: function(index) { 12733 var item = mfp.items[index], 12734 type; 12735 12736 if(item.tagName) { 12737 item = { el: $(item) }; 12738 } else { 12739 type = item.type; 12740 item = { data: item, src: item.src }; 12741 } 12742 12743 if(item.el) { 12744 var types = mfp.types; 12745 12746 // check for 'mfp-TYPE' class 12747 for(var i = 0; i < types.length; i++) { 12748 if( item.el.hasClass('mfp-'+types[i]) ) { 12749 type = types[i]; 12750 break; 12751 } 12752 } 12753 12754 item.src = item.el.attr('data-mfp-src'); 12755 if(!item.src) { 12756 item.src = item.el.attr('href'); 12757 } 12758 } 12759 12760 item.type = type || mfp.st.type || 'inline'; 12761 item.index = index; 12762 item.parsed = true; 12763 mfp.items[index] = item; 12764 _mfpTrigger('ElementParse', item); 12765 12766 return mfp.items[index]; 12767 }, 12768 12769 12770 /** 12771 * Initializes single popup or a group of popups 12772 */ 12773 addGroup: function(el, options) { 12774 var eHandler = function(e) { 12775 e.mfpEl = this; 12776 mfp._openClick(e, el, options); 12777 }; 12778 12779 if(!options) { 12780 options = {}; 12781 } 12782 12783 var eName = 'click.magnificPopup'; 12784 options.mainEl = el; 12785 12786 if(options.items) { 12787 options.isObj = true; 12788 el.off(eName).on(eName, eHandler); 12789 } else { 12790 options.isObj = false; 12791 if(options.delegate) { 12792 el.off(eName).on(eName, options.delegate , eHandler); 12793 } else { 12794 options.items = el; 12795 el.off(eName).on(eName, eHandler); 12796 } 12797 } 12798 }, 12799 _openClick: function(e, el, options) { 12800 var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick; 12801 12802 12803 if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey ) ) { 12804 return; 12805 } 12806 12807 var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn; 12808 12809 if(disableOn) { 12810 if($.isFunction(disableOn)) { 12811 if( !disableOn.call(mfp) ) { 12812 return true; 12813 } 12814 } else { // else it's number 12815 if( _window.width() < disableOn ) { 12816 return true; 12817 } 12818 } 12819 } 12820 12821 if(e.type) { 12822 e.preventDefault(); 12823 12824 // This will prevent popup from closing if element is inside and popup is already opened 12825 if(mfp.isOpen) { 12826 e.stopPropagation(); 12827 } 12828 } 12829 12830 12831 options.el = $(e.mfpEl); 12832 if(options.delegate) { 12833 options.items = el.find(options.delegate); 12834 } 12835 mfp.open(options); 12836 }, 12837 12838 12839 /** 12840 * Updates text on preloader 12841 */ 12842 updateStatus: function(status, text) { 12843 12844 if(mfp.preloader) { 12845 if(_prevStatus !== status) { 12846 mfp.container.removeClass('mfp-s-'+_prevStatus); 12847 } 12848 12849 if(!text && status === 'loading') { 12850 text = mfp.st.tLoading; 12851 } 12852 12853 var data = { 12854 status: status, 12855 text: text 12856 }; 12857 // allows to modify status 12858 _mfpTrigger('UpdateStatus', data); 12859 12860 status = data.status; 12861 text = data.text; 12862 12863 mfp.preloader.html(text); 12864 12865 mfp.preloader.find('a').on('click', function(e) { 12866 e.stopImmediatePropagation(); 12867 }); 12868 12869 mfp.container.addClass('mfp-s-'+status); 12870 _prevStatus = status; 12871 } 12872 }, 12873 12874 12875 /* 12876 "Private" helpers that aren't private at all 12877 */ 12878 // Check to close popup or not 12879 // "target" is an element that was clicked 12880 _checkIfClose: function(target) { 12881 12882 if($(target).hasClass(PREVENT_CLOSE_CLASS)) { 12883 return; 12884 } 12885 12886 var closeOnContent = mfp.st.closeOnContentClick; 12887 var closeOnBg = mfp.st.closeOnBgClick; 12888 12889 if(closeOnContent && closeOnBg) { 12890 return true; 12891 } else { 12892 12893 // We close the popup if click is on close button or on preloader. Or if there is no content. 12894 if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) { 12895 return true; 12896 } 12897 12898 // if click is outside the content 12899 if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) { 12900 if(closeOnBg) { 12901 // last check, if the clicked element is in DOM, (in case it's removed onclick) 12902 if( $.contains(document, target) ) { 12903 return true; 12904 } 12905 } 12906 } else if(closeOnContent) { 12907 return true; 12908 } 12909 12910 } 12911 return false; 12912 }, 12913 _addClassToMFP: function(cName) { 12914 mfp.bgOverlay.addClass(cName); 12915 mfp.wrap.addClass(cName); 12916 }, 12917 _removeClassFromMFP: function(cName) { 12918 this.bgOverlay.removeClass(cName); 12919 mfp.wrap.removeClass(cName); 12920 }, 12921 _hasScrollBar: function(winHeight) { 12922 return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) ); 12923 }, 12924 _setFocus: function() { 12925 (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus(); 12926 }, 12927 _onFocusIn: function(e) { 12928 if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) { 12929 mfp._setFocus(); 12930 return false; 12931 } 12932 }, 12933 _parseMarkup: function(template, values, item) { 12934 var arr; 12935 if(item.data) { 12936 values = $.extend(item.data, values); 12937 } 12938 _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] ); 12939 12940 $.each(values, function(key, value) { 12941 if(value === undefined || value === false) { 12942 return true; 12943 } 12944 arr = key.split('_'); 12945 if(arr.length > 1) { 12946 var el = template.find(EVENT_NS + '-'+arr[0]); 12947 12948 if(el.length > 0) { 12949 var attr = arr[1]; 12950 if(attr === 'replaceWith') { 12951 if(el[0] !== value[0]) { 12952 el.replaceWith(value); 12953 } 12954 } else if(attr === 'img') { 12955 if(el.is('img')) { 12956 el.attr('src', value); 12957 } else { 12958 el.replaceWith( '<img src="'+value+'" class="' + el.attr('class') + '" />' ); 12959 } 12960 } else { 12961 el.attr(arr[1], value); 12962 } 12963 } 12964 12965 } else { 12966 template.find(EVENT_NS + '-'+key).html(value); 12967 } 12968 }); 12969 }, 12970 12971 _getScrollbarSize: function() { 12972 // thx David 12973 if(mfp.scrollbarSize === undefined) { 12974 var scrollDiv = document.createElement("div"); 12975 scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'; 12976 document.body.appendChild(scrollDiv); 12977 mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth; 12978 document.body.removeChild(scrollDiv); 12979 } 12980 return mfp.scrollbarSize; 12981 } 12982 12983}; /* MagnificPopup core prototype end */ 12984 12985 12986 12987 12988/** 12989 * Public static functions 12990 */ 12991$.magnificPopup = { 12992 instance: null, 12993 proto: MagnificPopup.prototype, 12994 modules: [], 12995 12996 open: function(options, index) { 12997 _checkInstance(); 12998 12999 if(!options) { 13000 options = {}; 13001 } else { 13002 options = $.extend(true, {}, options); 13003 } 13004 13005 13006 options.isObj = true; 13007 options.index = index || 0; 13008 return this.instance.open(options); 13009 }, 13010 13011 close: function() { 13012 return $.magnificPopup.instance && $.magnificPopup.instance.close(); 13013 }, 13014 13015 registerModule: function(name, module) { 13016 if(module.options) { 13017 $.magnificPopup.defaults[name] = module.options; 13018 } 13019 $.extend(this.proto, module.proto); 13020 this.modules.push(name); 13021 }, 13022 13023 defaults: { 13024 13025 // Info about options is in docs: 13026 // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options 13027 13028 disableOn: 0, 13029 13030 key: null, 13031 13032 midClick: false, 13033 13034 mainClass: '', 13035 13036 preloader: true, 13037 13038 focus: '', // CSS selector of input to focus after popup is opened 13039 13040 closeOnContentClick: false, 13041 13042 closeOnBgClick: true, 13043 13044 closeBtnInside: true, 13045 13046 showCloseBtn: true, 13047 13048 enableEscapeKey: true, 13049 13050 modal: false, 13051 13052 alignTop: false, 13053 13054 removalDelay: 0, 13055 13056 prependTo: null, 13057 13058 fixedContentPos: 'auto', 13059 13060 fixedBgPos: 'auto', 13061 13062 overflowY: 'auto', 13063 13064 closeMarkup: '<button title="%title%" type="button" class="mfp-close">×</button>', 13065 13066 tClose: 'Close (Esc)', 13067 13068 tLoading: 'Loading...' 13069 13070 } 13071}; 13072 13073 13074 13075$.fn.magnificPopup = function(options) { 13076 _checkInstance(); 13077 13078 var jqEl = $(this); 13079 13080 // We call some API method of first param is a string 13081 if (typeof options === "string" ) { 13082 13083 if(options === 'open') { 13084 var items, 13085 itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup, 13086 index = parseInt(arguments[1], 10) || 0; 13087 13088 if(itemOpts.items) { 13089 items = itemOpts.items[index]; 13090 } else { 13091 items = jqEl; 13092 if(itemOpts.delegate) { 13093 items = items.find(itemOpts.delegate); 13094 } 13095 items = items.eq( index ); 13096 } 13097 mfp._openClick({mfpEl:items}, jqEl, itemOpts); 13098 } else { 13099 if(mfp.isOpen) 13100 mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1)); 13101 } 13102 13103 } else { 13104 // clone options obj 13105 options = $.extend(true, {}, options); 13106 13107 /* 13108 * As Zepto doesn't support .data() method for objects 13109 * and it works only in normal browsers 13110 * we assign "options" object directly to the DOM element. FTW! 13111 */ 13112 if(_isJQ) { 13113 jqEl.data('magnificPopup', options); 13114 } else { 13115 jqEl[0].magnificPopup = options; 13116 } 13117 13118 mfp.addGroup(jqEl, options); 13119 13120 } 13121 return jqEl; 13122}; 13123 13124 13125//Quick benchmark 13126/* 13127var start = performance.now(), 13128 i, 13129 rounds = 1000; 13130 13131for(i = 0; i < rounds; i++) { 13132 13133} 13134console.log('Test #1:', performance.now() - start); 13135 13136start = performance.now(); 13137for(i = 0; i < rounds; i++) { 13138 13139} 13140console.log('Test #2:', performance.now() - start); 13141*/ 13142 13143 13144/*>>core*/ 13145 13146/*>>inline*/ 13147 13148var INLINE_NS = 'inline', 13149 _hiddenClass, 13150 _inlinePlaceholder, 13151 _lastInlineElement, 13152 _putInlineElementsBack = function() { 13153 if(_lastInlineElement) { 13154 _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach(); 13155 _lastInlineElement = null; 13156 } 13157 }; 13158 13159$.magnificPopup.registerModule(INLINE_NS, { 13160 options: { 13161 hiddenClass: 'hide', // will be appended with `mfp-` prefix 13162 markup: '', 13163 tNotFound: 'Content not found' 13164 }, 13165 proto: { 13166 13167 initInline: function() { 13168 mfp.types.push(INLINE_NS); 13169 13170 _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() { 13171 _putInlineElementsBack(); 13172 }); 13173 }, 13174 13175 getInline: function(item, template) { 13176 13177 _putInlineElementsBack(); 13178 13179 if(item.src) { 13180 var inlineSt = mfp.st.inline, 13181 el = $(item.src); 13182 13183 if(el.length) { 13184 13185 // If target element has parent - we replace it with placeholder and put it back after popup is closed 13186 var parent = el[0].parentNode; 13187 if(parent && parent.tagName) { 13188 if(!_inlinePlaceholder) { 13189 _hiddenClass = inlineSt.hiddenClass; 13190 _inlinePlaceholder = _getEl(_hiddenClass); 13191 _hiddenClass = 'mfp-'+_hiddenClass; 13192 } 13193 // replace target inline element with placeholder 13194 _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass); 13195 } 13196 13197 mfp.updateStatus('ready'); 13198 } else { 13199 mfp.updateStatus('error', inlineSt.tNotFound); 13200 el = $('<div>'); 13201 } 13202 13203 item.inlineElement = el; 13204 return el; 13205 } 13206 13207 mfp.updateStatus('ready'); 13208 mfp._parseMarkup(template, {}, item); 13209 return template; 13210 } 13211 } 13212}); 13213 13214/*>>inline*/ 13215 13216/*>>ajax*/ 13217var AJAX_NS = 'ajax', 13218 _ajaxCur, 13219 _removeAjaxCursor = function() { 13220 if(_ajaxCur) { 13221 _body.removeClass(_ajaxCur); 13222 } 13223 }, 13224 _destroyAjaxRequest = function() { 13225 _removeAjaxCursor(); 13226 if(mfp.req) { 13227 mfp.req.abort(); 13228 } 13229 }; 13230 13231$.magnificPopup.registerModule(AJAX_NS, { 13232 13233 options: { 13234 settings: null, 13235 cursor: 'mfp-ajax-cur', 13236 tError: '<a href="%url%">The content</a> could not be loaded.' 13237 }, 13238 13239 proto: { 13240 initAjax: function() { 13241 mfp.types.push(AJAX_NS); 13242 _ajaxCur = mfp.st.ajax.cursor; 13243 13244 _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest); 13245 _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest); 13246 }, 13247 getAjax: function(item) { 13248 13249 if(_ajaxCur) 13250 _body.addClass(_ajaxCur); 13251 13252 mfp.updateStatus('loading'); 13253 13254 var opts = $.extend({ 13255 url: item.src, 13256 success: function(data, textStatus, jqXHR) { 13257 var temp = { 13258 data:data, 13259 xhr:jqXHR 13260 }; 13261 13262 _mfpTrigger('ParseAjax', temp); 13263 13264 mfp.appendContent( $(temp.data), AJAX_NS ); 13265 13266 item.finished = true; 13267 13268 _removeAjaxCursor(); 13269 13270 mfp._setFocus(); 13271 13272 setTimeout(function() { 13273 mfp.wrap.addClass(READY_CLASS); 13274 }, 16); 13275 13276 mfp.updateStatus('ready'); 13277 13278 _mfpTrigger('AjaxContentAdded'); 13279 }, 13280 error: function() { 13281 _removeAjaxCursor(); 13282 item.finished = item.loadError = true; 13283 mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src)); 13284 } 13285 }, mfp.st.ajax.settings); 13286 13287 mfp.req = $.ajax(opts); 13288 13289 return ''; 13290 } 13291 } 13292}); 13293 13294 13295 13296 13297 13298 13299 13300/*>>ajax*/ 13301 13302/*>>image*/ 13303var _imgInterval, 13304 _getTitle = function(item) { 13305 if(item.data && item.data.title !== undefined) 13306 return item.data.title; 13307 13308 var src = mfp.st.image.titleSrc; 13309 13310 if(src) { 13311 if($.isFunction(src)) { 13312 return src.call(mfp, item); 13313 } else if(item.el) { 13314 return item.el.attr(src) || ''; 13315 } 13316 } 13317 return ''; 13318 }; 13319 13320$.magnificPopup.registerModule('image', { 13321 13322 options: { 13323 markup: '<div class="mfp-figure">'+ 13324 '<div class="mfp-close"></div>'+ 13325 '<figure>'+ 13326 '<div class="mfp-img"></div>'+ 13327 '<figcaption>'+ 13328 '<div class="mfp-bottom-bar">'+ 13329 '<div class="mfp-title"></div>'+ 13330 '<div class="mfp-counter"></div>'+ 13331 '</div>'+ 13332 '</figcaption>'+ 13333 '</figure>'+ 13334 '</div>', 13335 cursor: 'mfp-zoom-out-cur', 13336 titleSrc: 'title', 13337 verticalFit: true, 13338 tError: '<a href="%url%">The image</a> could not be loaded.' 13339 }, 13340 13341 proto: { 13342 initImage: function() { 13343 var imgSt = mfp.st.image, 13344 ns = '.image'; 13345 13346 mfp.types.push('image'); 13347 13348 _mfpOn(OPEN_EVENT+ns, function() { 13349 if(mfp.currItem.type === 'image' && imgSt.cursor) { 13350 _body.addClass(imgSt.cursor); 13351 } 13352 }); 13353 13354 _mfpOn(CLOSE_EVENT+ns, function() { 13355 if(imgSt.cursor) { 13356 _body.removeClass(imgSt.cursor); 13357 } 13358 _window.off('resize' + EVENT_NS); 13359 }); 13360 13361 _mfpOn('Resize'+ns, mfp.resizeImage); 13362 if(mfp.isLowIE) { 13363 _mfpOn('AfterChange', mfp.resizeImage); 13364 } 13365 }, 13366 resizeImage: function() { 13367 var item = mfp.currItem; 13368 if(!item || !item.img) return; 13369 13370 if(mfp.st.image.verticalFit) { 13371 var decr = 0; 13372 // fix box-sizing in ie7/8 13373 if(mfp.isLowIE) { 13374 decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10); 13375 } 13376 item.img.css('max-height', mfp.wH-decr); 13377 } 13378 }, 13379 _onImageHasSize: function(item) { 13380 if(item.img) { 13381 13382 item.hasSize = true; 13383 13384 if(_imgInterval) { 13385 clearInterval(_imgInterval); 13386 } 13387 13388 item.isCheckingImgSize = false; 13389 13390 _mfpTrigger('ImageHasSize', item); 13391 13392 if(item.imgHidden) { 13393 if(mfp.content) 13394 mfp.content.removeClass('mfp-loading'); 13395 13396 item.imgHidden = false; 13397 } 13398 13399 } 13400 }, 13401 13402 /** 13403 * Function that loops until the image has size to display elements that rely on it asap 13404 */ 13405 findImageSize: function(item) { 13406 13407 var counter = 0, 13408 img = item.img[0], 13409 mfpSetInterval = function(delay) { 13410 13411 if(_imgInterval) { 13412 clearInterval(_imgInterval); 13413 } 13414 // decelerating interval that checks for size of an image 13415 _imgInterval = setInterval(function() { 13416 if(img.naturalWidth > 0) { 13417 mfp._onImageHasSize(item); 13418 return; 13419 } 13420 13421 if(counter > 200) { 13422 clearInterval(_imgInterval); 13423 } 13424 13425 counter++; 13426 if(counter === 3) { 13427 mfpSetInterval(10); 13428 } else if(counter === 40) { 13429 mfpSetInterval(50); 13430 } else if(counter === 100) { 13431 mfpSetInterval(500); 13432 } 13433 }, delay); 13434 }; 13435 13436 mfpSetInterval(1); 13437 }, 13438 13439 getImage: function(item, template) { 13440 13441 var guard = 0, 13442 13443 // image load complete handler 13444 onLoadComplete = function() { 13445 if(item) { 13446 if (item.img[0].complete) { 13447 item.img.off('.mfploader'); 13448 13449 if(item === mfp.currItem){ 13450 mfp._onImageHasSize(item); 13451 13452 mfp.updateStatus('ready'); 13453 } 13454 13455 item.hasSize = true; 13456 item.loaded = true; 13457 13458 _mfpTrigger('ImageLoadComplete'); 13459 13460 } 13461 else { 13462 // if image complete check fails 200 times (20 sec), we assume that there was an error. 13463 guard++; 13464 if(guard < 200) { 13465 setTimeout(onLoadComplete,100); 13466 } else { 13467 onLoadError(); 13468 } 13469 } 13470 } 13471 }, 13472 13473 // image error handler 13474 onLoadError = function() { 13475 if(item) { 13476 item.img.off('.mfploader'); 13477 if(item === mfp.currItem){ 13478 mfp._onImageHasSize(item); 13479 mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); 13480 } 13481 13482 item.hasSize = true; 13483 item.loaded = true; 13484 item.loadError = true; 13485 } 13486 }, 13487 imgSt = mfp.st.image; 13488 13489 13490 var el = template.find('.mfp-img'); 13491 if(el.length) { 13492 var img = document.createElement('img'); 13493 img.className = 'mfp-img'; 13494 if(item.el && item.el.find('img').length) { 13495 img.alt = item.el.find('img').attr('alt'); 13496 } 13497 item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError); 13498 img.src = item.src; 13499 13500 // without clone() "error" event is not firing when IMG is replaced by new IMG 13501 // TODO: find a way to avoid such cloning 13502 if(el.is('img')) { 13503 item.img = item.img.clone(); 13504 } 13505 13506 img = item.img[0]; 13507 if(img.naturalWidth > 0) { 13508 item.hasSize = true; 13509 } else if(!img.width) { 13510 item.hasSize = false; 13511 } 13512 } 13513 13514 mfp._parseMarkup(template, { 13515 title: _getTitle(item), 13516 img_replaceWith: item.img 13517 }, item); 13518 13519 mfp.resizeImage(); 13520 13521 if(item.hasSize) { 13522 if(_imgInterval) clearInterval(_imgInterval); 13523 13524 if(item.loadError) { 13525 template.addClass('mfp-loading'); 13526 mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); 13527 } else { 13528 template.removeClass('mfp-loading'); 13529 mfp.updateStatus('ready'); 13530 } 13531 return template; 13532 } 13533 13534 mfp.updateStatus('loading'); 13535 item.loading = true; 13536 13537 if(!item.hasSize) { 13538 item.imgHidden = true; 13539 template.addClass('mfp-loading'); 13540 mfp.findImageSize(item); 13541 } 13542 13543 return template; 13544 } 13545 } 13546}); 13547 13548 13549 13550/*>>image*/ 13551 13552/*>>zoom*/ 13553var hasMozTransform, 13554 getHasMozTransform = function() { 13555 if(hasMozTransform === undefined) { 13556 hasMozTransform = document.createElement('p').style.MozTransform !== undefined; 13557 } 13558 return hasMozTransform; 13559 }; 13560 13561$.magnificPopup.registerModule('zoom', { 13562 13563 options: { 13564 enabled: false, 13565 easing: 'ease-in-out', 13566 duration: 300, 13567 opener: function(element) { 13568 return element.is('img') ? element : element.find('img'); 13569 } 13570 }, 13571 13572 proto: { 13573 13574 initZoom: function() { 13575 var zoomSt = mfp.st.zoom, 13576 ns = '.zoom', 13577 image; 13578 13579 if(!zoomSt.enabled || !mfp.supportsTransition) { 13580 return; 13581 } 13582 13583 var duration = zoomSt.duration, 13584 getElToAnimate = function(image) { 13585 var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'), 13586 transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing, 13587 cssObj = { 13588 position: 'fixed', 13589 zIndex: 9999, 13590 left: 0, 13591 top: 0, 13592 '-webkit-backface-visibility': 'hidden' 13593 }, 13594 t = 'transition'; 13595 13596 cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition; 13597 13598 newImg.css(cssObj); 13599 return newImg; 13600 }, 13601 showMainContent = function() { 13602 mfp.content.css('visibility', 'visible'); 13603 }, 13604 openTimeout, 13605 animatedImg; 13606 13607 _mfpOn('BuildControls'+ns, function() { 13608 if(mfp._allowZoom()) { 13609 13610 clearTimeout(openTimeout); 13611 mfp.content.css('visibility', 'hidden'); 13612 13613 // Basically, all code below does is clones existing image, puts in on top of the current one and animated it 13614 13615 image = mfp._getItemToZoom(); 13616 13617 if(!image) { 13618 showMainContent(); 13619 return; 13620 } 13621 13622 animatedImg = getElToAnimate(image); 13623 13624 animatedImg.css( mfp._getOffset() ); 13625 13626 mfp.wrap.append(animatedImg); 13627 13628 openTimeout = setTimeout(function() { 13629 animatedImg.css( mfp._getOffset( true ) ); 13630 openTimeout = setTimeout(function() { 13631 13632 showMainContent(); 13633 13634 setTimeout(function() { 13635 animatedImg.remove(); 13636 image = animatedImg = null; 13637 _mfpTrigger('ZoomAnimationEnded'); 13638 }, 16); // avoid blink when switching images 13639 13640 }, duration); // this timeout equals animation duration 13641 13642 }, 16); // by adding this timeout we avoid short glitch at the beginning of animation 13643 13644 13645 // Lots of timeouts... 13646 } 13647 }); 13648 _mfpOn(BEFORE_CLOSE_EVENT+ns, function() { 13649 if(mfp._allowZoom()) { 13650 13651 clearTimeout(openTimeout); 13652 13653 mfp.st.removalDelay = duration; 13654 13655 if(!image) { 13656 image = mfp._getItemToZoom(); 13657 if(!image) { 13658 return; 13659 } 13660 animatedImg = getElToAnimate(image); 13661 } 13662 13663 13664 animatedImg.css( mfp._getOffset(true) ); 13665 mfp.wrap.append(animatedImg); 13666 mfp.content.css('visibility', 'hidden'); 13667 13668 setTimeout(function() { 13669 animatedImg.css( mfp._getOffset() ); 13670 }, 16); 13671 } 13672 13673 }); 13674 13675 _mfpOn(CLOSE_EVENT+ns, function() { 13676 if(mfp._allowZoom()) { 13677 showMainContent(); 13678 if(animatedImg) { 13679 animatedImg.remove(); 13680 } 13681 image = null; 13682 } 13683 }); 13684 }, 13685 13686 _allowZoom: function() { 13687 return mfp.currItem.type === 'image'; 13688 }, 13689 13690 _getItemToZoom: function() { 13691 if(mfp.currItem.hasSize) { 13692 return mfp.currItem.img; 13693 } else { 13694 return false; 13695 } 13696 }, 13697 13698 // Get element postion relative to viewport 13699 _getOffset: function(isLarge) { 13700 var el; 13701 if(isLarge) { 13702 el = mfp.currItem.img; 13703 } else { 13704 el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem); 13705 } 13706 13707 var offset = el.offset(); 13708 var paddingTop = parseInt(el.css('padding-top'),10); 13709 var paddingBottom = parseInt(el.css('padding-bottom'),10); 13710 offset.top -= ( $(window).scrollTop() - paddingTop ); 13711 13712 13713 /* 13714 13715 Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa. 13716 13717 */ 13718 var obj = { 13719 width: el.width(), 13720 // fix Zepto height+padding issue 13721 height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop 13722 }; 13723 13724 // I hate to do this, but there is no another option 13725 if( getHasMozTransform() ) { 13726 obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)'; 13727 } else { 13728 obj.left = offset.left; 13729 obj.top = offset.top; 13730 } 13731 return obj; 13732 } 13733 13734 } 13735}); 13736 13737 13738 13739/*>>zoom*/ 13740 13741/*>>iframe*/ 13742 13743var IFRAME_NS = 'iframe', 13744 _emptyPage = '//about:blank', 13745 13746 _fixIframeBugs = function(isShowing) { 13747 if(mfp.currTemplate[IFRAME_NS]) { 13748 var el = mfp.currTemplate[IFRAME_NS].find('iframe'); 13749 if(el.length) { 13750 // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug 13751 if(!isShowing) { 13752 el[0].src = _emptyPage; 13753 } 13754 13755 // IE8 black screen bug fix 13756 if(mfp.isIE8) { 13757 el.css('display', isShowing ? 'block' : 'none'); 13758 } 13759 } 13760 } 13761 }; 13762 13763$.magnificPopup.registerModule(IFRAME_NS, { 13764 13765 options: { 13766 markup: '<div class="mfp-iframe-scaler">'+ 13767 '<div class="mfp-close"></div>'+ 13768 '<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+ 13769 '</div>', 13770 13771 srcAction: 'iframe_src', 13772 13773 // we don't care and support only one default type of URL by default 13774 patterns: { 13775 youtube: { 13776 index: 'youtube.com', 13777 id: 'v=', 13778 src: '//www.youtube.com/embed/%id%?autoplay=1' 13779 }, 13780 vimeo: { 13781 index: 'vimeo.com/', 13782 id: '/', 13783 src: '//player.vimeo.com/video/%id%?autoplay=1' 13784 }, 13785 gmaps: { 13786 index: '//maps.google.', 13787 src: '%id%&output=embed' 13788 } 13789 } 13790 }, 13791 13792 proto: { 13793 initIframe: function() { 13794 mfp.types.push(IFRAME_NS); 13795 13796 _mfpOn('BeforeChange', function(e, prevType, newType) { 13797 if(prevType !== newType) { 13798 if(prevType === IFRAME_NS) { 13799 _fixIframeBugs(); // iframe if removed 13800 } else if(newType === IFRAME_NS) { 13801 _fixIframeBugs(true); // iframe is showing 13802 } 13803 }// else { 13804 // iframe source is switched, don't do anything 13805 //} 13806 }); 13807 13808 _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() { 13809 _fixIframeBugs(); 13810 }); 13811 }, 13812 13813 getIframe: function(item, template) { 13814 var embedSrc = item.src; 13815 var iframeSt = mfp.st.iframe; 13816 13817 $.each(iframeSt.patterns, function() { 13818 if(embedSrc.indexOf( this.index ) > -1) { 13819 if(this.id) { 13820 if(typeof this.id === 'string') { 13821 embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length); 13822 } else { 13823 embedSrc = this.id.call( this, embedSrc ); 13824 } 13825 } 13826 embedSrc = this.src.replace('%id%', embedSrc ); 13827 return false; // break; 13828 } 13829 }); 13830 13831 var dataObj = {}; 13832 if(iframeSt.srcAction) { 13833 dataObj[iframeSt.srcAction] = embedSrc; 13834 } 13835 mfp._parseMarkup(template, dataObj, item); 13836 13837 mfp.updateStatus('ready'); 13838 13839 return template; 13840 } 13841 } 13842}); 13843 13844 13845 13846/*>>iframe*/ 13847 13848/*>>gallery*/ 13849/** 13850 * Get looped index depending on number of slides 13851 */ 13852var _getLoopedId = function(index) { 13853 var numSlides = mfp.items.length; 13854 if(index > numSlides - 1) { 13855 return index - numSlides; 13856 } else if(index < 0) { 13857 return numSlides + index; 13858 } 13859 return index; 13860 }, 13861 _replaceCurrTotal = function(text, curr, total) { 13862 return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total); 13863 }; 13864 13865$.magnificPopup.registerModule('gallery', { 13866 13867 options: { 13868 enabled: false, 13869 arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>', 13870 preload: [0,2], 13871 navigateByImgClick: true, 13872 arrows: true, 13873 13874 tPrev: 'Previous (Left arrow key)', 13875 tNext: 'Next (Right arrow key)', 13876 tCounter: '%curr% of %total%' 13877 }, 13878 13879 proto: { 13880 initGallery: function() { 13881 13882 var gSt = mfp.st.gallery, 13883 ns = '.mfp-gallery', 13884 supportsFastClick = Boolean($.fn.mfpFastClick); 13885 13886 mfp.direction = true; // true - next, false - prev 13887 13888 if(!gSt || !gSt.enabled ) return false;
13889 13890 _wrapClasses += ' mfp-gallery'; 13891 13892 _mfpOn(OPEN_EVENT+ns, function() { 13893 13894 if(gSt.navigateByImgClick) { 13895 mfp.wrap.on('click'+ns, '.mfp-img', function() { 13896 if(mfp.items.length > 1) { 13897 mfp.next(); 13898 return false; 13899 } 13900 }); 13901 } 13902 13903 _document.on('keydown'+ns, function(e) { 13904 if (e.keyCode === 37) { 13905 mfp.prev(); 13906 } else if (e.keyCode === 39) { 13907 mfp.next(); 13908 } 13909 }); 13910 }); 13911 13912 _mfpOn('UpdateStatus'+ns, function(e, data) { 13913 if(data.text) { 13914 data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length); 13915 } 13916 }); 13917 13918 _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) { 13919 var l = mfp.items.length; 13920 values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : ''; 13921 }); 13922 13923 _mfpOn('BuildControls' + ns, function() { 13924 if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) { 13925 var markup = gSt.arrowMarkup, 13926 arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS), 13927 arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS); 13928 13929 var eName = supportsFastClick ? 'mfpFastClick' : 'click'; 13930 arrowLeft[eName](function() { 13931 mfp.prev(); 13932 }); 13933 arrowRight[eName](function() { 13934 mfp.next(); 13935 }); 13936 13937 // Polyfill for :before and :after (adds elements with classes mfp-a and mfp-b) 13938 if(mfp.isIE7) { 13939 _getEl('b', arrowLeft[0], false, true); 13940 _getEl('a', arrowLeft[0], false, true); 13941 _getEl('b', arrowRight[0], false, true); 13942 _getEl('a', arrowRight[0], false, true); 13943 } 13944 13945 mfp.container.append(arrowLeft.add(arrowRight)); 13946 } 13947 }); 13948 13949 _mfpOn(CHANGE_EVENT+ns, function() { 13950 if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout); 13951 13952 mfp._preloadTimeout = setTimeout(function() { 13953 mfp.preloadNearbyImages(); 13954 mfp._preloadTimeout = null; 13955 }, 16); 13956 }); 13957 13958 13959 _mfpOn(CLOSE_EVENT+ns, function() { 13960 _document.off(ns); 13961 mfp.wrap.off('click'+ns); 13962 13963 if(mfp.arrowLeft && supportsFastClick) { 13964 mfp.arrowLeft.add(mfp.arrowRight).destroyMfpFastClick(); 13965 } 13966 mfp.arrowRight = mfp.arrowLeft = null; 13967 }); 13968 13969 }, 13970 next: function() { 13971 mfp.direction = true; 13972 mfp.index = _getLoopedId(mfp.index + 1); 13973 mfp.updateItemHTML(); 13974 }, 13975 prev: function() { 13976 mfp.direction = false; 13977 mfp.index = _getLoopedId(mfp.index - 1); 13978 mfp.updateItemHTML(); 13979 }, 13980 goTo: function(newIndex) { 13981 mfp.direction = (newIndex >= mfp.index); 13982 mfp.index = newIndex; 13983 mfp.updateItemHTML(); 13984 }, 13985 preloadNearbyImages: function() { 13986 var p = mfp.st.gallery.preload, 13987 preloadBefore = Math.min(p[0], mfp.items.length), 13988 preloadAfter = Math.min(p[1], mfp.items.length), 13989 i; 13990 13991 for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) { 13992 mfp._preloadItem(mfp.index+i); 13993 } 13994 for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) { 13995 mfp._preloadItem(mfp.index-i); 13996 } 13997 }, 13998 _preloadItem: function(index) { 13999 index = _getLoopedId(index); 14000 14001 if(mfp.items[index].preloaded) { 14002 return; 14003 } 14004 14005 var item = mfp.items[index]; 14006 if(!item.parsed) { 14007 item = mfp.parseEl( index ); 14008 } 14009 14010 _mfpTrigger('LazyLoad', item); 14011 14012 if(item.type === 'image') { 14013 item.img = $('<img class="mfp-img" />').on('load.mfploader', function() { 14014 item.hasSize = true; 14015 }).on('error.mfploader', function() { 14016 item.hasSize = true; 14017 item.loadError = true; 14018 _mfpTrigger('LazyLoadError', item); 14019 }).attr('src', item.src); 14020 } 14021 14022 14023 item.preloaded = true; 14024 } 14025 } 14026}); 14027 14028/* 14029Touch Support that might be implemented some day 14030 14031addSwipeGesture: function() { 14032 var startX, 14033 moved, 14034 multipleTouches; 14035 14036 return; 14037 14038 var namespace = '.mfp', 14039 addEventNames = function(pref, down, move, up, cancel) { 14040 mfp._tStart = pref + down + namespace; 14041 mfp._tMove = pref + move + namespace; 14042 mfp._tEnd = pref + up + namespace; 14043 mfp._tCancel = pref + cancel + namespace; 14044 }; 14045 14046 if(window.navigator.msPointerEnabled) { 14047 addEventNames('MSPointer', 'Down', 'Move', 'Up', 'Cancel'); 14048 } else if('ontouchstart' in window) { 14049 addEventNames('touch', 'start', 'move', 'end', 'cancel'); 14050 } else { 14051 return; 14052 } 14053 _window.on(mfp._tStart, function(e) { 14054 var oE = e.originalEvent; 14055 multipleTouches = moved = false;
14056 startX = oE.pageX || oE.changedTouches[0].pageX; 14057 }).on(mfp._tMove, function(e) { 14058 if(e.originalEvent.touches.length > 1) { 14059 multipleTouches = e.originalEvent.touches.length; 14060 } else { 14061 //e.preventDefault(); 14062 moved = true; 14063 } 14064 }).on(mfp._tEnd + ' ' + mfp._tCancel, function(e) { 14065 if(moved && !multipleTouches) { 14066 var oE = e.originalEvent, 14067 diff = startX - (oE.pageX || oE.changedTouches[0].pageX); 14068 14069 if(diff > 20) { 14070 mfp.next(); 14071 } else if(diff < -20) { 14072 mfp.prev(); 14073 } 14074 } 14075 }); 14076}, 14077*/ 14078 14079 14080/*>>gallery*/ 14081 14082/*>>retina*/ 14083 14084var RETINA_NS = 'retina'; 14085 14086$.magnificPopup.registerModule(RETINA_NS, { 14087 options: { 14088 replaceSrc: function(item) { 14089 return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; }); 14090 }, 14091 ratio: 1 // Function or number. Set to 1 to disable. 14092 }, 14093 proto: { 14094 initRetina: function() { 14095 if(window.devicePixelRatio > 1) { 14096 14097 var st = mfp.st.retina, 14098 ratio = st.ratio; 14099 14100 ratio = !isNaN(ratio) ? ratio : ratio(); 14101 14102 if(ratio > 1) { 14103 _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) { 14104 item.img.css({ 14105 'max-width': item.img[0].naturalWidth / ratio, 14106 'width': '100%' 14107 }); 14108 }); 14109 _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) { 14110 item.src = st.replaceSrc(item, ratio); 14111 }); 14112 } 14113 } 14114 14115 } 14116 } 14117}); 14118 14119/*>>retina*/ 14120 14121/*>>fastclick*/ 14122/** 14123 * FastClick event implementation. (removes 300ms delay on touch devices) 14124 * Based on https://developers.google.com/mobile/articles/fast_buttons 14125 * 14126 * You may use it outside the Magnific Popup by calling just: 14127 * 14128 * $('.your-el').mfpFastClick(function() { 14129 * console.log('Clicked!'); 14130 * }); 14131 * 14132 * To unbind: 14133 * $('.your-el').destroyMfpFastClick(); 14134 * 14135 * 14136 * Note that it's a very basic and simple implementation, it blocks ghost click on the same element where it was bound. 14137 * If you need something more advanced, use plugin by FT Labs https://github.com/ftlabs/fastclick 14138 * 14139 */ 14140 14141(function() { 14142 var ghostClickDelay = 1000, 14143 supportsTouch = 'ontouchstart' in window, 14144 unbindTouchMove = function() { 14145 _window.off('touchmove'+ns+' touchend'+ns); 14146 }, 14147 eName = 'mfpFastClick', 14148 ns = '.'+eName; 14149 14150 14151 // As Zepto.js doesn't have an easy way to add custom events (like jQuery), so we implement it in this way 14152 $.fn.mfpFastClick = function(callback) { 14153 14154 return $(this).each(function() { 14155 14156 var elem = $(this), 14157 lock; 14158 14159 if( supportsTouch ) { 14160 14161 var timeout, 14162 startX, 14163 startY, 14164 pointerMoved, 14165 point, 14166 numPointers; 14167 14168 elem.on('touchstart' + ns, function(e) { 14169 pointerMoved = false; 14170 numPointers = 1; 14171 14172 point = e.originalEvent ? e.originalEvent.touches[0] : e.touches[0]; 14173 startX = point.clientX; 14174 startY = point.clientY; 14175 14176 _window.on('touchmove'+ns, function(e) { 14177 point = e.originalEvent ? e.originalEvent.touches : e.touches; 14178 numPointers = point.length; 14179 point = point[0]; 14180 if (Math.abs(point.clientX - startX) > 10 || 14181 Math.abs(point.clientY - startY) > 10) { 14182 pointerMoved = true; 14183 unbindTouchMove(); 14184 } 14185 }).on('touchend'+ns, function(e) { 14186 unbindTouchMove(); 14187 if(pointerMoved || numPointers > 1) { 14188 return; 14189 } 14190 lock = true; 14191 e.preventDefault(); 14192 clearTimeout(timeout); 14193 timeout = setTimeout(function() { 14194 lock = false; 14195 }, ghostClickDelay); 14196 callback(); 14197 }); 14198 }); 14199 14200 } 14201 14202 elem.on('click' + ns, function() { 14203 if(!lock) { 14204 callback(); 14205 } 14206 }); 14207 }); 14208 }; 14209 14210 $.fn.destroyMfpFastClick = function() { 14211 $(this).off('touchstart' + ns + ' click' + ns); 14212 if(supportsTouch) _window.off('touchmove'+ns+' touchend'+ns); 14213 }; 14214})(); 14215 14216/*>>fastclick*/ 14217 _checkInstance(); })); 14218;/*})'"*/ 14219;/*})'"*/ 14220/* 14221 * Vide - v0.3.5 14222 * Easy as hell jQuery plugin for video backgrounds. 14223 * http://vodkabears.github.io/vide/ 14224 * 14225 * Made by Ilya Makarov 14226 * Under MIT License 14227 */ 14228!(function(root, factory) { 14229 if (typeof define === 'function' && define.amd) { 14230 define(['jquery'], factory); 14231 } else if (typeof exports === 'object') { 14232 factory(require('jquery')); 14233 } else { 14234 factory(root.jQuery); 14235 } 14236})(this, function($) { 14237 14238 'use strict'; 14239 14240 /** 14241 * Name of the plugin 14242 * @private 14243 * @const 14244 * @type {String} 14245 */
14246 var PLUGIN_NAME = 'vide'; 14247 14248 /** 14249 * Default settings 14250 * @private 14251 * @const 14252 * @type {Object} 14253 */ 14254 var DEFAULTS = { 14255 volume: 1, 14256 playbackRate: 1, 14257 muted: true, 14258 loop: true, 14259 autoplay: true, 14260 position: '50% 50%', 14261 posterType: 'detect', 14262 resizing: true 14263 }; 14264 14265 /** 14266 * Parse a string with options 14267 * @private 14268 * @param {String} str 14269 * @returns {Object|String} 14270 */ 14271 function parseOptions(str) { 14272 var obj = {}; 14273 var delimiterIndex; 14274 var option; 14275 var prop; 14276 var val; 14277 var arr; 14278 var len; 14279 var i; 14280 14281 // Remove spaces around delimiters and split 14282 arr = str.replace(/\s*:\s*/g, ':').replace(/\s*,\s*/g, ',').split(','); 14283 14284 // Parse a string 14285 for (i = 0, len = arr.length; i < len; i++) { 14286 option = arr[i]; 14287 14288 // Ignore urls and a string without colon delimiters 14289 if ( 14290 option.search(/^(http|https|ftp):\/\//) !== -1 || 14291 option.search(':') === -1 14292 ) { 14293 break; 14294 } 14295 14296 delimiterIndex = option.indexOf(':'); 14297 prop = option.substring(0, delimiterIndex); 14298 val = option.substring(delimiterIndex + 1); 14299 14300 // If val is an empty string, make it undefined 14301 if (!val) { 14302 val = undefined; 14303 } 14304 14305 // Convert a string value if it is like a boolean 14306 if (typeof val === 'string') { 14307 val = val === 'true' || (val === 'false' ? false : val); 14308 } 14309 14310 // Convert a string value if it is like a number 14311 if (typeof val === 'string') { 14312 val = !isNaN(val) ? +val : val; 14313 } 14314 14315 obj[prop] = val; 14316 } 14317 14318 // If nothing is parsed 14319 if (prop == null && val == null) { 14320 return str; 14321 } 14322 14323 return obj; 14324 } 14325 14326 /** 14327 * Parse a position option 14328 * @private 14329 * @param {String} str 14330 * @returns {Object} 14331 */ 14332 function parsePosition(str) { 14333 str = '' + str; 14334 14335 // Default value is a center 14336 var args = str.split(/\s+/); 14337 var x = '50%'; 14338 var y = '50%'; 14339 var len; 14340 var arg; 14341 var i; 14342 14343 for (i = 0, len = args.length; i < len; i++) { 14344 arg = args[i]; 14345 14346 // Convert values 14347 if (arg === 'left') { 14348 x = '0%'; 14349 } else if (arg === 'right') { 14350 x = '100%'; 14351 } else if (arg === 'top') { 14352 y = '0%'; 14353 } else if (arg === 'bottom') { 14354 y = '100%'; 14355 } else if (arg === 'center') { 14356 if (i === 0) { 14357 x = '50%'; 14358 } else { 14359 y = '50%'; 14360 } 14361 } else { 14362 if (i === 0) { 14363 x = arg; 14364 } else { 14365 y = arg; 14366 } 14367 } 14368 } 14369 14370 return { x: x, y: y }; 14371 } 14372 14373 /** 14374 * Search a poster 14375 * @private 14376 * @param {String} path 14377 * @param {Function} callback 14378 */ 14379 function findPoster(path, callback) { 14380 var onLoad = function() { 14381 callback(this.src); 14382 }; 14383 14384 $('<img src="' + path + '.gif">').load(onLoad); 14385 $('<img src="' + path + '.jpg">').load(onLoad); 14386 $('<img src="' + path + '.jpeg">').load(onLoad); 14387 $('<img src="' + path + '.png">').load(onLoad); 14388 } 14389 14390 /** 14391 * Vide constructor 14392 * @param {HTMLElement} element 14393 * @param {Object|String} path 14394 * @param {Object|String} options 14395 * @constructor 14396 */ 14397 function Vide(element, path, options) { 14398 this.$element = $(element); 14399 14400 // Parse path 14401 if (typeof path === 'string') { 14402 path = parseOptions(path); 14403 } 14404 14405 // Parse options 14406 if (!options) { 14407 options = {}; 14408 } else if (typeof options === 'string') { 14409 options = parseOptions(options); 14410 } 14411 14412 // Remove an extension 14413 if (typeof path === 'string') { 14414 path = path.replace(/\.\w*$/, ''); 14415 } else if (typeof path === 'object') { 14416 for (var i in path) { 14417 if (path.hasOwnProperty(i)) { 14418 path[i] = path[i].replace(/\.\w*$/, ''); 14419 } 14420 } 14421 } 14422 14423 this.settings = $.extend({}, DEFAULTS, options); 14424 this.path = path; 14425 14426 this.init(); 14427 } 14428 14429 /** 14430 * Initialization 14431 * @public 14432 */ 14433 Vide.prototype.init = function() { 14434 var vide = this; 14435 var position = parsePosition(vide.settings.position); 14436 var sources = ''; 14437 var poster; 14438 14439 // Set styles of a video wrapper
14440 vide.$wrapper = $('<div>').css({ 14441 position: 'absolute', 14442 'z-index': -1, 14443 top: 0, 14444 left: 0, 14445 bottom: 0, 14446 right: 0, 14447 overflow: 'hidden', 14448 '-webkit-background-size': 'cover', 14449 '-moz-background-size': 'cover', 14450 '-o-background-size': 'cover', 14451 'background-size': 'cover', 14452 'background-repeat': 'no-repeat', 14453 'background-position': position.x + ' ' + position.y 14454 }); 14455 14456 // Get a poster path 14457 poster = vide.path; 14458 if (typeof vide.path === 'object') { 14459 if (vide.path.poster) { 14460 poster = vide.path.poster; 14461 } else { 14462 if (vide.path.mp4) { 14463 poster = vide.path.mp4; 14464 } else if (vide.path.webm) { 14465 poster = vide.path.webm; 14466 } else if (vide.path.ogv) { 14467 poster = vide.path.ogv; 14468 } 14469 } 14470 } 14471 14472 // Set a video poster 14473 if (vide.settings.posterType === 'detect') { 14474 findPoster(poster, function(url) { 14475 vide.$wrapper.css('background-image', 'url(' + url + ')'); 14476 }); 14477 } else if (vide.settings.posterType !== 'none') { 14478 vide.$wrapper 14479 .css('background-image', 'url(' + poster + '.' + vide.settings.posterType + ')'); 14480 } 14481 14482 // If a parent element has a static position, make it relative 14483 if (vide.$element.css('position') === 'static') { 14484 vide.$element.css('position', 'relative'); 14485 } 14486 14487 vide.$element.prepend(vide.$wrapper); 14488 14489 if (typeof vide.path === 'object') { 14490 if (vide.path.mp4) { 14491 sources += '<source src="' + vide.path.mp4 + '.mp4" type="video/mp4">'; 14492 } 14493 14494 if (vide.path.webm) { 14495 sources += '<source src="' + vide.path.webm + '.webm" type="video/webm">'; 14496 } 14497 14498 if (vide.path.ogv) { 14499 sources += '<source src="' + vide.path.ogv + '.ogv" type="video/ogv">'; 14500 } 14501 14502 vide.$video = $('<video>' + sources + '</video>'); 14503 } else { 14504 vide.$video = $('<video>' + 14505 '<source src="' + vide.path + '.mp4" type="video/mp4">' + 14506 '<source src="' + vide.path + '.webm" type="video/webm">' + 14507 '<source src="' + vide.path + '.ogv" type="video/ogg">' + 14508 '</video>'); 14509 } 14510 14511 vide.$video 14512 14513 // Set video properties 14514 .prop({ 14515 autoplay: vide.settings.autoplay, 14516 loop: vide.settings.loop, 14517 volume: vide.settings.volume, 14518 muted: vide.settings.muted, 14519 defaultMuted: vide.settings.muted, 14520 playbackRate: vide.settings.playbackRate, 14521 defaultPlaybackRate: vide.settings.playbackRate 14522 }) 14523 14524 // Video alignment 14525 .css({ 14526 margin: 'auto', 14527 position: 'absolute', 14528 'z-index': -1, 14529 top: position.y, 14530 left: position.x, 14531 '-webkit-transform': 'translate(-' + position.x + ', -' + position.y + ')',
14532 '-ms-transform': 'translate(-' + position.x + ', -' + position.y + ')', 14533 '-moz-transform': 'translate(-' + position.x + ', -' + position.y + ')', 14534 transform: 'translate(-' + position.x + ', -' + position.y + ')', 14535 14536 // Disable visibility, while loading 14537 visibility: 'hidden' 14538 }) 14539 14540 // Resize a video, when it's loaded 14541 .one('canplaythrough.' + PLUGIN_NAME, function() { 14542 vide.resize(); 14543 }) 14544 14545 // Make it visible, when it's already playing 14546 .one('playing.' + PLUGIN_NAME, function() { 14547 vide.$video.css('visibility', 'visible'); 14548 vide.$wrapper.css('background-image', 'none'); 14549 }); 14550 14551 // Resize event is available only for 'window' 14552 // Use another code solutions to detect DOM elements resizing 14553 vide.$element.on('resize.' + PLUGIN_NAME, function() { 14554 if (vide.settings.resizing) { 14555 vide.resize(); 14556 } 14557 }); 14558 14559 // Append a video 14560 vide.$wrapper.append(vide.$video); 14561 }; 14562 14563 /** 14564 * Get a video element 14565 * @public 14566 * @returns {HTMLVideoElement} 14567 */ 14568 Vide.prototype.getVideoObject = function() { 14569 return this.$video[0]; 14570 }; 14571 14572 /** 14573 * Resize a video background 14574 * @public 14575 */ 14576 Vide.prototype.resize = function() { 14577 if (!this.$video) { 14578 return; 14579 } 14580 14581 // Get a native video size 14582 var videoHeight = this.$video[0].videoHeight; 14583 var videoWidth = this.$video[0].videoWidth; 14584 14585 // Get a wrapper size 14586 var wrapperHeight = this.$wrapper.height(); 14587 var wrapperWidth = this.$wrapper.width(); 14588 14589 if (wrapperWidth / videoWidth > wrapperHeight / videoHeight) { 14590 this.$video.css({ 14591 14592 // +2 pixels to prevent an empty space after transformation
14593 width: wrapperWidth + 2, 14594 height: 'auto' 14595 }); 14596 } else { 14597 this.$video.css({ 14598 width: 'auto', 14599 14600 // +2 pixels to prevent an empty space after transformation 14601 height: wrapperHeight + 2 14602 }); 14603 } 14604 }; 14605 14606 /** 14607 * Destroy a video background 14608 * @public 14609 */ 14610 Vide.prototype.destroy = function() { 14611 this.$element.off(PLUGIN_NAME); 14612 14613 if (this.$video) { 14614 this.$video.off(PLUGIN_NAME); 14615 } 14616 14617 delete $[PLUGIN_NAME].lookup[this.index]; 14618 this.$element.removeData(PLUGIN_NAME); 14619 this.$wrapper.remove(); 14620 }; 14621 14622 /** 14623 * Special plugin object for instances. 14624 * @public 14625 * @type {Object} 14626 */ 14627 $[PLUGIN_NAME] = { 14628 lookup: [] 14629 }; 14630 14631 /** 14632 * Plugin constructor 14633 * @param {Object|String} path 14634 * @param {Object|String} options 14635 * @returns {JQuery} 14636 * @constructor 14637 */ 14638 $.fn[PLUGIN_NAME] = function(path, options) { 14639 var instance; 14640 14641 this.each(function() { 14642 instance = $.data(this, PLUGIN_NAME); 14643 14644 if (instance) { 14645 14646 // Destroy the plugin instance if exists 14647 instance.destroy(); 14648 } 14649 14650 // Create the plugin instance 14651 instance = new Vide(this, path, options); 14652 instance.index = $[PLUGIN_NAME].lookup.push(instance) - 1; 14653 $.data(this, PLUGIN_NAME, instance); 14654 }); 14655 14656 return this; 14657 }; 14658 14659 $(document).ready(function() { 14660 var $window = $(window); 14661 14662 // Window resize event listener 14663 $window.on('resize.' + PLUGIN_NAME, function() { 14664 for (var len = $[PLUGIN_NAME].lookup.length, i = 0, instance; i < len; i++) { 14665 instance = $[PLUGIN_NAME].lookup[i]; 14666 14667 if (instance && instance.settings.resizing) { 14668 instance.resize(); 14669 } 14670 } 14671 }); 14672 14673 // https://github.com/VodkaBears/Vide/issues/68 14674 $window.on('unload.' + PLUGIN_NAME, function() { 14675 return false; 14676 }); 14677 14678 // Auto initialization 14679 // Add 'data-vide-bg' attribute with a path to the video without extension 14680 // Also you can pass options throw the 'data-vide-options' attribute 14681 // 'data-vide-options' must be like 'muted: false, volume: 0.5' 14682 $(document).find('[data-' + PLUGIN_NAME + '-bg]').each(function(i, element) { 14683 var $element = $(element); 14684 var options = $element.data(PLUGIN_NAME + '-options'); 14685 var path = $element.data(PLUGIN_NAME + '-bg'); 14686 14687 $element[PLUGIN_NAME](path, options); 14688 }); 14689 }); 14690 14691}); 14692 14693;/*})'"*/ 14694;/*})'"*/ 14695/** 14696 * jquery.flipshow.js v1.0.0 14697 * http://www.codrops.com 14698 * 14699 * Licensed under the MIT license. 14700 * http://www.opensource.org/licenses/mit-license.php 14701 * 14702 * Copyright 2013, Codrops 14703 * http://www.codrops.com 14704 */ 14705;( function( $, window, undefined ) { 14706 14707 'use strict'; 14708 14709 // ======================= imagesLoaded Plugin =============================== 14710 // https://github.com/desandro/imagesloaded 14711 14712 // $('#my-container').imagesLoaded(myFunction) 14713 // execute a callback when all images have loaded. 14714 // needed because .load() doesn't work on cached images 14715 14716 // callback function gets image collection as argument 14717 // this is the container 14718 14719 // original: mit license. paul irish. 2010. 14720 // contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou 14721 14722 // blank image data-uri bypasses webkit log warning (thx doug jones) 14723 // blank image data-uri bypasses webkit log warning (thx doug jones) 14724 var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; 14725 14726 $.fn.imagesLoaded = function( callback ) { 14727 var $this = this, 14728 deferred = $.isFunction($.Deferred) ? $.Deferred() : 0, 14729 hasNotify = $.isFunction(deferred.notify), 14730 $images = $this.find('img').add( $this.filter('img') ), 14731 loaded = [], 14732 proper = [], 14733 broken = []; 14734 14735 // Register deferred callbacks 14736 if ($.isPlainObject(callback)) { 14737 $.each(callback, function (key, value) { 14738 if (key === 'callback') { 14739 callback = value; 14740 } else if (deferred) { 14741 deferred[key](value); 14742 } 14743 }); 14744 } 14745 14746 function doneLoading() { 14747 var $proper = $(proper), 14748 $broken = $(broken); 14749 14750 if ( deferred ) { 14751 if ( broken.length ) { 14752 deferred.reject( $images, $proper, $broken ); 14753 } else { 14754 deferred.resolve( $images ); 14755 } 14756 } 14757 14758 if ( $.isFunction( callback ) ) { 14759 callback.call( $this, $images, $proper, $broken ); 14760 } 14761 } 14762 14763 function imgLoadedHandler( event ) { 14764 imgLoaded( event.target, event.type === 'error' ); 14765 } 14766 14767 function imgLoaded( img, isBroken ) { 14768 // don't proceed if BLANK image, or image is already loaded 14769 if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) { 14770 return; 14771 } 14772 14773 // store element in loaded images array 14774 loaded.push( img ); 14775 14776 // keep track of broken and properly loaded images 14777 if ( isBroken ) { 14778 broken.push( img ); 14779 } else { 14780 proper.push( img ); 14781 } 14782 14783 // cache image and its state for future calls 14784 $.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } ); 14785 14786 // trigger deferred progress method if present 14787 if ( hasNotify ) { 14788 deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] ); 14789 } 14790 14791 // call doneLoading and clean listeners if all images are loaded 14792 if ( $images.length === loaded.length ) { 14793 setTimeout( doneLoading ); 14794 $images.unbind( '.imagesLoaded', imgLoadedHandler ); 14795 } 14796 } 14797 14798 // if no images, trigger immediately 14799 if ( !$images.length ) { 14800 doneLoading(); 14801 } else { 14802 $images.bind( 'load.imagesLoaded error.imagesLoaded', imgLoadedHandler ) 14803 .each( function( i, el ) { 14804 var src = el.src; 14805 14806 // find out if this image has been already checked for status 14807 // if it was, and src has not changed, call imgLoaded on it 14808 var cached = $.data( el, 'imagesLoaded' ); 14809 if ( cached && cached.src === src ) { 14810 imgLoaded( el, cached.isBroken ); 14811 return; 14812 } 14813 14814 // if complete is true and browser supports natural sizes, try 14815 // to check for image status manually
14816 if ( el.complete && el.naturalWidth !== undefined ) { 14817 imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 ); 14818 return; 14819 } 14820 14821 // cached images don't fire load sometimes, so we reset src, but only when 14822 // dealing with IE, or image is complete (loaded) and failed manual check 14823 // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f 14824 if ( el.readyState || el.complete ) { 14825 el.src = BLANK; 14826 el.src = src; 14827 } 14828 }); 14829 } 14830 14831 return deferred ? deferred.promise( $this ) : $this; 14832 }; 14833 14834 // global 14835 var Modernizr = window.Modernizr; 14836 14837 $.Flipshow = function( options, element ) { 14838 this.$el = $( element ); 14839 this._init( options ); 14840 }; 14841 14842 // the options 14843 $.Flipshow.defaults = { 14844 // default transition speed (ms) 14845 speed : 700, 14846 // default transition easing 14847 easing : 'ease-out' 14848 }; 14849 14850 $.Flipshow.prototype = { 14851 _init : function( options ) { 14852 14853 // options 14854 this.options = $.extend( true, {}, $.Flipshow.defaults, options ); 14855 // support for CSS Transitions & 3D transforms 14856 this.support = Modernizr.csstransitions && Modernizr.csstransforms3d && !(/MSIE (\d+\.\d+);/.test(navigator.userAgent)); 14857 // transition end event name and transform name 14858 var transEndEventNames = { 14859 'WebkitTransition' : 'webkitTransitionEnd', 14860 'MozTransition' : 'transitionend', 14861 'OTransition' : 'oTransitionEnd', 14862 'msTransition' : 'MSTransitionEnd', 14863 'transition' : 'transitionend' 14864 }, 14865 transformNames = { 14866 'WebkitTransform' : '-webkit-transform',
14867 'MozTransform' : '-moz-transform', 14868 'OTransform' : '-o-transform', 14869 'msTransform' : '-ms-transform', 14870 'transform' : 'transform' 14871 }; 14872 14873 if( this.support ) { 14874 this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.cbpFWSlider'; 14875 this.transformName = transformNames[ Modernizr.prefixed( 'transform' ) ]; 14876 } 14877 this.transitionProperties = this.transformName + ' ' + this.options.speed + 'ms ' + this.options.easing; 14878 14879 // the list of items 14880 this.$listItems = this.$el.children( 'ul.fc-slides' ); 14881 // the items 14882 this.$items = this.$listItems.children( 'li' ).hide(); 14883 // total number of items 14884 this.itemsCount = this.$items.length; 14885 // current item´s index 14886 this.current = 0; 14887 this.$listItems.imagesLoaded( $.proxy( function() { 14888 // show first item 14889 this.$items.eq( this.current ).show(); 14890 // add navigation and flipping structure 14891 if( this.itemsCount > 0 ) { 14892 this._addNav(); 14893 if( this.support ) { 14894 this._layout(); 14895 } 14896 } 14897 }, this ) ); 14898 14899 }, 14900 _addNav : function() { 14901 14902 var self = this, 14903 $navLeft = $( '<div class="fc-left"><span></span><span></span><span></span><i class="fa fa-arrow-left"></i></div>' ), 14904 $navRight = $( '<div class="fc-right"><span></span><span></span><span></span><i class="fa fa-arrow-right"></i></div>' ); 14905 14906 $( '<nav></nav>' ).append( $navLeft, $navRight ).appendTo( this.$el ); 14907 14908 $navLeft.find( 'span' ).on( 'click.flipshow touchstart.flipshow', function() { 14909 self._navigate( $( this ), 'left' ); 14910 } ); 14911 14912 $navRight.find( 'span' ).on( 'click.flipshow touchstart.flipshow', function() { 14913 self._navigate( $( this ), 'right' ); 14914 } ); 14915 14916 }, 14917 _layout : function( $current, $next ) { 14918 14919 this.$flipFront = $( '<div class="fc-front"><div></div></div>' ); 14920 this.$frontContent = this.$flipFront.children( 'div:first' ); 14921 this.$flipBack = $( '<div class="fc-back"><div></div></div>' ); 14922 this.$backContent = this.$flipBack.children( 'div:first' ); 14923 this.$flipEl = $( '<div class="fc-flip"></div>' ).append( this.$flipFront, this.$flipBack ).hide().appendTo( this.$el ); 14924 14925 }, 14926 _navigate : function( $nav, dir ) { 14927 14928 if( this.isAnimating && this.support ) { 14929 return false; 14930 } 14931 this.isAnimating = true; 14932 14933 var $currentItem = this.$items.eq( this.current ).hide(); 14934 14935 if( dir === 'right' ) { 14936 this.current < this.itemsCount - 1 ? ++this.current : this.current = 0; 14937 } 14938 else if( dir === 'left' ) { 14939 this.current > 0 ? --this.current : this.current = this.itemsCount - 1; 14940 } 14941 14942 var $nextItem = this.$items.eq( this.current ); 14943 14944 if( this.support ) { 14945 this._flip( $currentItem, $nextItem, dir, $nav.index() ); 14946 } 14947 else { 14948 $nextItem.show(); 14949 } 14950 14951 }, 14952 _flip : function( $currentItem, $nextItem, dir, angle ) { 14953 14954 var transformProperties = '', 14955 // overlays 14956 $overlayLight = $( '<div class="fc-overlay-light"></div>' ), 14957 $overlayDark = $( '<div class="fc-overlay-dark"></div>' ); 14958 14959 this.$flipEl.css( 'transition', this.transitionProperties ); 14960 14961 this.$flipFront.find( 'div.fc-overlay-light, div.fc-overlay-dark' ).remove(); 14962 this.$flipBack.find( 'div.fc-overlay-light, div.fc-overlay-dark' ).remove(); 14963 14964 if( dir === 'right' ) { 14965 this.$flipFront.append( $overlayLight ); 14966 this.$flipBack.append( $overlayDark ); 14967 $overlayDark.css( 'opacity', 1 ); 14968 } 14969 else if( dir === 'left' ) { 14970 this.$flipFront.append( $overlayDark ); 14971 this.$flipBack.append( $overlayLight ); 14972 $overlayLight.css( 'opacity', 1 ); 14973 } 14974 var overlayStyle = { transition : 'opacity ' + ( this.options.speed / 1.3 ) + 'ms' }; 14975 $overlayLight.css( overlayStyle ); 14976 $overlayDark.css( overlayStyle ); 14977 14978 switch( angle ) { 14979 case 0 : 14980 transformProperties = dir === 'left' ? 'rotate3d(-1,1,0,-179deg) rotate3d(-1,1,0,-1deg)' : 'rotate3d(1,1,0,180deg)'; 14981 break; 14982 case 1 : 14983 transformProperties = dir === 'left' ? 'rotate3d(0,1,0,-179deg) rotate3d(0,1,0,-1deg)' : 'rotate3d(0,1,0,180deg)'; 14984 break; 14985 case 2 : 14986 transformProperties = dir === 'left' ? 'rotate3d(1,1,0,-179deg) rotate3d(1,1,0,-1deg)' : 'rotate3d(-1,1,0,179deg) rotate3d(-1,1,0,1deg)'; 14987 break; 14988 } 14989 14990 this.$flipBack.css( 'transform', transformProperties ); 14991 14992 this.$frontContent.empty().html( $currentItem.html() ); 14993 this.$backContent.empty().html( $nextItem.html() ); 14994 this.$flipEl.show(); 14995 14996 var self = this; 14997 setTimeout( function() { 14998 14999 self.$flipEl.css( 'transform', transformProperties ); 15000 $overlayLight.css( 'opacity', dir === 'right' ? 1 : 0 ); 15001 $overlayDark.css( 'opacity', dir === 'right' ? 0 : 1 ); 15002 self.$flipEl.on( self.transEndEventName, function( event ) { 15003 if( event.target.className === 'fc-overlay-light' || event.target.className === 'fc-overlay-dark' ) return; 15004 self._ontransitionend( $nextItem ); 15005 } ); 15006 15007 }, 25 ); 15008 15009 }, 15010 _ontransitionend : function( $nextItem ) { 15011 $nextItem.show(); 15012 this.$flipEl.off( this.transEndEventName ).css( {
15013 transition : 'none', 15014 transform : 'none' 15015 } ).hide(); 15016 this.isAnimating = false; 15017 } 15018 }; 15019 15020 var logError = function( message ) { 15021 if ( window.console ) { 15022 window.console.error( message ); 15023 } 15024 }; 15025 15026 $.fn.flipshow = function( options ) { 15027 if ( typeof options === 'string' ) { 15028 var args = Array.prototype.slice.call( arguments, 1 ); 15029 this.each(function() { 15030 var instance = $.data( this, 'flipshow' ); 15031 if ( !instance ) { 15032 logError( "cannot call methods on flipshow prior to initialization; " + 15033 "attempted to call method '" + options + "'" ); 15034 return; 15035 } 15036 if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) { 15037 logError( "no such method '" + options + "' for flipshow instance" ); 15038 return; 15039 } 15040 instance[ options ].apply( instance, args ); 15041 }); 15042 } 15043 else { 15044 this.each(function() { 15045 var instance = $.data( this, 'flipshow' ); 15046 if ( instance ) { 15047 instance._init(); 15048 } 15049 else { 15050 instance = $.data( this, 'flipshow', new $.Flipshow( options, this ) ); 15051 } 15052 }); 15053 } 15054 return this; 15055 }; 15056 15057} )( jQuery, window ); 15058;/*})'"*/ 15059;/*})'"*/ 15060jQuery(document).ready(function ($) { 15061 Drupal.TBMegaMenu = Drupal.TBMegaMenu || {}; 15062 15063 // 15064 // Modified not to use the default touch processing when mobile menu is shown. 15065 // 15066 var items = $('.tb-megamenu ul.nav li.mega').has('.dropdown-menu'); 15067 items.children('a').each( function() { 15068 var $item = $(this); 15069 $item.click( function(event) { 15070 if (Drupal.TBMegaMenu.displayedMenuMobile) { 15071 if ($(event.target).is('i.fa.fa-caret-down')) { 15072 $item.removeClass('tb-megamenu-clicked'); 15073 } else { 15074 var $uri = $item.attr('href'); 15075 window.location.href = $uri; 15076 } 15077 } 15078 }); 15079 }); 15080 15081 15082 // 15083 // Sticky Scrolling Sidenav 15084 // 15085 15086 // Activate Sidebar Affix 15087 $('#sidenav-scrolling-affix').affix({ 15088 offset: { 15089 top: function () { 15090 return ($('#content-col').offset().top) 15091 }, 15092 bottom: function () { 15093 return (this.bottom = $('#footer').outerHeight(true)) 15094 } 15095 } 15096 }); 15097 15098 // Activate Scrollspy 15099 $('body.page-node-5173').scrollspy({ 15100 target: '#sidenav-scrolling', 15101 offset: 120 15102 }); 15103 15104 // Activate Sidebar Affix 15105 $('.product-scrolling-affix').affix({ 15106 offset: { 15107 top: function () { 15108 return ($('#block-system-main').offset().top) 15109 }, 15110 bottom: function () { 15111 return (this.bottom = $('#footer').outerHeight(true) + 250) 15112 } 15113 } 15114 }); 15115 15116 // Activate Horizontal tabs Affix 15117 $('#product-htabs-affix').affix({ 15118 offset: { 15119 top: function () { 15120 return ($('#block-system-main').offset().top) 15121 }, 15122 bottom: function () { 15123 return (this.bottom = $('#footer').outerHeight(true) + $('.product-scrolling-affix ul').outerHeight(true) + 290) 15124 } 15125 } 15126 }); 15127 15128 // Activate Scrollspy 15129 $('body.node-type-ssis').scrollspy({ 15130 target: '.product-scrolling', 15131 offset: 140 15132 }); 15133 15134 // Smooth scrolling sections 15135 $('a.smooth-scroll').click(function() { 15136 if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { 15137 var target = $(this.hash); 15138 target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); 15139 if (target.length) { 15140 var tabNav = $('#product-htabs-affix'); 15141 var ajustment = 47; // compensates margin-top removal 15142 if (tabNav.length) { 15143 ajustment += 68; 15144 if (tabNav.hasClass('affix-top')) { 15145 ajustment += tabNav.height() 15146 } 15147 } 15148 $('html,body').animate({ 15149 scrollTop: target.offset().top - ajustment 15150 }, 750); 15151 return false; 15152 } 15153 } 15154 }); 15155 15156 $('#product-htabs-affix li a').click(function() { 15157 $('html,body').animate({ 15158 scrollTop: 29 15159 }, 'fast'); 15160 }); 15161 15162 15163}); 15164;/*})'"*/ 15165;/*})'"*/
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.