1(()=>{(function(){var Scroller,stats,type,text,totop,loading_text,isIE=-1!==navigator.userAgent.search("MSIE");if(isIE){var IEVersion=navigator.userAgent.match(/MSIE\s?(\d+)\.?\d*;/);IEVersion=parseInt(IEVersion[1])}function fullscreenState(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement?1:0}"https:"===document.location.protocol&&(infiniteScroll.settings.ajaxurl=infiniteScroll.settings.ajaxurl.replace("http://","https://")),Scroller=function(e){var t=this;this.id=e.id,this.body=document.body,this.window=window,this.element=document.getElementById(e.id),this.wrapperClass=e.wrapper_class,this.ready=!0,this.disabled=!1,this.page=1,this.offset=e.offset,this.currentday=e.currentday,this.order=e.order,this.throttle=!1,this.click_handle=e.click_handle,this.google_analytics=e.google_analytics,this.history=e.history,this.origURL=window.location.href,this.handle=document.createElement("div"),this.handle.setAttribute("id","infinite-handle");var n=document.createElement("span"),i=document.createElement("button");i.textContent=text,n.appendChild(i),this.handle.appendChild(n),this.footer={el:document.getElementById("infinite-footer"),wrap:e.footer},this.checkViewportOnLoadBound=t.checkViewportOnLoad.bind(this),this.wpMediaelement=null,"scroll"===type?(this.window.addEventListener("scroll",function(){t.throttle=!0}),t.gotop(),setInterval(function(){t.throttle&&(t.throttle=!1,t.thefooter(),t.refresh(),t.determineURL())},250),t.ensureFilledViewport(),this.body.addEventListener("is.post-load",t.checkViewportOnLoadBound)):"click"===type&&(this.click_handle&&this.element.appendChild(this.handle),this.handle.addEventListener("click",function(){t.click_handle&&t.handle.parentNode.removeChild(t.handle),t.refresh()})),this.body.addEventListener("is.post-load",t.initializeMejs)},Scroller.prototype.getScrollTop=function(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},Scroller.prototype.extend=function(e){e=e||{};for(var t=1;t<arguments.length;t++)if(arguments[t])for(var n in arguments[t])Object.hasOwn(arguments[t],n)&&(e[n]=arguments[t][n]);return e},Scroller.prototype.check=function(){return this.measure(this.element,[this.wrapperClass]).bottom<2*this.window.innerHeight},Scroller.prototype.render=function(e){var t=Array.prototype.slice.call(e.fragment.childNodes);for(this.body.classList.add("infinity-success");t.length>0;){var n=t.shift();this.element.appendChild(n)}this.trigger(this.body,"is.post-load",{jqueryEventName:"post-load",data:e}),this.ready=!0},Scroller.prototype.query=function(){return{page:this.page+this.offset,currentday:this.currentday,order:this.order,scripts:window.infiniteScroll.settings.scripts,styles:window.infiniteScroll.settings.styles,query_args:window.infiniteScroll.settings.query_args,query_before:window.infiniteScroll.settings.query_before,last_post_date:window.infiniteScroll.settings.last_post_date}},Scroller.prototype.animate=function(e,t){var n=performance.now();requestAnimationFrame(function i(o){var r=Math.min(1,(o-n)/t);e(r),r<1&&requestAnimationFrame(i)})},Scroller.prototype.gotop=function(){var e=document.getElementById("infinity-blog-title"),t=this;e&&(e.setAttribute("title",totop),e.addEventListener("click",function(e){var n=t.window.pageYOffset;e.preventDefault(),t.animate(function(e){var t=n-n*e;document.documentElement.scrollTop=document.body.scrollTop=t},200)}))},Scroller.prototype.thefooter=function(){var e,t,n,i,o=this;if(this.footer&&this.footer.el){if("string"==typeof this.footer.wrap){try{t=(t=document.getElementById(this.footer.wrap).getBoundingClientRect()).width}catch{t=0}t>479&&(e=this.footer.el.querySelector(".container"))&&(e.style.width=t+"px")}n=parseInt(o.footer.el.style.bottom||-50,10),i=this.window.pageYOffset>=350?0:-50,n!==i&&o.animate(function(e){var t=n+(i-n)*e;o.footer.el.style.bottom=t+"px",1===e&&(n=i)},200)}},Scroller.prototype.urlEncodeJSON=function(e,t){var n,i,o=[];for(var r in e)n=encodeURIComponent(r),i=t?t+"["+n+"]":n,"object"==typeof e[r]?!Array.isArray(e[r])||e[r].length>0?o.push(this.urlEncodeJSON(e[r],i)):o.push(i+"[]="):o.push(i+"="+encodeURIComponent(e[r]));return o.join("&")},Scroller.prototype.refresh=function(){var self=this,query,xhr,loader,customized;if(!this.disabled&&this.ready&&this.check())return this.ready=!1,this.click_handle&&(loader||(document.getElementById("infinite-aria").textContent=loading_text,loader=document.createElement("div"),loader.classList.add("infinite-loader"),loader.setAttribute("role","progress"),loader.innerHTML='<svg class="jetpack-spinner infinite-loader-spinner spinner" width="28" height="28" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><circle cx="50" cy="50" r="46" fill="none" stroke="#ddd" stroke-width="8"/><path d="M 50 4 A 46 46 0 0 1 96 50" fill="none" stroke="currentColor" stroke-width="8" stroke-linecap="round"><animateTransform attributeName="transform" type="rotate" dur="1.4s" from="0 50 50" to="360 50 50" repeatCount="indef
1inite"/></path></svg>'),this.element.appendChild(loader)),query=self.extend({action:"infinite_scroll"},this.query()),"undefined"!=typeof wp&&wp.customize&&wp.customize.settings.theme&&(customized={},query.wp_customize="on",query.theme=wp.customize.settings.theme.stylesheet,wp.customize.each(function(e){e._dirty&&(customized[e.id]=e())}),query.customized=JSON.stringify(customized),query.nonce=wp.customize.settings.nonce.preview),xhr=new XMLHttpRequest,xhr.open("POST",infiniteScroll.settings.ajaxurl,!0),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),xhr.send(self.urlEncodeJSON(query)),xhr.onerror=function(){self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader),self.ready=!0},xhr.onload=function(){var response=JSON.parse(xhr.responseText),httpCheck=xhr.status>=200&&xhr.status<300,responseCheck=void 0!==response.html;if(response&&httpCheck&&responseCheck){if(self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader),response.scripts&&Array.isArray(response.scripts)&&response.scripts.forEach(function(e){var t=e.footer?"body":"head";window.infiniteScroll.settings.scripts.push(e.handle),e.extra_data&&self.appendInlineScript(e.extra_data,t),e.before_handle&&self.appendInlineScript(e.before_handle,t);var n=document.createElement("script");n.type="text/javascript",n.src=e.src,n.id=e.handle,n.async=!1,e.after_handle&&(n.onload=function(){self.appendInlineScript(e.after_handle,t)}),"wp-mediaelement"===e.handle&&self.body.removeEventListener("is.post-load",self.initializeMejs),"wp-mediaelement"===e.handle&&"undefined"==typeof mejs?(self.wpMediaelement={},self.wpMediaelement.tag=n,self.wpMediaelement.element=t,setTimeout(self.maybeLoadMejs.bind(self),250)):document.getElementsByTagName(t)[0].appendChild(n)}),response.styles&&Array.isArray(response.styles)&&response.styles.forEach(function(item){window.infiniteScroll.settings.styles.push(item.handle);var style=document.createElement("link");style.rel="stylesheet",style.href=item.src,style.id=item.handle+"-css",!item.conditional||isIE&&eval(item.conditional.replace(/%ver/g,IEVersion))||(style=!1),style&&document.getElementsByTagName("head")[0].appendChild(style)}),response.fragment=document.createElement("div"),response.fragment.innerHTML=response.html,self.page++,stats&&((new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?"+stats+"&post=0&baba="+Math.random()),"object"==typeof response.postflair&&"object"==typeof WPCOM_sharing_counts&&(WPCOM_sharing_counts=self.extend(WPCOM_sharing_counts,response.postflair)),self.render.call(self,response),"click"===type?(infiniteScroll.settings.wrapper&&document.querySelector("#infinite-view-"+(self.page+self.offset-1)+" a:first-of-type").focus({preventScroll:!0}),response.lastbatch?self.click_handle?(self.body.classList.add("infinity-end"),self.body.classList.remove("infinity-success")):self.trigger(this.body,"infinite-scroll-posts-end"):self.click_handle?self.element.appendChild(self.handle):self.trigger(this.body,"infinite-scroll-posts-more")):response.lastbatch&&(self.disabled=!0,self.body.classList.add("infinity-end"),self.body.classList.remove("infinity-success")),response.currentday&&(self.currentday=response.currentday),self.google_analytics){var ga_url=self.history.path.replace(/%d/,self.page);"object"==typeof _gaq&&_gaq.push(["_trackPageview",ga_url]),"function"==typeof ga&&ga("send","pageview",ga_url)}}else self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader)},xhr},Scroller.prototype.appendInlineScript=function(e,t){var n=document.createElement("script"),i=document.createTextNode("//<![CDATA[ \n"+e+"\n//]]>");n.type="text/javascript",n.appendChild(i),document.getElementsByTagName(t)[0].appendChild(n)},Scroller.prototype.maybeLoadMejs=function(){null!==this.wpMediaelement&&("undefined"==typeof mejs?setTimeout(this.maybeLoadMejs.bind(this),250):(document.getElementsByTagName(this.wpMediaelement.element)[0].appendChild(this.wpMediaelement.tag),this.wpMediaelement=null,this.body.addEventListener("is.post-load",this.initializeMejs)))},Scroller.prototype.initializeMejs=function(e){if(e.detail&&e.detail.html&&(-1!==e.detail.html.indexOf("wp-audio-shortcode")||-1!==e.detail.html.indexOf("wp-video-shortcode"))&&"undefined"!=typeof mejs){var t,n={};"undefined"!=typeof _wpmejsSettings&&(n.pluginPath=_wpmejsSettings.pluginPath),n.success=function(e){var t=e.attributes.autoplay&&"false"!==e.attributes.autoplay;"flash"===e.pluginType&&t&&e.addEventListener("canplay",function(){e.play()},!1)},t=document.querySelectorAll(".wp-audio-shortcode, .wp-video-shortcode"),t=(t=Array.prototype.slice.call(t)).filter(function(e){for(;e.parentNode;){if(e.classList.contains("mejs-container"))return!1;e=e.parentNode}return!0});for(var i=0;i<t.length;i++)new MediaElementPlayer(t[i],n)}},Scroller.prototype.measure=function(e,t){t=t||[];for(var n,i,o,r=Array.prototype.slice.call(e.children),s=Number.MAX_VALUE,l=0;r.length>0;){for(n=r.shift(),o=0;o<t.length;o++)if(n.classList.contains(t[o])){r=r.concat(Array.prototype.slice.call(n.children));break}i=n.getBoundingClientRect(),s=Math.min(s,i.top),l=Math.max(l,i.bottom)}var a=Math.round(window.innerHeight/2),d=s<=a&&l>=a;return{top:s,bottom:l,height:l-s,factor:(Math.min(l,a)-Math.max(s,0))/a,isActive:d}},Scroller.prototype.ensureFilledViewport=function(){var e=this,t=e.window.innerHeight,n=e.measure(e.element,[e.wrapperClass]);e.body.removeEventListener("is.post-load",e.checkViewportOnLoadBound),0!==n.bottom&&n.bottom<t&&(e.ready=!0,e.refresh())},Scroller.prototype.checkViewportOnLoad=function(){this.ensureFilledViewport()};var previousFullScrenState=fullscreenState();Scroller.prototype.determineURL=function(){var e,t=this,n=-1,i=fullscreenState(),o=0;if(previousFullScrenState^i)previousFullScrenState=i;else{previousFullScrenState=i,e=document.querySelectorAll("."+t.wrapperClass);for(var r=0;r<e.length;r++){var s=t.measure(e[r]);if(s.isActive){n=parseInt(e[r].dataset.pageNum,10);break}s.factor>o&&(n=parseInt(e[r].dataset.pageNum,10),o=s.factor)}t.updateURL(n)}},Scroller.prototype.updateURL=function(e){if(window.history.pushState){var t=this,n=t.origURL;-1!==e&&(n=window.location.protocol+"//"+t.history.host+t.history.path.replace(/%d/,e)+t.history.parameters),window.location.href!==n&&history.pushState(null,null,n)}},Scroller.prototype.pause=function(){this.disabled=!0},Scroller.prototype.resume=function(){this.disabled=!1},Scroller.prototype.trigger=function(e,t,n){var i;(n=n||{}).jqueryEventName&&"undefined"!=typeof jQuery&&jQuery(e).trigger(n.jqueryEventName,n.data||null);try{i=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n.data||null})}catch{(i=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,n.data||null)}e.dispatchEvent(i)};var jetpackInfinityModule=function(){if("object"==typeof infiniteScroll&&(infiniteScroll.
1settings.body_class.split(" ").forEach(function(e){e&&document.body.classList.add(e)}),stats=infiniteScroll.settings.stats,type=infiniteScroll.settings.type,text=infiniteScroll.settings.text,totop=infiniteScroll.settings.totop,loading_text=infiniteScroll.settings.loading_text,infiniteScroll.scroller=new Scroller(infiniteScroll.settings),"click"===type)){var e=null;window.addEventListener("scroll",function(){e||(e=setTimeout(function(){infiniteScroll.scroller.determineURL(),e=null},250))})}};"interactive"===document.readyState||"complete"===document.readyState?jetpackInfinityModule():document.addEventListener("DOMContentLoaded",jetpackInfinityModule)})()})();; 2!function(e){var o={};function n(t){if(o[t])return o[t].exports;var r=o[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:t})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,o){if(1&o&&(e=n(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var r in e)n.d(t,r,function(o){return e[o]}.bind(null,r));return t},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},n.p="",n(n.s=273)}({273:function(e,o){!function(){"use strict";let e,o;function n(e){return new Promise((o,n)=>{const t=document.createElement("script");t.onload=()=>o(),t.onerror=e=>n(e),t.src=e,document.body.appendChild(t)})}function t(){if(e)return e;const o=window.wpcom_coblocks_js;return e=n(o.coblocks_lightbox_js),e}function r(){if(o)return o;window.wpcomJQueryUsageLoggerDisabled=!0;const e=window.wpcom_coblocks_js,t=window.jQuery?Promise.resolve():n(e.jquery_core_js).then(()=>n(e.jquery_migrate_js)),r=t.then(()=>window.imagesLoaded?Promise.resolve():n(e.imagesloaded_js)),c=t.then(()=>window.Masonry?Promise.resolve():n(e.masonry_js)),u=Promise.all([t,r,c]).then(()=>n(e.coblocks_masonry_js));return o=u,o}function c(){document.querySelector(".wp-block-coblocks-gallery-masonry")&&r(),document.querySelector(".has-lightbox")&&t(),document.body.classList.contains("block-editor-page")&&(r(),t())}"loading"!==document.readyState?c():document.addEventListener("DOMContentLoaded",c)}()}});; 3/*! 4 * imagesLoaded PACKAGED v3.1.8 5 * JavaScript is all like "You images are done yet or what?" 6 * MIT License 7 */ 8 9 10/*! 11 * EventEmitter v4.2.6 - git.io/ee 12 * Oliver Caldwell 13 * MIT license 14 * @preserve 15 */ 16 17(function () { 18 19 20 /** 21 * Class for managing events. 22 * Can be extended to provide event functionality in other classes. 23 * 24 * @class EventEmitter Manages event registering and emitting. 25 */ 26 function EventEmitter() {} 27 28 // Shortcuts to improve speed and size 29 var proto = EventEmitter.prototype; 30 var exports = this; 31 var originalGlobalValue = exports.EventEmitter; 32 33 /** 34 * Finds the index of the listener for the event in it's storage array. 35 * 36 * @param {Function[]} listeners Array of listeners to search through. 37 * @param {Function} listener Method to look for. 38 * @return {Number} Index of the specified listener, -1 if not found 39 * @api private 40 */ 41 function indexOfListener(listeners, listener) { 42 var i = listeners.length; 43 while (i--) { 44 if (listeners[i].listener === listener) { 45 return i; 46 } 47 } 48 49 return -1; 50 } 51 52 /** 53 * Alias a method while keeping the context correct, to allow for overwriting of target method. 54 * 55 * @param {String} name The name of the target method. 56 * @return {Function} The aliased method 57 * @api private 58 */ 59 function alias(name) { 60 return function aliasClosure() { 61 return this[name].apply(this, arguments); 62 }; 63 } 64 65 /** 66 * Returns the listener array for the specified event. 67 * Will initialise the event object and listener arrays if required. 68 * Will return an object if you use a regex search. The object c
68ontains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. 69 * Each property in the object response is an array of listener functions. 70 * 71 * @param {String|RegExp} evt Name of the event to return the listeners from. 72 * @return {Function[]|Object} All listener functions for the event. 73 */ 74 proto.getListeners = function getListeners(evt) { 75 var events = this._getEvents(); 76 var response; 77 var key; 78 79 // Return a concatenated array of all matching events if 80 // the selector is a regular expression. 81 if (typeof evt === 'object') { 82 response = {}; 83 for (key in events) { 84 if (events.hasOwnProperty(key) && evt.test(key)) { 85 response[key] = events[key]; 86 } 87 } 88 } 89 else { 90 response = events[evt] || (events[evt] = []); 91 } 92 93 return response; 94 }; 95 96 /** 97 * Takes a list of listener objects and flattens it into a list of listener functions. 98 * 99 * @param {Object[]} listeners Raw listener objects. 100 * @return {Function[]} Just the listener functions. 101 */ 102 proto.flattenListeners = function flattenListeners(listeners) { 103 var flatListeners = []; 104 var i; 105 106 for (i = 0; i < listeners.length; i += 1) { 107 flatListeners.push(listeners[i].listener); 108 } 109 110 return flatListeners; 111 }; 112 113 /** 114 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. 115 * 116 * @param {String|RegExp} evt Name of the event to return the listeners from. 117 * @return {Object} All listener functions for an event in an object. 118 */ 119 proto.getListenersAsObject = function getListenersAsObject(evt) { 120 var listeners = this.getListeners(evt); 121 var response; 122 123 if (listeners instanceof Array) { 124 response = {}; 125 response[evt] = listeners; 126 } 127 128 return response || listeners; 129 }; 130 131 /** 132 * Adds a listener function to the specified event. 133 * The listener will not be added if it is a duplicate. 134 * If the listener returns true then it will be removed after it is called. 135 * If you pass a regular expression as the event name then the listener will be added to all events that match it. 136 * 137 * @param {String|RegExp} evt Name of the event to attach the listener to. 138 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 139 * @return {Object} Current instance of EventEmitter for chaining. 140 */ 141 proto.addListener = function addListener(evt, listener) { 142 var listeners = this.getListenersAsObject(evt); 143 var listenerIsWrapped = typeof listener === 'object'; 144 var key; 145 146 for (key in listeners) { 147 if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { 148 listeners[key].push(listenerIsWrapped ? listener : { 149 listener: listener, 150 once: false 151 }); 152 } 153 } 154 155 return this; 156 }; 157 158 /** 159 * Alias of addListener 160 */ 161 proto.on = alias('addListener'); 162 163 /** 164 * Semi-alias of addListener. It will add a listener that will be 165 * automatically removed after it's first execution. 166 * 167 * @param {String|RegExp} evt Name of the event to attach the listener to. 168 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 169 * @return {Object} Current instance of EventEmitter for chaining. 170 */ 171 proto.addOnceListener = function addOnceListener(evt, listener) { 172 return this.addListener(evt, { 173 listener: listener, 174 once: true 175 }); 176 }; 177 178 /** 179 * Alias of addOnceListener. 180 */ 181 proto.once = alias('addOnceListener'); 182 183 /** 184 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. 185 * You need to tell it what event names should be matched by a regex. 186 * 187 * @param {String} evt Name of the event to create. 188 * @return {Object} Current instance of EventEmitter for chaining. 189 */ 190 proto.defineEvent = function defineEvent(evt) { 191 this.getListeners(evt); 192 return this; 193 }; 194 195 /** 196 * Uses defineEvent to define multiple events. 197 * 198 * @param {String[]} evts An array of event names to define. 199 * @return {Object} Current instance of EventEmitter for chaining. 200 */ 201 proto.defineEvents = function defineEvents(evts) { 202 for (var i = 0; i < evts.length; i += 1) { 203 this.defineEvent(evts[i]); 204 } 205 return this; 206 }; 207 208 /** 209 * Removes a listener function from the specified event. 210 * When passed a regular expression as the event name, it will remove the listener from all events that match it. 211 * 212 * @param {String|RegExp} evt Name of the event to remove the listener from. 213 * @param {Function} listener Method to remove from the event. 214 * @return {Object} Current instance of EventEmitter for chaining. 215 */ 216 proto.removeListener = function removeListener(evt, listener) { 217 var listeners = this.getListenersAsObject(evt); 218 var index; 219 var key; 220 221 for (key in listeners) { 222 if (listeners.hasOwnProperty(key)) { 223 index = indexOfListener(listeners[key], listener); 224 225 if (index !== -1) { 226 listeners[key].splice(index, 1); 227 } 228 } 229 } 230 231 return this; 232 }; 233 234 /** 235 * Alias of removeListener 236 */ 237 proto.off = alias('removeListener'); 238 239 /** 240 * Adds listeners in bulk using the manipulateListeners method. 241 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. 242 * You can also pass it a regular expression to add the array of listeners to all events that match it. 243 * Yeah, this function does quite a bit. That's probably a bad thing. 244 * 245 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. 246 * @param {Function[]} [listeners] An optional array of listener functions to add. 247 * @return {Object} Current instance of EventEmitter for chaining. 248 */ 249 proto.addListeners = function addListeners(evt, listeners) { 250 // Pass through to manipulateListeners 251 return this.manipulateListeners(false, evt, listeners); 252 }; 253 254 /** 255 * Removes listeners in bulk using the manipulateListeners method. 256 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 257 * You can also pass it an event name and an array of listeners to be removed. 258 * You can also pass it a regular expression to remove the listeners from all events that match it. 259 * 260 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. 261 * @param {Function[]} [listeners] An optional array of listener functions to remove. 262 * @return {Object} Current instance of EventEmitter for chaining. 263 */ 264 proto.removeListeners = function removeListeners(evt, listeners) { 265 // Pass through to manipulateListeners 266 return this.manipulateListeners(true, evt, listeners); 267 }; 268 269 /** 270 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. 271 * The first argument will determine if the listeners are removed (true) or added (false). 272 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 273 * You can also pass it an event name and an array of listeners to be added/removed. 274 * You can also pass it a regular expression to manipulate the listeners of all events that match it. 275 * 276 * @param {Boolean} remove True if you want to remove listeners, false if you want to add. 277 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. 278 * @param {Function[]} [listeners] An optional array of listener functions to add/remove. 279 * @return {Object} Current instance of EventEmitter for chaining. 280 */ 281 proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { 282 var i; 283 var value; 284 var single = remove ? this.removeListener : this.addListener; 285 var multiple = remove ? this.removeListeners : this.addListeners; 286 287 // If evt is an object then pass each of it's properties to this method 288 if (typeof evt === 'object' && !(evt instanceof RegExp)) { 289 for (i in evt) { 290 if (evt.hasOwnProperty(i) && (value = evt[i])) { 291 // Pass the single listener straight through to the singular method 292 if (typeof value === 'function') { 293 single.call(this, i, value); 294 } 295 else { 296 // Otherwise pass back to the multiple function 297 multiple.call(this, i, value); 298 } 299 } 300 } 301 } 302 else { 303 // So evt must be a string 304 // And listeners must be an array of listeners 305 // Loop over it and pass each one to the multiple method 306 i = listeners.length; 307 while (i--) { 308 single.call(this, evt, listeners[i]); 309 } 310 } 311 312 return this; 313 }; 314 315 /** 316 * Removes all listeners from a specified event. 317 * If you do not specify an event then all listeners will be removed. 318 * That means every event will be emptied. 319 * You can also pass a regex to remove all events that match it. 320 * 321 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. 322 * @return {Object} Current instance of EventEmitter for chaining. 323 */ 324 proto.removeEvent = function removeEvent(evt) { 325 var type = typeof evt; 326 var events = this._getEvents(); 327 var key; 328 329 // Remove different things depending on the state of evt 330 if (type === 'string') { 331 // Remove all listeners for the specified event 332 delete events[evt]; 333 } 334 else if (type === 'object') { 335 // Remove all events matching the regex. 336 for (key in events) { 337 if (events.hasOwnProperty(key) && evt.test(key)) { 338 delete events[key]; 339 } 340 } 341 } 342 else { 343 // Remove all listeners in all events 344 delete this._events; 345 } 346 347 return this; 348 }; 349 350 /** 351 * Alias of removeEvent. 352 * 353 * Added to mirror the node API. 354 */ 355 proto.removeAllListeners = alias('removeEvent'); 356 357 /** 358 * Emits an event of your choice. 359 * When emitted, every listener attached to that event will be executed. 360 * If you pass the optional argument array then those arguments will be passed to every listener upon execution. 361 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
362 * So they will not arrive within the array on the other side, they will be separate. 363 * You can also pass a regular expression to emit to all events that match it. 364 * 365 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 366 * @param {Array} [args] Optional array of arguments to be passed to each listener. 367 * @return {Object} Current instance of EventEmitter for chaining. 368 */ 369 proto.emitEvent = function emitEvent(evt, args) { 370 var listeners = this.getListenersAsObject(evt); 371 var listener; 372 var i; 373 var key; 374 var response; 375 376 for (key in listeners) { 377 if (listeners.hasOwnProperty(key)) { 378 i = listeners[key].length; 379 380 while (i--) { 381 // If the listener returns true then it shall be removed from the event 382 // The function is executed either with a basic call or an apply if there is an args array 383 listener = listeners[key][i]; 384 385 if (listener.once === true) { 386 this.removeListener(evt, listener.listener); 387 } 388 389 response = listener.listener.apply(this, args || []); 390 391 if (response === this._getOnceReturnValue()) { 392 this.removeListener(evt, listener.listener); 393 } 394 } 395 } 396 } 397 398 return this; 399 }; 400 401 /** 402 * Alias of emitEvent 403 */ 404 proto.trigger = alias('emitEvent'); 405 406 /** 407 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. 408 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. 409 * 410 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 411 * @param {...*} Optional additional arguments to be passed to each listener. 412 * @return {Object} Current instance of EventEmitter for chaining. 413 */ 414 proto.emit = function emit(evt) { 415 var args = Array.prototype.slice.call(arguments, 1); 416 return this.emitEvent(evt, args); 417 }; 418 419 /** 420 * Sets the current value to check against when executing listeners. If a 421 * listeners return value matches the one set here then it will be removed 422 * after execution. This value defaults to true. 423 * 424 * @param {*} value The new value to check for when executing listeners. 425 * @return {Object} Current instance of EventEmitter for chaining. 426 */ 427 proto.setOnceReturnValue = function setOnceReturnValue(value) { 428 this._onceReturnValue = value; 429 return this; 430 }; 431 432 /** 433 * Fetches the current value to check against when executing listeners. If 434 * the listeners return value matches this one then it should be removed 435 * automatically. It will return true by default. 436 * 437 * @return {*|Boolean} The current value to check for or the default, true. 438 * @api private 439 */ 440 proto._getOnceReturnValue = function _getOnceReturnValue() { 441 if (this.hasOwnProperty('_onceReturnValue')) { 442 return this._onceReturnValue; 443 } 444 else { 445 return true; 446 } 447 }; 448 449 /** 450 * Fetches the events object and creates one if required. 451 * 452 * @return {Object} The events storage object. 453 * @api private 454 */ 455 proto._getEvents = function _getEvents() { 456 return this._events || (this._events = {}); 457 }; 458 459 /** 460 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. 461 * 462 * @return {Function} Non conflicting EventEmitter class. 463 */ 464 EventEmitter.noConflict = function noConflict() { 465 exports.EventEmitter = originalGlobalValue; 466 return EventEmitter; 467 }; 468 469 // Expose the class either via AMD, CommonJS or the global object 470 if (typeof define === 'function' && define.amd) { 471 define('eventEmitter/EventEmitter',[],function () { 472 return EventEmitter; 473 }); 474 } 475 else if (typeof module === 'object' && module.exports){ 476 module.exports = EventEmitter; 477 } 478 else { 479 this.EventEmitter = EventEmitter; 480 } 481}.call(this)); 482 483/*! 484 * eventie v1.0.4 485 * event binding helper 486 * eventie.bind( elem, 'click', myFn ) 487 * eventie.unbind( elem, 'click', myFn ) 488 */ 489 490/*jshint browser: true, undef: true, unused: true */ 491/*global define: false */ 492 493( function( window ) { 494 495 496 497var docElem = document.documentElement; 498 499var bind = function() {}; 500 501function getIEEvent( obj ) { 502 var event = window.event; 503 // add event.target 504 event.target = event.target || event.srcElement || obj; 505 return event; 506} 507 508if ( docElem.addEventListener ) { 509 bind = function( obj, type, fn ) { 510 obj.addEventListener( type, fn, false ); 511 }; 512} else if ( docElem.attachEvent ) { 513 bind = function( obj, type, fn ) { 514 obj[ type + fn ] = fn.handleEvent ? 515 function() { 516 var event = getIEEvent( obj ); 517 fn.handleEvent.call( fn, event ); 518 } : 519 function() { 520 var event = getIEEvent( obj ); 521 fn.call( obj, event ); 522 }; 523 obj.attachEvent( "on" + type, obj[ type + fn ] ); 524 }; 525} 526 527var unbind = function() {}; 528 529if ( docElem.removeEventListener ) { 530 unbind = function( obj, type, fn ) { 531 obj.removeEventListener( type, fn, false ); 532 }; 533} else if ( docElem.detachEvent ) { 534 unbind = function( obj, type, fn ) { 535 obj.detachEvent( "on" + type, obj[ type + fn ] ); 536 try { 537 delete obj[ type + fn ]; 538 } catch ( err ) { 539 // can't delete window object properties 540 obj[ type + fn ] = undefined; 541 } 542 }; 543} 544 545var eventie = { 546 bind: bind, 547 unbind: unbind 548}; 549 550// transport 551if ( typeof define === 'function' && define.amd ) { 552 // AMD 553 define( 'eventie/eventie',eventie ); 554} else { 555 // browser global 556 window.eventie = eventie; 557} 558 559})( this ); 560 561/*! 562 * imagesLoaded v3.1.8 563 * JavaScript is all like "You images are done yet or what?" 564 * MIT License 565 */ 566 567( function( window, factory ) { 568 // universal module definition 569 570 /*global define: false, module: false, require: false */ 571 572 if ( typeof define === 'function' && define.amd ) { 573 // AMD 574 define( [ 575 'eventEmitter/EventEmitter', 576 'eventie/eventie' 577 ], function( EventEmitter, eventie ) { 578 return factory( window, EventEmitter, eventie ); 579 }); 580 } else if ( typeof exports === 'object' ) { 581 // CommonJS 582 module.exports = factory( 583 window, 584 require('wolfy87-eventemitter'), 585 require('eventie') 586 ); 587 } else { 588 // browser global 589 window.imagesLoaded = factory( 590 window, 591 window.EventEmitter, 592 window.eventie 593 ); 594 } 595 596})( window, 597 598// -------------------------- factory -------------------------- // 599 600function factory( window, EventEmitter, eventie ) { 601 602 603 604var $ = window.jQuery; 605var console = window.console; 606var hasConsole = typeof console !== 'undefined'; 607 608// -------------------------- helpers -------------------------- // 609 610// extend objects 611function extend( a, b ) { 612 for ( var prop in b ) { 613 a[ prop ] = b[ prop ]; 614 } 615 return a; 616} 617 618var objToString = Object.prototype.toString; 619function isArray( obj ) { 620 return objToString.call( obj ) === '[object Array]'; 621} 622 623// turn element or nodeList into an array 624function makeArray( obj ) { 625 var ary = []; 626 if ( isArray( obj ) ) { 627 // use object if already an array 628 ary = obj; 629 } else if ( typeof obj.length === 'number' ) { 630 // convert nodeList to array 631 for ( var i=0, len = obj.length; i < len; i++ ) { 632 ary.push( obj[i] ); 633 } 634 } else { 635 // array of single index 636 ary.push( obj ); 637 } 638 return ary; 639} 640 641 // -------------------------- imagesLoaded -------------------------- // 642 643 /** 644 * @param {Array, Element, NodeList, String} elem 645 * @param {Object or Function} options - if function, use as callback 646 * @param {Function} onAlways - callback function 647 */ 648 function ImagesLoaded( elem, options, onAlways ) { 649 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 650 if ( !( this instanceof ImagesLoaded ) ) { 651 return new ImagesLoaded( elem, options ); 652 } 653 // use elem as selector string 654 if ( typeof elem === 'string' ) { 655 elem = document.querySelectorAll( elem ); 656 } 657 658 this.elements = makeArray( elem ); 659 this.options = extend( {}, this.options ); 660 661 if ( typeof options === 'function' ) { 662 onAlways = options; 663 } else { 664 extend( this.options, options ); 665 } 666 667 if ( onAlways ) { 668 this.on( 'always', onAlways ); 669 } 670 671 this.getImages(); 672 673 if ( $ ) { 674 // add jQuery Deferred object 675 this.jqDeferred = new $.Deferred(); 676 } 677 678 // HACK check async to allow time to bind listeners 679 var _this = this; 680 setTimeout( function() { 681 _this.check(); 682 }); 683 } 684 685 ImagesLoaded.prototype = new EventEmitter(); 686 687 ImagesLoaded.prototype.options = {}; 688 689 ImagesLoaded.prototype.getImages = function() { 690 this.images = []; 691 692 // filter & find items if we have an item selector 693 for ( var i=0, len = this.elements.length; i < len; i++ ) { 694 var elem = this.elements[i]; 695 // filter siblings 696 if ( elem.nodeName === 'IMG' ) { 697 this.addImage( elem ); 698 } 699 // find children 700 // no non-element nodes, #143 701 var nodeType = elem.nodeType; 702 if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) { 703 continue; 704 } 705 var childElems = elem.querySelectorAll('img'); 706 // concat childElems to filterFound array 707 for ( var j=0, jLen = childElems.length; j < jLen; j++ ) { 708 var img = childElems[j]; 709 this.addImage( img ); 710 } 711 } 712 }; 713 714 /** 715 * @param {Image} img 716 */ 717 ImagesLoaded.prototype.addImage = function( img ) { 718 var loadingImage = new LoadingImage( img ); 719 this.images.push( loadingImage ); 720 }; 721
722 ImagesLoaded.prototype.check = function() { 723 var _this = this; 724 var checkedCount = 0; 725 var length = this.images.length; 726 this.hasAnyBroken = false; 727 // complete if no images 728 if ( !length ) { 729 this.complete(); 730 return; 731 } 732 733 function onConfirm( image, message ) { 734 if ( _this.options.debug && hasConsole ) { 735 console.log( 'confirm', image, message ); 736 } 737 738 _this.progress( image ); 739 checkedCount++; 740 if ( checkedCount === length ) { 741 _this.complete(); 742 } 743 return true; // bind once 744 } 745 746 for ( var i=0; i < length; i++ ) { 747 var loadingImage = this.images[i]; 748 loadingImage.on( 'confirm', onConfirm ); 749 loadingImage.check(); 750 } 751 }; 752 753 ImagesLoaded.prototype.progress = function( image ) { 754 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 755 // HACK - Chrome triggers event before object properties have changed. #83 756 var _this = this; 757 setTimeout( function() { 758 _this.emit( 'progress', _this, image ); 759 if ( _this.jqDeferred && _this.jqDeferred.notify ) { 760 _this.jqDeferred.notify( _this, image ); 761 } 762 }); 763 }; 764 765 ImagesLoaded.prototype.complete = function() { 766 var eventName = this.hasAnyBroken ? 'fail' : 'done'; 767 this.isComplete = true; 768 var _this = this; 769 // HACK - another setTimeout so that confirm happens after progress 770 setTimeout( function() { 771 _this.emit( eventName, _this ); 772 _this.emit( 'always', _this ); 773 if ( _this.jqDeferred ) { 774 var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve'; 775 _this.jqDeferred[ jqMethod ]( _this ); 776 } 777 }); 778 }; 779 780 // -------------------------- jquery -------------------------- // 781 782 if ( $ ) { 783 $.fn.imagesLoaded = function( options, callback ) { 784 var instance = new ImagesLoaded( this, options, callback ); 785 return instance.jqDeferred.promise( $(this) ); 786 }; 787 } 788 789 790 // -------------------------- -------------------------- // 791 792 function LoadingImage( img ) { 793 this.img = img; 794 } 795 796 LoadingImage.prototype = new EventEmitter(); 797 798 LoadingImage.prototype.check = function() { 799 // first check cached any previous images that have same src 800 var resource = cache[ this.img.src ] || new Resource( this.img.src ); 801 if ( resource.isConfirmed ) { 802 this.confirm( resource.isLoaded, 'cached was confirmed' ); 803 return; 804 } 805 806 // If complete is true and browser supports natural sizes, 807 // try to check for image status manually. 808 if ( this.img.complete && this.img.naturalWidth !== undefined ) { 809 // report based on naturalWidth 810 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 811 return; 812 } 813 814 // If none of the checks above matched, simulate loading on detached element. 815 var _this = this; 816 resource.on( 'confirm', function( resrc, message ) { 817 _this.confirm( resrc.isLoaded, message ); 818 return true; 819 }); 820 821 resource.check(); 822 }; 823 824 LoadingImage.prototype.confirm = function( isLoaded, message ) { 825 this.isLoaded = isLoaded; 826 this.emit( 'confirm', this, message ); 827 }; 828 829 // -------------------------- Resource -------------------------- // 830 831 // Resource checks each src, only once 832 // separate class from LoadingImage to prevent memory leaks. See #115 833 834 var cache = {}; 835 836 function Resource( src ) { 837 this.src = src; 838 // add to cache 839 cache[ src ] = this; 840 } 841 842 Resource.prototype = new EventEmitter(); 843 844 Resource.prototype.check = function() { 845 // only trigger checking once 846 if ( this.isChecked ) { 847 return; 848 } 849 // simulate loading on detached element 850 var proxyImage = new Image(); 851 eventie.bind( proxyImage, 'load', this ); 852 eventie.bind( proxyImage, 'error', this ); 853 proxyImage.src = this.src; 854 // set flag 855 this.isChecked = true; 856 }; 857 858 // ----- events ----- // 859 860 // trigger specified handler for event type 861 Resource.prototype.handleEvent = function( event ) { 862 var method = 'on' + event.type; 863 if ( this[ method ] ) { 864 this[ method ]( event ); 865 } 866 }; 867 868 Resource.prototype.onload = function( event ) { 869 this.confirm( true, 'onload' ); 870 this.unbindProxyEvents( event ); 871 }; 872 873 Resource.prototype.onerror = function( event ) { 874 this.confirm( false, 'onerror' ); 875 this.unbindProxyEvents( event ); 876 }; 877 878 // ----- confirm ----- // 879 880 Resource.prototype.confirm = function( isLoaded, message ) { 881 this.isConfirmed = true; 882 this.isLoaded = isLoaded;
883 this.emit( 'confirm', this, message ); 884 }; 885 886 Resource.prototype.unbindProxyEvents = function( event ) { 887 eventie.unbind( event.target, 'load', this ); 888 eventie.unbind( event.target, 'error', this ); 889 }; 890 891 // ----- ----- // 892 893 return ImagesLoaded; 894 895}); 896; 897/*! 898Waypoints - 3.0.0 899Copyright 2011-2014 Caleb Troughton 900Licensed under the MIT license. 901https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 902*/ 903(function() { 904 'use strict' 905 906 var keyCounter = 0 907 var allWaypoints = {} 908 909 /* http://imakewebthings.com/waypoints/api/waypoint */ 910 function Waypoint(options) { 911 if (!options) { 912 throw new Error('No options passed to Waypoint constructor') 913 } 914 if (!options.element) { 915 throw new Error('No element option passed to Waypoint constructor') 916 } 917 if (!options.handler) { 918 throw new Error('No handler option passed to Waypoint constructor') 919 } 920 921 this.key = 'waypoint-' + keyCounter 922 this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) 923 this.element = this.options.element 924 this.adapter = new Waypoint.Adapter(this.element) 925 this.callback = options.handler 926 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 927 this.enabled = this.options.enabled 928 this.triggerPoint = null 929 this.group = Waypoint.Group.findOrCreate({ 930 name: this.options.group, 931 axis: this.axis 932 }) 933 this.context = Waypoint.Context.findOrCreateByElement(this.options.context) 934 935 if (Waypoint.offsetAliases[this.options.offset]) { 936 this.options.offset = Waypoint.offsetAliases[this.options.offset] 937 } 938 this.group.add(this) 939 this.context.add(this) 940 allWaypoints[this.key] = this 941 keyCounter += 1 942 } 943 944 /* Private */ 945 Waypoint.prototype.queueTrigger = function(direction) { 946 this.group.queueTrigger(this, direction) 947 } 948 949 /* Private */ 950 Waypoint.prototype.trigger = function(args) { 951 if (!this.enabled) { 952 return 953 } 954 if (this.callback) { 955 this.callback.apply(this, args) 956 } 957 } 958 959 /* Public */ 960 /* http://imakewebthings.com/waypoints/api/destroy */ 961 Waypoint.prototype.destroy = function() { 962 this.context.remove(this) 963 this.group.remove(this) 964 delete allWaypoints[this.key] 965 } 966 967 /* Public */ 968 /* http://imakewebthings.com/waypoints/api/disable */ 969 Waypoint.prototype.disable = function() { 970 this.enabled = false 971 return this 972 } 973 974 /* Public */ 975 /* http://imakewebthings.com/waypoints/api/enable */ 976 Waypoint.prototype.enable = function() { 977 this.context.refresh() 978 this.enabled = true 979 return this 980 } 981 982 /* Public */ 983 /* http://imakewebthings.com/waypoints/api/next */ 984 Waypoint.prototype.next = function() { 985 return this.group.next(this) 986 } 987 988 /* Public */ 989 /* http://imakewebthings.com/waypoints/api/previous */ 990 Waypoint.prototype.previous = function() { 991 return this.group.previous(this) 992 } 993 994 /* Public */ 995 /* http://imakewebthings.com/waypoints/api/destroy-all */ 996 Waypoint.destroyAll = function() { 997 var allWaypointsArray = []
998 for (var waypointKey in allWaypoints) { 999 allWaypointsArray.push(allWaypoints[waypointKey]) 1000 } 1001 for (var i = 0, end = allWaypointsArray.length; i < end; i++) { 1002 allWaypointsArray[i].destroy() 1003 } 1004 } 1005 1006 /* Public */ 1007 /* http://imakewebthings.com/waypoints/api/refresh-all */ 1008 Waypoint.refreshAll = function() { 1009 Waypoint.Context.refreshAll() 1010 } 1011 1012 /* Public */ 1013 /* http://imakewebthings.com/waypoints/api/viewport-height */ 1014 Waypoint.viewportHeight = function() { 1015 return window.innerHeight || document.documentElement.clientHeight 1016 } 1017 1018 /* Public */ 1019 /* http://imakewebthings.com/waypoints/api/viewport-width */ 1020 Waypoint.viewportWidth = function() { 1021 return document.documentElement.clientWidth 1022 } 1023 1024 Waypoint.adapters = [] 1025 1026 Waypoint.defaults = { 1027 context: window, 1028 continuous: true, 1029 enabled: true, 1030 group: 'default', 1031 horizontal: false, 1032 offset: 0 1033 } 1034 1035 Waypoint.offsetAliases = { 1036 'bottom-in-view': function() { 1037 return this.context.innerHeight() - this.adapter.outerHeight() 1038 }, 1039 'right-in-view': function() { 1040 return this.context.innerWidth() - this.adapter.outerWidth() 1041 } 1042 } 1043 1044 window.Waypoint = Waypoint 1045}()) 1046;(function() { 1047 'use strict' 1048 1049 function requestAnimationFrameShim(callback) { 1050 window.setTimeout(callback, 1000 / 60) 1051 } 1052 1053 var keyCounter = 0 1054 var contexts = {} 1055 var Waypoint = window.Waypoint 1056 var requestAnimationFrame = window.requestAnimationFrame || 1057 window.mozRequestAnimationFrame || 1058 window.webkitRequestAnimationFrame || 1059 requestAnimationFrameShim 1060 var oldWindowLoad = window.onload 1061 1062 /* http://imakewebthings.com/waypoints/api/context */ 1063 function Context(element) { 1064 this.element = element 1065 this.Adapter = Waypoint.Adapter 1066 this.adapter = new this.Adapter(element) 1067 this.key = 'waypoint-context-' + keyCounter 1068 this.didScroll = false 1069 this.didResize = false 1070 this.oldScroll = { 1071 x: this.adapter.scrollLeft(), 1072 y: this.adapter.scrollTop() 1073 } 1074 this.waypoints = { 1075 vertical: {}, 1076 horizontal: {} 1077 } 1078 1079 element.waypointContextKey = this.key 1080 contexts[element.waypointContextKey] = this 1081 keyCounter += 1 1082 1083 this.createThrottledScrollHandler() 1084 this.createThrottledResizeHandler() 1085 } 1086 1087 /* Private */ 1088 Context.prototype.add = function(waypoint) { 1089 var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' 1090 this.waypoints[axis][waypoint.key] = waypoint 1091 this.refresh() 1092 } 1093 1094 /* Private */ 1095 Context.prototype.checkEmpty = function() { 1096 var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) 1097 var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) 1098 if (horizontalEmpty && verticalEmpty) { 1099 this.adapter.off('.waypoints') 1100 delete contexts[this.key] 1101 } 1102 } 1103 1104 /* Private */ 1105 Context.prototype.createThrottledResizeHandler = function() { 1106 var self = this 1107 1108 function resizeHandler() { 1109 self.handleResize() 1110 self.didResize = false 1111 } 1112 1113 this.adapter.on('resize.waypoints', function() { 1114 if (!self.didResize) { 1115 self.didResize = true 1116 requestAnimationFrame(resizeHandler) 1117 } 1118 }) 1119 } 1120 1121 /* Private */ 1122 Context.prototype.createThrottledScrollHandler = function() { 1123 var self = this 1124 function scrollHandler() { 1125 self.handleScroll() 1126 self.didScroll = false 1127 } 1128 1129 this.adapter.on('scroll.waypoints', function() { 1130 if (!self.didScroll || Waypoint.isTouch) { 1131 self.didScroll = true 1132 requestAnimationFrame(scrollHandler) 1133 } 1134 }) 1135 } 1136 1137 /* Private */ 1138 Context.prototype.handleResize = function() { 1139 Waypoint.Context.refreshAll() 1140 } 1141 1142 /* Private */ 1143 Context.prototype.handleScroll = function() { 1144 var triggeredGroups = {} 1145 var axes = { 1146 horizontal: { 1147 newScroll: this.adapter.scrollLeft(), 1148 oldScroll: this.oldScroll.x, 1149 forward: 'right', 1150 backward: 'left' 1151 }, 1152 vertical: { 1153 newScroll: this.adapter.scrollTop(), 1154 oldScroll: this.oldScroll.y, 1155 forward: 'down', 1156 backward: 'up' 1157 } 1158 } 1159 1160 for (var axisKey in axes) { 1161 var axis = axes[axisKey] 1162 var isForward = axis.newScroll > axis.oldScroll 1163 var direction = isForward ? axis.forward : axis.backward 1164
1165 for (var waypointKey in this.waypoints[axisKey]) { 1166 var waypoint = this.waypoints[axisKey][waypointKey] 1167 var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint 1168 var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint 1169 var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint 1170 var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint 1171 if (crossedForward || crossedBackward) { 1172 waypoint.queueTrigger(direction) 1173 triggeredGroups[waypoint.group.id] = waypoint.group 1174 } 1175 } 1176 } 1177 1178 for (var groupKey in triggeredGroups) { 1179 triggeredGroups[groupKey].flushTriggers() 1180 } 1181 1182 this.oldScroll = { 1183 x: axes.horizontal.newScroll, 1184 y: axes.vertical.newScroll 1185 } 1186 } 1187 1188 /* Private */ 1189 Context.prototype.innerHeight = function() { 1190 if (this.element === this.element.window) { 1191 return Waypoint.viewportHeight() 1192 } 1193 return this.adapter.innerHeight() 1194 } 1195 1196 /* Private */ 1197 Context.prototype.remove = function(waypoint) { 1198 delete this.waypoints[waypoint.axis][waypoint.key] 1199 this.checkEmpty() 1200 } 1201 1202 /* Private */ 1203 Context.prototype.innerWidth = function() { 1204 if (this.element === this.element.window) { 1205 return Waypoint.viewportWidth() 1206 } 1207 return this.adapter.innerWidth() 1208 } 1209 1210 /* Public */ 1211 /* http://imakewebthings.com/waypoints/api/context-destroy */ 1212 Context.prototype.destroy = function() { 1213 var allWaypoints = [] 1214 for (var axis in this.waypoints) {
1215 for (var waypointKey in this.waypoints[axis]) { 1216 allWaypoints.push(this.waypoints[axis][waypointKey]) 1217 } 1218 } 1219 for (var i = 0, end = allWaypoints.length; i < end; i++) { 1220 allWaypoints[i].destroy() 1221 } 1222 } 1223 1224 /* Public */ 1225 /* http://imakewebthings.com/waypoints/api/context-refresh */ 1226 Context.prototype.refresh = function() { 1227 var isWindow = this.element === this.element.window 1228 var contextOffset = this.adapter.offset() 1229 var triggeredGroups = {} 1230 var axes 1231 1232 this.handleScroll() 1233 axes = { 1234 horizontal: { 1235 contextOffset: isWindow ? 0 : contextOffset.left, 1236 contextScroll: isWindow ? 0 : this.oldScroll.x, 1237 contextDimension: this.innerWidth(), 1238 oldScroll: this.oldScroll.x, 1239 forward: 'right', 1240 backward: 'left', 1241 offsetProp: 'left' 1242 }, 1243 vertical: { 1244 contextOffset: isWindow ? 0 : contextOffset.top, 1245 contextScroll: isWindow ? 0 : this.oldScroll.y, 1246 contextDimension: this.innerHeight(), 1247 oldScroll: this.oldScroll.y, 1248 forward: 'down', 1249 backward: 'up', 1250 offsetProp: 'top' 1251 } 1252 } 1253 1254 for (var axisKey in axes) { 1255 var axis = axes[axisKey]
1256 for (var waypointKey in this.waypoints[axisKey]) { 1257 var waypoint = this.waypoints[axisKey][waypointKey] 1258 var adjustment = waypoint.options.offset 1259 var oldTriggerPoint = waypoint.triggerPoint 1260 var elementOffset = 0 1261 var freshWaypoint = oldTriggerPoint == null 1262 var contextModifier, wasBeforeScroll, nowAfterScroll 1263 var triggeredBackward, triggeredForward 1264 1265 if (waypoint.element !== waypoint.element.window) { 1266 elementOffset = waypoint.adapter.offset()[axis.offsetProp] 1267 } 1268 1269 if (typeof adjustment === 'function') { 1270 adjustment = adjustment.apply(waypoint) 1271 } 1272 else if (typeof adjustment === 'string') { 1273 adjustment = parseFloat(adjustment) 1274 if (waypoint.options.offset.indexOf('%') > - 1) { 1275 adjustment = Math.ceil(axis.contextDimension * adjustment / 100) 1276 } 1277 } 1278 1279 contextModifier = axis.contextScroll - axis.contextOffset 1280 waypoint.triggerPoint = elementOffset + contextModifier - adjustment 1281 wasBeforeScroll = oldTriggerPoint < axis.oldScroll 1282 nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll 1283 triggeredBackward = wasBeforeScroll && nowAfterScroll 1284 triggeredForward = !wasBeforeScroll && !nowAfterScroll 1285 1286 if (!freshWaypoint && triggeredBackward) { 1287 waypoint.queueTrigger(axis.backward) 1288 triggeredGroups[waypoint.group.id] = waypoint.group 1289 } 1290 else if (!freshWaypoint && triggeredForward) { 1291 waypoint.queueTrigger(axis.forward) 1292 triggeredGroups[waypoint.group.id] = waypoint.group 1293 } 1294 else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { 1295 waypoint.queueTrigger(axis.forward) 1296 triggeredGroups[waypoint.group.id] = waypoint.group 1297 } 1298 } 1299 } 1300 1301 for (var groupKey in triggeredGroups) { 1302 triggeredGroups[groupKey].flushTriggers() 1303 } 1304 1305 return this 1306 } 1307 1308 /* Private */ 1309 Context.findOrCreateByElement = function(element) { 1310 return Context.findByElement(element) || new Context(element) 1311 } 1312 1313 /* Private */ 1314 Context.refreshAll = function() { 1315 for (var contextId in contexts) { 1316 contexts[contextId].refresh() 1317 } 1318 } 1319 1320 /* Public */ 1321 /* http://imakewebthings.com/waypoints/api/context-find-by-element */ 1322 Context.findByElement = function(element) { 1323 return contexts[element.waypointContextKey] 1324 } 1325 1326 window.onload = function() { 1327 if (oldWindowLoad) { 1328 oldWindowLoad() 1329 } 1330 Context.refreshAll() 1331 } 1332 Waypoint.Context = Context 1333}()) 1334;(function() { 1335 'use strict' 1336 1337 function byTriggerPoint(a, b) { 1338 return a.triggerPoint - b.triggerPoint 1339 } 1340 1341 function byReverseTriggerPoint(a, b) { 1342 return b.triggerPoint - a.triggerPoint 1343 } 1344 1345 var groups = { 1346 vertical: {}, 1347 horizontal: {} 1348 } 1349 var Waypoint = window.Waypoint 1350 1351 /* http://imakewebthings.com/waypoints/api/group */ 1352 function Group(options) { 1353 this.name = options.name 1354 this.axis = options.axis 1355 this.id = this.name + '-' + this.axis 1356 this.waypoints = [] 1357 this.clearTriggerQueues() 1358 groups[this.axis][this.name] = this 1359 } 1360 1361 /* Private */ 1362 Group.prototype.add = function(waypoint) { 1363 this.waypoints.push(waypoint) 1364 } 1365 1366 /* Private */ 1367 Group.prototype.clearTriggerQueues = function() { 1368 this.triggerQueues = { 1369 up: [], 1370 down: [], 1371 left: [], 1372 right: [] 1373 } 1374 } 1375 1376 /* Private */ 1377 Group.prototype.flushTriggers = function() { 1378 for (var direction in this.triggerQueues) { 1379 var waypoints = this.triggerQueues[direction] 1380 var reverse = direction === 'up' || direction === 'left' 1381 waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) 1382 for (var i = 0, end = waypoints.length; i < end; i += 1) { 1383 var waypoint = waypoints[i] 1384 if (waypoint.options.continuous || i === waypoints.length - 1) { 1385 waypoint.trigger([direction]) 1386 } 1387 } 1388 } 1389 this.clearTriggerQueues() 1390 } 1391 1392 /* Private */ 1393 Group.prototype.next = function(waypoint) { 1394 this.waypoints.sort(byTriggerPoint) 1395 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 1396 var isLast = index === this.waypoints.length - 1 1397 return isLast ? null : this.waypoints[index + 1] 1398 } 1399 1400 /* Private */ 1401 Group.prototype.previous = function(waypoint) { 1402 this.waypoints.sort(byTriggerPoint) 1403 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 1404 return index ? this.waypoints[index - 1] : null 1405 } 1406 1407 /* Private */ 1408 Group.prototype.queueTrigger = function(waypoint, direction) { 1409 this.triggerQueues[direction].push(waypoint) 1410 } 1411 1412 /* Private */ 1413 Group.prototype.remove = function(waypoint) { 1414 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 1415 if (index > -1) { 1416 this.waypoints.splice(index, 1) 1417 } 1418 } 1419 1420 /* Public */ 1421 /* http://imakewebthings.com/waypoints/api/first */ 1422 Group.prototype.first = function() { 1423 return this.waypoints[0] 1424 } 1425 1426 /* Public */ 1427 /* http://imakewebthings.com/waypoints/api/last */ 1428 Group.prototype.last = function() { 1429 return this.waypoints[this.waypoints.length - 1] 1430 } 1431 1432 /* Private */ 1433 Group.findOrCreate = function(options) { 1434 return groups[options.axis][options.name] || new Group(options) 1435 } 1436 1437 Waypoint.Group = Group 1438}()) 1439;(function() { 1440 'use strict' 1441 1442 var $ = window.jQuery 1443 var Waypoint = window.Waypoint 1444 1445 function JQueryAdapter(element) { 1446 this.$element = $(element) 1447 } 1448 1449 $.each([
1450 'innerHeight', 1451 'innerWidth', 1452 'off', 1453 'offset', 1454 'on', 1455 'outerHeight', 1456 'outerWidth', 1457 'scrollLeft', 1458 'scrollTop' 1459 ], function(i, method) { 1460 JQueryAdapter.prototype[method] = function() { 1461 var args = Array.prototype.slice.call(arguments) 1462 return this.$element[method].apply(this.$element, args) 1463 } 1464 }) 1465 1466 $.each([ 1467 'extend', 1468 'inArray', 1469 'isEmptyObject' 1470 ], function(i, method) { 1471 JQueryAdapter[method] = $[method] 1472 }) 1473 1474 Waypoint.adapters.push({ 1475 name: 'jquery', 1476 Adapter: JQueryAdapter 1477 }) 1478 Waypoint.Adapter = JQueryAdapter 1479}()) 1480;(function() { 1481 'use strict' 1482 1483 var Waypoint = window.Waypoint 1484 1485 function createExtension(framework) { 1486 return function() { 1487 var waypoints = [] 1488 var overrides = arguments[0] 1489 1490 if (framework.isFunction(arguments[0])) { 1491 overrides = framework.extend({}, arguments[1]) 1492 overrides.handler = arguments[0] 1493 } 1494 1495 this.each(function() { 1496 var options = framework.extend({}, overrides, { 1497 element: this 1498 }) 1499 if (typeof options.context === 'string') { 1500 options.context = framework(this).closest(options.context)[0] 1501 } 1502 waypoints.push(new Waypoint(options)) 1503 }) 1504 1505 return waypoints 1506 } 1507 } 1508 1509 if (window.jQuery) { 1510 window.jQuery.fn.waypoint = createExtension(window.jQuery) 1511 } 1512 if (window.Zepto) { 1513 window.Zepto.fn.waypoint = createExtension(window.Zepto) 1514 } 1515}()) 1516;; 1517/*! 1518Waypoints Sticky Element Shortcut - 3.0.0 1519Copyright 2011-2014 Caleb Troughton 1520Licensed under the MIT license. 1521https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 1522*/ 1523(function() { 1524 'use strict' 1525 1526 var $ = window.jQuery 1527 var Waypoint = window.Waypoint 1528 1529 /* http://imakewebthings.com/waypoints/shortcuts/sticky-elements */ 1530 function Sticky(options) { 1531 this.options = $.extend({}, Waypoint.defaults, Sticky.defaults, options) 1532 this.element = this.options.element 1533 this.$element = $(this.element) 1534 this.createWrapper() 1535 this.createWaypoint() 1536 } 1537 1538 /* Private */ 1539 Sticky.prototype.createWaypoint = function() { 1540 var originalHandler = this.options.handler 1541 1542 this.waypoint = new Waypoint($.extend({}, this.options, { 1543 element: this.wrapper, 1544 handler: $.proxy(function(direction) { 1545 var shouldBeStuck = this.options.direction.indexOf(direction) > -1 1546 var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : '' 1547 1548 this.$wrapper.height(wrapperHeight) 1549 this.$element.toggleClass(this.options.stuckClass, shouldBeStuck) 1550 1551 if (originalHandler) { 1552 originalHandler.call(this, direction) 1553 } 1554 }, this) 1555 })) 1556 } 1557 1558 /* Private */ 1559 Sticky.prototype.createWrapper = function() { 1560 this.$element.wrap(this.options.wrapper) 1561 this.$wrapper = this.$element.parent() 1562 this.wrapper = this.$wrapper[0] 1563 } 1564 1565 /* Public */ 1566 Sticky.prototype.destroy = function() { 1567 if (this.$element.parent()[0] === this.wrapper) { 1568 this.waypoint.destroy() 1569 this.$element.removeClass(this.options.stuckClass).unwrap() 1570 } 1571 } 1572 1573 Sticky.defaults = { 1574 wrapper: '<div class="sticky-wrapper" />', 1575 stuckClass: 'stuck', 1576 direction: 'down right' 1577 } 1578
vendor: 11,063 bytes, lines 1579-1976
1579 Waypoint.Sticky = Sticky 1580}()) 1581; 1582 1583/** 1584 * Sticky Menu v1.0 - depends on `waypoints.js` 1585 * Contains handlers for the sticky menu 1586 * 1587 * Copyright (c) 2013-2015 DesignOrbital.com 1588 * License: GNU General Public License v2 or later 1589 * http://www.gnu.org/licenses/gpl-2.0.html 1590 */ 1591 1592( function( $ ) { 1593 1594 var dicotStickyMenu = { 1595 1596 // Sticky Menu Init 1597 stickyMenuInit: function() { 1598 1599 var stickyMenu; 1600 1601 enquire.register( 'screen and ( min-width: 768px )' , { 1602 1603 match : function() { 1604 1605 // Sticky Menu Setup 1606 stickyMenu = new Waypoint.Sticky( { 1607 1608 element: $( '.main-navigation' )[0], 1609 wrapper: '<div class="main-navigation-sticky-wrapper waypoint" />', 1610 stuckClass: 'stuck animated fadeInDown' 1611 1612 } ); 1613 1614 }, 1615 unmatch : function() { 1616 1617 // Sticky Menu Destroy 1618 stickyMenu.destroy(); 1619 1620 } 1621 1622 }); 1623 1624 } 1625 1626 } 1627 1628 // Document Ready 1629 $( document ).ready( function() { 1630 1631 // Sticky Menu 1632 dicotStickyMenu.stickyMenuInit(); 1633 1634 } ); 1635 1636} )( jQuery );; 1637/*! 1638 * wow.js v1.0.2 - Reveal CSS animation as you scroll down a page. 1639 * Copyright (C) 2014; Matthieu Aussaguel 1640 * License: MIT 1641 */ 1642 1643(function() { 1644 var MutationObserver, Util, WeakMap, getComputedStyle, getComputedStyleRX, 1645 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 1646 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; 1647 1648 Util = (function() { 1649 function Util() {} 1650 1651 Util.prototype.extend = function(custom, defaults) { 1652 var key, value; 1653 for (key in defaults) { 1654 value = defaults[key]; 1655 if (custom[key] == null) { 1656 custom[key] = value; 1657 } 1658 } 1659 return custom; 1660 }; 1661 1662 Util.prototype.isMobile = function(agent) { 1663 return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent); 1664 }; 1665 1666 Util.prototype.addEvent = function(elem, event, fn) { 1667 if (elem.addEventListener != null) { 1668 return elem.addEventListener(event, fn, false); 1669 } else if (elem.attachEvent != null) { 1670 return elem.attachEvent("on" + event, fn); 1671 } else { 1672 return elem[event] = fn; 1673 } 1674 }; 1675 1676 Util.prototype.removeEvent = function(elem, event, fn) { 1677 if (elem.removeEventListener != null) { 1678 return elem.removeEventListener(event, fn, false); 1679 } else if (elem.detachEvent != null) { 1680 return elem.detachEvent("on" + event, fn); 1681 } else { 1682 return delete elem[event]; 1683 } 1684 }; 1685 1686 Util.prototype.innerHeight = function() { 1687 if ('innerHeight' in window) { 1688 return window.innerHeight; 1689 } else { 1690 return document.documentElement.clientHeight; 1691 } 1692 }; 1693 1694 return Util; 1695 1696 })(); 1697 1698 WeakMap = this.WeakMap || this.MozWeakMap || (WeakMap = (function() { 1699 function WeakMap() { 1700 this.keys = []; 1701 this.values = []; 1702 } 1703 1704 WeakMap.prototype.get = function(key) { 1705 var i, item, _i, _len, _ref; 1706 _ref = this.keys; 1707 for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { 1708 item = _ref[i]; 1709 if (item === key) { 1710 return this.values[i]; 1711 } 1712 } 1713 }; 1714 1715 WeakMap.prototype.set = function(key, value) { 1716 var i, item, _i, _len, _ref; 1717 _ref = this.keys; 1718 for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { 1719 item = _ref[i]; 1720 if (item === key) { 1721 this.values[i] = value; 1722 return; 1723 } 1724 } 1725 this.keys.push(key); 1726 return this.values.push(value); 1727 }; 1728 1729 return WeakMap; 1730 1731 })()); 1732 1733 MutationObserver = this.MutationObserver || this.WebkitMutationObserver || this.MozMutationObserver || (MutationObserver = (function() { 1734 function MutationObserver() { 1735 if (typeof console !== "undefined" && console !== null) { 1736 console.warn('MutationObserver is not supported by your browser.'); 1737 } 1738 if (typeof console !== "undefined" && console !== null) { 1739 console.warn('WOW.js cannot detect dom mutations, please call .sync() after loading new content.'); 1740 } 1741 } 1742 1743 MutationObserver.notSupported = true; 1744 1745 MutationObserver.prototype.observe = function() {}; 1746 1747 return MutationObserver; 1748 1749 })()); 1750 1751 getComputedStyle = this.getComputedStyle || function(el, pseudo) { 1752 this.getPropertyValue = function(prop) { 1753 var _ref; 1754 if (prop === 'float') { 1755 prop = 'styleFloat'; 1756 } 1757 if (getComputedStyleRX.test(prop)) { 1758 prop.replace(getComputedStyleRX, function(_, _char) { 1759 return _char.toUpperCase(); 1760 }); 1761 } 1762 return ((_ref = el.currentStyle) != null ? _ref[prop] : void 0) || null; 1763 }; 1764 return this; 1765 }; 1766 1767 getComputedStyleRX = /(\-([a-z]){1})/g; 1768 1769 this.WOW = (function() { 1770 WOW.prototype.defaults = { 1771 boxClass: 'wow', 1772 animateClass: 'animated', 1773 offset: 0, 1774 mobile: true, 1775 live: true 1776 }; 1777 1778 function WOW(options) { 1779 if (options == null) { 1780 options = {}; 1781 } 1782 this.scrollCallback = __bind(this.scrollCallback, this); 1783 this.scrollHandler = __bind(this.scrollHandler, this); 1784 this.start = __bind(this.start, this); 1785 this.scrolled = true; 1786 this.config = this.util().extend(options, this.defaults); 1787 this.animationNameCache = new WeakMap(); 1788 } 1789 1790 WOW.prototype.init = function() { 1791 var _ref; 1792 this.element = window.document.documentElement; 1793 if ((_ref = document.readyState) === "interactive" || _ref === "complete") { 1794 this.start(); 1795 } else { 1796 this.util().addEvent(document, 'DOMContentLoaded', this.start); 1797 } 1798 return this.finished = []; 1799 }; 1800 1801 WOW.prototype.start = function() { 1802 var box, _i, _len, _ref; 1803 this.stopped = false; 1804 this.boxes = (function() { 1805 var _i, _len, _ref, _results; 1806 _ref = this.element.querySelectorAll("." + this.config.boxClass); 1807 _results = []; 1808 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1809 box = _ref[_i]; 1810 _results.push(box); 1811 } 1812 return _results; 1813 }).call(this); 1814 this.all = (function() { 1815 var _i, _len, _ref, _results; 1816 _ref = this.boxes; 1817 _results = []; 1818 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1819 box = _ref[_i]; 1820 _results.push(box); 1821 } 1822 return _results; 1823 }).call(this); 1824 if (this.boxes.length) { 1825 if (this.disabled()) { 1826 this.resetStyle(); 1827 } else { 1828 _ref = this.boxes; 1829 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1830 box = _ref[_i]; 1831 this.applyStyle(box, true); 1832 } 1833 } 1834 } 1835 if (!this.disabled()) { 1836 this.util().addEvent(window, 'scroll', this.scrollHandler); 1837 this.util().addEvent(window, 'resize', this.scrollHandler); 1838 this.interval = setInterval(this.scrollCallback, 50); 1839 } 1840 if (this.config.live) { 1841 return new MutationObserver((function(_this) { 1842 return function(records) { 1843 var node, record, _j, _len1, _results; 1844 _results = []; 1845 for (_j = 0, _len1 = records.length; _j < _len1; _j++) { 1846 record = records[_j]; 1847 _results.push((function() { 1848 var _k, _len2, _ref1, _results1; 1849 _ref1 = record.addedNodes || []; 1850 _results1 = []; 1851 for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { 1852 node = _ref1[_k]; 1853 _results1.push(this.doSync(node)); 1854 } 1855 return _results1; 1856 }).call(_this)); 1857 } 1858 return _results; 1859 }; 1860 })(this)).observe(document.body, { 1861 childList: true, 1862 subtree: true 1863 }); 1864 } 1865 }; 1866 1867 WOW.prototype.stop = function() { 1868 this.stopped = true; 1869 this.util().removeEvent(window, 'scroll', this.scrollHandler); 1870 this.util().removeEvent(window, 'resize', this.scrollHandler); 1871 if (this.interval != null) { 1872 return clearInterval(this.interval); 1873 } 1874 }; 1875 1876 WOW.prototype.sync = function(element) { 1877 if (MutationObserver.notSupported) { 1878 return this.doSync(this.element); 1879 } 1880 }; 1881 1882 WOW.prototype.doSync = function(element) { 1883 var box, _i, _len, _ref, _results; 1884 if (element == null) { 1885 element = this.element; 1886 } 1887 if (element.nodeType !== 1) { 1888 return; 1889 } 1890 element = element.parentNode || element; 1891 _ref = element.querySelectorAll("." + this.config.boxClass); 1892 _results = []; 1893 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1894 box = _ref[_i]; 1895 if (__indexOf.call(this.all, box) < 0) { 1896 this.boxes.push(box); 1897 this.all.push(box); 1898 if (this.stopped || this.disabled()) { 1899 this.resetStyle(); 1900 } else { 1901 this.applyStyle(box, true); 1902 } 1903 _results.push(this.scrolled = true); 1904 } else { 1905 _results.push(void 0); 1906 } 1907 } 1908 return _results; 1909 }; 1910 1911 WOW.prototype.show = function(box) { 1912 this.applyStyle(box); 1913 return box.className = "" + box.className + " " + this.config.animateClass; 1914 }; 1915 1916 WOW.prototype.applyStyle = function(box, hidden) { 1917 var delay, duration, iteration; 1918 duration = box.getAttribute('data-wow-duration'); 1919 delay = box.getAttribute('data-wow-delay'); 1920 iteration = box.getAttribute('data-wow-iteration'); 1921 return this.animate((function(_this) { 1922 return function() { 1923 return _this.customStyle(box, hidden, duration, delay, iteration); 1924 }; 1925 })(this)); 1926 }; 1927 1928 WOW.prototype.animate = (function() { 1929 if ('requestAnimationFrame' in window) { 1930 return function(callback) { 1931 return window.requestAnimationFrame(callback); 1932 }; 1933 } else { 1934 return function(callback) { 1935 return callback(); 1936 }; 1937 } 1938 })(); 1939 1940 WOW.prototype.resetStyle = function() { 1941 var box, _i, _len, _ref, _results; 1942 _ref = this.boxes; 1943 _results = []; 1944 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1945 box = _ref[_i]; 1946 _results.push(box.style.visibility = 'visible'); 1947 } 1948 return _results; 1949 }; 1950 1951 WOW.prototype.customStyle = function(box, hidden, duration, delay, iteration) { 1952 if (hidden) { 1953 this.cacheAnimationName(box); 1954 } 1955 box.style.visibility = hidden ? 'hidden' : 'visible'; 1956 if (duration) { 1957 this.vendorSet(box.style, { 1958 animationDuration: duration 1959 }); 1960 } 1961 if (delay) { 1962 this.vendorSet(box.style, { 1963 animationDelay: delay 1964 }); 1965 } 1966 if (iteration) { 1967 this.vendorSet(box.style, { 1968 animationIterationCount: iteration 1969 }); 1970 } 1971 this.vendorSet(box.style, { 1972 animationName: hidden ? 'none' : this.cachedAnimationName(box) 1973 }); 1974 return box; 1975 }; 1976
1977 WOW.prototype.vendors = ["moz", "webkit"]; 1978 1979 WOW.prototype.vendorSet = function(elem, properties) { 1980 var name, value, vendor, _results; 1981 _results = []; 1982 for (name in properties) { 1983 value = properties[name]; 1984 elem["" + name] = value; 1985 _results.push((function() { 1986 var _i, _len, _ref, _results1; 1987 _ref = this.vendors; 1988 _results1 = []; 1989 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1990 vendor = _ref[_i]; 1991 _results1.push(elem["" + vendor + (name.charAt(0).toUpperCase()) + (name.substr(1))] = value); 1992 } 1993 return _results1; 1994 }).call(this)); 1995 } 1996 return _results; 1997 }; 1998 1999 WOW.prototype.vendorCSS = function(elem, property) { 2000 var result, style, vendor, _i, _len, _ref; 2001 style = getComputedStyle(elem); 2002 result = style.getPropertyCSSValue(property); 2003 _ref = this.vendors; 2004 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 2005 vendor = _ref[_i]; 2006 result = result || style.getPropertyCSSValue("-" + vendor + "-" + property); 2007 } 2008 return result; 2009 }; 2010 2011 WOW.prototype.animationName = function(box) { 2012 var animationName; 2013 try { 2014 animationName = this.vendorCSS(box, 'animation-name').cssText; 2015 } catch (_error) { 2016 animationName = getComputedStyle(box).getPropertyValue('animation-name'); 2017 } 2018 if (animationName === 'none') { 2019 return ''; 2020 } else { 2021 return animationName; 2022 } 2023 }; 2024 2025 WOW.prototype.cacheAnimationName = function(box) { 2026 return this.animationNameCache.set(box, this.animationName(box)); 2027 }; 2028 2029 WOW.prototype.cachedAnimationName = function(box) { 2030 return this.animationNameCache.get(box); 2031 }; 2032 2033 WOW.prototype.scrollHandler = function() { 2034 return this.scrolled = true; 2035 }; 2036 2037 WOW.prototype.scrollCallback = function() { 2038 var box; 2039 if (this.scrolled) { 2040 this.scrolled = false; 2041 this.boxes = (function() { 2042 var _i, _len, _ref, _results; 2043 _ref = this.boxes; 2044 _results = []; 2045 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 2046 box = _ref[_i]; 2047 if (!(box)) { 2048 continue; 2049 } 2050 if (this.isVisible(box)) { 2051 this.show(box); 2052 continue; 2053 } 2054 _results.push(box); 2055 } 2056 return _results; 2057 }).call(this); 2058 if (!(this.boxes.length || this.config.live)) { 2059 return this.stop(); 2060 } 2061 } 2062 }; 2063 2064 WOW.prototype.offsetTop = function(element) { 2065 var top; 2066 while (element.offsetTop === void 0) { 2067 element = element.parentNode; 2068 } 2069 top = element.offsetTop; 2070 while (element = element.offsetParent) { 2071 top += element.offsetTop; 2072 } 2073 return top; 2074 }; 2075 2076 WOW.prototype.isVisible = function(box) { 2077 var bottom, offset, top, viewBottom, viewTop; 2078 offset = box.getAttribute('data-wow-offset') || this.config.offset; 2079 viewTop = window.pageYOffset; 2080 viewBottom = viewTop + Math.min(this.element.clientHeight, this.util().innerHeight()) - offset; 2081 top = this.offsetTop(box); 2082 bottom = top + box.clientHeight; 2083 return top <= viewBottom && bottom >= viewTop; 2084 }; 2085 2086 WOW.prototype.util = function() { 2087 return this._util != null ? this._util : this._util = new Util(); 2088 }; 2089 2090 WOW.prototype.disabled = function() { 2091 return !this.config.mobile && this.util().isMobile(navigator.userAgent); 2092 }; 2093 2094 return WOW; 2095 2096 })(); 2097 2098}).call(this); 2099; 2100/** 2101 * Animation v1.0 - depends on `wow.js` 2102 * Contains handlers for the animation of different site content 2103 * e.g. Featured Content, Sidebar & Footer Widgets, Post Blocks 2104 * 2105 * Copyright (c) 2013-2015 DesignOrbital.com 2106 * License: GNU General Public License v2 or later 2107 * http://www.gnu.org/licenses/gpl-2.0.html 2108 */ 2109 2110( function( $ ) { 2111 2112 // Document Ready 2113 $( document ).ready( function() { 2114 2115 new WOW( { 2116 2117 boxClass: 'wow', 2118 animateClass: 'animated', 2119 offset: 10, 2120 mobile: true, 2121 live: true 2122 2123 } ).init(); 2124 2125 } ); 2126 2127} )( jQuery );; 2128/*! 2129 * enquire.js v2.1.2 - Awesome Media Queries in JavaScript 2130 * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/enquire.js 2131 * License: MIT (http://www.opensource.org/licenses/mit-license.php) 2132 */ 2133 2134;(function (name, context, factory) { 2135 var matchMedia = window.matchMedia; 2136 2137 if (typeof module !== 'undefined' && module.exports) { 2138 module.exports = factory(matchMedia); 2139 } 2140 else if (typeof define === 'function' && define.amd) { 2141 define(function() { 2142 return (context[name] = factory(matchMedia)); 2143 }); 2144 } 2145 else { 2146 context[name] = factory(matchMedia); 2147 } 2148}('enquire', this, function (matchMedia) { 2149 2150 'use strict'; 2151 2152 /*jshint unused:false */ 2153 /** 2154 * Helper function for iterating over a collection 2155 * 2156 * @param collection 2157 * @param fn 2158 */ 2159 function each(collection, fn) { 2160 var i = 0, 2161 length = collection.length, 2162 cont; 2163 2164 for(i; i < length; i++) { 2165 cont = fn(collection[i], i); 2166 if(cont === false) { 2167 break; //allow early exit 2168 } 2169 } 2170 } 2171 2172 /** 2173 * Helper function for determining whether target object is an array 2174 * 2175 * @param target the object under test 2176 * @return {Boolean} true if array, false otherwise 2177 */ 2178 function isArray(target) { 2179 return Object.prototype.toString.apply(target) === '[object Array]'; 2180 } 2181 2182 /** 2183 * Helper function for determining whether target object is a function 2184 * 2185 * @param target the object under test 2186 * @return {Boolean} true if function, false otherwise 2187 */ 2188 function isFunction(target) { 2189 return typeof target === 'function'; 2190 } 2191 2192 /** 2193 * Delegate to handle a media query being matched and unmatched. 2194 * 2195 * @param {object} options 2196 * @param {function} options.match callback for when the media query is matched 2197 * @param {function} [options.unmatch] callback for when the media query is unmatched 2198 * @param {function} [options.setup] one-time callback triggered the first time a query is matched 2199 * @param {boolean} [options.deferSetup=false] should the setup callback be run immediately, rather than first time query is matched? 2200 * @constructor 2201 */ 2202 function QueryHandler(options) { 2203 this.options = options; 2204 !options.deferSetup && this.setup(); 2205 } 2206 QueryHandler.prototype = { 2207 2208 /** 2209 * coordinates setup of the handler 2210 * 2211 * @function 2212 */ 2213 setup : function() { 2214 if(this.options.setup) { 2215 this.options.setup(); 2216 }
2217 this.initialised = true; 2218 }, 2219 2220 /** 2221 * coordinates setup and triggering of the handler 2222 * 2223 * @function 2224 */ 2225 on : function() { 2226 !this.initialised && this.setup(); 2227 this.options.match && this.options.match(); 2228 }, 2229 2230 /** 2231 * coordinates the unmatch event for the handler 2232 * 2233 * @function 2234 */ 2235 off : function() { 2236 this.options.unmatch && this.options.unmatch(); 2237 }, 2238 2239 /** 2240 * called when a handler is to be destroyed. 2241 * delegates to the destroy or unmatch callbacks, depending on availability. 2242 * 2243 * @function 2244 */ 2245 destroy : function() { 2246 this.options.destroy ? this.options.destroy() : this.off(); 2247 }, 2248 2249 /** 2250 * determines equality by reference. 2251 * if object is supplied compare options, if function, compare match callback 2252 * 2253 * @function 2254 * @param {object || function} [target] the target for comparison 2255 */ 2256 equals : function(target) { 2257 return this.options === target || this.options.match === target; 2258 } 2259 2260 }; 2261 /** 2262 * Represents a single media query, manages it's state and registered handlers for this query 2263 * 2264 * @constructor 2265 * @param {string} query the media query string 2266 * @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design 2267 */ 2268 function MediaQuery(query, isUnconditional) { 2269 this.query = query; 2270 this.isUnconditional = isUnconditional; 2271 this.handlers = []; 2272 this.mql = matchMedia(query); 2273 2274 var self = this; 2275 this.listener = function(mql) { 2276 self.mql = mql; 2277 self.assess(); 2278 }; 2279 this.mql.addListener(this.listener); 2280 } 2281 MediaQuery.prototype = { 2282 2283 /** 2284 * add a handler for this query, triggering if already active 2285 * 2286 * @param {object} handler 2287 * @param {function} handler.match callback for when query is activated 2288 * @param {function} [handler.unmatch] callback for when query is deactivated 2289 * @param {function} [handler.setup] callback for immediate execution when a query handler is registered 2290 * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched? 2291 */ 2292 addHandler : function(handler) { 2293 var qh = new QueryHandler(handler); 2294 this.handlers.push(qh); 2295 2296 this.matches() && qh.on(); 2297 }, 2298 2299 /** 2300 * removes the given handler from the collection, and calls it's destroy methods 2301 * 2302 * @param {object || function} handler the handler to remove 2303 */ 2304 removeHandler : function(handler) { 2305 var handlers = this.handlers; 2306 each(handlers, function(h, i) { 2307 if(h.equals(handler)) { 2308 h.destroy(); 2309 return !handlers.splice(i,1); //remove from array and exit each early 2310 } 2311 }); 2312 }, 2313 2314 /** 2315 * Determine whether the media query should be considered a match 2316 * 2317 * @return {Boolean} true if media query can be considered a match, false otherwise 2318 */ 2319 matches : function() { 2320 return this.mql.matches || this.isUnconditional; 2321 }, 2322 2323 /** 2324 * Clears all handlers and unbinds events 2325 */ 2326 clear : function() { 2327 each(this.handlers, function(handler) { 2328 handler.destroy(); 2329 }); 2330 this.mql.removeListener(this.listener); 2331 this.handlers.length = 0; //clear array 2332 }, 2333 2334 /* 2335 * Assesses the query, turning on all handlers if it matches, turning them off if it doesn't match 2336 */ 2337 assess : function() { 2338 var action = this.matches() ? 'on' : 'off'; 2339 2340 each(this.handlers, function(handler) { 2341 handler[action](); 2342 }); 2343 } 2344 }; 2345 /** 2346 * Allows for registration of query handlers. 2347 * Manages the query handler's state and is responsible for wiring up browser events 2348 * 2349 * @constructor 2350 */ 2351 function MediaQueryDispatch () { 2352 if(!matchMedia) {
2353 throw new Error('matchMedia not present, legacy browsers require a polyfill'); 2354 } 2355 2356 this.queries = {}; 2357 this.browserIsIncapable = !matchMedia('only all').matches; 2358 } 2359 2360 MediaQueryDispatch.prototype = { 2361 2362 /** 2363 * Registers a handler for the given media query 2364 * 2365 * @param {string} q the media query 2366 * @param {object || Array || Function} options either a single query handler object, a function, or an array of query handlers 2367 * @param {function} options.match fired when query matched 2368 * @param {function} [options.unmatch] fired when a query is no longer matched 2369 * @param {function} [options.setup] fired when handler first triggered 2370 * @param {boolean} [options.deferSetup=false] whether setup should be run immediately or deferred until query is first matched 2371 * @param {boolean} [shouldDegrade=false] whether this particular media query should always run on incapable browsers 2372 */ 2373 register : function(q, options, shouldDegrade) { 2374 var queries = this.queries, 2375 isUnconditional = shouldDegrade && this.browserIsIncapable; 2376 2377 if(!queries[q]) { 2378 queries[q] = new MediaQuery(q, isUnconditional); 2379 } 2380 2381 //normalise to object in an array 2382 if(isFunction(options)) { 2383 options = { match : options }; 2384 } 2385 if(!isArray(options)) { 2386 options = [options]; 2387 } 2388 each(options, function(handler) { 2389 if (isFunction(handler)) { 2390 handler = { match : handler }; 2391 } 2392 queries[q].addHandler(handler); 2393 }); 2394 2395 return this; 2396 }, 2397 2398 /** 2399 * unregisters a query and all it's handlers, or a specific handler for a query 2400 * 2401 * @param {string} q the media query to target 2402 * @param {object || function} [handler] specific handler to unregister 2403 */ 2404 unregister : function(q, handler) { 2405 var query = this.queries[q]; 2406 2407 if(query) { 2408 if(handler) { 2409 query.removeHandler(handler); 2410 } 2411 else { 2412 query.clear(); 2413 delete this.queries[q]; 2414 } 2415 } 2416 2417 return this; 2418 } 2419 }; 2420 2421 return new MediaQueryDispatch(); 2422 2423}));; 2424/** 2425 * hoverIntent is similar to jQuery's built-in "hover" method except that 2426 * instead of firing the handlerIn function immediately, hoverIntent checks 2427 * to see if the user's mouse has slowed down (beneath the sensitivity 2428 * threshold) before firing the event. The handlerOut function is only 2429 * called after a matching handlerIn. 2430 * 2431 * hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+ 2432 * http://cherne.net/brian/resources/jquery.hoverIntent.html 2433 * 2434 * You may use hoverIntent under the terms of the MIT license. Basically that 2435 * means you are free to use hoverIntent as long as this header is left intact. 2436 * Copyright 2007, 2013 Brian Cherne 2437 * 2438 * // basic usage ... just like .hover() 2439 * .hoverIntent( handlerIn, handlerOut ) 2440 * .hoverIntent( handlerInOut ) 2441 * 2442 * // basic usage ... with event delegation! 2443 * .hoverIntent( handlerIn, handlerOut, selector ) 2444 * .hoverIntent( handlerInOut, selector ) 2445 * 2446 * // using a basic configuration object 2447 * .hoverIntent( config ) 2448 * 2449 * @param handlerIn function OR configuration object 2450 * @param handlerOut function OR selector for delegation OR undefined 2451 * @param selector selector OR undefined 2452 * @author Brian Cherne <brian(at)cherne(dot)net> 2453 **/ 2454(function($) { 2455 $.fn.hoverIntent = function(handlerIn,handlerOut,selector) { 2456 2457 // default configuration values 2458 var cfg = { 2459 interval: 100, 2460 sensitivity: 7, 2461 timeout: 0 2462 }; 2463 2464 if ( typeof handlerIn === "object" ) { 2465 cfg = $.extend(cfg, handlerIn ); 2466 } else if ($.isFunction(handlerOut)) { 2467 cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } ); 2468 } else { 2469 cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } ); 2470 } 2471 2472 // instantiate variables 2473 // cX, cY = current X and Y position of mouse, updated by mousemove event 2474 // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval 2475 var cX, cY, pX, pY; 2476 2477 // A private function for getting mouse position 2478 var track = function(ev) { 2479 cX = ev.pageX; 2480 cY = ev.pageY; 2481 }; 2482 2483 // A private function for comparing current and previous mouse position 2484 var compare = function(ev,ob) { 2485 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 2486 // compare mouse positions to see if they've crossed the threshold 2487 if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { 2488 $(ob).off("mousemove.hoverIntent",track); 2489 // set hoverIntent state to true (so mouseOut can be called) 2490 ob.hoverIntent_s = 1; 2491 return cfg.over.apply(ob,[ev]); 2492 } else {
2493 // set previous coordinates for next time 2494 pX = cX; pY = cY; 2495 // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) 2496 ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); 2497 } 2498 }; 2499 2500 // A private function for delaying the mouseOut function 2501 var delay = function(ev,ob) { 2502 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 2503 ob.hoverIntent_s = 0; 2504 return cfg.out.apply(ob,[ev]); 2505 }; 2506 2507 // A private function for handling mouse 'hovering' 2508 var handleHover = function(e) { 2509 // copy objects to be passed into t (required for event object to be passed in IE) 2510 var ev = jQuery.extend({},e); 2511 var ob = this; 2512 2513 // cancel hoverIntent timer if it exists 2514 if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } 2515 2516 // if e.type == "mouseenter" 2517 if (e.type == "mouseenter") { 2518 // set "previous" X and Y position based on initial entry point 2519 pX = ev.pageX; pY = ev.pageY; 2520 // update "current" X and Y position based on mousemove 2521 $(ob).on("mousemove.hoverIntent",track); 2522 // start polling interval (self-calling timeout) to compare mouse coordinates over time 2523 if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} 2524 2525 // else e.type == "mouseleave" 2526 } else { 2527 // unbind expensive mousemove event 2528 $(ob).off("mousemove.hoverIntent",track); 2529 // if hoverIntent state is true, then call the mouseOut function after the specified delay 2530 if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} 2531 } 2532 }; 2533 2534 // listen for mouseenter and mouseleave 2535 return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector); 2536 }; 2537})(jQuery);; 2538/* 2539 * jQuery Superfish Menu Plugin - v1.7.5 2540 * Copyright (c) 2014 Joel Birch 2541 * 2542 * Dual licensed under the MIT and GPL licenses: 2543 * http://www.opensource.org/licenses/mit-license.php 2544 * http://www.gnu.org/licenses/gpl.html 2545 */ 2546 2547;(function ($, w) { 2548 "use strict"; 2549 2550 var methods = (function () { 2551 // private properties and methods go here 2552 var c = { 2553 bcClass: 'sf-breadcrumb', 2554 menuClass: 'sf-js-enabled', 2555 anchorClass: 'sf-with-ul', 2556 menuArrowClass: 'sf-arrows' 2557 }, 2558 ios = (function () { 2559 var ios = /iPhone|iPad|iPod/i.test(navigator.userAgent); 2560 if (ios) { 2561 // iOS clicks only bubble as far as body children 2562 $(w).load(function () { 2563 $('body').children().on('click', $.noop); 2564 }); 2565 } 2566 return ios; 2567 })(), 2568 wp7 = (function () { 2569 var style = document.documentElement.style; 2570 return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent)); 2571 })(), 2572 unprefixedPointerEvents = (function () { 2573 return (!!w.PointerEvent); 2574 })(), 2575 toggleMenuClasses = function ($menu, o) { 2576 var classes = c.menuClass; 2577 if (o.cssArrows) { 2578 classes += ' ' + c.menuArrowClass; 2579 } 2580 $menu.toggleClass(classes); 2581 }, 2582 setPathToCurrent = function ($menu, o) { 2583 return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels) 2584 .addClass(o.hoverClass + ' ' + c.bcClass) 2585 .filter(function () { 2586 return ($(this).children(o.popUpSelector).hide().show().length); 2587 }).removeClass(o.pathClass); 2588 }, 2589 toggleAnchorClass = function ($li) { 2590 $li.children('a').toggleClass(c.anchorClass); 2591 }, 2592 toggleTouchAction = function ($menu) { 2593 var msTouchAction = $menu.css('ms-touch-action'); 2594 var touchAction = $menu.css('touch-action'); 2595 touchAction = touchAction || msTouchAction; 2596 touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y'; 2597 $menu.css({ 2598 'ms-touch-action': touchAction, 2599 'touch-action': touchAction 2600 }); 2601 }, 2602 applyHandlers = function ($menu, o) { 2603 var targets = 'li:has(' + o.popUpSelector + ')'; 2604 if ($.fn.hoverIntent && !o.disableHI) { 2605 $menu.hoverIntent(over, out, targets); 2606 } 2607 else { 2608 $menu 2609 .on('mouseenter.superfish', targets, over)
vendor: 4,773 bytes, lines 2610-2785
2610 .on('mouseleave.superfish', targets, out); 2611 } 2612 var touchevent = 'MSPointerDown.superfish'; 2613 if (unprefixedPointerEvents) { 2614 touchevent = 'pointerdown.superfish'; 2615 } 2616 if (!ios) { 2617 touchevent += ' touchend.superfish'; 2618 } 2619 if (wp7) { 2620 touchevent += ' mousedown.superfish'; 2621 } 2622 $menu 2623 .on('focusin.superfish', 'li', over) 2624 .on('focusout.superfish', 'li', out) 2625 .on(touchevent, 'a', o, touchHandler); 2626 }, 2627 touchHandler = function (e) { 2628 var $this = $(this), 2629 $ul = $this.siblings(e.data.popUpSelector); 2630 2631 if ($ul.length > 0 && $ul.is(':hidden')) { 2632 $this.one('click.superfish', false); 2633 if (e.type === 'MSPointerDown' || e.type === 'pointerdown') { 2634 $this.trigger('focus'); 2635 } else { 2636 $.proxy(over, $this.parent('li'))(); 2637 } 2638 } 2639 }, 2640 over = function () { 2641 var $this = $(this), 2642 o = getOptions($this); 2643 clearTimeout(o.sfTimer); 2644 $this.siblings().superfish('hide').end().superfish('show'); 2645 }, 2646 out = function () { 2647 var $this = $(this), 2648 o = getOptions($this); 2649 if (ios) { 2650 $.proxy(close, $this, o)(); 2651 } 2652 else { 2653 clearTimeout(o.sfTimer); 2654 o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay); 2655 } 2656 }, 2657 close = function (o) { 2658 o.retainPath = ($.inArray(this[0], o.$path) > -1); 2659 this.superfish('hide'); 2660 2661 if (!this.parents('.' + o.hoverClass).length) { 2662 o.onIdle.call(getMenu(this)); 2663 if (o.$path.length) { 2664 $.proxy(over, o.$path)(); 2665 } 2666 } 2667 }, 2668 getMenu = function ($el) { 2669 return $el.closest('.' + c.menuClass); 2670 }, 2671 getOptions = function ($el) { 2672 return getMenu($el).data('sf-options'); 2673 }; 2674 2675 return { 2676 // public methods 2677 hide: function (instant) { 2678 if (this.length) { 2679 var $this = this, 2680 o = getOptions($this); 2681 if (!o) { 2682 return this; 2683 } 2684 var not = (o.retainPath === true) ? o.$path : '', 2685 $ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector), 2686 speed = o.speedOut; 2687 2688 if (instant) { 2689 $ul.show(); 2690 speed = 0; 2691 } 2692 o.retainPath = false; 2693 o.onBeforeHide.call($ul); 2694 $ul.stop(true, true).animate(o.animationOut, speed, function () { 2695 var $this = $(this); 2696 o.onHide.call($this); 2697 }); 2698 } 2699 return this; 2700 }, 2701 show: function () { 2702 var o = getOptions(this); 2703 if (!o) { 2704 return this; 2705 } 2706 var $this = this.addClass(o.hoverClass), 2707 $ul = $this.children(o.popUpSelector); 2708 2709 o.onBeforeShow.call($ul); 2710 $ul.stop(true, true).animate(o.animation, o.speed, function () { 2711 o.onShow.call($ul); 2712 }); 2713 return this; 2714 }, 2715 destroy: function () { 2716 return this.each(function () { 2717 var $this = $(this), 2718 o = $this.data('sf-options'), 2719 $hasPopUp; 2720 if (!o) { 2721 return false; 2722 } 2723 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 2724 clearTimeout(o.sfTimer); 2725 toggleMenuClasses($this, o); 2726 toggleAnchorClass($hasPopUp); 2727 toggleTouchAction($this); 2728 // remove event handlers 2729 $this.off('.superfish').off('.hoverIntent'); 2730 // clear animation's inline display style 2731 $hasPopUp.children(o.popUpSelector).attr('style', function (i, style) { 2732 return style.replace(/display[^;]+;?/g, ''); 2733 }); 2734 // reset 'current' path classes 2735 o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass); 2736 $this.find('.' + o.hoverClass).removeClass(o.hoverClass); 2737 o.onDestroy.call($this); 2738 $this.removeData('sf-options'); 2739 }); 2740 }, 2741 init: function (op) { 2742 return this.each(function () { 2743 var $this = $(this); 2744 if ($this.data('sf-options')) { 2745 return false; 2746 } 2747 var o = $.extend({}, $.fn.superfish.defaults, op), 2748 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 2749 o.$path = setPathToCurrent($this, o); 2750 2751 $this.data('sf-options', o); 2752 2753 toggleMenuClasses($this, o); 2754 toggleAnchorClass($hasPopUp); 2755 toggleTouchAction($this); 2756 applyHandlers($this, o); 2757 2758 $hasPopUp.not('.' + c.bcClass).superfish('hide', true); 2759 2760 o.onInit.call(this); 2761 }); 2762 } 2763 }; 2764 })(); 2765 2766 $.fn.superfish = function (method, args) { 2767 if (methods[method]) { 2768 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 2769 } 2770 else if (typeof method === 'object' || ! method) { 2771 return methods.init.apply(this, arguments); 2772 } 2773 else { 2774 return $.error('Method ' + method + ' does not exist on jQuery.fn.superfish'); 2775 } 2776 }; 2777 2778 $.fn.superfish.defaults = { 2779 popUpSelector: 'ul,.sf-mega', // within menu context 2780 hoverClass: 'sfHover', 2781 pathClass: 'overrideThisToUse', 2782 pathLevels: 1, 2783 delay: 800, 2784 animation: {opacity: 'show'}, 2785 animationOut: {opacity: 'hide'},
2786 speed: 'normal', 2787 speedOut: 'fast', 2788 cssArrows: true, 2789 disableHI: false, 2790 onInit: $.noop, 2791 onBeforeShow: $.noop, 2792 onShow: $.noop, 2793 onBeforeHide: $.noop, 2794 onHide: $.noop, 2795 onIdle: $.noop, 2796 onDestroy: $.noop 2797 }; 2798 2799})(jQuery, window); 2800; 2801/** 2802 * Owl carousel 2803 * @version 2.0.0 2804 * @author Bartosz Wojciechowski 2805 * @license The MIT License (MIT) 2806 * @todo Lazy Load Icon 2807 * @todo prevent animationend bubling 2808 * @todo itemsScaleUp 2809 * @todo Test Zepto 2810 * @todo stagePadding calculate wrong active classes 2811 */ 2812;(function($, window, document, undefined) { 2813 2814 var drag, state, e; 2815 2816 /** 2817 * Template for status information about drag and touch events. 2818 * @private 2819 */ 2820 drag = { 2821 start: 0, 2822 startX: 0, 2823 startY: 0, 2824 current: 0, 2825 currentX: 0, 2826 currentY: 0, 2827 offsetX: 0, 2828 offsetY: 0, 2829 distance: null, 2830 startTime: 0, 2831 endTime: 0, 2832 updatedX: 0, 2833 targetEl: null 2834 }; 2835 2836 /** 2837 * Template for some status informations. 2838 * @private 2839 */ 2840 state = { 2841 isTouch: false, 2842 isScrolling: false, 2843 isSwiping: false, 2844 direction: false, 2845 inMotion: false 2846 }; 2847 2848 /** 2849 * Event functions references. 2850 * @private 2851 */ 2852 e = { 2853 _onDragStart: null, 2854 _onDragMove: null, 2855 _onDragEnd: null, 2856 _transitionEnd: null, 2857 _resizer: null, 2858 _responsiveCall: null, 2859 _goToLoop: null, 2860 _checkVisibile: null 2861 }; 2862 2863 /** 2864 * Creates a carousel. 2865 * @class The Owl Carousel. 2866 * @public 2867 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 2868 * @param {Object} [options] - The options 2869 */ 2870 function Owl(element, options) { 2871 2872 /** 2873 * Current settings for the carousel. 2874 * @public 2875 */ 2876 this.settings = null; 2877 2878 /** 2879 * Current options set by the caller including defaults. 2880 * @public 2881 */ 2882 this.options = $.extend({}, Owl.Defaults, options); 2883 2884 /** 2885 * Plugin element. 2886 * @public 2887 */ 2888 this.$element = $(element); 2889 2890 /** 2891 * Caches informations about drag and touch events. 2892 */ 2893 this.drag = $.extend({}, drag); 2894 2895 /** 2896 * Caches some status informations. 2897 * @protected 2898 */ 2899 this.state = $.extend({}, state); 2900 2901 /** 2902 * @protected 2903 * @todo Must be documented 2904 */ 2905 this.e = $.extend({}, e); 2906 2907 /** 2908 * References to the running plugins of this carousel. 2909 * @protected 2910 */ 2911 this._plugins = {}; 2912 2913 /** 2914 * Currently suppressed events to prevent them from beeing retriggered. 2915 * @protected 2916 */ 2917 this._supress = {}; 2918 2919 /** 2920 * Absolute current position. 2921 * @protected 2922 */ 2923 this._current = null; 2924 2925 /** 2926 * Animation speed in milliseconds. 2927 * @protected 2928 */ 2929 this._speed = null; 2930 2931 /** 2932 * Coordinates of all items in pixel. 2933 * @todo The name of this member is missleading. 2934 * @protected 2935 */ 2936 this._coordinates = []; 2937 2938 /** 2939 * Current breakpoint. 2940 * @todo Real media queries would be nice. 2941 * @protected 2942 */ 2943 this._breakpoint = null; 2944 2945 /** 2946 * Current width of the plugin element. 2947 */ 2948 this._width = null; 2949 2950 /** 2951 * All real items. 2952 * @protected 2953 */ 2954 this._items = []; 2955 2956 /** 2957 * All cloned items. 2958 * @protected 2959 */ 2960 this._clones = []; 2961 2962 /** 2963 * Merge values of all items. 2964 * @todo Maybe this could be part of a plugin. 2965 * @protected 2966 */ 2967 this._mergers = []; 2968 2969 /** 2970 * Invalidated parts within the update process. 2971 * @protected 2972 */ 2973 this._invalidated = {}; 2974 2975 /** 2976 * Ordered list of workers for the update process. 2977 * @protected 2978 */ 2979 this._pipe = []; 2980 2981 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 2982 this._plugins[key[0].toLowerCase() + key.slice(1)] 2983 = new plugin(this); 2984 }, this)); 2985 2986 $.each(Owl.Pipe, $.proxy(function(priority, worker) { 2987 this._pipe.push({ 2988 'filter': worker.filter, 2989 'run': $.proxy(worker.run, this) 2990 }); 2991 }, this)); 2992 2993 this.setup(); 2994 this.initialize(); 2995 } 2996 2997 /** 2998 * Default options for the carousel. 2999 * @public 3000 */ 3001 Owl.Defaults = { 3002 items: 3, 3003 loop: false, 3004 center: false, 3005 3006 mouseDrag: true, 3007 touchDrag: true, 3008 pullDrag: true, 3009 freeDrag: false, 3010 3011 margin: 0, 3012 stagePadding: 0, 3013 3014 merge: false, 3015 mergeFit: true, 3016 autoWidth: false, 3017 3018 startPosition: 0, 3019 rtl: false, 3020 3021 smartSpeed: 250, 3022 fluidSpeed: false, 3023 dragEndSpeed: false, 3024 3025 responsive: {}, 3026 responsiveRefreshRate: 200, 3027 responsiveBaseElement: window,
3028 responsiveClass: false, 3029 3030 fallbackEasing: 'swing', 3031 3032 info: false, 3033 3034 nestedItemSelector: false, 3035 itemElement: 'div', 3036 stageElement: 'div', 3037 3038 // Classes and Names 3039 themeClass: 'owl-theme', 3040 baseClass: 'owl-carousel', 3041 itemClass: 'owl-item', 3042 centerClass: 'center', 3043 activeClass: 'active' 3044 }; 3045 3046 /** 3047 * Enumeration for width. 3048 * @public 3049 * @readonly 3050 * @enum {String} 3051 */ 3052 Owl.Width = { 3053 Default: 'default', 3054 Inner: 'inner', 3055 Outer: 'outer' 3056 }; 3057 3058 /** 3059 * Contains all registered plugins. 3060 * @public 3061 */ 3062 Owl.Plugins = {}; 3063 3064 /** 3065 * Update pipe. 3066 */ 3067 Owl.Pipe = [ { 3068 filter: [ 'width', 'items', 'settings' ], 3069 run: function(cache) { 3070 cache.current = this._items && this._items[this.relative(this._current)]; 3071 } 3072 }, { 3073 filter: [ 'items', 'settings' ], 3074 run: function() { 3075 var cached = this._clones, 3076 clones = this.$stage.children('.cloned'); 3077 3078 if (clones.length !== cached.length || (!this.settings.loop && cached.length > 0)) { 3079 this.$stage.children('.cloned').remove(); 3080 this._clones = []; 3081 } 3082 } 3083 }, { 3084 filter: [ 'items', 'settings' ], 3085 run: function() { 3086 var i, n, 3087 clones = this._clones, 3088 items = this._items, 3089 delta = this.settings.loop ? clones.length - Math.max(this.settings.items * 2, 4) : 0; 3090 3091 for (i = 0, n = Math.abs(delta / 2); i < n; i++) { 3092 if (delta > 0) { 3093 this.$stage.children().eq(items.length + clones.length - 1).remove(); 3094 clones.pop(); 3095 this.$stage.children().eq(0).remove(); 3096 clones.pop(); 3097 } else { 3098 clones.push(clones.length / 2); 3099 this.$stage.append(items[clones[clones.length - 1]].clone().addClass('cloned')); 3100 clones.push(items.length - 1 - (clones.length - 1) / 2); 3101 this.$stage.prepend(items[clones[clones.length - 1]].clone().addClass('cloned')); 3102 } 3103 } 3104 } 3105 }, { 3106 filter: [ 'width', 'items', 'settings' ], 3107 run: function() { 3108 var rtl = (this.settings.rtl ? 1 : -1), 3109 width = (this.width() / this.settings.items).toFixed(3), 3110 coordinate = 0, merge, i, n; 3111 3112 this._coordinates = []; 3113 for (i = 0, n = this._clones.length + this._items.length; i < n; i++) { 3114 merge = this._mergers[this.relative(i)]; 3115 merge = (this.settings.mergeFit && Math.min(merge, this.settings.items)) || merge; 3116 coordinate += (this.settings.autoWidth ? this._items[this.relative(i)].width() + this.settings.margin : width * merge) * rtl; 3117 3118 this._coordinates.push(coordinate); 3119 } 3120 } 3121 }, { 3122 filter: [ 'width', 'items', 'settings' ], 3123 run: function() { 3124 var i, n, width = (this.width() / this.settings.items).toFixed(3), css = { 3125 'width': Math.abs(this._coordinates[this._coordinates.length - 1]) + this.settings.stagePadding * 2, 3126 'padding-left': this.settings.stagePadding || '', 3127 'padding-right': this.settings.stagePadding || '' 3128 }; 3129 3130 this.$stage.css(css); 3131 3132 css = { 'width': this.settings.autoWidth ? 'auto' : width - this.settings.margin }; 3133 css[this.settings.rtl ? 'margin-left' : 'margin-right'] = this.settings.margin; 3134 3135 if (!this.settings.autoWidth && $.grep(this._mergers, function(v) { return v > 1 }).length > 0) { 3136 for (i = 0, n = this._coordinates.length; i < n; i++) { 3137 css.width = Math.abs(this._coordinates[i]) - Math.abs(this._coordinates[i - 1] || 0) - this.settings.margin; 3138 this.$stage.children().eq(i).css(css); 3139 } 3140 } else { 3141 this.$stage.children().css(css); 3142 } 3143 } 3144 }, { 3145 filter: [ 'width', 'items', 'settings' ], 3146 run: function(cache) { 3147 cache.current && this.reset(this.$stage.children().index(cache.current)); 3148 } 3149 }, { 3150 filter: [ 'position' ], 3151 run: function() { 3152 this.animate(this.coordinates(this._current)); 3153 } 3154 }, { 3155 filter: [ 'width', 'position', 'items', 'settings' ], 3156 run: function() { 3157 var rtl = this.settings.rtl ? 1 : -1, 3158 padding = this.settings.stagePadding * 2, 3159 begin = this.coordinates(this.current()) + padding, 3160 end = begin + this.width() * rtl, 3161 inner, outer, matches = [], i, n; 3162 3163 for (i = 0, n = this._coordinates.length; i < n; i++) { 3164 inner = this._coordinates[i - 1] || 0; 3165 outer = Math.abs(this._coordinates[i]) + padding * rtl; 3166 3167 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 3168 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 3169 matches.push(i); 3170 } 3171 } 3172 3173 this.$stage.children('.' + this.settings.activeClass).removeClass(this.settings.activeClass); 3174 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass(this.settings.activeClass); 3175 3176 if (this.settings.center) { 3177 this.$stage.children('.' + this.settings.centerClass).removeClass(this.settings.centerClass); 3178 this.$stage.children().eq(this.current()).addClass(this.settings.centerClass); 3179 } 3180 } 3181 } ]; 3182 3183 /** 3184 * Initializes the carousel. 3185 * @protected 3186 */ 3187 Owl.prototype.initialize = function() { 3188 this.trigger('initialize'); 3189 3190 this.$element 3191 .addClass(this.settings.baseClass) 3192 .addClass(this.settings.themeClass) 3193 .toggleClass('owl-rtl', this.settings.rtl); 3194 3195 // check support 3196 this.browserSupport(); 3197 3198 if (this.settings.autoWidth && this.state.imagesLoaded !== true) { 3199 var imgs, nestedSelector, width; 3200 imgs = this.$element.find('img'); 3201 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 3202 width = this.$element.children(nestedSelector).width(); 3203 3204 if (imgs.length && width <= 0) { 3205 this.preloadAutoWidthImages(imgs); 3206 return false;
3207 } 3208 } 3209 3210 this.$element.addClass('owl-loading'); 3211 3212 // create stage 3213 this.$stage = $('<' + this.settings.stageElement + ' class="owl-stage"/>') 3214 .wrap('<div class="owl-stage-outer">'); 3215 3216 // append stage 3217 this.$element.append(this.$stage.parent()); 3218 3219 // append content 3220 this.replace(this.$element.children().not(this.$stage.parent())); 3221 3222 // set view width 3223 this._width = this.$element.width(); 3224 3225 // update view 3226 this.refresh(); 3227 3228 this.$element.removeClass('owl-loading').addClass('owl-loaded'); 3229 3230 // attach generic events 3231 this.eventsCall(); 3232 3233 // attach generic events 3234 this.internalEvents(); 3235 3236 // attach custom control events 3237 this.addTriggerableEvents(); 3238 3239 this.trigger('initialized'); 3240 }; 3241 3242 /** 3243 * Setups the current settings. 3244 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 3245 * @todo Support for media queries by using `matchMedia` would be nice. 3246 * @public 3247 */ 3248 Owl.prototype.setup = function() { 3249 var viewport = this.viewport(), 3250 overwrites = this.options.responsive, 3251 match = -1, 3252 settings = null; 3253 3254 if (!overwrites) { 3255 settings = $.extend({}, this.options); 3256 } else { 3257 $.each(overwrites, function(breakpoint) { 3258 if (breakpoint <= viewport && breakpoint > match) { 3259 match = Number(breakpoint); 3260 } 3261 }); 3262 3263 settings = $.extend({}, this.options, overwrites[match]); 3264 delete settings.responsive; 3265 3266 // responsive class 3267 if (settings.responsiveClass) { 3268 this.$element.attr('class', function(i, c) { 3269 return c.replace(/\b owl-responsive-\S+/g, ''); 3270 }).addClass('owl-responsive-' + match); 3271 } 3272 } 3273 3274 if (this.settings === null || this._breakpoint !== match) { 3275 this.trigger('change', { property: { name: 'settings', value: settings } }); 3276 this._breakpoint = match; 3277 this.settings = settings; 3278 this.invalidate('settings'); 3279 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 3280 } 3281 }; 3282 3283 /** 3284 * Updates option logic if necessery. 3285 * @protected 3286 */ 3287 Owl.prototype.optionsLogic = function() { 3288 // Toggle Center class 3289 this.$element.toggleClass('owl-center', this.settings.center); 3290 3291 // if items number is less than in body 3292 if (this.settings.loop && this._items.length < this.settings.items) { 3293 this.settings.loop = false; 3294 } 3295 3296 if (this.settings.autoWidth) { 3297 this.settings.stagePadding = false; 3298 this.settings.merge = false; 3299 } 3300 }; 3301 3302 /** 3303 * Prepares an item before add. 3304 * @todo Rename event parameter `content` to `item`. 3305 * @protected 3306 * @returns {jQuery|HTMLElement} - The item container. 3307 */ 3308 Owl.prototype.prepare = function(item) { 3309 var event = this.trigger('prepare', { content: item }); 3310 3311 if (!event.data) { 3312 event.data = $('<' + this.settings.itemElement + '/>') 3313 .addClass(this.settings.itemClass).append(item) 3314 } 3315 3316 this.trigger('prepared', { content: event.data }); 3317 3318 return event.data; 3319 }; 3320 3321 /** 3322 * Updates the view. 3323 * @public 3324 */ 3325 Owl.prototype.update = function() { 3326 var i = 0, 3327 n = this._pipe.length, 3328 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 3329 cache = {}; 3330 3331 while (i < n) { 3332 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 3333 this._pipe[i].run(cache); 3334 } 3335 i++; 3336 } 3337 3338 this._invalidated = {}; 3339 }; 3340 3341 /** 3342 * Gets the width of the view. 3343 * @public 3344 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 3345 * @returns {Number} - The width of the view in pixel. 3346 */ 3347 Owl.prototype.width = function(dimension) { 3348 dimension = dimension || Owl.Width.Default; 3349 switch (dimension) { 3350 case Owl.Width.Inner: 3351 case Owl.Width.Outer: 3352 return this._width; 3353 default: 3354 return this._width - this.settings.stagePadding * 2 + this.settings.margin; 3355 } 3356 }; 3357 3358 /** 3359 * Refreshes the carousel primarily for adaptive purposes. 3360 * @public 3361 */ 3362 Owl.prototype.refresh = function() { 3363 if (this._items.length === 0) { 3364 return false; 3365 } 3366 3367 var start = new Date().getTime(); 3368 3369 this.trigger('refresh'); 3370 3371 this.setup(); 3372 3373 this.optionsLogic(); 3374 3375 // hide and show methods helps here to set a proper widths, 3376 // this prevents scrollbar to be calculated in stage width 3377 this.$stage.addClass('owl-refresh'); 3378 3379 this.update(); 3380 3381 this.$stage.removeClass('owl-refresh'); 3382 3383 this.state.orientation = window.orientation; 3384 3385 this.watchVisibility(); 3386 3387 this.trigger('refreshed'); 3388 }; 3389 3390 /** 3391 * Save internal event references and add event based functions. 3392 * @protected 3393 */ 3394 Owl.prototype.eventsCall = function() { 3395 // Save events references 3396 this.e._onDragStart = $.proxy(function(e) { 3397 this.onDragStart(e); 3398 }, this); 3399 this.e._onDragMove = $.proxy(function(e) { 3400 this.onDragMove(e); 3401 }, this); 3402 this.e._onDragEnd = $.proxy(function(e) { 3403 this.onDragEnd(e); 3404 }, this); 3405 this.e._onResize = $.proxy(function(e) { 3406 this.onResize(e); 3407 }, this); 3408 this.e._transitionEnd = $.proxy(function(e) { 3409 this.transitionEnd(e); 3410 }, this); 3411 this.e._preventClick = $.proxy(function(e) { 3412 this.preventClick(e); 3413 }, this); 3414 }; 3415 3416 /** 3417 * Checks window `resize` event. 3418 * @protected 3419 */ 3420 Owl.prototype.onThrottledResize = function() { 3421 window.clearTimeout(this.resizeTimer); 3422 this.resizeTimer = window.setTimeout(this.e._onResize, this.settings.responsiveRefreshRate); 3423 }; 3424 3425 /** 3426 * Checks window `resize` event. 3427 * @protected 3428 */ 3429 Owl.prototype.onResize = function() { 3430 if (!this._items.length) { 3431 return false;
3432 } 3433 3434 if (this._width === this.$element.width()) { 3435 return false; 3436 } 3437 3438 if (this.trigger('resize').isDefaultPrevented()) { 3439 return false; 3440 } 3441 3442 this._width = this.$element.width(); 3443 3444 this.invalidate('width'); 3445 3446 this.refresh(); 3447 3448 this.trigger('resized'); 3449 }; 3450 3451 /** 3452 * Checks for touch/mouse drag event type and add run event handlers. 3453 * @protected 3454 */ 3455 Owl.prototype.eventsRouter = function(event) { 3456 var type = event.type; 3457 3458 if (type === "mousedown" || type === "touchstart") { 3459 this.onDragStart(event); 3460 } else if (type === "mousemove" || type === "touchmove") { 3461 this.onDragMove(event); 3462 } else if (type === "mouseup" || type === "touchend") { 3463 this.onDragEnd(event); 3464 } else if (type === "touchcancel") { 3465 this.onDragEnd(event); 3466 } 3467 }; 3468 3469 /** 3470 * Checks for touch/mouse drag options and add necessery event handlers. 3471 * @protected 3472 */ 3473 Owl.prototype.internalEvents = function() { 3474 var isTouch = isTouchSupport(), 3475 isTouchIE = isTouchSupportIE(); 3476 3477 if (this.settings.mouseDrag){ 3478 this.$stage.on('mousedown', $.proxy(function(event) { this.eventsRouter(event) }, this)); 3479 this.$stage.on('dragstart', function() { return false }); 3480 this.$stage.get(0).onselectstart = function() { return false }; 3481 } else { 3482 this.$element.addClass('owl-text-select-on'); 3483 } 3484 3485 if (this.settings.touchDrag && !isTouchIE){ 3486 this.$stage.on('touchstart touchcancel', $.proxy(function(event) { this.eventsRouter(event) }, this)); 3487 } 3488 3489 // catch transitionEnd event 3490 if (this.transitionEndVendor) { 3491 this.on(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd, false); 3492 } 3493 3494 // responsive 3495 if (this.settings.responsive !== false) { 3496 this.on(window, 'resize', $.proxy(this.onThrottledResize, this)); 3497 } 3498 }; 3499 3500 /** 3501 * Handles touchstart/mousedown event. 3502 * @protected 3503 * @param {Event} event - The event arguments. 3504 */ 3505 Owl.prototype.onDragStart = function(event) { 3506 var ev, isTouchEvent, pageX, pageY, animatedPos; 3507 3508 ev = event.originalEvent || event || window.event; 3509 3510 // prevent right click 3511 if (ev.which === 3 || this.state.isTouch) { 3512 return false; 3513 } 3514 3515 if (ev.type === 'mousedown') { 3516 this.$stage.addClass('owl-grab'); 3517 } 3518 3519 this.trigger('drag'); 3520 this.drag.startTime = new Date().getTime(); 3521 this.speed(0); 3522 this.state.isTouch = true; 3523 this.state.isScrolling = false; 3524 this.state.isSwiping = false; 3525 this.drag.distance = 0; 3526 3527 pageX = getTouches(ev).x; 3528 pageY = getTouches(ev).y; 3529 3530 // get stage position left 3531 this.drag.offsetX = this.$stage.position().left; 3532 this.drag.offsetY = this.$stage.position().top; 3533 3534 if (this.settings.rtl) { 3535 this.drag.offsetX = this.$stage.position().left + this.$stage.width() - this.width() 3536 + this.settings.margin; 3537 } 3538 3539 // catch position // ie to fix 3540 if (this.state.inMotion && this.support3d) { 3541 animatedPos = this.getTransformProperty(); 3542 this.drag.offsetX = animatedPos; 3543 this.animate(animatedPos); 3544 this.state.inMotion = true; 3545 } else if (this.state.inMotion && !this.support3d) { 3546 this.state.inMotion = false; 3547 return false; 3548 } 3549 3550 this.drag.startX = pageX - this.drag.offsetX; 3551 this.drag.startY = pageY - this.drag.offsetY; 3552 3553 this.drag.start = pageX - this.drag.startX; 3554 this.drag.targetEl = ev.target || ev.srcElement; 3555 this.drag.updatedX = this.drag.start; 3556 3557 // to do/check 3558 // prevent links and images dragging; 3559 if (this.drag.targetEl.tagName === "IMG" || this.drag.targetEl.tagName === "A") { 3560 this.drag.targetEl.draggable = false; 3561 } 3562 3563 $(document).on('mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents', $.proxy(function(event) {this.eventsRouter(event)},this)); 3564 }; 3565 3566 /** 3567 * Handles the touchmove/mousemove events. 3568 * @todo Simplify 3569 * @protected 3570 * @param {Event} event - The event arguments. 3571 */ 3572 Owl.prototype.onDragMove = function(event) { 3573 var ev, isTouchEvent, pageX, pageY, minValue, maxValue, pull; 3574 3575 if (!this.state.isTouch) { 3576 return; 3577 } 3578 3579 if (this.state.isScrolling) { 3580 return; 3581 } 3582 3583 ev = event.originalEvent || event || window.event; 3584 3585 pageX = getTouches(ev).x; 3586 pageY = getTouches(ev).y; 3587 3588 // Drag Direction 3589 this.drag.currentX = pageX - this.drag.startX; 3590 this.drag.currentY = pageY - this.drag.startY; 3591 this.drag.distance = this.drag.currentX - this.drag.offsetX; 3592 3593 // Check move direction 3594 if (this.drag.distance < 0) { 3595 this.state.direction = this.settings.rtl ? 'right' : 'left'; 3596 } else if (this.drag.distance > 0) { 3597 this.state.direction = this.settings.rtl ? 'left' : 'right'; 3598 } 3599 // Loop 3600 if (this.settings.loop) { 3601 if (this.op(this.drag.currentX, '>', this.coordinates(this.minimum())) && this.state.direction === 'right') { 3602 this.drag.currentX -= (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length); 3603 } else if (this.op(this.drag.currentX, '<', this.coordinates(this.maximum())) && this.state.direction === 'left') { 3604 this.drag.currentX += (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length); 3605 } 3606 } else { 3607 // pull 3608 minValue = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 3609 maxValue = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 3610 pull = this.settings.pullDrag ? this.drag.distance / 5 : 0; 3611 this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull); 3612 } 3613 3614 // Lock browser if swiping horizontal 3615 3616 if ((this.drag.distance > 8 || this.drag.distance < -8)) { 3617 if (ev.preventDefault !== undefined) { 3618 ev.preventDefault(); 3619 } else { 3620 ev.returnValue = false;
3621 } 3622 this.state.isSwiping = true; 3623 } 3624 3625 this.drag.updatedX = this.drag.currentX; 3626 3627 // Lock Owl if scrolling 3628 if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) { 3629 this.state.isScrolling = true; 3630 this.drag.updatedX = this.drag.start; 3631 } 3632 3633 this.animate(this.drag.updatedX); 3634 }; 3635 3636 /** 3637 * Handles the touchend/mouseup events. 3638 * @protected 3639 */ 3640 Owl.prototype.onDragEnd = function(event) { 3641 var compareTimes, distanceAbs, closest; 3642 3643 if (!this.state.isTouch) { 3644 return; 3645 } 3646 3647 if (event.type === 'mouseup') { 3648 this.$stage.removeClass('owl-grab'); 3649 } 3650 3651 this.trigger('dragged'); 3652 3653 // prevent links and images dragging; 3654 this.drag.targetEl.removeAttribute("draggable"); 3655 3656 // remove drag event listeners 3657 3658 this.state.isTouch = false; 3659 this.state.isScrolling = false; 3660 this.state.isSwiping = false; 3661 3662 // to check 3663 if (this.drag.distance === 0 && this.state.inMotion !== true) { 3664 this.state.inMotion = false; 3665 return false; 3666 } 3667 3668 // prevent clicks while scrolling 3669 3670 this.drag.endTime = new Date().getTime(); 3671 compareTimes = this.drag.endTime - this.drag.startTime; 3672 distanceAbs = Math.abs(this.drag.distance); 3673 3674 // to test 3675 if (distanceAbs > 3 || compareTimes > 300) { 3676 this.removeClick(this.drag.targetEl); 3677 } 3678 3679 closest = this.closest(this.drag.updatedX); 3680 3681 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 3682 this.current(closest); 3683 this.invalidate('position'); 3684 this.update(); 3685 3686 // if pullDrag is off then fire transitionEnd event manually when stick 3687 // to border 3688 if (!this.settings.pullDrag && this.drag.updatedX === this.coordinates(closest)) { 3689 this.transitionEnd(); 3690 } 3691 3692 this.drag.distance = 0; 3693 3694 $(document).off('.owl.dragEvents'); 3695 }; 3696 3697 /** 3698 * Attaches `preventClick` to disable link while swipping. 3699 * @protected 3700 * @param {HTMLElement} [target] - The target of the `click` event. 3701 */ 3702 Owl.prototype.removeClick = function(target) { 3703 this.drag.targetEl = target; 3704 $(target).on('click.preventClick', this.e._preventClick); 3705 // to make sure click is removed: 3706 window.setTimeout(function() { 3707 $(target).off('click.preventClick'); 3708 }, 300); 3709 }; 3710 3711 /** 3712 * Suppresses click event. 3713 * @protected 3714 * @param {Event} ev - The event arguments. 3715 */ 3716 Owl.prototype.preventClick = function(ev) { 3717 if (ev.preventDefault) { 3718 ev.preventDefault(); 3719 } else { 3720 ev.returnValue = false; 3721 } 3722 if (ev.stopPropagation) { 3723 ev.stopPropagation(); 3724 } 3725 $(ev.target).off('click.preventClick'); 3726 }; 3727 3728 /** 3729 * Catches stage position while animate (only CSS3). 3730 * @protected 3731 * @returns 3732 */ 3733 Owl.prototype.getTransformProperty = function() { 3734 var transform, matrix3d; 3735 3736 transform = window.getComputedStyle(this.$stage.get(0), null).getPropertyValue(this.vendorName + 'transform'); 3737 // var transform = this.$stage.css(this.vendorName + 'transform') 3738 transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(','); 3739 matrix3d = transform.length === 16; 3740 3741 return matrix3d !== true ? transform[4] : transform[12]; 3742 }; 3743 3744 /** 3745 * Gets absolute position of the closest item for a coordinate. 3746 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 3747 * @protected 3748 * @param {Number} coordinate - The coordinate in pixel. 3749 * @return {Number} - The absolute position of the closest item. 3750 */ 3751 Owl.prototype.closest = function(coordinate) { 3752 var position = -1, pull = 30, width = this.width(), coordinates = this.coordinates(); 3753 3754 if (!this.settings.freeDrag) { 3755 // check closest item 3756 $.each(coordinates, $.proxy(function(index, value) { 3757 if (coordinate > value - pull && coordinate < value + pull) { 3758 position = index; 3759 } else if (this.op(coordinate, '<', value) 3760 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 3761 position = this.state.direction === 'left' ? index + 1 : index; 3762 } 3763 return position === -1; 3764 }, this)); 3765 } 3766 3767 if (!this.settings.loop) { 3768 // non loop boundries 3769 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 3770 position = coordinate = this.minimum(); 3771 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 3772 position = coordinate = this.maximum(); 3773 } 3774 } 3775 3776 return position; 3777 }; 3778 3779 /** 3780 * Animates the stage. 3781 * @public 3782 * @param {Number} coordinate - The coordinate in pixels. 3783 */ 3784 Owl.prototype.animate = function(coordinate) { 3785 this.trigger('translate'); 3786 this.state.inMotion = this.speed() > 0; 3787 3788 if (this.support3d) { 3789 this.$stage.css({ 3790 transform: 'translate3d(' + coordinate + 'px' + ',0px, 0px)', 3791 transition: (this.speed() / 1000) + 's' 3792 }); 3793 } else if (this.state.isTouch) { 3794 this.$stage.css({ 3795 left: coordinate + 'px' 3796 }); 3797 } else { 3798 this.$stage.animate({ 3799 left: coordinate 3800 }, this.speed() / 1000, this.settings.fallbackEasing, $.proxy(function() { 3801 if (this.state.inMotion) { 3802 this.transitionEnd(); 3803 } 3804 }, this)); 3805 } 3806 }; 3807 3808 /** 3809 * Sets the absolute position of the current item. 3810 * @public 3811 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 3812 * @returns {Number} - The absolute position of the current item. 3813 */ 3814 Owl.prototype.current = function(position) { 3815 if (position === undefined) { 3816 return this._current; 3817 } 3818 3819 if (this._items.length === 0) { 3820 return undefined; 3821 } 3822 3823 position = this.normalize(position); 3824 3825 if (this._current !== position) { 3826 var event = this.trigger('change', { property: { name: 'position', value: position } }); 3827 3828 if (event.data !== undefined) { 3829 position = this.normalize(event.data); 3830 } 3831 3832 this._current = position; 3833 3834 this.invalidate('position'); 3835 3836 this.trigger('changed', { property: { name: 'position', value: this._current } }); 3837 } 3838 3839 return this._current; 3840 }; 3841 3842 /** 3843 * Invalidates the given part of the update routine. 3844 * @param {String}
3844 part - The part to invalidate. 3845 */ 3846 Owl.prototype.invalidate = function(part) { 3847 this._invalidated[part] = true; 3848 } 3849 3850 /** 3851 * Resets the absolute position of the current item. 3852 * @public 3853 * @param {Number} position - The absolute position of the new item. 3854 */ 3855 Owl.prototype.reset = function(position) { 3856 position = this.normalize(position); 3857 3858 if (position === undefined) { 3859 return; 3860 } 3861 3862 this._speed = 0; 3863 this._current = position; 3864 3865 this.suppress([ 'translate', 'translated' ]); 3866 3867 this.animate(this.coordinates(position)); 3868 3869 this.release([ 'translate', 'translated' ]); 3870 }; 3871 3872 /** 3873 * Normalizes an absolute or a relative position for an item. 3874 * @public 3875 * @param {Number} position - The absolute or relative position to normalize. 3876 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 3877 * @returns {Number} - The normalized position. 3878 */ 3879 Owl.prototype.normalize = function(position, relative) { 3880 var n = (relative ? this._items.length : this._items.length + this._clones.length); 3881 3882 if (!$.isNumeric(position) || n < 1) { 3883 return undefined; 3884 } 3885 3886 if (this._clones.length) { 3887 position = ((position % n) + n) % n; 3888 } else { 3889 position = Math.max(this.minimum(relative), Math.min(this.maximum(relative), position)); 3890 } 3891 3892 return position; 3893 }; 3894 3895 /** 3896 * Converts an absolute position for an item into a relative position. 3897 * @public 3898 * @param {Number} position - The absolute position to convert. 3899 * @returns {Number} - The converted position. 3900 */ 3901 Owl.prototype.relative = function(position) { 3902 position = this.normalize(position); 3903 position = position - this._clones.length / 2; 3904 return this.normalize(position, true); 3905 }; 3906 3907 /** 3908 * Gets the maximum position for an item. 3909 * @public 3910 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 3911 * @returns {Number} 3912 */ 3913 Owl.prototype.maximum = function(relative) { 3914 var maximum, width, i = 0, coordinate, 3915 settings = this.settings; 3916 3917 if (relative) { 3918 return this._items.length - 1; 3919 } 3920 3921 if (!settings.loop && settings.center) { 3922 maximum = this._items.length - 1; 3923 } else if (!settings.loop && !settings.center) { 3924 maximum = this._items.length - settings.items; 3925 } else if (settings.loop || settings.center) { 3926 maximum = this._items.length + settings.items; 3927 } else if (settings.autoWidth || settings.merge) { 3928 revert = settings.rtl ? 1 : -1; 3929 width = this.$stage.width() - this.$element.width(); 3930 while (coordinate = this.coordinates(i)) { 3931 if (coordinate * revert >= width) { 3932 break; 3933 } 3934 maximum = ++i; 3935 } 3936 } else { 3937 throw 'Can not detect maximum absolute position.' 3938 } 3939 3940 return maximum; 3941 }; 3942 3943 /** 3944 * Gets the minimum position for an item. 3945 * @public 3946 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 3947 * @returns {Number} 3948 */ 3949 Owl.prototype.minimum = function(relative) { 3950 if (relative) { 3951 return 0; 3952 } 3953 3954 return this._clones.length / 2; 3955 }; 3956 3957 /** 3958 * Gets an item at the specified relative position. 3959 * @public 3960 * @param {Number} [position] - The relative position of the item. 3961 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 3962 */ 3963 Owl.prototype.items = function(position) { 3964 if (position === undefined) { 3965 return this._items.slice(); 3966 } 3967 3968 position = this.normalize(position, true); 3969 return this._items[position]; 3970 }; 3971 3972 /** 3973 * Gets an item at the specified relative position. 3974 * @public 3975 * @param {Number} [position] - The relative position of the item. 3976 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 3977 */ 3978 Owl.prototype.mergers = function(position) { 3979 if (position === undefined) { 3980 return this._mergers.slice(); 3981 } 3982 3983 position = this.normalize(position, true); 3984 return this._mergers[position]; 3985 }; 3986 3987 /** 3988 * Gets the absolute positions of clones for an item. 3989 * @public 3990 * @param {Number} [position] - The relative position of the item. 3991 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 3992 */ 3993 Owl.prototype.clones = function(position) { 3994 var odd = this._clones.length / 2, 3995 even = odd + this._items.length, 3996 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd
3996- (index + 1) / 2 }; 3997 3998 if (position === undefined) { 3999 return $.map(this._clones, function(v, i) { return map(i) }); 4000 } 4001 4002 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 4003 }; 4004 4005 /** 4006 * Sets the current animation speed. 4007 * @public 4008 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 4009 * @returns {Number} - The current animation speed in milliseconds. 4010 */ 4011 Owl.prototype.speed = function(speed) { 4012 if (speed !== undefined) { 4013 this._speed = speed; 4014 } 4015 4016 return this._speed; 4017 }; 4018 4019 /** 4020 * Gets the coordinate of an item. 4021 * @todo The name of this method is missleanding. 4022 * @public 4023 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 4024 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 4025 */ 4026 Owl.prototype.coordinates = function(position) { 4027 var coordinate = null; 4028 4029 if (position === undefined) { 4030 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 4031 return this.coordinates(index); 4032 }, this)); 4033 } 4034 4035 if (this.settings.center) { 4036 coordinate = this._coordinates[position]; 4037 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 4038 } else { 4039 coordinate = this._coordinates[position - 1] || 0; 4040 } 4041 4042 return coordinate; 4043 }; 4044 4045 /** 4046 * Calculates the speed for a translation. 4047 * @protected 4048 * @param {Number} from - The absolute position of the start item. 4049 * @param {Number} to - The absolute position of the target item. 4050 * @param {Number} [factor=undefined] - The time factor in milliseconds. 4051 * @returns {Number} - The time in milliseconds for the translation. 4052 */ 4053 Owl.prototype.duration = function(from, to, factor) { 4054 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 4055 }; 4056 4057 /** 4058 * Slides to the specified item. 4059 * @public 4060 * @param {Number} position - The position of the item. 4061 * @param {Number} [speed] - The time in milliseconds for the transition. 4062 */ 4063 Owl.prototype.to = function(position, speed) { 4064 if (this.settings.loop) { 4065 var distance = position - this.relative(this.current()), 4066 revert = this.current(), 4067 before = this.current(), 4068 after = this.current() + distance, 4069 direction = before - after < 0 ? true : false, 4070 items = this._clones.length + this._items.length; 4071 4072 if (after < this.settings.items && direction === false) { 4073 revert = before + this._items.length; 4074 this.reset(revert); 4075 } else if (after >= items - this.settings.items && direction === true) { 4076 revert = before - this._items.length; 4077 this.reset(revert); 4078 } 4079 window.clearTimeout(this.e._goToLoop); 4080 this.e._goToLoop = window.setTimeout($.proxy(function() { 4081 this.speed(this.duration(this.current(), revert + distance, speed)); 4082 this.current(revert + distance); 4083 this.update(); 4084 }, this), 30); 4085 } else { 4086 this.speed(this.duration(this.current(), position, speed)); 4087 this.current(position); 4088 this.update(); 4089 } 4090 }; 4091 4092 /** 4093 * Slides to the next item. 4094 * @public 4095 * @param {Number} [speed] - The time in milliseconds for the transition. 4096 */ 4097 Owl.prototype.next = function(speed) { 4098 speed = speed || false; 4099 this.to(this.relative(this.current()) + 1, speed); 4100 }; 4101 4102 /** 4103 * Slides to the previous item. 4104 * @public 4105 * @param {Number} [speed] - The time in milliseconds for the transition. 4106 */ 4107 Owl.prototype.prev = function(speed) { 4108 speed = speed || false; 4109 this.to(this.relative(this.current()) - 1, speed); 4110 }; 4111 4112 /** 4113 * Handles the end of an animation. 4114 * @protected 4115 * @param {Event} event - The event arguments. 4116 */ 4117 Owl.prototype.transitionEnd = function(event) { 4118 4119 // if css2 animation then event object is undefined 4120 if (event !== undefined) { 4121 event.stopPropagation(); 4122 4123 // Catch only owl-stage transitionEnd event 4124 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 4125 return false; 4126 } 4127 } 4128 4129 this.state.inMotion = false; 4130 this.trigger('translated'); 4131 }; 4132 4133 /** 4134 * Gets viewport width. 4135 * @protected 4136 * @return {Number} - The width in pixel. 4137 */ 4138 Owl.prototype.viewport = function() { 4139 var width; 4140 if (this.options.responsiveBaseElement !== window) { 4141 width = $(this.options.responsiveBaseElement).width(); 4142 } else if (window.innerWidth) { 4143 width = window.innerWidth; 4144 } else if (document.documentElement && document.documentElement.clientWidth) { 4145 width = document.documentElement.clientWidth; 4146 } else { 4147 throw 'Can not detect viewport width.'; 4148 } 4149 return width; 4150 }; 4151 4152 /** 4153 * Replaces the current content. 4154 * @public 4155 * @param {HTMLElement|jQuery|String} content - The new content. 4156 */ 4157 Owl.prototype.replace = function(content) { 4158 this.$stage.empty(); 4159 this._items = []; 4160 4161 if (content) { 4162 content = (content instanceof jQuery) ? content : $(content); 4163 } 4164 4165 if (this.settings.nestedItemSelector) { 4166 content = content.find('.' + this.settings.nestedItemSelector); 4167 } 4168 4169 content.filter(function() { 4170 return this.nodeType === 1; 4171 }).each($.proxy(function(index, item) { 4172 item = this.prepare(item); 4173 this.$stage.append(item); 4174 this._items.push(item); 4175 this._mergers.push(item.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 4176 }, this)); 4177 4178 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 4179 4180 this.invalidate('items'); 4181 }; 4182 4183 /** 4184 * Adds an item. 4185 * @todo Use `item` instead of `content` for the event arguments. 4186 * @public 4187 * @param {HTMLElement|jQuery|String} content - The item content to add. 4188 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 4189 */ 4190 Owl.prototype.add = function(content, position) { 4191 position = position === undefined ? this._items.length : this.normalize(position, true); 4192 4193 this.trigger('add', { content: content, position: position }); 4194 4195 if (this._items.length === 0 || position === this._items.length) { 4196 this.$stage.append(content); 4197 this._items.push(content); 4198 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 4199 } else { 4200 this._items[position].before(content); 4201 this._items.splice(position, 0, content); 4202 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 4203 } 4204 4205 this.invalidate('items'); 4206 4207 this.trigger('added', { content: content, position: position }); 4208 }; 4209 4210 /** 4211 * Removes an item by its position. 4212 * @todo Use `item` instead of `content` for the event arguments. 4213 * @public 4214 * @param {Number} position - The relative position of the item to remove. 4215 */ 4216 Owl.prototype.remove = function(position) { 4217 position = this.normalize(position, true); 4218 4219 if (position === undefined) { 4220 return; 4221 } 4222
4223 this.trigger('remove', { content: this._items[position], position: position }); 4224 4225 this._items[position].remove(); 4226 this._items.splice(position, 1); 4227 this._mergers.splice(position, 1); 4228 4229 this.invalidate('items'); 4230 4231 this.trigger('removed', { content: null, position: position }); 4232 }; 4233 4234 /** 4235 * Adds triggerable events. 4236 * @protected 4237 */ 4238 Owl.prototype.addTriggerableEvents = function() { 4239 var handler = $.proxy(function(callback, event) { 4240 return $.proxy(function(e) { 4241 if (e.relatedTarget !== this) { 4242 this.suppress([ event ]); 4243 callback.apply(this, [].slice.call(arguments, 1)); 4244 this.release([ event ]); 4245 } 4246 }, this); 4247 }, this); 4248 4249 $.each({ 4250 'next': this.next, 4251 'prev': this.prev, 4252 'to': this.to, 4253 'destroy': this.destroy, 4254 'refresh': this.refresh, 4255 'replace': this.replace, 4256 'add': this.add, 4257 'remove': this.remove 4258 }, $.proxy(function(event, callback) { 4259 this.$element.on(event + '.owl.carousel', handler(callback, event + '.owl.carousel')); 4260 }, this)); 4261 4262 }; 4263 4264 /** 4265 * Watches the visibility of the carousel element. 4266 * @protected 4267 */ 4268 Owl.prototype.watchVisibility = function() { 4269 4270 // test on zepto 4271 if (!isElVisible(this.$element.get(0))) { 4272 this.$element.addClass('owl-hidden'); 4273 window.clearInterval(this.e._checkVisibile); 4274 this.e._checkVisibile = window.setInterval($.proxy(checkVisible, this), 500); 4275 } 4276 4277 function isElVisible(el) { 4278 return el.offsetWidth > 0 && el.offsetHeight > 0; 4279 } 4280 4281 function checkVisible() { 4282 if (isElVisible(this.$element.get(0))) { 4283 this.$element.removeClass('owl-hidden'); 4284 this.refresh(); 4285 window.clearInterval(this.e._checkVisibile); 4286 } 4287 } 4288 }; 4289 4290 /** 4291 * Preloads images with auto width. 4292 * @protected 4293 * @todo Still to test 4294 */ 4295 Owl.prototype.preloadAutoWidthImages = function(imgs) { 4296 var loaded, that, $el, img; 4297 4298 loaded = 0; 4299 that = this; 4300 imgs.each(function(i, el) { 4301 $el = $(el); 4302 img = new Image(); 4303 4304 img.onload = function() { 4305 loaded++; 4306 $el.attr('src', img.src); 4307 $el.css('opacity', 1); 4308 if (loaded >= imgs.length) { 4309 that.state.imagesLoaded = true; 4310 that.initialize(); 4311 } 4312 }; 4313 4314 img.src = $el.attr('src') || $el.attr('data-src') || $el.attr('data-src-retina'); 4315 }); 4316 }; 4317 4318 /** 4319 * Destroys the carousel. 4320 * @public 4321 */ 4322 Owl.prototype.destroy = function() { 4323 4324 if (this.$element.hasClass(this.settings.themeClass)) { 4325 this.$element.removeClass(this.settings.themeClass); 4326 } 4327 4328 if (this.settings.responsive !== false) { 4329 $(window).off('resize.owl.carousel'); 4330 } 4331 4332 if (this.transitionEndVendor) { 4333 this.off(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd); 4334 } 4335 4336 for ( var i in this._plugins) { 4337 this._plugins[i].destroy(); 4338 } 4339 4340 if (this.settings.mouseDrag || this.settings.touchDrag) { 4341 this.$stage.off('mousedown touchstart touchcancel'); 4342 $(document).off('.owl.dragEvents'); 4343 this.$stage.get(0).onselectstart = function() {}; 4344 this.$stage.off('dragstart', function() { return false }); 4345 } 4346 4347 // remove event handlers in the ".owl.carousel" namespace 4348 this.$element.off('.owl'); 4349 4350 this.$stage.children('.cloned').remove(); 4351 this.e = null; 4352 this.$element.removeData('owlCarousel'); 4353 4354 this.$stage.children().contents().unwrap(); 4355 this.$stage.children().unwrap(); 4356 this.$stage.unwrap(); 4357 }; 4358 4359 /** 4360 * Operators to calculate right-to-left and left-to-right. 4361 * @protected 4362 * @param {Number} [a] - The left side operand. 4363 * @param {String} [o] - The operator. 4364 * @param {Number} [b] - The right side operand. 4365 */ 4366 Owl.prototype.op = function(a, o, b) { 4367 var rtl = this.settings.rtl; 4368 switch (o) { 4369 case '<': 4370 return rtl ? a > b : a < b; 4371 case '>': 4372 return rtl ? a < b : a > b; 4373 case '>=': 4374 return rtl ? a <= b : a >= b; 4375 case '<=': 4376 return rtl ? a >= b : a <= b; 4377 default: 4378 break; 4379 } 4380 }; 4381 4382 /** 4383 * Attaches to an internal event. 4384 * @protected 4385 * @param {HTMLElement} element - The event source. 4386 * @param {String} event - The event name. 4387 * @param {Function} listener - The event handler to attach. 4388 * @param {Boolean} capture - Wether the event should be handled at the capturing p
4388hase or not. 4389 */ 4390 Owl.prototype.on = function(element, event, listener, capture) { 4391 if (element.addEventListener) { 4392 element.addEventListener(event, listener, capture); 4393 } else if (element.attachEvent) { 4394 element.attachEvent('on' + event, listener); 4395 } 4396 }; 4397 4398 /** 4399 * Detaches from an internal event. 4400 * @protected 4401 * @param {HTMLElement} element - The event source. 4402 * @param {String} event - The event name. 4403 * @param {Function} listener - The attached event handler to detach. 4404 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 4405 */ 4406 Owl.prototype.off = function(element, event, listener, capture) { 4407 if (element.removeEventListener) { 4408 element.removeEventListener(event, listener, capture); 4409 } else if (element.detachEvent) { 4410 element.detachEvent('on' + event, listener); 4411 } 4412 }; 4413 4414 /** 4415 * Triggers an public event. 4416 * @protected 4417 * @param {String} name - The event name. 4418 * @param {*} [data=null] - The event data. 4419 * @param {String} [namespace=.owl.carousel] - The event namespace. 4420 * @returns {Event} - The event arguments. 4421 */ 4422 Owl.prototype.trigger = function(name, data, namespace) { 4423 var status = { 4424 item: { count: this._items.length, index: this.current() } 4425 }, handler = $.camelCase( 4426 $.grep([ 'on', name, namespace ], function(v) { return v }) 4427 .join('-').toLowerCase() 4428 ), event = $.Event( 4429 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 4430 $.extend({ relatedTarget: this }, status, data) 4431 ); 4432 4433 if (!this._supress[name]) { 4434 $.each(this._plugins, function(name, plugin) { 4435 if (plugin.onTrigger) { 4436 plugin.onTrigger(event); 4437 } 4438 }); 4439 4440 this.$element.trigger(event); 4441 4442 if (this.settings && typeof this.settings[handler] === 'function') { 4443 this.settings[handler].apply(this, event); 4444 } 4445 } 4446 4447 return event; 4448 }; 4449 4450 /** 4451 * Suppresses events. 4452 * @protected 4453 * @param {Array.<String>} events - The events to suppress. 4454 */ 4455 Owl.prototype.suppress = function(events) { 4456 $.each(events, $.proxy(function(index, event) { 4457 this._supress[event] = true; 4458 }, this)); 4459 } 4460 4461 /** 4462 * Releases suppressed events. 4463 * @protected 4464 * @param {Array.<String>} events - The events to release. 4465 */ 4466 Owl.prototype.release = function(events) { 4467 $.each(events, $.proxy(function(index, event) { 4468 delete this._supress[event]; 4469 }, this)); 4470 } 4471 4472 /** 4473 * Checks the availability of some browser features. 4474 * @protected 4475 */ 4476 Owl.prototype.browserSupport = function() { 4477 this.support3d = isPerspective(); 4478 4479 if (this.support3d) { 4480 this.transformVendor = isTransform(); 4481 4482 // take transitionend event name by detecting transition 4483 var endVendors = [ 'transitionend', 'webkitTransitionEnd', 'transitionend', 'oTransitionEnd' ]; 4484 this.transitionEndVendor = endVendors[isTransition()]; 4485 4486 // take vendor name from transform name 4487 this.vendorName = this.transformVendor.replace(/Transform/i, ''); 4488 this.vendorName = this.vendorName !== '' ? '-' + this.vendorName.toLowerCase() + '-' : ''; 4489 } 4490 4491 this.state.orientation = window.orientation; 4492 }; 4493 4494 /** 4495 * Get touch/drag coordinats. 4496 * @private 4497 * @param {event} - mousedown/touchstart event 4498 * @returns {object} - Contains X and Y of current mouse/touch position 4499 */ 4500 4501 function getTouches(event) { 4502 if (event.touches !== undefined) { 4503 return { 4504 x: event.touches[0].pageX, 4505 y: event.touches[0].pageY 4506 }; 4507 } 4508 4509 if (event.touches === undefined) { 4510 if (event.pageX !== undefined) { 4511 return { 4512 x: event.pageX, 4513 y: event.pageY 4514 }; 4515 } 4516 4517 if (event.pageX === undefined) { 4518 return { 4519 x: event.clientX, 4520 y: event.clientY 4521 }; 4522 } 4523 } 4524 } 4525 4526 /** 4527 * Checks for CSS support. 4528 * @private 4529 * @param {Array} array - The CSS properties to check for. 4530 * @returns {Array} - Contains the supported CSS property name and its index or `false`. 4531 */ 4532 function isStyleSupported(array) { 4533 var p, s, fake = document.createElement('div'), list = array; 4534 for (p in list) { 4535 s = list[p]; 4536 if (typeof fake.style[s] !== 'undefined') { 4537 fake = null; 4538 return [ s, p ]; 4539 } 4540 } 4541 return [ false ]; 4542 } 4543 4544 /** 4545 * Checks for CSS transition support. 4546 * @private 4547 * @todo Realy bad design 4548 * @returns {Number} 4549 */ 4550 function isTransition() { 4551 return isStyleSupported([ 'transition', 'WebkitTransition', 'MozTransition', 'OTransition' ])[1]; 4552 } 4553 4554 /** 4555 * Checks for CSS transform support. 4556 * @private 4557 * @returns {String} The supported property name or false. 4558 */ 4559 function isTransform() { 4560 return isStyleSupported([ 'transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ])[0]; 4561 } 4562 4563 /** 4564 * Checks for CSS perspective support. 4565 * @private 4566 * @returns {String} The supported property name or false. 4567 */ 4568 function isPerspective() { 4569 return isStyleSupported([ 'perspective', 'webkitPerspective', 'MozPerspective', 'OPerspective', 'MsPerspective' ])[0]; 4570 } 4571 4572 /** 4573 * Checks wether touch is supported or not. 4574 * @private 4575 * @returns {Boolean} 4576 */ 4577 function isTouchSupport() { 4578 return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints); 4579 } 4580 4581 /** 4582 * Checks wether touch is supported or not for IE. 4583 * @private 4584 * @returns {Boolean} 4585 */ 4586 function isTouchSupportIE() { 4587 return window.navigator.msPointerEnabled; 4588 } 4589 4590 /** 4591 * The jQuery Plugin for the Owl Carousel
4592 * @public 4593 */ 4594 $.fn.owlCarousel = function(options) { 4595 return this.each(function() { 4596 if (!$(this).data('owlCarousel')) { 4597 $(this).data('owlCarousel', new Owl(this, options)); 4598 } 4599 }); 4600 }; 4601 4602 /** 4603 * The constructor for the jQuery Plugin 4604 * @public 4605 */ 4606 $.fn.owlCarousel.Constructor = Owl; 4607 4608})(window.Zepto || window.jQuery, window, document); 4609 4610/** 4611 * Lazy Plugin 4612 * @version 2.0.0 4613 * @author Bartosz Wojciechowski 4614 * @license The MIT License (MIT) 4615 */ 4616;(function($, window, document, undefined) { 4617 4618 /** 4619 * Creates the lazy plugin. 4620 * @class The Lazy Plugin 4621 * @param {Owl} carousel - The Owl Carousel 4622 */ 4623 var Lazy = function(carousel) { 4624 4625 /** 4626 * Reference to the core. 4627 * @protected 4628 * @type {Owl} 4629 */ 4630 this._core = carousel; 4631 4632 /** 4633 * Already loaded items. 4634 * @protected 4635 * @type {Array.<jQuery>} 4636 */ 4637 this._loaded = []; 4638 4639 /** 4640 * Event handlers. 4641 * @protected 4642 * @type {Object} 4643 */ 4644 this._handlers = { 4645 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 4646 if (!e.namespace) { 4647 return; 4648 } 4649 4650 if (!this._core.settings || !this._core.settings.lazyLoad) { 4651 return; 4652 } 4653 4654 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 4655 var settings = this._core.settings, 4656 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 4657 i = ((settings.center && n * -1) || 0), 4658 position = ((e.property && e.property.value) || this._core.current()) + i, 4659 clones = this._core.clones().length, 4660 load = $.proxy(function(i, v) { this.load(v) }, this); 4661 4662 while (i++ < n) { 4663 this.load(clones / 2 + this._core.relative(position)); 4664 clones && $.each(this._core.clones(this._core.relative(position++)), load); 4665 } 4666 } 4667 }, this) 4668 }; 4669 4670 // set the default options 4671 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 4672 4673 // register event handler 4674 this._core.$element.on(this._handlers); 4675 } 4676 4677 /** 4678 * Default options. 4679 * @public 4680 */ 4681 Lazy.Defaults = { 4682 lazyLoad: false 4683 } 4684 4685 /** 4686 * Loads all resources of an item at the specified position. 4687 * @param {Number} position - The absolute position of the item. 4688 * @protected 4689 */ 4690 Lazy.prototype.load = function(position) { 4691 var $item = this._core.$stage.children().eq(position), 4692 $elements = $item && $item.find('.owl-lazy'); 4693 4694 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 4695 return; 4696 } 4697 4698 $elements.each($.proxy(function(index, element) { 4699 var $element = $(element), image, 4700 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 4701 4702 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 4703 4704 if ($element.is('img')) { 4705 $element.one('load.owl.lazy', $.proxy(function() { 4706 $element.css('opacity', 1); 4707 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 4708 }, this)).attr('src', url); 4709 } else { 4710 image = new Image(); 4711 image.onload = $.proxy(function() { 4712 $element.css({ 4713 'background-image': 'url(' + url + ')', 4714 'opacity': '1' 4715 }); 4716 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 4717 }, this); 4718 image.src = url; 4719 } 4720 }, this)); 4721 4722 this._loaded.push($item.get(0)); 4723 } 4724 4725 /** 4726 * Destroys the plugin. 4727 * @public 4728 */ 4729 Lazy.prototype.destroy = function() { 4730 var handler, property; 4731 4732 for (handler in this.handlers) { 4733 this._core.$element.off(handler, this.handlers[handler]); 4734 } 4735 for (property in Object.getOwnPropertyNames(this)) { 4736 typeof this[property] != 'function' && (this[property] = null); 4737 } 4738 } 4739 4740 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 4741 4742})(window.Zepto || window.jQuery, window, document); 4743 4744/** 4745 * AutoHeight Plugin 4746 * @version 2.0.0 4747 * @author Bartosz Wojciechowski 4748 * @license The MIT License (MIT) 4749 */ 4750;(function($, window, document, undefined) { 4751 4752 /** 4753 * Creates the auto height plugin. 4754 * @class The Auto Height Plugin 4755 * @param {Owl} carousel - The Owl Carousel 4756 */ 4757 var AutoHeight = function(carousel) { 4758 /** 4759 * Reference to the core. 4760 * @protected 4761 * @type {Owl} 4762 */ 4763 this._core = carousel; 4764 4765 /** 4766 * All event handlers. 4767 * @protected 4768 * @type {Object} 4769 */ 4770 this._handlers = { 4771 'initialized.owl.carousel': $.proxy(function() { 4772 if (this._core.settings.autoHeight) { 4773 this.update(); 4774 } 4775 }, this), 4776 'changed.owl.carousel': $.proxy(function(e) { 4777 if (this._core.settings.autoHeight && e.property.name == 'position'){ 4778 this.update(); 4779 } 4780 }, this), 4781 'loaded.owl.lazy': $.proxy(function(e) { 4782 if (this._core.settings.autoHeight && e.element.closest('.' + this._core.settings.itemClass) 4783 === this._core.$stage.children().eq(this._core.current())) { 4784 this.update(); 4785 } 4786 }, this) 4787 }; 4788 4789 // set default options 4790 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 4791 4792 // register event handlers 4793 this._core.$element.on(this._handlers); 4794 }; 4795 4796 /** 4797 * Default options. 4798 * @public 4799 */ 4800 AutoHeight.Defaults = { 4801 autoHeight: false, 4802 autoHeightClass: 'owl-height' 4803 }; 4804 4805 /** 4806 * Updates the view. 4807 */ 4808 AutoHeight.prototype.update = function() { 4809 this._core.$stage.parent() 4810 .height(this._core.$stage.children().eq(this._core.current()).height()) 4811 .addClass(this._core.settings.autoHeightClass); 4812 }; 4813 4814 AutoHeight.prototype.destroy = function() { 4815 var handler, property; 4816 4817 for (handler in this._handlers) { 4818 this._core.$element.off(handler, this._handlers[handler]); 4819 } 4820 for (property in Object.getOwnPropertyNames(this)) { 4821 typeof this[property] != 'function' && (this[property] = null); 4822 } 4823 }; 4824 4825 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 4826 4827})(window.Zepto || window.jQuery, window, document); 4828 4829/** 4830 * Video Plugin 4831 * @version 2.0.0 4832 * @author Bartosz Wojciechowski 4833 * @license The MIT License (MIT) 4834 */ 4835;(function($, window, document, undefined) { 4836 4837 /** 4838 * Creates the video plugin. 4839 * @class The Video Plugin 4840 * @param {Owl} carousel - The Owl Carousel
4841 */ 4842 var Video = function(carousel) { 4843 /** 4844 * Reference to the core. 4845 * @protected 4846 * @type {Owl} 4847 */ 4848 this._core = carousel; 4849 4850 /** 4851 * Cache all video URLs. 4852 * @protected 4853 * @type {Object} 4854 */ 4855 this._videos = {}; 4856 4857 /** 4858 * Current playing item. 4859 * @protected 4860 * @type {jQuery} 4861 */ 4862 this._playing = null; 4863 4864 /** 4865 * Whether this is in fullscreen or not. 4866 * @protected 4867 * @type {Boolean} 4868 */ 4869 this._fullscreen = false; 4870 4871 /** 4872 * All event handlers. 4873 * @protected 4874 * @type {Object} 4875 */ 4876 this._handlers = { 4877 'resize.owl.carousel': $.proxy(function(e) { 4878 if (this._core.settings.video && !this.isInFullScreen()) { 4879 e.preventDefault(); 4880 } 4881 }, this), 4882 'refresh.owl.carousel changed.owl.carousel': $.proxy(function(e) { 4883 if (this._playing) { 4884 this.stop(); 4885 } 4886 }, this), 4887 'prepared.owl.carousel': $.proxy(function(e) { 4888 var $element = $(e.content).find('.owl-video'); 4889 if ($element.length) { 4890 $element.css('display', 'none'); 4891 this.fetch($element, $(e.content)); 4892 } 4893 }, this) 4894 }; 4895 4896 // set default options 4897 this._core.options = $.extend({}, Video.Defaults, this._core.options); 4898 4899 // register event handlers 4900 this._core.$element.on(this._handlers); 4901 4902 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 4903 this.play(e); 4904 }, this)); 4905 }; 4906 4907 /** 4908 * Default options. 4909 * @public 4910 */ 4911 Video.Defaults = { 4912 video: false, 4913 videoHeight: false, 4914 videoWidth: false 4915 }; 4916 4917 /** 4918 * Gets the video ID and the type (YouTube/Vimeo only). 4919 * @protected 4920 * @param {jQuery} target - The target containing the video data. 4921 * @param {jQuery} item - The item containing the video. 4922 */ 4923 Video.prototype.fetch = function(target, item) { 4924 4925 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 4926 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 4927 width = target.attr('data-width') || this._core.settings.videoWidth, 4928 height = target.attr('data-height') || this._core.settings.videoHeight, 4929 url = target.attr('href'); 4930 4931 if (url) { 4932 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+)?/); 4933 4934 if (id[3].indexOf('youtu') > -1) { 4935 type = 'youtube'; 4936 } else if (id[3].indexOf('vimeo') > -1) { 4937 type = 'vimeo'; 4938 } else { 4939 throw new Error('Video URL not supported.'); 4940 } 4941 id = id[6]; 4942 } else { 4943 throw new Error('Missing video URL.'); 4944 } 4945 4946 this._videos[url] = { 4947 type: type, 4948 id: id, 4949 width: width, 4950 height: height 4951 }; 4952 4953 item.attr('data-video', url); 4954 4955 this.thumbnail(target, this._videos[url]); 4956 }; 4957 4958 /** 4959 * Creates video thumbnail. 4960 * @protected 4961 * @param {jQuery} target - The target containing the video data. 4962 * @param {Object} info - The video info object. 4963 * @see `fetch` 4964 */ 4965 Video.prototype.thumbnail = function(target, video) { 4966 4967 var tnLink, 4968 icon, 4969 path, 4970 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 4971 customTn = target.find('img'), 4972 srcType = 'src', 4973 lazyClass = '', 4974 settings = this._core.settings, 4975 create = function(path) { 4976 icon = '<div class="owl-video-play-icon"></div>'; 4977 4978 if (settings.lazyLoad) { 4979 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 4980 } else { 4981 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 4982 } 4983 target.after(tnLink); 4984 target.after(icon); 4985 }; 4986 4987 // wrap video content into owl-video-wrapper div 4988 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 4989 4990 if (this._core.settings.lazyLoad) { 4991 srcType = 'data-src'; 4992 lazyClass = 'owl-lazy'; 4993 } 4994 4995 // custom thumbnail 4996 if (customTn.length) { 4997 create(customTn.attr(srcType)); 4998 customTn.remove(); 4999 return false; 5000 } 5001 5002 if (video.type === 'youtube') { 5003 path = "http://img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 5004 create(path); 5005 } else if (video.type === 'vimeo') { 5006 $.ajax({ 5007 type: 'GET', 5008 url: 'http://vimeo.com/api/v2/video/' + video.id + '.json', 5009 jsonp: 'callback', 5010 dataType: 'jsonp', 5011 success: function(data) { 5012 path = data[0].thumbnail_large; 5013 create(path); 5014 } 5015 }); 5016 } 5017 }; 5018 5019 /** 5020 * Stops the current video. 5021 * @public 5022 */ 5023 Video.prototype.stop = function() { 5024 this._core.trigger('stop', null, 'video'); 5025 this._playing.find('.owl-video-frame').remove(); 5026 this._playing.removeClass('owl-video-playing'); 5027 this._playing = null; 5028 }; 5029 5030 /** 5031 * Starts the current video. 5032 * @public 5033 * @param {Event} ev - The event arguments. 5034 */ 5035 Video.prototype.play = function(ev) { 5036 this._core.trigger('play', null, 'video'); 5037 5038 if (this._playing) { 5039 this.stop(); 5040 } 5041 5042 var target = $(ev.target || ev.srcElement), 5043 item = target.closest('.' + this._core.settings.itemClass), 5044 video = this._videos[item.attr('data-video')], 5045 width = video.width || '100%', 5046 height = video.height || this._core.$stage.height(), 5047 html, wrap; 5048 5049 if (video.type === 'youtube') { 5050 html = '<iframe width="' + width + '" height="' + height + '" src="http://www.youtube.com/embed/' 5051 + video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 5052 } else if (video.type === 'vimeo') { 5053 html = '<iframe src="http://player.vimeo.com/video/' + video.id + '?autoplay=1" width="' + width 5054 + '" height="' + height
5055 + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 5056 } 5057 5058 item.addClass('owl-video-playing'); 5059 this._playing = item; 5060 5061 wrap = $('<div style="height:' + height + 'px; width:' + width + 'px" class="owl-video-frame">' 5062 + html + '</div>'); 5063 target.after(wrap); 5064 }; 5065 5066 /** 5067 * Checks whether an video is currently in full screen mode or not. 5068 * @todo Bad style because looks like a readonly method but changes members. 5069 * @protected 5070 * @returns {Boolean} 5071 */ 5072 Video.prototype.isInFullScreen = function() { 5073 5074 // if Vimeo Fullscreen mode 5075 var element = document.fullscreenElement || document.mozFullScreenElement 5076 || document.webkitFullscreenElement; 5077 5078 if (element && $(element).parent().hasClass('owl-video-frame')) { 5079 this._core.speed(0); 5080 this._fullscreen = true; 5081 } 5082 5083 if (element && this._fullscreen && this._playing) { 5084 return false; 5085 } 5086 5087 // comming back from fullscreen 5088 if (this._fullscreen) { 5089 this._fullscreen = false; 5090 return false; 5091 } 5092 5093 // check full screen mode and window orientation 5094 if (this._playing) { 5095 if (this._core.state.orientation !== window.orientation) { 5096 this._core.state.orientation = window.orientation; 5097 return false; 5098 } 5099 } 5100 5101 return true; 5102 }; 5103 5104 /** 5105 * Destroys the plugin. 5106 */ 5107 Video.prototype.destroy = function() { 5108 var handler, property; 5109 5110 this._core.$element.off('click.owl.video'); 5111 5112 for (handler in this._handlers) { 5113 this._core.$element.off(handler, this._handlers[handler]); 5114 } 5115 for (property in Object.getOwnPropertyNames(this)) { 5116 typeof this[property] != 'function' && (this[property] = null); 5117 } 5118 }; 5119 5120 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 5121 5122})(window.Zepto || window.jQuery, window, document); 5123 5124/** 5125 * Animate Plugin 5126 * @version 2.0.0 5127 * @author Bartosz Wojciechowski 5128 * @license The MIT License (MIT) 5129 */ 5130;(function($, window, document, undefined) { 5131 5132 /** 5133 * Creates the animate plugin. 5134 * @class The Navigation Plugin 5135 * @param {Owl} scope - The Owl Carousel 5136 */ 5137 var Animate = function(scope) { 5138 this.core = scope; 5139 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 5140 this.swapping = true; 5141 this.previous = undefined; 5142 this.next = undefined; 5143 5144 this.handlers = { 5145 'change.owl.carousel': $.proxy(function(e) { 5146 if (e.property.name == 'position') { 5147 this.previous = this.core.current(); 5148 this.next = e.property.value; 5149 } 5150 }, this), 5151 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 5152 this.swapping = e.type == 'translated'; 5153 }, this), 5154 'translate.owl.carousel': $.proxy(function(e) { 5155 if (this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 5156 this.swap(); 5157 } 5158 }, this) 5159 }; 5160 5161 this.core.$element.on(this.handlers); 5162 }; 5163 5164 /** 5165 * Default options. 5166 * @public 5167 */ 5168 Animate.Defaults = { 5169 animateOut: false, 5170 animateIn: false 5171 }; 5172 5173 /** 5174 * Toggles the animation classes whenever an translations starts. 5175 * @protected 5176 * @returns {Boolean|undefined} 5177 */ 5178 Animate.prototype.swap = function() { 5179 5180 if (this.core.settings.items !== 1 || !this.core.support3d) { 5181 return; 5182 } 5183 5184 this.core.speed(0); 5185 5186 var left, 5187 clear = $.proxy(this.clear, this), 5188 previous = this.core.$stage.children().eq(this.previous), 5189 next = this.core.$stage.children().eq(this.next), 5190 incoming = this.core.settings.animateIn, 5191 outgoing = this.core.settings.animateOut; 5192 5193 if (this.core.current() === this.previous) { 5194 return; 5195 } 5196 5197 if (outgoing) { 5198 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 5199 previous.css( { 'left': left + 'px' } ) 5200 .addClass('animated owl-animated-out') 5201 .addClass(outgoing) 5202 .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); 5203 } 5204 5205 if (incoming) { 5206 next.addClass('animated owl-animated-in') 5207 .addClass(incoming) 5208 .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); 5209 } 5210 }; 5211 5212 Animate.prototype.clear = function(e) { 5213 $(e.target).css( { 'left': '' } ) 5214 .removeClass('animated owl-animated-out owl-animated-in') 5215 .removeClass(this.core.settings.animateIn) 5216 .removeClass(this.core.settings.animateOut); 5217 this.core.transitionEnd(); 5218 } 5219 5220 /** 5221 * Destroys the plugin. 5222 * @public 5223 */ 5224 Animate.prototype.destroy = function() { 5225 var handler, property; 5226 5227 for (handler in this.handlers) { 5228 this.core.$element.off(handler, this.handlers[handler]); 5229 } 5230 for (property in Object.getOwnPropertyNames(this)) { 5231 typeof this[property] != 'function' && (this[property] = null); 5232 } 5233 }; 5234 5235 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 5236 5237})(window.Zepto || window.jQuery, window, document); 5238 5239/** 5240 * Autoplay Plugin 5241 * @version 2.0.0 5242 * @author Bartosz Wojciechowski 5243 * @license The MIT License (MIT) 5244 */ 5245;(function($, window, document, undefined) { 5246 5247 /** 5248 * Creates the autoplay plugin. 5249 * @class The Autoplay Plugin 5250 * @param {Owl} scope - The Owl Carousel
5251 */ 5252 var Autoplay = function(scope) { 5253 this.core = scope; 5254 this.core.options = $.extend({}, Autoplay.Defaults, this.core.options); 5255 5256 this.handlers = { 5257 'translated.owl.carousel refreshed.owl.carousel': $.proxy(function() { 5258 this.autoplay(); 5259 }, this), 5260 'play.owl.autoplay': $.proxy(function(e, t, s) { 5261 this.play(t, s); 5262 }, this), 5263 'stop.owl.autoplay': $.proxy(function() { 5264 this.stop(); 5265 }, this), 5266 'mouseover.owl.autoplay': $.proxy(function() { 5267 if (this.core.settings.autoplayHoverPause) { 5268 this.pause(); 5269 } 5270 }, this), 5271 'mouseleave.owl.autoplay': $.proxy(function() { 5272 if (this.core.settings.autoplayHoverPause) { 5273 this.autoplay(); 5274 } 5275 }, this) 5276 }; 5277 5278 this.core.$element.on(this.handlers); 5279 }; 5280 5281 /** 5282 * Default options. 5283 * @public 5284 */ 5285 Autoplay.Defaults = { 5286 autoplay: false, 5287 autoplayTimeout: 5000, 5288 autoplayHoverPause: false, 5289 autoplaySpeed: false 5290 }; 5291 5292 /** 5293 * @protected 5294 * @todo Must be documented. 5295 */ 5296 Autoplay.prototype.autoplay = function() { 5297 if (this.core.settings.autoplay && !this.core.state.videoPlay) { 5298 window.clearInterval(this.interval); 5299 5300 this.interval = window.setInterval($.proxy(function() { 5301 this.play(); 5302 }, this), this.core.settings.autoplayTimeout); 5303 } else { 5304 window.clearInterval(this.interval); 5305 } 5306 }; 5307 5308 /** 5309 * Starts the autoplay. 5310 * @public 5311 * @param {Number} [timeout] - ... 5312 * @param {Number} [speed] - ... 5313 * @returns {Boolean|undefined} - ... 5314 * @todo Must be documented. 5315 */ 5316 Autoplay.prototype.play = function(timeout, speed) { 5317 // if tab is inactive - doesnt work in <IE10 5318 if (document.hidden === true) { 5319 return; 5320 } 5321 5322 if (this.core.state.isTouch || this.core.state.isScrolling 5323 || this.core.state.isSwiping || this.core.state.inMotion) { 5324 return; 5325 } 5326 5327 if (this.core.settings.autoplay === false) { 5328 window.clearInterval(this.interval); 5329 return; 5330 } 5331 5332 this.core.next(this.core.settings.autoplaySpeed); 5333 }; 5334 5335 /** 5336 * Stops the autoplay. 5337 * @public 5338 */ 5339 Autoplay.prototype.stop = function() { 5340 window.clearInterval(this.interval); 5341 }; 5342 5343 /** 5344 * Pauses the autoplay. 5345 * @public 5346 */ 5347 Autoplay.prototype.pause = function() { 5348 window.clearInterval(this.interval); 5349 }; 5350 5351 /** 5352 * Destroys the plugin. 5353 */ 5354 Autoplay.prototype.destroy = function() { 5355 var handler, property; 5356 5357 window.clearInterval(this.interval); 5358 5359 for (handler in this.handlers) { 5360 this.core.$element.off(handler, this.handlers[handler]); 5361 } 5362 for (property in Object.getOwnPropertyNames(this)) { 5363 typeof this[property] != 'function' && (this[property] = null); 5364 } 5365 }; 5366 5367 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 5368 5369})(window.Zepto || window.jQuery, window, document); 5370 5371/** 5372 * Navigation Plugin 5373 * @version 2.0.0 5374 * @author Artus Kolanowski 5375 * @license The MIT License (MIT) 5376 */ 5377;(function($, window, document, undefined) { 5378 'use strict'; 5379 5380 /** 5381 * Creates the navigation plugin. 5382 * @class The Navigation Plugin 5383 * @param {Owl} carousel - The Owl Carousel. 5384 */ 5385 var Navigation = function(carousel) { 5386 /** 5387 * Reference to the core. 5388 * @protected 5389 * @type {Owl} 5390 */ 5391 this._core = carousel; 5392 5393 /** 5394 * Indicates whether the plugin is initialized or not. 5395 * @protected 5396 * @type {Boolean} 5397 */ 5398 this._initialized = false; 5399 5400 /** 5401 * The current paging indexes. 5402 * @protected 5403 * @type {Array} 5404 */ 5405 this._pages = []; 5406 5407 /** 5408 * All DOM elements of the user interface. 5409 * @protected 5410 * @type {Object} 5411 */ 5412 this._controls = {}; 5413 5414 /** 5415 * Markup for an indicator. 5416 * @protected 5417 * @type {Array.<String>} 5418 */ 5419 this._templates = []; 5420 5421 /** 5422 * The carousel element. 5423 * @type {jQuery} 5424 */ 5425 this.$element = this._core.$element; 5426 5427 /** 5428 * Overridden methods of the carousel. 5429 * @protected 5430 * @type {Object} 5431 */ 5432 this._overrides = { 5433 next: this._core.next, 5434 prev: this._core.prev, 5435 to: this._core.to 5436 }; 5437 5438 /** 5439 * All event handlers. 5440 * @protected 5441 * @type {Object} 5442 */ 5443 this._handlers = { 5444 'prepared.owl.carousel': $.proxy(function(e) { 5445 if (this._core.settings.dotsData) { 5446 this._templates.push($(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot')); 5447 } 5448 }, this), 5449 'add.owl.carousel': $.proxy(function(e) { 5450 if (this._core.settings.dotsData) { 5451 this._templates.splice(e.position, 0, $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot')); 5452 } 5453 }, this), 5454 'remove.owl.carousel prepared.owl.carousel': $.proxy(function(e) { 5455 if (this._core.settings.dotsData) { 5456 this._templates.splice(e.position, 1); 5457 } 5458 }, this), 5459 'change.owl.carousel': $.proxy(function(e) { 5460 if (e.property.name == 'position') { 5461 if (!this._core.state.revert && !this._core.settings.loop && this._core.settings.navRewind) { 5462 var current = this._core.current(), 5463 maximum = this._core.maximum(), 5464 minimum = this._core.minimum(); 5465 e.data = e.property.value > maximum 5466 ? current >= maximum ? minimum : maximum 5467 : e.property.value < minimum ? maximum : e.property.value; 5468 } 5469 } 5470 }, this), 5471 'changed.owl.carousel': $.proxy(function(e) { 5472 if (e.property.name == 'position') { 5473 this.draw(); 5474 } 5475 }, this), 5476 'refreshed.owl.carousel': $.proxy(function() { 5477 if (!this._initialized) { 5478 this.initialize(); 5479 this._initialized = true; 5480 } 5481 this._core.trigger('refresh', null, 'navigation'); 5482 this.update(); 5483 this.draw(); 5484 this._core.trigger('refreshed', null, 'navigation'); 5485 }, this) 5486 }; 5487 5488 // set default options 5489 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 5490 5491 // register event handlers 5492 this.$element.on(this._handlers); 5493 } 5494 5495 /** 5496 * Default options. 5497 * @public 5498 * @todo Rename `slideBy` to `navBy` 5499 */ 5500 Navigation.Defaults = { 5501 nav: false, 5502 navRewind: true, 5503 navText: [ 'prev', 'next' ], 5504 navSpeed: false, 5505 navElement: 'div', 5506 navContainer: false, 5507 navContainerClass: 'owl-nav', 5508 navClass: [ 'owl-prev', 'owl-next' ], 5509 slideBy: 1, 5510 dotClass: 'owl-dot', 5511 dotsClass: 'owl-dots', 5512 dots: true, 5513 dotsEach: false, 5514 dotData: false, 5515 dotsSpeed: false, 5516 dotsContainer: false,
5517 controlsClass: 'owl-controls' 5518 } 5519 5520 /** 5521 * Initializes the layout of the plugin and extends the carousel. 5522 * @protected 5523 */ 5524 Navigation.prototype.initialize = function() { 5525 var $container, override, 5526 options = this._core.settings; 5527 5528 // create the indicator template 5529 if (!options.dotsData) { 5530 this._templates = [ $('<div>') 5531 .addClass(options.dotClass) 5532 .append($('<span>')) 5533 .prop('outerHTML') ]; 5534 } 5535 5536 // create controls container if needed 5537 if (!options.navContainer || !options.dotsContainer) { 5538 this._controls.$container = $('<div>') 5539 .addClass(options.controlsClass) 5540 .appendTo(this.$element); 5541 } 5542 5543 // create DOM structure for absolute navigation 5544 this._controls.$indicators = options.dotsContainer ? $(options.dotsContainer) 5545 : $('<div>').hide().addClass(options.dotsClass).appendTo(this._controls.$container); 5546 5547 this._controls.$indicators.on('click', 'div', $.proxy(function(e) { 5548 var index = $(e.target).parent().is(this._controls.$indicators) 5549 ? $(e.target).index() : $(e.target).parent().index(); 5550 5551 e.preventDefault(); 5552 5553 this.to(index, options.dotsSpeed); 5554 }, this)); 5555 5556 // create DOM structure for relative navigation 5557 $container = options.navContainer ? $(options.navContainer) 5558 : $('<div>').addClass(options.navContainerClass).prependTo(this._controls.$container); 5559 5560 this._controls.$next = $('<' + options.navElement + '>'); 5561 this._controls.$previous = this._controls.$next.clone(); 5562 5563 this._controls.$previous 5564 .addClass(options.navClass[0]) 5565 .html(options.navText[0]) 5566 .hide() 5567 .prependTo($container) 5568 .on('click', $.proxy(function(e) { 5569 this.prev(options.navSpeed); 5570 }, this)); 5571 this._controls.$next 5572 .addClass(options.navClass[1]) 5573 .html(options.navText[1]) 5574 .hide() 5575 .appendTo($container) 5576 .on('click', $.proxy(function(e) { 5577 this.next(options.navSpeed); 5578 }, this)); 5579 5580 // override public methods of the carousel 5581 for (override in this._overrides) { 5582 this._core[override] = $.proxy(this[override], this); 5583 } 5584 } 5585 5586 /** 5587 * Destroys the plugin. 5588 * @protected 5589 */ 5590 Navigation.prototype.destroy = function() { 5591 var handler, control, property, override; 5592 5593 for (handler in this._handlers) { 5594 this.$element.off(handler, this._handlers[handler]); 5595 } 5596 for (control in this._controls) { 5597 this._controls[control].remove(); 5598 } 5599 for (override in this.overides) { 5600 this._core[override] = this._overrides[override]; 5601 } 5602 for (property in Object.getOwnPropertyNames(this)) { 5603 typeof this[property] != 'function' && (this[property] = null); 5604 } 5605 } 5606 5607 /** 5608 * Updates the internal state. 5609 * @protected 5610 */ 5611 Navigation.prototype.update = function() { 5612 var i, j, k, 5613 options = this._core.settings, 5614 lower = this._core.clones().length / 2, 5615 upper = lower + this._core.items().length, 5616 size = options.center || options.autoWidth || options.dotData 5617 ? 1 : options.dotsEach || options.items; 5618 5619 if (options.slideBy !== 'page') { 5620 options.slideBy = Math.min(options.slideBy, options.items); 5621 } 5622 5623 if (options.dots || options.slideBy == 'page') { 5624 this._pages = []; 5625 5626 for (i = lower, j = 0, k = 0; i < upper; i++) { 5627 if (j >= size || j === 0) { 5628 this._pages.push({ 5629 start: i - lower, 5630 end: i - lower + size - 1 5631 }); 5632 j = 0, ++k; 5633 } 5634 j += this._core.mergers(this._core.relative(i)); 5635 } 5636 } 5637 } 5638 5639 /** 5640 * Draws the user interface. 5641 * @todo The option `dotData` wont work. 5642 * @protected 5643 */ 5644 Navigation.prototype.draw = function() { 5645 var difference, i, html = '', 5646 options = this._core.settings, 5647 $items = this._core.$stage.children(), 5648 index = this._core.relative(this._core.current()); 5649 5650 if (options.nav && !options.loop && !options.navRewind) { 5651 this._controls.$previous.toggleClass('disabled', index <= 0); 5652 this._controls.$next.toggleClass('disabled', index >= this._core.maximum()); 5653 } 5654 5655 this._controls.$previous.toggle(options.nav); 5656 this._controls.$next.toggle(options.nav); 5657 5658 if (options.dots) { 5659 difference = this._pages.length - this._controls.$indicators.children().length; 5660 5661 if (options.dotData && difference !== 0) { 5662 for (i = 0; i < this._controls.$indicators.children().length; i++) { 5663 html += this._templates[this._core.relative(i)]; 5664 } 5665 this._controls.$indicators.html(html); 5666 } else if (difference > 0) { 5667 html = new Array(difference + 1).join(this._templates[0]); 5668 this._controls.$indicators.append(html); 5669 } else if (difference < 0) { 5670 this._controls.$indicators.children().slice(difference).remove(); 5671 } 5672 5673 this._controls.$indicators.find('.active').removeClass('active'); 5674 this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 5675 } 5676 5677 this._controls.$indicators.toggle(options.dots); 5678 } 5679 5680 /** 5681 * Extends event data. 5682 * @protected 5683 * @param {Event} event - The event object which gets thrown. 5684 */ 5685 Navigation.prototype.onTrigger = function(event) { 5686 var settings = this._core.settings; 5687 5688 event.page = { 5689 index: $.inArray(this.current(), this._pages), 5690 count: this._pages.length,
5691 size: settings && (settings.center || settings.autoWidth || settings.dotData 5692 ? 1 : settings.dotsEach || settings.items) 5693 }; 5694 } 5695 5696 /** 5697 * Gets the current page position of the carousel. 5698 * @protected 5699 * @returns {Number} 5700 */ 5701 Navigation.prototype.current = function() { 5702 var index = this._core.relative(this._core.current()); 5703 return $.grep(this._pages, function(o) { 5704 return o.start <= index && o.end >= index; 5705 }).pop(); 5706 } 5707 5708 /** 5709 * Gets the current succesor/predecessor position. 5710 * @protected 5711 * @returns {Number} 5712 */ 5713 Navigation.prototype.getPosition = function(successor) { 5714 var position, length, 5715 options = this._core.settings; 5716 5717 if (options.slideBy == 'page') { 5718 position = $.inArray(this.current(), this._pages); 5719 length = this._pages.length; 5720 successor ? ++position : --position; 5721 position = this._pages[((position % length) + length) % length].start; 5722 } else { 5723 position = this._core.relative(this._core.current()); 5724 length = this._core.items().length; 5725 successor ? position += options.slideBy : position -= options.slideBy; 5726 } 5727 return position; 5728 } 5729 5730 /** 5731 * Slides to the next item or page. 5732 * @public 5733 * @param {Number} [speed=false] - The time in milliseconds for the transition. 5734 */ 5735 Navigation.prototype.next = function(speed) { 5736 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 5737 } 5738 5739 /** 5740 * Slides to the previous item or page. 5741 * @public 5742 * @param {Number} [speed=false] - The time in milliseconds for the transition. 5743 */ 5744 Navigation.prototype.prev = function(speed) { 5745 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 5746 } 5747 5748 /** 5749 * Slides to the specified item or page. 5750 * @public 5751 * @param {Number} position - The position of the item or page. 5752 * @param {Number} [speed] - The time in milliseconds for the transition. 5753 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 5754 */ 5755 Navigation.prototype.to = function(position, speed, standard) { 5756 var length; 5757 5758 if (!standard) { 5759 length = this._pages.length; 5760 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 5761 } else { 5762 $.proxy(this._overrides.to, this._core)(position, speed); 5763 } 5764 } 5765 5766 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 5767 5768})(window.Zepto || window.jQuery, window, document); 5769 5770/** 5771 * Hash Plugin 5772 * @version 2.0.0 5773 * @author Artus Kolanowski 5774 * @license The MIT License (MIT) 5775 */ 5776;(function($, window, document, undefined) { 5777 'use strict'; 5778 5779 /** 5780 * Creates the hash plugin. 5781 * @class The Hash Plugin 5782 * @param {Owl} carousel - The Owl Carousel 5783 */ 5784 var Hash = function(carousel) { 5785 /** 5786 * Reference to the core. 5787 * @protected 5788 * @type {Owl} 5789 */ 5790 this._core = carousel; 5791 5792 /** 5793 * Hash table for the hashes. 5794 * @protected 5795 * @type {Object} 5796 */ 5797 this._hashes = {}; 5798 5799 /** 5800 * The carousel element. 5801 * @type {jQuery} 5802 */ 5803 this.$element = this._core.$element; 5804 5805 /** 5806 * All event handlers. 5807 * @protected 5808 * @type {Object} 5809 */ 5810 this._handlers = { 5811 'initialized.owl.carousel': $.proxy(function() { 5812 if (this._core.settings.startPosition == 'URLHash') { 5813 $(window).trigger('hashchange.owl.navigation'); 5814 } 5815 }, this), 5816 'prepared.owl.carousel': $.proxy(function(e) { 5817 var hash = $(e.content).find('[data-hash]').andSelf('[data-hash]').attr('data-hash'); 5818 this._hashes[hash] = e.content; 5819 }, this) 5820 }; 5821 5822 // set default options 5823 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 5824 5825 // register the event handlers 5826 this.$element.on(this._handlers); 5827 5828 // register event listener for hash navigation 5829 $(window).on('hashchange.owl.navigation', $.proxy(function() { 5830 var hash = window.location.hash.substring(1), 5831 items = this._core.$stage.children(), 5832 position = this._hashes[hash] && items.index(this._hashes[hash]) || 0; 5833 5834 if (!hash) { 5835 return false; 5836 } 5837 5838 this._core.to(position, false, true); 5839 }, this)); 5840 } 5841 5842 /** 5843 * Default options. 5844 * @public 5845 */ 5846 Hash.Defaults = { 5847 URLhashListener: false 5848 } 5849 5850 /** 5851 * Destroys the plugin. 5852 * @public 5853 */ 5854 Hash.prototype.destroy = function() { 5855 var handler, property; 5856 5857 $(window).off('hashchange.owl.navigation'); 5858 5859 for (handler in this._handlers) { 5860 this._core.$element.off(handler, this._handlers[handler]); 5861 } 5862 for (property in Object.getOwnPropertyNames(this)) { 5863 typeof this[property] != 'function' && (this[property] = null); 5864 } 5865 } 5866 5867 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 5868 5869})(window.Zepto || window.jQuery, window, document); 5870; 5871/*! 5872 * scrollup v2.4.0 5873 * Url: http://markgoodyear.com/labs/scrollup/ 5874 * Copyright (c) Mark Goodyear @markgdyr http://markgoodyear.com 5875 * License: MIT 5876 */ 5877 5878(function ($, window, document) { 5879 'use strict'; 5880 5881 // Main function 5882 $.fn.scrollUp = function (options) { 5883 5884 // Ensure that only one scrollUp exists 5885 if (!$.data(document.body, 'scrollUp')) { 5886 $.data(document.body, 'scrollUp', true); 5887 $.fn.scrollUp.init(options); 5888 } 5889 }; 5890 5891 // Init 5892 $.fn.scrollUp.init = function (options) { 5893 5894 // Define vars 5895 var o = $.fn.scrollUp.settings = $.extend({}, $.fn.scrollUp.defaults, options), 5896 triggerVisible = false, 5897 animIn, animOut, animSpeed, scrollDis, scrollEvent, scrollTarget, $self; 5898 5899 // Create element 5900 if (o.scrollTrigger) { 5901 $self = $(o.scrollTrigger); 5902 } else { 5903 $self = $('<a/>', { 5904 id: o.scrollName, 5905 href: '#top' 5906 }); 5907 } 5908 5909 // Set scrollTitle if there is one 5910 if (o.scrollTitle) { 5911 $self.attr('title', o.scrollTitle); 5912 } 5913 5914 $self.appendTo('body'); 5915 5916 // If not using an image display text 5917 if (!(o.scrollImg || o.scrollTrigger)) { 5918 $self.html(o.scrollText); 5919 } 5920 5921 // Minimum CSS to make the magic happen 5922 $self.css({ 5923 display: 'none', 5924 position: 'fixed', 5925 zIndex: o.zIndex 5926 }); 5927 5928 // Active point overlay 5929 if (o.activeOverlay) { 5930 $('<div/>', { 5931 id: o.scrollName + '-active' 5932 }).css({ 5933 position: 'absolute', 5934 'top': o.scrollDistance + 'px', 5935 width: '100%', 5936 borderTop: '1px dotted' + o.activeOverlay, 5937 zIndex: o.zIndex 5938 }).appendTo('body'); 5939 } 5940 5941 // Switch animation type 5942 switch (o.animation) { 5943 case 'fade': 5944 animIn = 'fadeIn'; 5945 animOut = 'fadeOut'; 5946 animSpeed = o.animationSpeed; 5947 break; 5948 5949 case 'slide': 5950 animIn = 'slideDown'; 5951 animOut = 'slideUp'; 5952 animSpeed = o.animationSpeed; 5953 break; 5954 5955 default: 5956 animIn = 'show'; 5957 animOut = 'hide'; 5958 animSpeed = 0; 5959 } 5960 5961 // If from top or bottom 5962 if (o.scrollFrom === 'top') { 5963 scrollDis = o.scrollDistance; 5964 } else { 5965 scrollDis = $(document).height() - $(window).height() - o.scrollDistance; 5966 } 5967 5968 // Scroll function 5969 scrollEvent = $(window).scroll(function () { 5970 if ($(window).scrollTop() > scrollDis) { 5971 if (!triggerVisible) { 5972 $self[animIn](animSpeed); 5973 triggerVisible = true; 5974 } 5975 } else { 5976 if (triggerVisible) { 5977 $self[animOut](animSpeed); 5978 triggerVisible = false;
5979 } 5980 } 5981 }); 5982 5983 if (o.scrollTarget) { 5984 if (typeof o.scrollTarget === 'number') { 5985 scrollTarget = o.scrollTarget; 5986 } else if (typeof o.scrollTarget === 'string') { 5987 scrollTarget = Math.floor($(o.scrollTarget).offset().top); 5988 } 5989 } else { 5990 scrollTarget = 0; 5991 } 5992 5993 // To the top 5994 $self.click(function (e) { 5995 e.preventDefault(); 5996 5997 $('html, body').animate({ 5998 scrollTop: scrollTarget 5999 }, o.scrollSpeed, o.easingType); 6000 }); 6001 }; 6002 6003 // Defaults 6004 $.fn.scrollUp.defaults = { 6005 scrollName: 'scrollUp', // Element ID 6006 scrollDistance: 300, // Distance from top/bottom before showing element (px) 6007 scrollFrom: 'top', // 'top' or 'bottom' 6008 scrollSpeed: 300, // Speed back to top (ms) 6009 easingType: 'linear', // Scroll to top easing (see http://easings.net/) 6010 animation: 'fade', // Fade, slide, none 6011 animationSpeed: 200, // Animation in speed (ms) 6012 scrollTrigger: false, // Set a custom triggering element. Can be an HTML string or jQuery object 6013 scrollTarget: false, // Set a custom target element for scrolling to. Can be element or number 6014 scrollText: 'Scroll to top', // Text for element, can contain HTML 6015 scrollTitle: false, // Set a custom <a> title if required. Defaults to scrollText 6016 scrollImg: false, // Set true to use image 6017 activeOverlay: false, // Set CSS color to display scrollUp active point, e.g '#00FFFF' 6018 zIndex: 2147483647 // Z-Index for the overlay 6019 }; 6020 6021 // Destroy scrollUp plugin and clean all modifications to the DOM 6022 $.fn.scrollUp.destroy = function (scrollEvent) { 6023 $.removeData(document.body, 'scrollUp'); 6024 $('#' + $.fn.scrollUp.settings.scrollName).remove(); 6025 $('#' + $.fn.scrollUp.settings.scrollName + '-active').remove(); 6026 6027 // If 1.7 or above use the new .off() 6028 if ($.fn.jquery.split('.')[1] >= 7) { 6029 $(window).off('scroll', scrollEvent); 6030 6031 // Else use the old .unbind() 6032 } else { 6033 $(window).unbind('scroll', scrollEvent); 6034 } 6035 }; 6036 6037 $.scrollUp = $.fn.scrollUp; 6038 6039})(jQuery, window, document);; 6040/** 6041 * Custom v1.0 6042 * Contains handlers for the different site functions 6043 * 6044 * Copyright (c) 2013-2015 DesignOrbital.com 6045 * License: GNU General Public License v2 or later 6046 * http://www.gnu.org/licenses/gpl-2.0.html 6047 */ 6048 6049( function( $ ) { 6050 6051 var dicot = { 6052 6053 // Menu 6054 menuInit: function() { 6055 6056 // Superfish Menu 6057 $( 'ul.sf-menu' ).superfish({ 6058 delay: 1200, 6059 animation: { opacity : 'show', height : 'show' }, 6060 speed: 'fast', 6061 autoArrows: false, 6062 cssArrows: true 6063 }); 6064 6065 }, 6066 6067 // Responsive Menu 6068 responsiveMenuInit: function() { 6069 6070 // Clone the Primary Menu and remove classes from clone to prevent css issues 6071 $primaryMenuClone = $( '.primary-menu' ).clone().removeAttr( 'class' ).addClass( 'primary-menu-responsive' ); 6072 $primaryMenuClone.removeAttr( 'style' ).find( '*' ).each( function( i,e ) { 6073 $( e ).removeAttr( 'style' ); 6074 } ); 6075 6076 // Insert the cloned menu after Primary Menu 6077 $( '<div class="site-primary-menu-responsive" />' ).insertAfter( '.site-primary-menu' ); 6078 $primaryMenuClone.appendTo( '.site-primary-menu-responsive' ); 6079 6080 // Add dropdown toggle that display child menu items. 6081 $( '.site-primary-menu-responsive .page_item_has_children > a, .site-primary-menu-responsive .menu-item-has-children > a' ).append( '<button class="dropdown-toggle fa" aria-expanded="false"/>' ); 6082 $( '.site-primary-menu-responsive .dropdown-toggle' ).off( 'click' ).on( 'click', function( e ) { 6083 e.preventDefault(); 6084 $( this ).toggleClass( 'toggle-on' ); 6085 $( this ).parent().next( '.children, .sub-menu' ).toggleClass( 'toggle-on' ); 6086 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) == 'false' ? 'true' : 'false'); 6087 } ); 6088 6089 }, 6090 6091 // Open Slide Panel 6092 slidePanelInit: function() { 6093 6094 // Elements 6095 var menuResponsive = $( '.site-primary-menu-responsive' ); 6096 var overlayEffect = $( '.overlay-effect' ); 6097 6098 // Responsive Menu Slide 6099 $( '.toggle-menu' ).off( 'click' ).on( 'click', function( e ) { 6100 6101 // Prevent Default 6102 e.preventDefault(); 6103 e.stopPropagation(); 6104 6105 // ToggleClass 6106 menuResponsive.toggleClass( 'show' ); 6107 overlayEffect.toggleClass( 'open' ); 6108 6109 } ); 6110 6111 // Overlay Slide Close 6112 overlayEffect.off( 'click' ).on( 'click', function( e ) { 6113 dicot.slidePanelCloseInit(); 6114 } ); 6115 6116 }, 6117 6118 // Close Slide Panel 6119 slidePanelCloseInit: function() { 6120 6121 // Elements 6122 var menuResponsive = $( '.site-primary-menu-responsive' ); 6123 var overlayEffect = $( '.overlay-effect' ); 6124 6125 // Slide Panel Close Logic 6126 if( overlayEffect.hasClass( 'open' ) ) { 6127 6128 // For Menu 6129 if( menuResponsive.hasClass( 'show' ) ) { 6130 menuResponsive.toggleClass( 'show' ); 6131 } 6132 6133 // Toggle Overlay Slide 6134 overlayEffect.toggleClass( 'open' ); 6135 6136 } 6137 6138 }, 6139 6140 // Blockquote Style 6141 blockquoteInit: function() { 6142 6143 $( '.has-post-thumbnail.format-quote .entry-content' ).each( function() { 6144 $( this ).find( 'blockquote' ).css( { 6145 'background-image' : 'url(' + $( this ).data( 'background' ) + ')' 6146 } ); 6147 } ); 6148 6149 }, 6150 6151 // Widget Logic 6152 widgetLogicInit: function() { 6153 6154 // Social Menu Widget 6155 $( '.widget_nav_menu > div.menu-social-menu-container' ).addClass( 'fa' ); 6156 $( '.widget_nav_menu > div.menu-social-menu-container > ul > li > a' ).wrapInner( '<span class="screen-reader-text"></span>' ); 6157 6158 // Custom Menu Widget 6159 $( '.widget_nav_menu .menu-item-has-children > a' ).append( '<span class="custom-menu-toggle fa" aria-expanded="false"></span>' ); 6160 $( '.widget_nav_menu .custom-menu-toggle' ).off( 'click' ).on( 'click', function( e ) { 6161 e.preventDefault(); 6162 $( this ).toggleClass( 'toggle-on' ); 6163 $( this ).parent().next( '.sub-menu' ).toggleClass( 'toggle-on' ); 6164 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) == 'false' ? 'true' : 'false'); 6165 } ); 6166 6167 // Pages Widget 6168 $( '.widget_pages .page_item_has_children > a' ).append( '<span class="page-toggle fa" aria-expanded="false"></span>' ); 6169 $( '.widget_pages .page-toggle' ).off( 'click' ).on( 'click', function( e ) { 6170 e.preventDefault(); 6171 $( this ).toggleClass( 'toggle-on' ); 6172 $( this ).parent().next( '.children' ).toggleClass( 'toggle-on' ); 6173 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) == 'false' ? 'true' : 'false'); 6174 } ); 6175 6176 // Categories Widget 6177 $( '.widget_categories' ).find( '.children' ).parent().addClass( 'category_item_has_children' ); 6178 $( '.widget_categories .category_item_has_children > a' ).append( '<span class="category-toggle fa" aria-expanded="false"></span>' ); 6179 $( '.widget_categories .category-toggle' ).off( 'click' ).on( 'click', function( e ) { 6180 e.preventDefault(); 6181 $( this ).toggleClass( 'toggle-on' ); 6182 $( this ).parent().next( '.children' ).toggleClass( 'toggle-on' ); 6183 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) == 'false' ? 'true' : 'false'); 6184 } ); 6185 6186 }, 6187 6188 // CSS3 Animation 6189 animationInit: function() { 6190 6191 // On Hover Effect 6192 $( '.img-postlist, .img-featured' ).hover( 6193 function() { 6194 $( this ).addClass( 'opacity-in' ); 6195 }, function() { 6196 $( this ).removeClass( 'opacity-in' ); 6197 } 6198 ); 6199 6200 }, 6201 6202 // Media Queries 6203 mqInit: function() { 6204 6205 enquire.register( 'screen and ( max-width: 767px )' , { 6206 6207 deferSetup : true, 6208 setup : function() { 6209 6210 // Responsive Menu 6211 dicot.responsiveMenuInit(); 6212 6213 }, 6214 match : function() { 6215 6216 // Sliding Panels for Menu 6217 dicot.slidePanelInit(); 6218 6219 // Document Keyup 6220 $( document ).keyup( function( e ) { 6221 6222 // Make the escape key to close the slide panel 6223 if ( e.keyCode == 27 ) { 6224 dicot.slidePanelCloseInit(); 6225 } 6226 6227 } ); 6228 6229 }, 6230 unmatch : function() { 6231 6232 // Responsive Menu Close 6233 dicot.slidePanelCloseInit(); 6234 6235 } 6236 6237 }); 6238 6239 } 6240 6241 } 6242 6243 // Document Ready 6244 $( document ).ready( function() { 6245 6246 // Menu 6247 dicot.menuInit(); 6248 6249 // Blockquote Style 6250 dicot.blockquoteInit(); 6251 6252 // Widget Logic 6253 dicot.widgetLogicInit(); 6254 6255 // CSS3 Animation 6256 dicot.animationInit(); 6257 6258 // Scroll Up 6259 $.scrollUp({ 6260 scrollDistance: 500, 6261 animation: 'slide', 6262 scrollText: '<span><i class="fa fa-chevron-up"></i></span>' 6263 }); 6264 6265 // Media Queries 6266 dicot.mqInit(); 6267 6268 } ); 6269 6270} )( jQuery ); 6271; 6272/**
6273 * Featured Content Carousel v1.0 - depends on `owl-carousel.js` 6274 * Contains handlers for the featured content carousel 6275 * 6276 * Copyright (c) 2013-2015 DesignOrbital.com 6277 * License: GNU General Public License v2 or later 6278 * http://www.gnu.org/licenses/gpl-2.0.html 6279 */ 6280 6281( function( $ ) { 6282 6283 // Document Ready 6284 $( document ).ready( function() { 6285 6286 // Images Loaded 6287 $( '.dicot-featured-content' ).imagesLoaded( function() { 6288 6289 var slideBy = $( '.dicot-featured-content' ).data( 'featured-content' ).slideBy; 6290 6291 // Featured Content Carousel 6292 $( '.dicot-featured-content' ).owlCarousel({ 6293 6294 rtl: ( $( 'body' ).hasClass( 'rtl' ) )? true : false, 6295 autoplay: $( '.dicot-featured-content' ).data( 'featured-content' ).autoplay, 6296 autoplayHoverPause: $( '.dicot-featured-content' ).data( 'featured-content' ).autoplayHoverPause, 6297 autoplayTimeout: $( '.dicot-featured-content' ).data( 'featured-content' ).autoplayTimeout, 6298 loop: true, 6299 margin: 30, 6300 nav: false, 6301 dots: true, 6302 responsive: { 6303 0: { 6304 items: 1, 6305 slideBy: 1 6306 }, 6307 360: { 6308 items: 2, 6309 slideBy: ( slideBy > 1 ) ? 2 : 1 6310 }, 6311 600: { 6312 items: 3, 6313 slideBy: ( slideBy > 1 ) ? 3 : 1 6314 }, 6315 768: { 6316 items: 3, 6317 slideBy: ( slideBy > 1 ) ? 3 : 1 6318 }, 6319 992: { 6320 items: 4, 6321 slideBy: ( slideBy > 1 ) ? 4 : 1 6322 } 6323 } 6324 6325 }); 6326 6327 // Show Carousel 6328 $( '.featured-content-spinner' ).remove(); 6329 $( '.featured-content-wrapper' ).removeClass( 'featured-content-loader' ); 6330 $( '.dicot-featured-content' ).animate( { 6331 'opacity' : 1 6332 }, 250 ); 6333 6334 }); 6335 6336 } ); 6337 6338} )( jQuery ); 6339;
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.