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.
vendor: 23,687 bytes, lines 1-533
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/* 3 * jQuery FlexSlider v2.6.1 4 * Copyright 2012 WooThemes 5 * Contributing Author: Tyler Smith 6 */ 7; 8(function ($) { 9 10 var focused = true; 11 12 //FlexSlider: Object Instance 13 $.flexslider = function(el, options) { 14 var slider = $(el); 15 16 // making variables public 17 slider.vars = $.extend({}, $.flexslider.defaults, options); 18 19 var namespace = slider.vars.namespace, 20 msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture, 21 touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch, 22 // depricating this idea, as devices are being released with both of these events 23 eventType = "click touchend MSPointerUp keyup", 24 watchedEvent = "", 25 watchedEventClearTimer, 26 vertical = slider.vars.direction === "vertical", 27 reverse = slider.vars.reverse, 28 carousel = (slider.vars.itemWidth > 0), 29 fade = slider.vars.animation === "fade", 30 asNav = slider.vars.asNavFor !== "", 31 methods = {}; 32 33 // Store a reference to the slider object 34 $.data(el, "flexslider", slider); 35 36 // Private slider methods 37 methods = { 38 init: function() { 39 slider.animating = false; 40 // Get current slide and make sure it is a number 41 slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0), 10 ); 42 if ( isNaN( slider.currentSlide ) ) { slider.currentSlide = 0; } 43 slider.animatingTo = slider.currentSlide; 44 slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last); 45 slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' ')); 46 slider.slides = $(slider.vars.selector, slider); 47 slider.container = $(slider.containerSelector, slider); 48 slider.count = slider.slides.length; 49 // SYNC: 50 slider.syncExists = $(slider.vars.sync).length > 0; 51 // SLIDE: 52 if (slider.vars.animation === "slide") { slider.vars.animation = "swing"; } 53 slider.prop = (vertical) ? "top" : "marginLeft"; 54 slider.args = {}; 55 // SLIDESHOW: 56 slider.manualPause = false; 57 slider.stopped = false; 58 //PAUSE WHEN INVISIBLE 59 slider.started = false; 60 slider.startTimeout = null; 61 // TOUCH/USECSS: 62 slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() { 63 var obj = document.createElement('div'), 64 props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; 65 for (var i in props) { 66 if ( obj.style[ props[i] ] !== undefined ) { 67 slider.pfx = props[i].replace('Perspective','').toLowerCase(); 68 slider.prop = "-" + slider.pfx + "-transform"; 69 return true; 70 } 71 } 72 return false; 73 }()); 74 slider.ensureAnimationEnd = ''; 75 // CONTROLSCONTAINER: 76 if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer); 77 // MANUAL: 78 if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls); 79 80 // CUSTOM DIRECTION NAV: 81 if (slider.vars.customDirectionNav !== "") slider.customDirectionNav = $(slider.vars.customDirectionNav).length === 2 && $(slider.vars.customDirectionNav); 82 83 // RANDOMIZE: 84 if (slider.vars.randomize) { 85 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); }); 86 slider.container.empty().append(slider.slides); 87 } 88 89 slider.doMath(); 90 91 // INIT 92 slider.setup("init"); 93 94 // CONTROLNAV: 95 if (slider.vars.controlNav) { methods.controlNav.setup(); } 96 97 // DIRECTIONNAV: 98 if (slider.vars.directionNav) { methods.directionNav.setup(); } 99 100 // KEYBOARD: 101 if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) { 102 $(document).bind('keyup', function(event) { 103 var keycode = event.keyCode; 104 if (!slider.animating && (keycode === 39 || keycode === 37)) { 105 var target = (keycode === 39) ? slider.getTarget('next') : 106 (keycode === 37) ? slider.getTarget('prev') : false; 107 slider.flexAnimate(target, slider.vars.pauseOnAction); 108 } 109 }); 110 } 111 // MOUSEWHEEL: 112 if (slider.vars.mousewheel) { 113 slider.bind('mousewheel', function(event, delta, deltaX, deltaY) { 114 event.preventDefault(); 115 var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev'); 116 slider.flexAnimate(target, slider.vars.pauseOnAction); 117 }); 118 } 119 120 // PAUSEPLAY 121 if (slider.vars.pausePlay) { methods.pausePlay.setup(); } 122 123 //PAUSE WHEN INVISIBLE 124 if (slider.vars.slideshow && slider.vars.pauseInvisible) { methods.pauseInvisible.init(); } 125 126 // SLIDSESHOW 127 if (slider.vars.slideshow) { 128 if (slider.vars.pauseOnHover) { 129 slider.hover(function() { 130 if (!slider.manualPlay && !slider.manualPause) { slider.pause(); } 131 }, function() { 132 if (!slider.manualPause && !slider.manualPlay && !slider.stopped) { slider.play(); } 133 }); 134 } 135 // initialize animation 136 //If we're visible, or we don't use PageVisibility API 137 if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) { 138 (slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play(); 139 } 140 } 141 142 // ASNAV: 143 if (asNav) { methods.asNav.setup(); } 144 145 // TOUCH 146 if (touch && slider.vars.touch) { methods.touch(); } 147 148 // FADE&&SMOOTHHEIGHT || SLIDE: 149 if (!fade || (fade && slider.vars.smoothHeight)) { $(window).bind("resize orientationchange focus", methods.resize); } 150 151 slider.find("img").attr("draggable", "false"); 152 153 // API: start() Callback 154 setTimeout(function(){ 155 slider.vars.start(slider); 156 }, 200); 157 }, 158 asNav: { 159 setup: function() { 160 slider.asNav = true; 161 slider.animatingTo = Math.floor(slider.currentSlide/slider.move); 162 slider.currentItem = slider.currentSlide; 163 slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide"); 164 if(!msGesture){ 165 slider.slides.on(eventType, function(e){ 166 e.preventDefault(); 167 var $slide = $(this), 168 target = $slide.index(); 169 var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container 170 if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) { 171 slider.flexAnimate(slider.getTarget("prev"), true); 172 } else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) { 173 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 174 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 175 } 176 }); 177 }else{ 178 el._slider = slider; 179 slider.slides.each(function (){ 180 var that = this; 181 that._gesture = new MSGesture(); 182 that._gesture.target = that; 183 that.addEventListener("MSPointerDown", function (e){ 184 e.preventDefault(); 185 if(e.currentTarget._gesture) { 186 e.currentTarget._gesture.addPointer(e.pointerId); 187 } 188 }, false); 189 that.addEventListener("MSGestureTap", function (e){ 190 e.preventDefault(); 191 var $slide = $(this), 192 target = $slide.index(); 193 if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) { 194 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 195 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 196 } 197 }); 198 }); 199 } 200 } 201 }, 202 controlNav: { 203 setup: function() { 204 if (!slider.manualControls) { 205 methods.controlNav.setupPaging(); 206 } else { // MANUALCONTROLS: 207 methods.controlNav.setupManual(); 208 } 209 }, 210 setupPaging: function() { 211 var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging', 212 j = 1, 213 item, 214 slide; 215 216 slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>'); 217 218 if (slider.pagingCount > 1) { 219 for (var i = 0; i < slider.pagingCount; i++) { 220 slide = slider.slides.eq(i); 221 222 if ( undefined === slide.attr( 'data-thumb-alt' ) ) { 223 slide.attr( 'data-thumb-alt', '' ); 224 } 225 226 item = $( '<a></a>' ).attr( 'href', '#' ).text( j ); 227 if ( slider.vars.controlNav === "thumbnails" ) { 228 item = $( '<img/>' ).attr( 'src', slide.attr( 'data-thumb' ) ); 229 } 230 231 if ( '' !== slide.attr( 'data-thumb-alt' ) ) { 232 item.attr( 'alt', slide.attr( 'data-thumb-alt' ) ); 233 } 234 235 if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) { 236 var captn = slide.attr( 'data-thumbcaption' ); 237 if ( '' !== captn && undefined !== captn ) { 238 var caption = $('<span></span>' ).addClass( namespace + 'caption' ).text( captn ); 239 item.append( caption ); 240 } 241 } 242 243 var liElement = $( '<li>' ); 244 item.appendTo( liElement ); 245 liElement.append( '</li>' ); 246 247 slider.controlNavScaffold.append(liElement); 248 j++; 249 } 250 } 251 252 // CONTROLSCONTAINER: 253 (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold); 254 methods.controlNav.set(); 255 256 methods.controlNav.active(); 257 258 slider.controlNavScaffold.delegate('a, img', eventType, function(event) { 259 event.preventDefault(); 260 261 if (watchedEvent === "" || watchedEvent === event.type) { 262 var $this = $(this), 263 target = slider.controlNav.index($this); 264 265 if (!$this.hasClass(namespace + 'active')) { 266 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 267 slider.flexAnimate(target, slider.vars.pauseOnAction); 268 } 269 } 270 271 // setup flags to prevent event duplication 272 if (watchedEvent === "") { 273 watchedEvent = event.type; 274 } 275 methods.setToClearWatchedEvent(); 276 277 }); 278 }, 279 setupManual: function() { 280 slider.controlNav = slider.manualControls; 281 methods.controlNav.active(); 282 283 slider.controlNav.bind(eventType, function(event) { 284 event.preventDefault(); 285 286 if (watchedEvent === "" || watchedEvent === event.type) { 287 var $this = $(this), 288 target = slider.controlNav.index($this); 289 290 if (!$this.hasClass(namespace + 'active')) { 291 (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev"; 292 slider.flexAnimate(target, slider.vars.pauseOnAction); 293 } 294 } 295 296 // setup flags to prevent event duplication 297 if (watchedEvent === "") { 298 watchedEvent = event.type; 299 } 300 methods.setToClearWatchedEvent(); 301 }); 302 }, 303 set: function() { 304 var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a'; 305 slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider); 306 }, 307 active: function() { 308 slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active"); 309 }, 310 update: function(action, pos) { 311 if (slider.pagingCount > 1 && action === "add") { 312 slider.controlNavScaffold.append($('<li><a href="#">' + slider.count + '</a></li>')); 313 } else if (slider.pagingCount === 1) { 314 slider.controlNavScaffold.find('li').remove(); 315 } else { 316 slider.controlNav.eq(pos).closest('li').remove(); 317 } 318 methods.controlNav.set(); 319 (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active(); 320 } 321 }, 322 directionNav: { 323 setup: function() { 324 var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li class="' + namespace + 'nav-prev"><a class="' + namespace + 'prev" href="#">' + slider.vars.prevText + '</a></li><li class="' + namespace + 'nav-next"><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>'); 325 326 // CUSTOM DIRECTION NAV: 327 if (slider.customDirectionNav) { 328 slider.directionNav = slider.customDirectionNav; 329 // CONTROLSCONTAINER: 330 } else if (slider.controlsContainer) { 331 $(slider.controlsContainer).append(directionNavScaffold); 332 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer); 333 } else { 334 slider.append(directionNavScaffold); 335 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider); 336 } 337 338 methods.directionNav.update(); 339 340 slider.directionNav.bind(eventType, function(event) { 341 event.preventDefault(); 342 var target; 343 344 if (watchedEvent === "" || watchedEvent === event.type) { 345 target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev'); 346 slider.flexAnimate(target, slider.vars.pauseOnAction); 347 } 348 349 // setup flags to prevent event duplication 350 if (watchedEvent === "") { 351 watchedEvent = event.type; 352 } 353 methods.setToClearWatchedEvent(); 354 }); 355 }, 356 update: function() { 357 var disabledClass = namespace + 'disabled'; 358 if (slider.pagingCount === 1) { 359 slider.directionNav.addClass(disabledClass).attr('tabindex', '-1'); 360 } else if (!slider.vars.animationLoop) { 361 if (slider.animatingTo === 0) { 362 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1'); 363 } else if (slider.animatingTo === slider.last) { 364 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1'); 365 } else { 366 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 367 } 368 } else { 369 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 370 } 371 } 372 }, 373 pausePlay: { 374 setup: function() { 375 var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a href="#"></a></div>'); 376 377 // CONTROLSCONTAINER: 378 if (slider.controlsContainer) { 379 slider.controlsContainer.append(pausePlayScaffold); 380 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer); 381 } else { 382 slider.append(pausePlayScaffold); 383 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider); 384 } 385 386 methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play'); 387 388 slider.pausePlay.bind(eventType, function(event) { 389 event.preventDefault(); 390 391 if (watchedEvent === "" || watchedEvent === event.type) { 392 if ($(this).hasClass(namespace + 'pause')) { 393 slider.manualPause = true; 394 slider.manualPlay = false; 395 slider.pause(); 396 } else { 397 slider.manualPause = false; 398 slider.manualPlay = true; 399 slider.play(); 400 } 401 } 402 403 // setup flags to prevent event duplication 404 if (watchedEvent === "") { 405 watchedEvent = event.type; 406 } 407 methods.setToClearWatchedEvent(); 408 }); 409 }, 410 update: function(state) { 411 (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').html(slider.vars.pauseText); 412 } 413 }, 414 touch: function() { 415 var startX, 416 startY, 417 offset, 418 cwidth, 419 dx, 420 startT, 421 onTouchStart, 422 onTouchMove, 423 onTouchEnd, 424 scrolling = false, 425 localX = 0, 426 localY = 0, 427 accDx = 0; 428 429 if(!msGesture){ 430 onTouchStart = function(e) { 431 if (slider.animating) { 432 e.preventDefault(); 433 } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) { 434 slider.pause(); 435 // CAROUSEL: 436 cwidth = (vertical) ? slider.h : slider. w; 437 startT = Number(new Date()); 438 // CAROUSEL: 439 440 // Local vars for X and Y points. 441 localX = e.touches[0].pageX; 442 localY = e.touches[0].pageY; 443 444 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 445 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 446 (carousel && slider.currentSlide === slider.last) ? slider.limit : 447 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 448 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 449 startX = (vertical) ? localY : localX; 450 startY = (vertical) ? localX : localY; 451 452 el.addEventListener('touchmove', onTouchMove, false); 453 el.addEventListener('touchend', onTouchEnd, false); 454 } 455 }; 456 457 onTouchMove = function(e) { 458 // Local vars for X and Y points. 459 460 localX = e.touches[0].pageX; 461 localY = e.touches[0].pageY; 462 463 dx = (vertical) ? startX - localY : startX - localX; 464 scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY)); 465 466 var fxms = 500; 467 468 if ( ! scrolling || Number( new Date() ) - startT > fxms ) { 469 e.preventDefault(); 470 if (!fade && slider.transitions) { 471 if (!slider.vars.animationLoop) { 472 dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1); 473 } 474 slider.setProps(offset + dx, "setTouch"); 475 } 476 } 477 }; 478 479 onTouchEnd = function(e) { 480 // finish the touch by undoing the touch session 481 el.removeEventListener('touchmove', onTouchMove, false); 482 483 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 484 var updateDx = (reverse) ? -dx : dx, 485 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 486 487 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 488 slider.flexAnimate(target, slider.vars.pauseOnAction); 489 } else { 490 if (!fade) { slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); } 491 } 492 } 493 el.removeEventListener('touchend', onTouchEnd, false); 494 495 startX = null; 496 startY = null; 497 dx = null; 498 offset = null; 499 }; 500 501 el.addEventListener('touchstart', onTouchStart, false); 502 }else{ 503 el.style.msTouchAction = "none"; 504 el._gesture = new MSGesture(); 505 el._gesture.target = el; 506 el.addEventListener("MSPointerDown", onMSPointerDown, false); 507 el._slider = slider; 508 el.addEventListener("MSGestureChange", onMSGestureChange, false); 509 el.addEventListener("MSGestureEnd", onMSGestureEnd, false); 510 511 function onMSPointerDown(e){ 512 e.stopPropagation(); 513 if (slider.animating) { 514 e.preventDefault(); 515 }else{ 516 slider.pause(); 517 el._gesture.addPointer(e.pointerId); 518 accDx = 0; 519 cwidth = (vertical) ? slider.h : slider. w; 520 startT = Number(new Date()); 521 // CAROUSEL: 522 523 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 524 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 525 (carousel && slider.currentSlide === slider.last) ? slider.limit : 526 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 527 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 528 } 529 } 530 531 function onMSGestureChange(e) { 532 e.stopPropagation(); 533 var slider = e.target._slider;
534 if(!slider){ 535 return; 536 } 537 var transX = -e.translationX, 538 transY = -e.translationY; 539 540 //Accumulate translations. 541 accDx = accDx + ((vertical) ? transY : transX); 542 dx =
vendor: 10,612 bytes, lines 542-799
542accDx; 543 scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY)); 544 545 if(e.detail === e.MSGESTURE_FLAG_INERTIA){ 546 setImmediate(function (){ 547 el._gesture.stop(); 548 }); 549 550 return; 551 } 552 553 if (!scrolling || Number(new Date()) - startT > 500) { 554 e.preventDefault(); 555 if (!fade && slider.transitions) { 556 if (!slider.vars.animationLoop) { 557 dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1); 558 } 559 slider.setProps(offset + dx, "setTouch"); 560 } 561 } 562 } 563 564 function onMSGestureEnd(e) { 565 e.stopPropagation(); 566 var slider = e.target._slider; 567 if(!slider){ 568 return; 569 } 570 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 571 var updateDx = (reverse) ? -dx : dx, 572 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 573 574 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 575 slider.flexAnimate(target, slider.vars.pauseOnAction); 576 } else { 577 if (!fade) { slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); } 578 } 579 } 580 581 startX = null; 582 startY = null; 583 dx = null; 584 offset = null; 585 accDx = 0; 586 } 587 } 588 }, 589 resize: function() { 590 if (!slider.animating && slider.is(':visible')) { 591 if (!carousel) { slider.doMath(); } 592 593 if (fade) { 594 // SMOOTH HEIGHT: 595 methods.smoothHeight(); 596 } else if (carousel) { //CAROUSEL: 597 slider.slides.width(slider.computedW); 598 slider.update(slider.pagingCount); 599 slider.setProps(); 600 } 601 else if (vertical) { //VERTICAL: 602 slider.viewport.height(slider.h); 603 slider.setProps(slider.h, "setTotal"); 604 } else { 605 // SMOOTH HEIGHT: 606 if (slider.vars.smoothHeight) { methods.smoothHeight(); } 607 slider.newSlides.width(slider.computedW); 608 slider.setProps(slider.computedW, "setTotal"); 609 } 610 } 611 }, 612 smoothHeight: function(dur) { 613 if (!vertical || fade) { 614 var $obj = (fade) ? slider : slider.viewport; 615 (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).innerHeight()}, dur) : $obj.innerHeight(slider.slides.eq(slider.animatingTo).innerHeight()); 616 } 617 }, 618 sync: function(action) { 619 var $obj = $(slider.vars.sync).data("flexslider"), 620 target = slider.animatingTo; 621 622 switch (action) { 623 case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break; 624 case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break; 625 case "pause": $obj.pause(); break; 626 } 627 }, 628 uniqueID: function($clone) { 629 // Append _clone to current level and children elements with id attributes 630 $clone.filter( '[id]' ).add($clone.find( '[id]' )).each(function() { 631 var $this = $(this); 632 $this.attr( 'id', $this.attr( 'id' ) + '_clone' ); 633 }); 634 return $clone; 635 }, 636 pauseInvisible: { 637 visProp: null, 638 init: function() { 639 var visProp = methods.pauseInvisible.getHiddenProp(); 640 if (visProp) { 641 var evtname = visProp.replace(/[H|h]idden/,'') + 'visibilitychange'; 642 document.addEventListener(evtname, function() { 643 if (methods.pauseInvisible.isHidden()) { 644 if(slider.startTimeout) { 645 clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible 646 } else { 647 slider.pause(); //Or just pause 648 } 649 } 650 else { 651 if(slider.started) { 652 slider.play(); //Initiated before, just play 653 } else { 654 if (slider.vars.initDelay > 0) { 655 setTimeout(slider.play, slider.vars.initDelay); 656 } else { 657 slider.play(); //Didn't init before: simply init or wait for it 658 } 659 } 660 } 661 }); 662 } 663 }, 664 isHidden: function() { 665 var prop = methods.pauseInvisible.getHiddenProp(); 666 if (!prop) { 667 return false; 668 } 669 return document[prop]; 670 }, 671 getHiddenProp: function() { 672 var prefixes = ['webkit','moz','ms','o']; 673 // if 'hidden' is natively supported just return it 674 if ('hidden' in document) { 675 return 'hidden'; 676 } 677 // otherwise loop over all the known prefixes until we find one 678 for ( var i = 0; i < prefixes.length; i++ ) { 679 if ((prefixes[i] + 'Hidden') in document) { 680 return prefixes[i] + 'Hidden'; 681 } 682 } 683 // otherwise it's not supported 684 return null; 685 } 686 }, 687 setToClearWatchedEvent: function() { 688 clearTimeout(watchedEventClearTimer); 689 watchedEventClearTimer = setTimeout(function() { 690 watchedEvent = ""; 691 }, 3000); 692 } 693 }; 694 695 // public methods 696 slider.flexAnimate = function(target, pause, override, withSync, fromNav) { 697 if (!slider.vars.animationLoop && target !== slider.currentSlide) { 698 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 699 } 700 701 if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev"; 702 703 if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) { 704 if (asNav && withSync) { 705 var master = $(slider.vars.asNavFor).data('flexslider'); 706 slider.atEnd = target === 0 || target === slider.count - 1; 707 master.flexAnimate(target, true, false, true, fromNav); 708 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 709 master.direction = slider.direction; 710 711 if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) { 712 slider.currentItem = target; 713 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 714 target = Math.floor(target/slider.visible); 715 } else { 716 slider.currentItem = target; 717 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 718 return false; 719 } 720 } 721 722 slider.animating = true; 723 slider.animatingTo = target; 724 725 // SLIDESHOW: 726 if (pause) { slider.pause(); } 727 728 // API: before() animation Callback 729 slider.vars.before(slider); 730 731 // SYNC: 732 if (slider.syncExists && !fromNav) { methods.sync("animate"); } 733 734 // CONTROLNAV 735 if (slider.vars.controlNav) { methods.controlNav.active(); } 736 737 // !CAROUSEL: 738 // CANDIDATE: slide active class (for add/remove slide) 739 if (!carousel) { slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide'); } 740 741 // INFINITE LOOP: 742 // CANDIDATE: atEnd 743 slider.atEnd = target === 0 || target === slider.last; 744 745 // DIRECTIONNAV: 746 if (slider.vars.directionNav) { methods.directionNav.update(); } 747 748 if (target === slider.last) { 749 // API: end() of cycle Callback 750 slider.vars.end(slider); 751 // SLIDESHOW && !INFINITE LOOP: 752 if (!slider.vars.animationLoop) { slider.pause(); } 753 } 754 755 // SLIDE: 756 if (!fade) { 757 var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW, 758 margin, slideString, calcNext; 759 760 // INFINITE LOOP / REVERSE: 761 if (carousel) { 762 margin = slider.vars.itemMargin; 763 calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo; 764 slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext; 765 } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") { 766 slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0; 767 } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") { 768 slideString = (reverse) ? 0 : (slider.count + 1) * dimension; 769 } else { 770 slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension; 771 } 772 slider.setProps(slideString, "", slider.vars.animationSpeed); 773 if (slider.transitions) { 774 if (!slider.vars.animationLoop || !slider.atEnd) { 775 slider.animating = false; 776 slider.currentSlide = slider.animatingTo; 777 } 778 779 // Unbind previous transitionEnd events and re-bind new transitionEnd event 780 slider.container.unbind("webkitTransitionEnd transitionend"); 781 slider.container.bind("webkitTransitionEnd transitionend", function() { 782 clearTimeout(slider.ensureAnimationEnd); 783 slider.wrapup(dimension); 784 }); 785 786 // Insurance for the ever-so-fickle transitionEnd event 787 clearTimeout(slider.ensureAnimationEnd); 788 slider.ensureAnimationEnd = setTimeout(function() { 789 slider.wrapup(dimension); 790 }, slider.vars.animationSpeed + 100); 791 792 } else { 793 slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){ 794 slider.wrapup(dimension); 795 }); 796 } 797 } else { // FADE: 798 if (!touch) { 799
vendor: 13,743 bytes, lines 799-1113
799//slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing); 800 //slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 801 802 slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing); 803 slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 804 805 } else { 806 slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 }); 807 slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 }); 808 slider.wrapup(dimension); 809 } 810 } 811 // SMOOTH HEIGHT: 812 if (slider.vars.smoothHeight) { methods.smoothHeight(slider.vars.animationSpeed); } 813 } 814 }; 815 slider.wrapup = function(dimension) { 816 // SLIDE: 817 if (!fade && !carousel) { 818 if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) { 819 slider.setProps(dimension, "jumpEnd"); 820 } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) { 821 slider.setProps(dimension, "jumpStart"); 822 } 823 } 824 slider.animating = false; 825 slider.currentSlide = slider.animatingTo; 826 // API: after() animation Callback 827 slider.vars.after(slider); 828 }; 829 830 // SLIDESHOW: 831 slider.animateSlides = function() { 832 if (!slider.animating && focused ) { slider.flexAnimate(slider.getTarget("next")); } 833 }; 834 // SLIDESHOW: 835 slider.pause = function() { 836 clearInterval(slider.animatedSlides); 837 slider.animatedSlides = null; 838 slider.playing = false; 839 // PAUSEPLAY: 840 if (slider.vars.pausePlay) { methods.pausePlay.update("play"); } 841 // SYNC: 842 if (slider.syncExists) { methods.sync("pause"); } 843 }; 844 // SLIDESHOW: 845 slider.play = function() { 846 if (slider.playing) { clearInterval(slider.animatedSlides); } 847 slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 848 slider.started = slider.playing = true; 849 // PAUSEPLAY: 850 if (slider.vars.pausePlay) { methods.pausePlay.update("pause"); } 851 // SYNC: 852 if (slider.syncExists) { methods.sync("play"); } 853 }; 854 // STOP: 855 slider.stop = function () { 856 slider.pause(); 857 slider.stopped = true; 858 }; 859 slider.canAdvance = function(target, fromNav) { 860 // ASNAV: 861 var last = (asNav) ? slider.pagingCount - 1 : slider.last; 862 return (fromNav) ? true : 863 (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true : 864 (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false : 865 (target === slider.currentSlide && !asNav) ? false : 866 (slider.vars.animationLoop) ? true : 867 (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false : 868 (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false : 869 true; 870 }; 871 slider.getTarget = function(dir) { 872 slider.direction = dir; 873 if (dir === "next") { 874 return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1; 875 } else { 876 return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1; 877 } 878 }; 879 880 // SLIDE: 881 slider.setProps = function(pos, special, dur) { 882 var target = (function() { 883 var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo, 884 posCalc = (function() { 885 if (carousel) { 886 return (special === "setTouch") ? pos : 887 (reverse && slider.animatingTo === slider.last) ? 0 : 888 (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 889 (slider.animatingTo === slider.last) ? slider.limit : posCheck; 890 } else { 891 switch (special) { 892 case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos; 893 case "setTouch": return (reverse) ? pos : pos; 894 case "jumpEnd": return (reverse) ? pos : slider.count * pos; 895 case "jumpStart": return (reverse) ? slider.count * pos : pos; 896 default: return pos; 897 } 898 } 899 }()); 900 901 return (posCalc * -1) + "px"; 902 }()); 903 904 if (slider.transitions) { 905 target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)"; 906 dur = (dur !== undefined) ? (dur/1000) + "s" : "0s"; 907 slider.container.css("-" + slider.pfx + "-transition-duration", dur); 908 slider.container.css("transition-duration", dur); 909 } 910 911 slider.args[slider.prop] = target; 912 if (slider.transitions || dur === undefined) { slider.container.css(slider.args); } 913 914 slider.container.css('transform',target); 915 }; 916 917 slider.setup = function(type) { 918 // SLIDE: 919 if (!fade) { 920 var sliderOffset, arr; 921 922 if (type === "init") { 923 slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container); 924 // INFINITE LOOP: 925 slider.cloneCount = 0; 926 slider.cloneOffset = 0; 927 // REVERSE: 928 if (reverse) { 929 arr = $.makeArray(slider.slides).reverse(); 930 slider.slides = $(arr); 931 slider.container.empty().append(slider.slides); 932 } 933 } 934 // INFINITE LOOP && !CAROUSEL: 935 if (slider.vars.animationLoop && !carousel) { 936 slider.cloneCount = 2; 937 slider.cloneOffset = 1; 938 // clear out old clones 939 if (type !== "init") { slider.container.find('.clone').remove(); } 940 slider.container.append(methods.uniqueID(slider.slides.first().clone().addClass('clone')).attr('aria-hidden', 'true')) 941 .prepend(methods.uniqueID(slider.slides.last().clone().addClass('clone')).attr('aria-hidden', 'true')); 942 } 943 slider.newSlides = $(slider.vars.selector, slider); 944 945 sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset; 946 // VERTICAL: 947 if (vertical && !carousel) { 948 slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%"); 949 setTimeout(function(){ 950 slider.newSlides.css({"display": "block"}); 951 slider.doMath(); 952 slider.viewport.height(slider.h); 953 slider.setProps(sliderOffset * slider.h, "init"); 954 }, (type === "init") ? 100 : 0); 955 } else { 956 slider.container.width((slider.count + slider.cloneCount) * 200 + "%"); 957 slider.setProps(sliderOffset * slider.computedW, "init"); 958 setTimeout(function(){ 959 slider.doMath(); 960 slider.newSlides.css({"width": slider.computedW, "marginRight" : slider.computedM, "float": "left", "display": "block"}); 961 // SMOOTH HEIGHT: 962 if (slider.vars.smoothHeight) { methods.smoothHeight(); } 963 }, (type === "init") ? 100 : 0); 964 } 965 } else { // FADE: 966 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"}); 967 if (type === "init") { 968 if (!touch) { 969 //slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing); 970 if (slider.vars.fadeFirstSlide == false) { 971 slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).css({"opacity": 1}); 972 } else { 973 slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing); 974 } 975 } else { 976 slider.slides.css({ "opacity": 0, "display": "block", "webkitTransition": "opacity " + slider.vars.animationSpeed / 1000 + "s ease", "zIndex": 1 }).eq(slider.currentSlide).css({ "opacity": 1, "zIndex": 2}); 977 } 978 } 979 // SMOOTH HEIGHT: 980 if (slider.vars.smoothHeight) { methods.smoothHeight(); } 981 } 982 // !CAROUSEL: 983 // CANDIDATE: active slide 984 if (!carousel) { slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide"); } 985 986 //FlexSlider: init() Callback 987 slider.vars.init(slider); 988 }; 989 990 slider.doMath = function() { 991 var slide = slider.slides.first(), 992 slideMargin = slider.vars.itemMargin, 993 minItems = slider.vars.minItems, 994 maxItems = slider.vars.maxItems; 995 996 slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width(); 997 slider.h = slide.height(); 998 slider.boxPadding = slide.outerWidth() - slide.width(); 999 1000 // CAROUSEL: 1001 if (carousel) { 1002 slider.itemT = slider.vars.itemWidth + slideMargin; 1003 slider.itemM = slideMargin; 1004 slider.minW = (minItems) ? minItems * slider.itemT : slider.w; 1005 slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w; 1006 slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems : 1007 (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems : 1008 (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth; 1009 1010 slider.visible = Math.floor(slider.w/(slider.itemW)); 1011 slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible; 1012 slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1); 1013 slider.last = slider.pagingCount - 1; 1014 slider.limit = (slider.pagingCount === 1) ? 0 : 1015 (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin; 1016 } else { 1017 slider.itemW = slider.w; 1018 slider.itemM = slideMargin; 1019 slider.pagingCount = slider.count; 1020 slider.last = slider.count - 1; 1021 } 1022 slider.computedW = slider.itemW - slider.boxPadding; 1023 slider.computedM = slider.itemM; 1024 }; 1025 1026 slider.update = function(pos, action) { 1027 slider.doMath(); 1028 1029 // update currentSlide and slider.animatingTo if necessary 1030 if (!carousel) { 1031 if (pos < slider.currentSlide) { 1032 slider.currentSlide += 1; 1033 } else if (pos <= slider.currentSlide && pos !== 0) { 1034 slider.currentSlide -= 1; 1035 } 1036 slider.animatingTo = slider.currentSlide; 1037 } 1038 1039 // update controlNav 1040 if (slider.vars.controlNav && !slider.manualControls) { 1041 if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) { 1042 methods.controlNav.update("add"); 1043 } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) { 1044 if (carousel && slider.currentSlide > slider.last) { 1045 slider.currentSlide -= 1; 1046 slider.animatingTo -= 1; 1047 } 1048 methods.controlNav.update("remove", slider.last); 1049 } 1050 } 1051 // update directionNav 1052 if (slider.vars.directionNav) { methods.directionNav.update(); } 1053 1054 }; 1055 1056 slider.addSlide = function(obj, pos) { 1057 var $obj = $(obj); 1058 1059 slider.count += 1; 1060 slider.last = slider.count - 1; 1061 1062 // append new slide 1063 if (vertical && reverse) { 1064 (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj); 1065 } else { 1066 (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj); 1067 } 1068 1069 // update currentSlide, animatingTo, controlNav, and directionNav 1070 slider.update(pos, "add"); 1071 1072 // update slider.slides 1073 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 1074 // re-setup the slider to accomdate new slide 1075 slider.setup(); 1076 1077 //FlexSlider: added() Callback 1078 slider.vars.added(slider); 1079 }; 1080 slider.removeSlide = function(obj) { 1081 var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj; 1082 1083 // update count 1084 slider.count -= 1; 1085 slider.last = slider.count - 1; 1086 1087 // remove slide 1088 if (isNaN(obj)) { 1089 $(obj, slider.slides).remove(); 1090 } else { 1091 (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove(); 1092 } 1093 1094 // update currentSlide, animatingTo, controlNav, and directionNav 1095 slider.doMath(); 1096 slider.update(pos, "remove"); 1097 1098 // update slider.slides 1099 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 1100 // re-setup the slider to accomdate new slide 1101 slider.setup(); 1102 1103 // FlexSlider: removed() Callback 1104 slider.vars.removed(slider); 1105 }; 1106 1107 //FlexSlider: Initialize 1108 methods.init(); 1109 }; 1110 1111 // Ensure the slider isn't focussed if the window loses focus. 1112 $( window ).blur( function ( e ) { 1113 focused = false;
1114 }).focus( function ( e ) { 1115 focused = true; 1116 }); 1117 1118 //FlexSlider: Default Settings 1119 $.flexslider.defaults = { 1120 namespace: "flex-", //{NEW} String: Prefix string attached to the class of every element generated by the plugin 1121 selector: ".slides > li", //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril 1122 animation: "fade", //String: Select your animation type, "fade" or "slide" 1123 easing: "swing", //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported! 1124 direction: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical" 1125 reverse: false, //{NEW} Boolean: Reverse the animation direction 1126 animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end 1127 smoothHeight: false, //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode 1128 startAt: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide) 1129 slideshow: true, //Boolean: Animate slider automatically 1130 slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds 1131 animationSpeed: 600, //Integer: Set the speed of animations, in milliseconds 1132 initDelay: 0, //{NEW} Integer: Set an initialization delay, in milliseconds 1133 randomize: false, //Boolean: Randomize slide order 1134 fadeFirstSlide: true, //Boolean: Fade in the first slide when animation type is "fade" 1135 thumbCaptions: false, //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav. 1136 1137 // Usability features 1138 pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended. 1139 pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering 1140 pauseInvisible: true, //{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage. 1141 useCSS: true, //{NEW} Boolean: Slider will use CSS3 transitions if available 1142 touch: true, //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices 1143 video: false, //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches 1144 1145 // Primary Controls 1146 controlNav: true, //Boolean: Create navigation for paging control of each slide? Note: Leave true for manualControls usage 1147 directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false) 1148 prevText: "Previous", //String: Set the text for the "previous" directionNav item 1149 nextText: "Next", //String: Set the text for the "next" directionNav item 1150 1151 // Secondary Navigation 1152 keyboard: true, //Boolean: Allow slider navigating via keyboard left/right keys 1153 multipleKeyboard: false, //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present. 1154 mousewheel: false, //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel 1155 pausePlay: false, //Boolean: Create pause/play dynamic element 1156 pauseText: "Pause", //String: Set the text for the "pause" pausePlay item 1157 playText: "Play", //String: Set the text for the "play" pausePlay item 1158 1159 // Special properties 1160 controlsContainer: "", //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found. 1161 manualControls: "", //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs. 1162 customDirectionNav: "", //{NEW}
1162 jQuery Object/Selector: Custom prev / next button. Must be two jQuery elements. In order to make the events work they have to have the classes "prev" and "next" (plus namespace) 1163 sync: "", //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care. 1164 asNavFor: "", //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider 1165 1166 // Carousel Options 1167 itemWidth: 0, //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding. 1168 itemMargin: 0, //{NEW} Integer: Margin between carousel items. 1169 minItems: 1, //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this. 1170 maxItems: 0, //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit. 1171 move: 0, //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items. 1172 allowOneSlide: true, //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide 1173 1174 // Callback API 1175 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide 1176 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation 1177 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes 1178 end: function(){}, //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous) 1179 added: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is added 1180 removed: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is removed 1181 init: function() {} //{NEW} Callback: function(slider) - Fires after the slider is initially setup 1182 }; 1183 1184 //FlexSlider: Plugin Function 1185 $.fn.flexslider = function(options) { 1186 if (options === undefined) { options = {}; } 1187 1188 if (typeof options === "object") { 1189 return this.each(function() { 1190 var $this = $(this), 1191 selector = (options.selector) ? options.selector : ".slides > li", 1192 $slides = $this.find(selector); 1193 1194 if ( ( $slides.length === 1 && options.allowOneSlide === false ) || $slides.length === 0 ) { 1195 $slides.fadeIn(400); 1196 if (options.start) { options.start($this); } 1197 } else if ($this.data('flexslider') === undefined) { 1198 new $.flexslider(this, options); 1199 } 1200 }); 1201 } else { 1202 // Helper strings to quickly perform functions on the slider 1203 var $slider = $(this).data('flexslider'); 1204 switch (options) { 1205 case "play": $slider.play(); break; 1206 case "pause": $slider.pause(); break; 1207 case "stop": $slider.stop(); break; 1208 case "next": $slider.flexAnimate($slider.getTarget("next"), true); break; 1209 case "prev": 1210 case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break; 1211 default: if (typeof options === "number") { $slider.flexAnimate(options, true); } 1212 } 1213 } 1214 }; 1215})(jQuery); 1216; 1217/** 1218 * Column list Plugin 1219 * - Breaks up a list into separate columns 1220 * - src: https://github.com/weblinc/jquery-columnlist 1221 * 1222 Copyright (c) 2012 WebLinc LLC 1223 1224 Permission is hereby granted, free of charge, to any person obtaining a copy 1225 of this software and associated documentation files (the "Software"), to deal 1226 in the Software without restriction, including without limitation the rights 1227 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1228 copies of the Software, and to permit persons to whom the Software is 1229 furnished to do so, subject to the following conditions: 1230 1231 The above copyright notice and this permission notice shall be included in 1232 all copies or substantial portions of the Software. 1233 */ 1234 1235(function($){ 1236 1237 jQuery.fn.columnlist = function( options ) { 1238 1239 options = $.extend( {}, $.fn.columnlist.defaults, options ); 1240 1241 return this.each(function () { 1242 1243 var $list = $( this ), 1244 size = options.size || $list.data( 'columnList' ) || 1, 1245 $children = $list.children('li'),
1246 perColumn = Math.ceil( $children.length / size ), 1247 $column; 1248 1249 for ( var i = 0; i < size; i++ ) { 1250 1251 // Set up column wrapper 1252 $column = $('<ul />'); 1253 1254 for ( var j = 0; j < perColumn; j++ ) { 1255 if ( $children.length > i * perColumn + j ) { 1256 // Add class to column wrapper 1257 $column.addClass(options['class']).addClass(options.incrementClass + i).append( $children[ i * perColumn + j ]); 1258 } 1259 } 1260 1261 // Add new columns 1262 $list.parent().append( $column ); 1263 } 1264 1265 // Remove original list 1266 $list.remove(); 1267 }); 1268 }; 1269 1270 // Defaults 1271 $.fn.columnlist.defaults = { 1272 'class' : 'nav-menu', 1273 incrementClass : 'nav-menu-' 1274 }; 1275 1276})(jQuery); 1277; 1278/** 1279 * File navigation.js. 1280 * 1281 * Handles toggling the navigation menu for small screens and enables TAB key 1282 * navigation support for dropdown menus. 1283 */ 1284 1285/* global altoFocusScreenReaderText */ 1286( function( $ ) { 1287 1288 var body, 1289 masthead = $( '#masthead' ), 1290 menuToggle = masthead.find( '.menu-toggle' ), 1291 siteMenu = masthead.find( '.top-navigation' ), 1292 siteNavigation = masthead.find( '.top-navigation > div' ), 1293 siteBrandingHeight = masthead.find( '.site-branding-wrap' ).outerHeight(), 1294 topNavigation = $( '.top-navigation' ); 1295 1296 /** 1297 * Initialize the main navigation 1298 */ 1299 function initMainNavigation( container ) { 1300 1301 // Add parent class to sub-menu parent items 1302 container.find( '.sub-menu, .children' ).parents( 'li' ).addClass( 'menu-item-has-children' ); 1303 1304 // Add dropdown toggle button 1305 var dropdownToggle = $( '<button />', { 1306 'class': 'dropdown-toggle', 1307 'aria-expanded': false 1308 } ).append( $( '<span />', { 1309 'class': 'screen-reader-text', 1310 text: altoFocusScreenReaderText.expand 1311 })).append( '<span class="meta-nav" aria-hidden="true"><svg class="dropdown-icon dropdown-icon-open" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><polyline class="line" points="2.5,3.8 5,6.2 7.5,3.8 "/></svg><svg class="dropdown-icon dropdown-icon-close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><line class="line" x1="2.5" y1="7.5" x2="7.5" y2="2.5"/><line class="line" x1="2.5" y1="2.5" x2="7.5" y2="7.5"/></svg></span>' ); 1312 1313 container.find( '.menu-item-has-children > a' ).after( dropdownToggle ); 1314 1315 // Change menu items with submenus to aria-haspopup="true". 1316 container.find( '.menu-item-has-children' ).attr( 'aria-haspopup', 'true' ); 1317 1318 // Drop down toggle setup 1319 container.find( '.dropdown-toggle' ).click( function( e ) { 1320 1321 var _this = $( this ), 1322 otherSubMenus = _this.parents( '.menu-item-has-children' ).siblings( '.menu-item-has-children' ), 1323 screenReaderSpan = _this.find( '.screen-reader-text' ); 1324 1325 // Disable default behavior 1326 e.preventDefault(); 1327 1328 // Stop click outside area function 1329 e.stopPropagation(); 1330 1331 // Reveal sub-menus 1332 _this.not( '.menu-toggle' ).toggleClass( 'toggled-on' ); 1333 _this.not( '.menu-toggle' ).parent().toggleClass( 'toggled-on' ); 1334 _this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' ); 1335 1336 // Close other sub-menus if they're open 1337 otherSubMenus.removeClass( 'toggled-on' ); 1338 otherSubMenus.find( '.toggled-on' ).removeClass( 'toggled-on' ); 1339 1340 // jscs:disable 1341 _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); 1342 // jscs:enable 1343 1344 // Update screen reader text 1345 screenReaderSpan.text( screenReaderSpan.text() === altoFocusScreenReaderText.expand ? altoFocusScreenReaderText.collapse : altoFocusScreenReaderText.expand ); 1346 1347 } ); 1348 1349 // Navigation height should never be shorter than site branding height 1350 container.css( "min-height", siteBrandingHeight ); 1351 1352 // Close sub-menus when click outside of menus 1353 $( 'html' ).click( function() { 1354 1355 container.find( '.toggled-on' ).removeClass( 'toggled-on' ); 1356 }); 1357 1358 // Close expanded sub-menus when clicking links 1359 container.find( 'a' ).click( function( e ) { 1360 1361 var _this = $( this ), 1362 anchor = _this.attr( 'href' ), 1363 otherSubMenus = container.find( '.toggled-on' ); 1364 1365 //console.log(anchor); 1366 e.preventDefault(); 1367 1368 otherSubMenus.removeClass( 'toggled-on' ).attr( 'aria-expanded', 'false' ).attr( 'aria-haspopup', 'false' ); 1369 1370 window.location.href = anchor; 1371 1372 } ); 1373 } 1374 1375 /** 1376 * Enable menuToggle 1377 */ 1378 function enableMenuToggle() { 1379 1380 // Return early if menuToggle is missing. 1381 if ( ! menuToggle.length ) { 1382 1383 return; 1384 } 1385 1386 // Add an initial values for the attribute.
1387 menuToggle.add( siteNavigation ).attr( 'aria-expanded', 'false' ); 1388 1389 menuToggle.on( 'click.altofocus', function() { 1390 1391 $( this ).toggleClass( 'toggled-on' ); 1392 1393 $( this ).add( siteMenu ).add( siteNavigation ).toggleClass( 'toggled-on' ); 1394 1395 // jscs:disable 1396 $( this ).add( siteMenu ).add( siteNavigation ).attr( 'aria-expanded', $( this ).add( siteNavigation ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); 1397 // jscs:enable 1398 } ); 1399 } 1400 1401 /** 1402 * Fix sub-menus for touch devices and better focus for hidden submenu items for accessibility 1403 */ 1404 function addTouchSupport() { 1405 1406 if ( ! siteNavigation.length || ! siteNavigation.children().length ) { 1407 1408 return; 1409 } 1410 1411 // Toggle `focus` class to allow submenu access on tablets. 1412 function toggleFocusClassTouchScreen() { 1413 1414 // if ( window.innerWidth >= 896 ) { 1415 $( document.body ).on( 'touchstart.altofocus', function( e ) { 1416 1417 if ( ! $( e.target ).closest( '.top-navigation li' ).length ) { 1418 1419 $( '.top-navigation li' ).removeClass( 'focus' ); 1420 } 1421 } ); 1422 1423 siteNavigation.find( '.menu-item-has-children > a' ).on( 'touchstart.altofocus', function( e ) { 1424 1425 var el = $( this ).parent( 'li' ); 1426 1427 if ( ! el.hasClass( 'focus' ) ) { 1428 1429 e.preventDefault(); 1430 el.toggleClass( 'focus' ); 1431 el.siblings( '.focus' ).removeClass( 'focus' ); 1432 } 1433 } ); 1434 } 1435 1436 if ( 'ontouchstart' in window ) { 1437 1438 $( window ).on( 'resize.altofocus', toggleFocusClassTouchScreen ); 1439 toggleFocusClassTouchScreen(); 1440 } 1441 1442 siteNavigation.find( 'a' ).on( 'focus.altofocus blur.altofocus', function() { 1443 1444 $( this ).parents( '.menu-item' ).toggleClass( 'focus' ); 1445 } ); 1446 } 1447 1448 /** 1449 * Add the default ARIA attributes for the menu toggle and the navigations 1450 */ 1451 function onResizeARIA() { 1452 1453 if ( window.innerWidth < 896 ) { 1454 1455 if ( menuToggle.hasClass( 'toggled-on' ) ) { 1456 1457 menuToggle.attr( 'aria-expanded', 'true' ); 1458 siteMenu.attr( 'aria-expanded', 'true' ); 1459 siteNavigation.attr( 'aria-expanded', 'true' ); 1460 1461 } else { 1462 1463 menuToggle.attr( 'aria-expanded', 'false' ); 1464 siteMenu.attr( 'aria-expanded', 'false' ); 1465 siteNavigation.attr( 'aria-expanded', 'false' ); 1466 } 1467 1468 } else { 1469 1470 menuToggle.removeAttr( 'aria-expanded' ); 1471 siteMenu.removeAttr( 'aria-expanded' ); 1472 siteNavigation.removeAttr( 'aria-expanded' ); 1473 } 1474 } 1475 1476 /** 1477 * Re-initialize the main navigation when it is updated in the customizer 1478 * - Borrowed from twentysixteen: https://goo.gl/O6msL1 1479 */ 1480 $( document ).on( 'customize-preview-menu-refreshed', function( e, params ) { 1481 1482 if ( 'menu-1' === params.wpNavMenuArgs.theme_location ) { 1483 1484 initMainNavigation( params.newContainer ); 1485 } 1486 }); 1487 1488 /** 1489 * Execute functions 1490 */ 1491 $( document ) 1492 .ready( initMainNavigation( topNavigation ) ) 1493 .ready( enableMenuToggle ) 1494 .ready( addTouchSupport ) 1495 .ready( function() { 1496 1497 body = $( document.body ); 1498 1499 $( window ) 1500 .on( 'load.altofocus', onResizeARIA ) 1501 .on( 'resize.altofocus', onResizeARIA ); 1502 }); 1503 1504} )( jQuery ); 1505; 1506/*! 1507 * imagesLoaded PACKAGED v4.1.1 1508 * JavaScript is all like "You images are done yet or what?" 1509 * MIT License 1510 */ 1511 1512/** 1513 * EvEmitter v1.0.3 1514 * Lil' event emitter 1515 * MIT License 1516 */ 1517 1518/* jshint unused: true, undef: true, strict: true */ 1519 1520( function( global, factory ) { 1521 // universal module definition 1522 /* jshint strict: false */ /* globals define, module, window */ 1523 if ( typeof define == 'function' && define.amd ) { 1524 // AMD - RequireJS 1525 define( 'ev-emitter/ev-emitter',factory ); 1526 } else if ( typeof module == 'object' && module.exports ) { 1527 // CommonJS - Browserify, Webpack 1528 module.exports = factory(); 1529 } else { 1530 // Browser globals 1531 global.EvEmitter = factory(); 1532 } 1533 1534}( typeof window != 'undefined' ? window : this, function() { 1535 1536 1537 1538function EvEmitter() {} 1539 1540var proto = EvEmitter.prototype; 1541 1542proto.on = function( eventName, listener ) { 1543 if ( !eventName || !listener ) { 1544 return; 1545 } 1546 // set events hash 1547 var events = this._events = this._events || {}; 1548 // set listeners array 1549 var listeners = events[ eventName ] = events[ eventName ] || []; 1550 // only add once 1551 if ( listeners.indexOf( listener ) == -1 ) { 1552 listeners.push( listener ); 1553 } 1554 1555 return this; 1556}; 1557 1558proto.once = function( eventName, listener ) { 1559 if ( !eventName || !listener ) { 1560 return; 1561 } 1562 // add event 1563 this.on( eventName, listener ); 1564 // set once flag 1565 // set onceEvents hash 1566 var onceEvents = this._onceEvents = this._onceEvents || {}; 1567 // set onceListeners object 1568 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 1569 // set flag 1570 onceListeners[ listener ] = true; 1571 1572 return this; 1573}; 1574 1575proto.off = function( eventName, listener ) { 1576 var listeners = this._events && this._events[ eventName ]; 1577 if ( !listeners || !listeners.length ) { 1578 return; 1579 } 1580 var index = listeners.indexOf( listener ); 1581 if ( index != -1 ) { 1582 listeners.splice( index, 1 ); 1583 } 1584 1585 return this; 1586}; 1587 1588proto.emitEvent = function( eventName, args ) { 1589 var listeners = this._events && this._events[ eventName ]; 1590 if ( !listeners || !listeners.length ) { 1591 return; 1592 } 1593 var i = 0; 1594 var listener = listeners[i]; 1595 args = args || []; 1596 // once stuff 1597 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 1598 1599 while ( listener ) { 1600 var isOnce = onceListeners && onceListeners[ listener ]; 1601 if ( isOnce ) { 1602 // remove listener 1603 // remove before trigger to prevent recursion 1604 this.off( eventName, listener ); 1605 // unset once flag 1606 delete onceListeners[ listener ]; 1607 } 1608 // trigger listener 1609 listener.apply( this, args ); 1610 // get next listener 1611 i += isOnce ? 0 : 1; 1612 listener = listeners[i]; 1613 } 1614 1615 return this; 1616}; 1617 1618return EvEmitter; 1619 1620})); 1621 1622/*! 1623 * imagesLoaded v4.1.1 1624 * JavaScript is all like "You images are done yet or what?" 1625 * MIT License 1626 */ 1627 1628( function( window, factory ) { 'use strict'; 1629 // universal module definition 1630 1631 /*global define: false, module: false, require: false */ 1632 1633 if ( typeof define == 'function' && define.amd ) { 1634 // AMD 1635 define( [ 1636 'ev-emitter/ev-emitter' 1637 ], function( EvEmitter ) { 1638 return factory( window, EvEmitter ); 1639 }); 1640 } else if ( typeof module == 'object' && module.exports ) { 1641 // CommonJS 1642 module.exports = factory( 1643 window, 1644 require('ev-emitter') 1645 ); 1646 } else { 1647 // browser global 1648 window.imagesLoaded = factory( 1649 window, 1650 window.EvEmitter 1651 ); 1652 } 1653 1654})( window, 1655 1656// -------------------------- factory -------------------------- // 1657 1658function factory( window, EvEmitter ) { 1659 1660 1661 1662var $ = window.jQuery; 1663var console = window.console; 1664 1665// -------------------------- helpers -------------------------- // 1666 1667// extend objects 1668function extend( a, b ) { 1669 for ( var prop in b ) { 1670 a[ prop ] = b[ prop ]; 1671 } 1672 return a; 1673} 1674 1675// turn element or nodeList into an array 1676function makeArray( obj ) { 1677 var ary = []; 1678 if ( Array.isArray( obj ) ) { 1679 // use object if already an array 1680 ary = obj; 1681 } else if ( typeof obj.length == 'number' ) { 1682 // convert nodeList to array 1683 for ( var i=0; i < obj.length; i++ ) { 1684 ary.push( obj[i] ); 1685 } 1686 } else { 1687 // array of single index 1688 ary.push( obj ); 1689 } 1690 return ary; 1691} 1692 1693// -------------------------- imagesLoaded -------------------------- // 1694 1695/** 1696 * @param {Array, Element, NodeList, String} elem 1697 * @param {Object or Function} options - if function, use as callback 1698 * @param {Function} onAlways - callback function 1699 */ 1700function ImagesLoaded( elem, options, onAlways ) { 1701 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 1702 if ( !( this instanceof ImagesLoaded ) ) { 1703 return new ImagesLoaded( elem, options, onAlways ); 1704 } 1705 // use elem as selector string 1706 if ( typeof elem == 'string' ) { 1707 elem = document.querySelectorAll( elem ); 1708 } 1709 1710 this.elements = makeArray( elem ); 1711 this.options = extend( {}, this.options ); 1712 1713 if ( typeof options == 'function' ) { 1714 onAlways = options; 1715 } else { 1716 extend( this.options, options ); 1717 } 1718 1719 if ( onAlways ) { 1720 this.on( 'always', onAlways ); 1721 } 1722 1723 this.getImages(); 1724 1725 if ( $ ) { 1726 // add jQuery Deferred object 1727 this.jqDeferred = new $.Deferred(); 1728 } 1729 1730 // HACK check async to allow time to bind listeners 1731 setTimeout( function() { 1732 this.check(); 1733 }.bind( this )); 1734} 1735 1736ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); 1737 1738ImagesLoaded.prototype.options = {}; 1739 1740ImagesLoaded.prototype.getImages = function() { 1741 this.images = []; 1742 1743 // filter & find items if we have an item selector
vendor: 4,347 bytes, lines 1744-1900
1744 this.elements.forEach( this.addElementImages, this ); 1745}; 1746 1747/** 1748 * @param {Node} element 1749 */ 1750ImagesLoaded.prototype.addElementImages = function( elem ) { 1751 // filter siblings 1752 if ( elem.nodeName == 'IMG' ) { 1753 this.addImage( elem ); 1754 } 1755 // get background image on element 1756 if ( this.options.background === true ) { 1757 this.addElementBackgroundImages( elem ); 1758 } 1759 1760 // find children 1761 // no non-element nodes, #143 1762 var nodeType = elem.nodeType; 1763 if ( !nodeType || !elementNodeTypes[ nodeType ] ) { 1764 return; 1765 } 1766 var childImgs = elem.querySelectorAll('img'); 1767 // concat childElems to filterFound array 1768 for ( var i=0; i < childImgs.length; i++ ) { 1769 var img = childImgs[i]; 1770 this.addImage( img ); 1771 } 1772 1773 // get child background images 1774 if ( typeof this.options.background == 'string' ) { 1775 var children = elem.querySelectorAll( this.options.background ); 1776 for ( i=0; i < children.length; i++ ) { 1777 var child = children[i]; 1778 this.addElementBackgroundImages( child ); 1779 } 1780 } 1781}; 1782 1783var elementNodeTypes = { 1784 1: true, 1785 9: true, 1786 11: true 1787}; 1788 1789ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { 1790 var style = getComputedStyle( elem ); 1791 if ( !style ) { 1792 // Firefox returns null if in a hidden iframe https://bugzil.la/548397 1793 return; 1794 } 1795 // get url inside url("...") 1796 var reURL = /url\((['"])?(.*?)\1\)/gi; 1797 var matches = reURL.exec( style.backgroundImage ); 1798 while ( matches !== null ) { 1799 var url = matches && matches[2]; 1800 if ( url ) { 1801 this.addBackground( url, elem ); 1802 } 1803 matches = reURL.exec( style.backgroundImage ); 1804 } 1805}; 1806 1807/** 1808 * @param {Image} img 1809 */ 1810ImagesLoaded.prototype.addImage = function( img ) { 1811 var loadingImage = new LoadingImage( img ); 1812 this.images.push( loadingImage ); 1813}; 1814 1815ImagesLoaded.prototype.addBackground = function( url, elem ) { 1816 var background = new Background( url, elem ); 1817 this.images.push( background ); 1818}; 1819 1820ImagesLoaded.prototype.check = function() { 1821 var _this = this; 1822 this.progressedCount = 0; 1823 this.hasAnyBroken = false; 1824 // complete if no images 1825 if ( !this.images.length ) { 1826 this.complete(); 1827 return; 1828 } 1829 1830 function onProgress( image, elem, message ) { 1831 // HACK - Chrome triggers event before object properties have changed. #83 1832 setTimeout( function() { 1833 _this.progress( image, elem, message ); 1834 }); 1835 } 1836 1837 this.images.forEach( function( loadingImage ) { 1838 loadingImage.once( 'progress', onProgress ); 1839 loadingImage.check(); 1840 }); 1841}; 1842 1843ImagesLoaded.prototype.progress = function( image, elem, message ) { 1844 this.progressedCount++; 1845 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 1846 // progress event 1847 this.emitEvent( 'progress', [ this, image, elem ] ); 1848 if ( this.jqDeferred && this.jqDeferred.notify ) { 1849 this.jqDeferred.notify( this, image ); 1850 } 1851 // check if completed 1852 if ( this.progressedCount == this.images.length ) { 1853 this.complete(); 1854 } 1855 1856 if ( this.options.debug && console ) { 1857 console.log( 'progress: ' + message, image, elem ); 1858 } 1859}; 1860 1861ImagesLoaded.prototype.complete = function() { 1862 var eventName = this.hasAnyBroken ? 'fail' : 'done'; 1863 this.isComplete = true; 1864 this.emitEvent( eventName, [ this ] ); 1865 this.emitEvent( 'always', [ this ] ); 1866 if ( this.jqDeferred ) { 1867 var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; 1868 this.jqDeferred[ jqMethod ]( this ); 1869 } 1870}; 1871 1872// -------------------------- -------------------------- // 1873 1874function LoadingImage( img ) { 1875 this.img = img; 1876} 1877 1878LoadingImage.prototype = Object.create( EvEmitter.prototype ); 1879 1880LoadingImage.prototype.check = function() { 1881 // If complete is true and browser supports natural sizes, 1882 // try to check for image status manually. 1883 var isComplete = this.getIsImageComplete(); 1884 if ( isComplete ) { 1885 // report based on naturalWidth 1886 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 1887 return; 1888 } 1889 1890 // If none of the checks above matched, simulate loading on detached element. 1891 this.proxyImage = new Image(); 1892 this.proxyImage.addEventListener( 'load', this ); 1893 this.proxyImage.addEventListener( 'error', this ); 1894 // bind to image as well for Firefox. #191 1895 this.img.addEventListener( 'load', this ); 1896 this.img.addEventListener( 'error', this ); 1897 this.proxyImage.src = this.img.src; 1898}; 1899 1900LoadingImage.prototype.getIsImageComplete = function() {
1901 return this.img.complete && this.img.naturalWidth !== undefined; 1902}; 1903 1904LoadingImage.prototype.confirm = function( isLoaded, message ) { 1905 this.isLoaded = isLoaded; 1906 this.emitEvent( 'progress', [ this, this.img, message ] ); 1907}; 1908 1909// ----- events ----- // 1910 1911// trigger specified handler for event type 1912LoadingImage.prototype.handleEvent = function( event ) { 1913 var method = 'on' + event.type; 1914 if ( this[ method ] ) { 1915 this[ method ]( event ); 1916 } 1917}; 1918 1919LoadingImage.prototype.onload = function() { 1920 this.confirm( true, 'onload' ); 1921 this.unbindEvents(); 1922}; 1923 1924LoadingImage.prototype.onerror = function() { 1925 this.confirm( false, 'onerror' ); 1926 this.unbindEvents(); 1927}; 1928 1929LoadingImage.prototype.unbindEvents = function() { 1930 this.proxyImage.removeEventListener( 'load', this ); 1931 this.proxyImage.removeEventListener( 'error', this ); 1932 this.img.removeEventListener( 'load', this ); 1933 this.img.removeEventListener( 'error', this ); 1934}; 1935 1936// -------------------------- Background -------------------------- // 1937 1938function Background( url, element ) { 1939 this.url = url; 1940 this.element = element; 1941 this.img = new Image(); 1942} 1943 1944// inherit LoadingImage prototype 1945Background.prototype = Object.create( LoadingImage.prototype ); 1946 1947Background.prototype.check = function() { 1948 this.img.addEventListener( 'load', this ); 1949 this.img.addEventListener( 'error', this ); 1950 this.img.src = this.url; 1951 // check if image is already complete 1952 var isComplete = this.getIsImageComplete(); 1953 if ( isComplete ) { 1954 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 1955 this.unbindEvents(); 1956 } 1957}; 1958 1959Background.prototype.unbindEvents = function() { 1960 this.img.removeEventListener( 'load', this ); 1961 this.img.removeEventListener( 'error', this ); 1962}; 1963 1964Background.prototype.confirm = function( isLoaded, message ) { 1965 this.isLoaded = isLoaded; 1966 this.emitEvent( 'progress', [ this, this.element, message ] ); 1967}; 1968 1969// -------------------------- jQuery -------------------------- // 1970 1971ImagesLoaded.makeJQueryPlugin = function( jQuery ) { 1972 jQuery = jQuery || window.jQuery; 1973 if ( !jQuery ) { 1974 return; 1975 } 1976 // set local variable 1977 $ = jQuery; 1978 // $().imagesLoaded() 1979 $.fn.imagesLoaded = function( options, callback ) { 1980 var instance = new ImagesLoaded( this, options, callback ); 1981 return instance.jqDeferred.promise( $(this) ); 1982 }; 1983}; 1984// try making plugin 1985ImagesLoaded.makeJQueryPlugin(); 1986 1987// -------------------------- -------------------------- // 1988 1989return ImagesLoaded; 1990 1991}); 1992; 1993/*! 1994 * Isotope PACKAGED v3.0.1 1995 * 1996 * Licensed GPLv3 for open source use 1997 * or Isotope Commercial License for commercial use 1998 * 1999 * http://isotope.metafizzy.co 2000 * Copyright 2016 Metafizzy 2001 */ 2002 2003/** 2004 * Bridget makes jQuery widgets 2005 * v2.0.0 2006 * MIT license 2007 */ 2008 2009/* jshint browser: true, strict: true, undef: true, unused: true */ 2010 2011( function( window, factory ) { 2012 'use strict'; 2013 /* globals define: false, module: false, require: false */ 2014 2015 if ( typeof define == 'function' && define.amd ) { 2016 // AMD 2017 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 2018 factory( window, jQuery ); 2019 }); 2020 } else if ( typeof module == 'object' && module.exports ) { 2021 // CommonJS 2022 module.exports = factory( 2023 window, 2024 require('jquery') 2025 ); 2026 } else { 2027 // browser global 2028 window.jQueryBridget = factory( 2029 window, 2030 window.jQuery 2031 ); 2032 } 2033 2034}( window, function factory( window, jQuery ) { 2035'use strict'; 2036 2037// ----- utils ----- // 2038 2039var arraySlice = Array.prototype.slice; 2040 2041// helper function for logging errors 2042// $.error breaks jQuery chaining 2043var console = window.console; 2044var logError = typeof console == 'undefined' ? function() {} : 2045 function( message ) { 2046 console.error( message ); 2047 }; 2048 2049// ----- jQueryBridget ----- // 2050 2051function jQueryBridget( namespace, PluginClass, $ ) { 2052 $ = $ || jQuery || window.jQuery; 2053 if ( !$ ) { 2054 return; 2055 } 2056 2057 // add option method -> $().plugin('option', {...}) 2058 if ( !PluginClass.prototype.option ) { 2059 // option setter 2060 PluginClass.prototype.option = function( opts ) { 2061 // bail out if not an object 2062 if ( !$.isPlainObject( opts ) ){ 2063 return; 2064 } 2065 this.options = $.extend( true, this.options, opts ); 2066 }; 2067 } 2068 2069 // make jQuery plugin 2070 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 2071 if ( typeof arg0 == 'string' ) { 2072 // method call $().plugin( 'methodName', { options } ) 2073 // shift arguments by 1 2074 var args = arraySlice.call( arguments, 1 ); 2075 return methodCall( this, arg0, args ); 2076 } 2077 // just $().plugin({ options }) 2078 plainCall( this, arg0 ); 2079 return this; 2080 }; 2081 2082 // $().plugin('methodName') 2083 function methodCall( $elems, methodName, args ) { 2084 var returnValue; 2085 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 2086 2087 $elems.each( function( i, elem ) { 2088 // get instance 2089 var instance = $.data( elem, namespace ); 2090 if ( !instance ) { 2091 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 2092 pluginMethodStr ); 2093 return; 2094 } 2095 2096 var method = instance[ methodName ]; 2097 if ( !method || methodName.charAt(0) == '_' ) { 2098 logError( pluginMethodStr + ' is not a valid method' ); 2099 return; 2100 } 2101 2102 // apply method, get return value 2103 var value = method.apply( instance, args ); 2104 // set return value if value is returned, use only first value 2105 returnValue = returnValue === undefined ? value : returnValue; 2106 }); 2107 2108 return returnValue !== undefined ? returnValue : $elems; 2109 } 2110 2111 function plainCall( $elems, options ) { 2112 $elems.each( function( i, elem ) { 2113 var instance = $.data( elem, namespace ); 2114 if ( instance ) { 2115 // set options & init 2116 instance.option( options ); 2117 instance._init(); 2118 } else { 2119 // initialize new instance 2120 instance = new PluginClass( elem, options ); 2121 $.data( elem, namespace, instance ); 2122 } 2123 }); 2124 } 2125 2126 updateJQuery( $ ); 2127 2128} 2129
vendor: 18,101 bytes, lines 2130-2881
2130// ----- updateJQuery ----- // 2131 2132// set $.bridget for v1 backwards compatibility 2133function updateJQuery( $ ) { 2134 if ( !$ || ( $ && $.bridget ) ) { 2135 return; 2136 } 2137 $.bridget = jQueryBridget; 2138} 2139 2140updateJQuery( jQuery || window.jQuery ); 2141 2142// ----- ----- // 2143 2144return jQueryBridget; 2145 2146})); 2147 2148/** 2149 * EvEmitter v1.0.3 2150 * Lil' event emitter 2151 * MIT License 2152 */ 2153 2154/* jshint unused: true, undef: true, strict: true */ 2155 2156( function( global, factory ) { 2157 // universal module definition 2158 /* jshint strict: false */ /* globals define, module, window */ 2159 if ( typeof define == 'function' && define.amd ) { 2160 // AMD - RequireJS 2161 define( 'ev-emitter/ev-emitter',factory ); 2162 } else if ( typeof module == 'object' && module.exports ) { 2163 // CommonJS - Browserify, Webpack 2164 module.exports = factory(); 2165 } else { 2166 // Browser globals 2167 global.EvEmitter = factory(); 2168 } 2169 2170}( typeof window != 'undefined' ? window : this, function() { 2171 2172 2173 2174function EvEmitter() {} 2175 2176var proto = EvEmitter.prototype; 2177 2178proto.on = function( eventName, listener ) { 2179 if ( !eventName || !listener ) { 2180 return; 2181 } 2182 // set events hash 2183 var events = this._events = this._events || {}; 2184 // set listeners array 2185 var listeners = events[ eventName ] = events[ eventName ] || []; 2186 // only add once 2187 if ( listeners.indexOf( listener ) == -1 ) { 2188 listeners.push( listener ); 2189 } 2190 2191 return this; 2192}; 2193 2194proto.once = function( eventName, listener ) { 2195 if ( !eventName || !listener ) { 2196 return; 2197 } 2198 // add event 2199 this.on( eventName, listener ); 2200 // set once flag 2201 // set onceEvents hash 2202 var onceEvents = this._onceEvents = this._onceEvents || {}; 2203 // set onceListeners object 2204 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 2205 // set flag 2206 onceListeners[ listener ] = true; 2207 2208 return this; 2209}; 2210 2211proto.off = function( eventName, listener ) { 2212 var listeners = this._events && this._events[ eventName ]; 2213 if ( !listeners || !listeners.length ) { 2214 return; 2215 } 2216 var index = listeners.indexOf( listener ); 2217 if ( index != -1 ) { 2218 listeners.splice( index, 1 ); 2219 } 2220 2221 return this; 2222}; 2223 2224proto.emitEvent = function( eventName, args ) { 2225 var listeners = this._events && this._events[ eventName ]; 2226 if ( !listeners || !listeners.length ) { 2227 return; 2228 } 2229 var i = 0; 2230 var listener = listeners[i]; 2231 args = args || []; 2232 // once stuff 2233 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 2234 2235 while ( listener ) { 2236 var isOnce = onceListeners && onceListeners[ listener ]; 2237 if ( isOnce ) { 2238 // remove listener 2239 // remove before trigger to prevent recursion 2240 this.off( eventName, listener ); 2241 // unset once flag 2242 delete onceListeners[ listener ]; 2243 } 2244 // trigger listener 2245 listener.apply( this, args ); 2246 // get next listener 2247 i += isOnce ? 0 : 1; 2248 listener = listeners[i]; 2249 } 2250 2251 return this; 2252}; 2253 2254return EvEmitter; 2255 2256})); 2257 2258/*! 2259 * getSize v2.0.2 2260 * measure size of elements 2261 * MIT license 2262 */ 2263 2264/*jshint browser: true, strict: true, undef: true, unused: true */ 2265/*global define: false, module: false, console: false */ 2266 2267( function( window, factory ) { 2268 'use strict'; 2269 2270 if ( typeof define == 'function' && define.amd ) { 2271 // AMD 2272 define( 'get-size/get-size',[],function() { 2273 return factory(); 2274 }); 2275 } else if ( typeof module == 'object' && module.exports ) { 2276 // CommonJS 2277 module.exports = factory(); 2278 } else { 2279 // browser global 2280 window.getSize = factory(); 2281 } 2282 2283})( window, function factory() { 2284'use strict'; 2285 2286// -------------------------- helpers -------------------------- // 2287 2288// get a number from a string, not a percentage 2289function getStyleSize( value ) { 2290 var num = parseFloat( value ); 2291 // not a percent like '100%', and a number 2292 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 2293 return isValid && num; 2294} 2295 2296function noop() {} 2297 2298var logError = typeof console == 'undefined' ? noop : 2299 function( message ) { 2300 console.error( message ); 2301 }; 2302 2303// -------------------------- measurements -------------------------- // 2304 2305var measurements = [ 2306 'paddingLeft', 2307 'paddingRight', 2308 'paddingTop', 2309 'paddingBottom', 2310 'marginLeft', 2311 'marginRight', 2312 'marginTop', 2313 'marginBottom', 2314 'borderLeftWidth', 2315 'borderRightWidth', 2316 'borderTopWidth', 2317 'borderBottomWidth' 2318]; 2319 2320var measurementsLength = measurements.length; 2321 2322function getZeroSize() { 2323 var size = { 2324 width: 0, 2325 height: 0, 2326 innerWidth: 0, 2327 innerHeight: 0, 2328 outerWidth: 0, 2329 outerHeight: 0 2330 }; 2331 for ( var i=0; i < measurementsLength; i++ ) { 2332 var measurement = measurements[i]; 2333 size[ measurement ] = 0; 2334 } 2335 return size; 2336} 2337 2338// -------------------------- getStyle -------------------------- // 2339 2340/** 2341 * getStyle, get style of element, check for Firefox bug 2342 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 2343 */ 2344function getStyle( elem ) { 2345 var style = getComputedStyle( elem ); 2346 if ( !style ) { 2347 logError( 'Style returned ' + style + 2348 '. Are you running this code in a hidden iframe on Firefox? ' + 2349 'See http://bit.ly/getsizebug1' ); 2350 } 2351 return style; 2352} 2353 2354// -------------------------- setup -------------------------- // 2355 2356var isSetup = false; 2357 2358var isBoxSizeOuter; 2359 2360/** 2361 * setup 2362 * check isBoxSizerOuter 2363 * do on first getSize() rather than on page load for Firefox bug 2364 */ 2365function setup() { 2366 // setup once 2367 if ( isSetup ) { 2368 return; 2369 } 2370 isSetup = true; 2371 2372 // -------------------------- box sizing -------------------------- // 2373 2374 /** 2375 * WebKit measures the outer-width on style.width on border-box elems 2376 * IE & Firefox<29 measures the inner-width 2377 */ 2378 var div = document.createElement('div'); 2379 div.style.width = '200px'; 2380 div.style.padding = '1px 2px 3px 4px'; 2381 div.style.borderStyle = 'solid'; 2382 div.style.borderWidth = '1px 2px 3px 4px'; 2383 div.style.boxSizing = 'border-box'; 2384 2385 var body = document.body || document.documentElement; 2386 body.appendChild( div ); 2387 var style = getStyle( div ); 2388 2389 getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200; 2390 body.removeChild( div ); 2391 2392} 2393 2394// -------------------------- getSize -------------------------- // 2395 2396function getSize( elem ) { 2397 setup(); 2398 2399 // use querySeletor if elem is string 2400 if ( typeof elem == 'string' ) { 2401 elem = document.querySelector( elem ); 2402 } 2403 2404 // do not proceed on non-objects 2405 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 2406 return; 2407 } 2408 2409 var style = getStyle( elem ); 2410 2411 // if hidden, everything is 0 2412 if ( style.display == 'none' ) { 2413 return getZeroSize(); 2414 } 2415 2416 var size = {}; 2417 size.width = elem.offsetWidth; 2418 size.height = elem.offsetHeight; 2419 2420 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 2421 2422 // get all measurements 2423 for ( var i=0; i < measurementsLength; i++ ) { 2424 var measurement = measurements[i]; 2425 var value = style[ measurement ]; 2426 var num = parseFloat( value ); 2427 // any 'auto', 'medium' value will be 0 2428 size[ measurement ] = !isNaN( num ) ? num : 0; 2429 } 2430 2431 var paddingWidth = size.paddingLeft + size.paddingRight; 2432 var paddingHeight = size.paddingTop + size.paddingBottom; 2433 var marginWidth = size.marginLeft + size.marginRight; 2434 var marginHeight = size.marginTop + size.marginBottom; 2435 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 2436 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 2437 2438 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 2439 2440 // overwrite width and height if we can get it from style 2441 var styleWidth = getStyleSize( style.width ); 2442 if ( styleWidth !== false ) { 2443 size.width = styleWidth + 2444 // add padding and border unless it's already including it 2445 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 2446 } 2447 2448 var styleHeight = getStyleSize( style.height ); 2449 if ( styleHeight !== false ) { 2450 size.height = styleHeight + 2451 // add padding and border unless it's already including it 2452 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 2453 } 2454 2455 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 2456 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 2457 2458 size.outerWidth = size.width + marginWidth; 2459 size.outerHeight = size.height + marginHeight; 2460 2461 return size; 2462} 2463 2464return getSize; 2465 2466}); 2467 2468/** 2469 * matchesSelector v2.0.1 2470 * matchesSelector( element, '.selector' ) 2471 * MIT license 2472 */ 2473 2474/*jshint browser: true, strict: true, undef: true, unused: true */ 2475 2476( function( window, factory ) { 2477 /*global define: false, module: false */ 2478 'use strict'; 2479 // universal module definition 2480 if ( typeof define == 'function' && define.amd ) { 2481 // AMD 2482 define( 'desandro-matches-selector/matches-selector',factory ); 2483 } else if ( typeof module == 'object' && module.exports ) { 2484 // CommonJS 2485 module.exports = factory(); 2486 } else { 2487 // browser global 2488 window.matchesSelector = factory(); 2489 } 2490 2491}( window, function factory() { 2492 'use strict'; 2493 2494 var matchesMethod = ( function() { 2495 var ElemProto = Element.prototype; 2496 // check for the standard method name first 2497 if ( ElemProto.matches ) { 2498 return 'matches'; 2499 } 2500 // check un-prefixed 2501 if ( ElemProto.matchesSelector ) { 2502 return 'matchesSelector'; 2503 } 2504 // check vendor prefixes 2505 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 2506 2507 for ( var i=0; i < prefixes.length; i++ ) { 2508 var prefix = prefixes[i]; 2509 var method = prefix + 'MatchesSelector'; 2510 if ( ElemProto[ method ] ) { 2511 return method; 2512 } 2513 } 2514 })(); 2515 2516 return function matchesSelector( elem, selector ) { 2517 return elem[ matchesMethod ]( selector ); 2518 }; 2519 2520})); 2521 2522/** 2523 * Fizzy UI utils v2.0.2 2524 * MIT license 2525 */ 2526 2527/*jshint browser: true, undef: true, unused: true, strict: true */ 2528 2529( function( window, factory ) { 2530 // universal module definition 2531 /*jshint strict: false */ /*globals define, module, require */ 2532 2533 if ( typeof define == 'function' && define.amd ) { 2534 // AMD 2535 define( 'fizzy-ui-utils/utils',[ 2536 'desandro-matches-selector/matches-selector' 2537 ], function( matchesSelector ) { 2538 return factory( window, matchesSelector ); 2539 }); 2540 } else if ( typeof module == 'object' && module.exports ) { 2541 // CommonJS 2542 module.exports = factory( 2543 window, 2544 require('desandro-matches-selector') 2545 ); 2546 } else { 2547 // browser global 2548 window.fizzyUIUtils = factory( 2549 window, 2550 window.matchesSelector 2551 ); 2552 } 2553 2554}( window, function factory( window, matchesSelector ) { 2555 2556 2557 2558var utils = {}; 2559 2560// ----- extend ----- // 2561 2562// extends objects 2563utils.extend = function( a, b ) { 2564 for ( var prop in b ) { 2565 a[ prop ] = b[ prop ]; 2566 } 2567 return a; 2568}; 2569 2570// ----- modulo ----- // 2571 2572utils.modulo = function( num, div ) { 2573 return ( ( num % div ) + div ) % div; 2574}; 2575 2576// ----- makeArray ----- // 2577 2578// turn element or nodeList into an array 2579utils.makeArray = function( obj ) { 2580 var ary = []; 2581 if ( Array.isArray( obj ) ) { 2582 // use object if already an array 2583 ary = obj; 2584 } else if ( obj && typeof obj.length == 'number' ) { 2585 // convert nodeList to array 2586 for ( var i=0; i < obj.length; i++ ) { 2587 ary.push( obj[i] ); 2588 } 2589 } else { 2590 // array of single index 2591 ary.push( obj ); 2592 } 2593 return ary; 2594}; 2595 2596// ----- removeFrom ----- // 2597 2598utils.removeFrom = function( ary, obj ) { 2599 var index = ary.indexOf( obj ); 2600 if ( index != -1 ) { 2601 ary.splice( index, 1 ); 2602 } 2603}; 2604 2605// ----- getParent ----- // 2606 2607utils.getParent = function( elem, selector ) { 2608 while ( elem != document.body ) { 2609 elem = elem.parentNode; 2610 if ( matchesSelector( elem, selector ) ) { 2611 return elem; 2612 } 2613 } 2614}; 2615 2616// ----- getQueryElement ----- // 2617 2618// use element as selector string 2619utils.getQueryElement = function( elem ) { 2620 if ( typeof elem == 'string' ) { 2621 return document.querySelector( elem ); 2622 } 2623 return elem; 2624}; 2625 2626// ----- handleEvent ----- // 2627 2628// enable .ontype to trigger from .addEventListener( elem, 'type' ) 2629utils.handleEvent = function( event ) { 2630 var method = 'on' + event.type; 2631 if ( this[ method ] ) { 2632 this[ method ]( event ); 2633 } 2634}; 2635 2636// ----- filterFindElements ----- // 2637 2638utils.filterFindElements = function( elems, selector ) { 2639 // make array of elems 2640 elems = utils.makeArray( elems ); 2641 var ffElems = []; 2642 2643 elems.forEach( function( elem ) { 2644 // check that elem is an actual element 2645 if ( !( elem instanceof HTMLElement ) ) { 2646 return; 2647 } 2648 // add elem if no selector 2649 if ( !selector ) { 2650 ffElems.push( elem ); 2651 return; 2652 } 2653 // filter & find items if we have a selector 2654 // filter 2655 if ( matchesSelector( elem, selector ) ) { 2656 ffElems.push( elem ); 2657 } 2658 // find children 2659 var childElems = elem.querySelectorAll( selector ); 2660 // concat childElems to filterFound array 2661 for ( var i=0; i < childElems.length; i++ ) { 2662 ffElems.push( childElems[i] ); 2663 } 2664 }); 2665 2666 return ffElems; 2667}; 2668 2669// ----- debounceMethod ----- // 2670 2671utils.debounceMethod = function( _class, methodName, threshold ) { 2672 // original method 2673 var method = _class.prototype[ methodName ]; 2674 var timeoutName = methodName + 'Timeout'; 2675 2676 _class.prototype[ methodName ] = function() { 2677 var timeout = this[ timeoutName ]; 2678 if ( timeout ) { 2679 clearTimeout( timeout ); 2680 } 2681 var args = arguments; 2682 2683 var _this = this; 2684 this[ timeoutName ] = setTimeout( function() { 2685 method.apply( _this, args ); 2686 delete _this[ timeoutName ]; 2687 }, threshold || 100 ); 2688 }; 2689}; 2690 2691// ----- docReady ----- // 2692 2693utils.docReady = function( callback ) { 2694 var readyState = document.readyState; 2695 if ( readyState == 'complete' || readyState == 'interactive' ) { 2696 callback(); 2697 } else { 2698 document.addEventListener( 'DOMContentLoaded', callback ); 2699 } 2700}; 2701 2702// ----- htmlInit ----- // 2703 2704// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 2705utils.toDashed = function( str ) { 2706 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 2707 return $1 + '-' + $2; 2708 }).toLowerCase(); 2709}; 2710 2711var console = window.console; 2712/** 2713 * allow user to initialize classes via [data-namespace] or .js-namespace class 2714 * htmlInit( Widget, 'widgetName' ) 2715 * options are parsed from data-namespace-options 2716 */ 2717utils.htmlInit = function( WidgetClass, namespace ) { 2718 utils.docReady( function() { 2719 var dashedNamespace = utils.toDashed( namespace ); 2720 var dataAttr = 'data-' + dashedNamespace; 2721 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 2722 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 2723 var elems = utils.makeArray( dataAttrElems ) 2724 .concat( utils.makeArray( jsDashElems ) ); 2725 var dataOptionsAttr = dataAttr + '-options'; 2726 var jQuery = window.jQuery; 2727 2728 elems.forEach( function( elem ) { 2729 var attr = elem.getAttribute( dataAttr ) || 2730 elem.getAttribute( dataOptionsAttr ); 2731 var options; 2732 try { 2733 options = attr && JSON.parse( attr ); 2734 } catch ( error ) { 2735 // log error, do not initialize 2736 if ( console ) { 2737 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 2738 ': ' + error ); 2739 } 2740 return; 2741 } 2742 // initialize 2743 var instance = new WidgetClass( elem, options ); 2744 // make available via $().data('layoutname') 2745 if ( jQuery ) { 2746 jQuery.data( elem, namespace, instance ); 2747 } 2748 }); 2749 2750 }); 2751}; 2752 2753// ----- ----- // 2754 2755return utils; 2756 2757})); 2758 2759/** 2760 * Outlayer Item 2761 */ 2762 2763( function( window, factory ) { 2764 // universal module definition 2765 /* jshint strict: false */ /* globals define, module, require */ 2766 if ( typeof define == 'function' && define.amd ) { 2767 // AMD - RequireJS 2768 define( 'outlayer/item',[ 2769 'ev-emitter/ev-emitter', 2770 'get-size/get-size' 2771 ], 2772 factory 2773 ); 2774 } else if ( typeof module == 'object' && module.exports ) { 2775 // CommonJS - Browserify, Webpack 2776 module.exports = factory( 2777 require('ev-emitter'), 2778 require('get-size') 2779 ); 2780 } else { 2781 // browser global 2782 window.Outlayer = {}; 2783 window.Outlayer.Item = factory( 2784 window.EvEmitter, 2785 window.getSize 2786 ); 2787 } 2788 2789}( window, function factory( EvEmitter, getSize ) { 2790'use strict'; 2791 2792// ----- helpers ----- // 2793 2794function isEmptyObj( obj ) { 2795 for ( var prop in obj ) { 2796 return false; 2797 } 2798 prop = null; 2799 return true; 2800} 2801 2802// -------------------------- CSS3 support -------------------------- // 2803 2804 2805var docElemStyle = document.documentElement.style; 2806 2807var transitionProperty = typeof docElemStyle.transition == 'string' ? 2808 'transition' : 'WebkitTransition'; 2809var transformProperty = typeof docElemStyle.transform == 'string' ? 2810 'transform' : 'WebkitTransform'; 2811 2812var transitionEndEvent = { 2813 WebkitTransition: 'webkitTransitionEnd', 2814 transition: 'transitionend' 2815}[ transitionProperty ]; 2816 2817// cache all vendor properties that could have vendor prefix 2818var vendorProperties = { 2819 transform: transformProperty, 2820 transition: transitionProperty, 2821 transitionDuration: transitionProperty + 'Duration', 2822 transitionProperty: transitionProperty + 'Property', 2823 transitionDelay: transitionProperty + 'Delay' 2824}; 2825 2826// -------------------------- Item -------------------------- // 2827 2828function Item( element, layout ) { 2829 if ( !element ) { 2830 return; 2831 } 2832 2833 this.element = element; 2834 // parent layout class, i.e. Masonry, Isotope, or Packery 2835 this.layout = layout; 2836 this.position = { 2837 x: 0, 2838 y: 0 2839 }; 2840 2841 this._create(); 2842} 2843 2844// inherit EvEmitter 2845var proto = Item.prototype = Object.create( EvEmitter.prototype ); 2846proto.constructor = Item; 2847 2848proto._create = function() { 2849 // transition objects 2850 this._transn = { 2851 ingProperties: {}, 2852 clean: {}, 2853 onEnd: {} 2854 }; 2855 2856 this.css({ 2857 position: 'absolute' 2858 }); 2859}; 2860 2861// trigger specified handler for event type 2862proto.handleEvent = function( event ) { 2863 var method = 'on' + event.type; 2864 if ( this[ method ] ) { 2865 this[ method ]( event ); 2866 } 2867}; 2868 2869proto.getSize = function() { 2870 this.size = getSize( this.element ); 2871}; 2872 2873/** 2874 * apply CSS styles to element 2875 * @param {Object} style 2876 */ 2877proto.css = function( style ) { 2878 var elemStyle = this.element.style; 2879 2880 for ( var prop in style ) { 2881 // use vendor property if available
2882 var supportedProp = vendorProperties[ prop ] || prop; 2883 elemStyle[ supportedProp ] = style[ prop ]; 2884 } 2885}; 2886 2887 // measure position, and sets it 2888proto.getPosition = function() { 2889 var style = getComputedStyle( this.element ); 2890 var isOriginLeft = this.layout._getOption('originLeft'); 2891 var isOriginTop = this.layout._getOption('originTop'); 2892 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 2893 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 2894 // convert percent to pixels 2895 var layoutSize = this.layout.size; 2896 var x = xValue.indexOf('%') != -1 ? 2897 ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 ); 2898 var y = yValue.indexOf('%') != -1 ? 2899 ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 ); 2900 2901 // clean up 'auto' or other non-integer values 2902 x = isNaN( x ) ? 0 : x; 2903 y = isNaN( y ) ? 0 : y; 2904 // remove padding from measurement 2905 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 2906 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 2907 2908 this.position.x = x; 2909 this.position.y = y; 2910}; 2911 2912// set settled position, apply padding 2913proto.layoutPosition = function() { 2914 var layoutSize = this.layout.size; 2915 var style = {}; 2916 var isOriginLeft = this.layout._getOption('originLeft'); 2917 var isOriginTop = this.layout._getOption('originTop'); 2918 2919 // x 2920 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 2921 var xProperty = isOriginLeft ? 'left' : 'right'; 2922 var xResetProperty = isOriginLeft ? 'right' : 'left'; 2923 2924 var x = this.position.x + layoutSize[ xPadding ]; 2925 // set in percentage or pixels 2926 style[ xProperty ] = this.getXValue( x ); 2927 // reset other property 2928 style[ xResetProperty ] = ''; 2929 2930 // y 2931 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 2932 var yProperty = isOriginTop ? 'top' : 'bottom'; 2933 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 2934 2935 var y = this.position.y + layoutSize[ yPadding ]; 2936 // set in percentage or pixels 2937 style[ yProperty ] = this.getYValue( y ); 2938 // reset other property 2939 style[ yResetProperty ] = ''; 2940 2941 this.css( style ); 2942 this.emitEvent( 'layout', [ this ] ); 2943}; 2944 2945proto.getXValue = function( x ) { 2946 var isHorizontal = this.layout._getOption('horizontal'); 2947 return this.layout.options.percentPosition && !isHorizontal ? 2948 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 2949}; 2950 2951proto.getYValue = function( y ) { 2952 var isHorizontal = this.layout._getOption('horizontal'); 2953 return this.layout.options.percentPosition && isHorizontal ? 2954 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 2955}; 2956 2957proto._transitionTo = function( x, y ) { 2958 this.getPosition(); 2959 // get current x & y from top/left 2960 var curX = this.position.x; 2961 var curY = this.position.y; 2962 2963 var compareX = parseInt( x, 10 ); 2964 var compareY = parseInt( y, 10 ); 2965 var didNotMove = compareX === this.position.x && compareY === this.position.y; 2966 2967 // save end position 2968 this.setPosition( x, y ); 2969 2970 // if did not move and not transitioning, just go to layout 2971 if ( didNotMove && !this.isTransitioning ) { 2972 this.layoutPosition(); 2973 return; 2974 } 2975 2976 var transX = x - curX; 2977 var transY = y - curY; 2978 var transitionStyle = {}; 2979 transitionStyle.transform = this.getTranslate( transX, transY ); 2980 2981 this.transition({ 2982 to: transitionStyle, 2983 onTransitionEnd: { 2984 transform: this.layoutPosition 2985 }, 2986 isCleaning: true 2987 }); 2988}; 2989 2990proto.getTranslate = function( x, y ) { 2991 // flip cooridinates if origin on right or bottom 2992 var isOriginLeft = this.layout._getOption('originLeft'); 2993 var isOriginTop = this.layout._getOption('originTop'); 2994 x = isOriginLeft ? x : -x; 2995 y = isOriginTop ? y : -y; 2996 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 2997}; 2998 2999// non transition + transform support 3000proto.goTo = function( x, y ) { 3001 this.setPosition( x, y ); 3002 this.layoutPosition(); 3003}; 3004 3005proto.moveTo = proto._transitionTo; 3006 3007proto.setPosition = function( x, y ) { 3008 this.position.x = parseInt( x, 10 ); 3009 this.position.y = parseInt( y, 10 ); 3010}; 3011 3012// ----- transition ----- // 3013 3014/** 3015 * @param {Object} style - CSS 3016 * @param {Function} onTransitionEnd 3017 */ 3018 3019// non transition, just trigger callback 3020proto._nonTransition = function( args ) { 3021 this.css( args.to ); 3022 if ( args.isCleaning ) { 3023 this._removeStyles( args.to ); 3024 } 3025 for ( var prop in args.onTransitionEnd ) { 3026 args.onTransitionEnd[ prop ].call( this ); 3027 } 3028}; 3029 3030/** 3031 * proper transition 3032 * @param {Object} args - arguments 3033 * @param {Object} to - style to transition to 3034 * @param {Object} from - style to start transition from 3035 * @param {Boolean} isCleaning - removes transition styles after transition 3036 * @param {Function} onTransitionEnd - callback 3037 */ 3038proto.transition = function( args ) { 3039 // redirect to nonTransition if no transition duration 3040 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 3041 this._nonTransition( args ); 3042 return; 3043 } 3044 3045 var _transition = this._transn; 3046 // keep track of onTransitionEnd callback by css property 3047 for ( var prop in args.onTransitionEnd ) { 3048 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 3049 } 3050 // keep track of properties that are transitioning 3051 for ( prop in args.to ) { 3052 _transition.ingProperties[ prop ] = true; 3053 // keep track of properties to clean up when transition is done 3054 if ( args.isCleaning ) { 3055 _transition.clean[ prop ] = true; 3056 } 3057 } 3058 3059 // set from styles 3060 if ( args.from ) { 3061 this.css( args.from ); 3062 // force redraw. http://blog.alexmaccaw.com/css-transitions 3063 var h = this.element.offsetHeight; 3064 // hack for JSHint to hush about unused var 3065 h = null; 3066 } 3067 // enable transition 3068 this.enableTransition( args.to ); 3069 // set styles that are transitioning 3070 this.css( args.to ); 3071 3072 this.isTransitioning = true; 3073 3074}; 3075 3076// dash before all cap letters, including first for 3077// WebkitTransform => -webkit-transform 3078function toDashedAll( str ) { 3079 return str.replace( /([A-Z])/g, function( $1 ) { 3080 return '-' + $1.toLowerCase(); 3081 }); 3082} 3083 3084var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 3085 3086proto.enableTransition = function(/* style */) { 3087 // HACK changing transitionProperty during a transition 3088 // will cause transition to jump 3089 if ( this.isTransitioning ) { 3090 return; 3091 } 3092 3093 // make `transition: foo, bar, baz` from style object 3094 // HACK un-comment this when enableTransition can work 3095 // while a transition is happening 3096 // var transitionValues = []; 3097 // for ( var prop in style ) { 3098 // // dash-ify camelCased properties like WebkitTransition
vendor: 5,416 bytes, lines 3099-3314
3099 // prop = vendorProperties[ prop ] || prop; 3100 // transitionValues.push( toDashedAll( prop ) ); 3101 // } 3102 // munge number to millisecond, to match stagger 3103 var duration = this.layout.options.transitionDuration; 3104 duration = typeof duration == 'number' ? duration + 'ms' : duration; 3105 // enable transition styles 3106 this.css({ 3107 transitionProperty: transitionProps, 3108 transitionDuration: duration, 3109 transitionDelay: this.staggerDelay || 0 3110 }); 3111 // listen for transition end event 3112 this.element.addEventListener( transitionEndEvent, this, false ); 3113}; 3114 3115// ----- events ----- // 3116 3117proto.onwebkitTransitionEnd = function( event ) { 3118 this.ontransitionend( event ); 3119}; 3120 3121proto.onotransitionend = function( event ) { 3122 this.ontransitionend( event ); 3123}; 3124 3125// properties that I munge to make my life easier 3126var dashedVendorProperties = { 3127 '-webkit-transform': 'transform' 3128}; 3129 3130proto.ontransitionend = function( event ) { 3131 // disregard bubbled events from children 3132 if ( event.target !== this.element ) { 3133 return; 3134 } 3135 var _transition = this._transn; 3136 // get property name of transitioned property, convert to prefix-free 3137 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 3138 3139 // remove property that has completed transitioning 3140 delete _transition.ingProperties[ propertyName ]; 3141 // check if any properties are still transitioning 3142 if ( isEmptyObj( _transition.ingProperties ) ) { 3143 // all properties have completed transitioning 3144 this.disableTransition(); 3145 } 3146 // clean style 3147 if ( propertyName in _transition.clean ) { 3148 // clean up style 3149 this.element.style[ event.propertyName ] = ''; 3150 delete _transition.clean[ propertyName ]; 3151 } 3152 // trigger onTransitionEnd callback 3153 if ( propertyName in _transition.onEnd ) { 3154 var onTransitionEnd = _transition.onEnd[ propertyName ]; 3155 onTransitionEnd.call( this ); 3156 delete _transition.onEnd[ propertyName ]; 3157 } 3158 3159 this.emitEvent( 'transitionEnd', [ this ] ); 3160}; 3161 3162proto.disableTransition = function() { 3163 this.removeTransitionStyles(); 3164 this.element.removeEventListener( transitionEndEvent, this, false ); 3165 this.isTransitioning = false; 3166}; 3167 3168/** 3169 * removes style property from element 3170 * @param {Object} style 3171**/ 3172proto._removeStyles = function( style ) { 3173 // clean up transition styles 3174 var cleanStyle = {}; 3175 for ( var prop in style ) { 3176 cleanStyle[ prop ] = ''; 3177 } 3178 this.css( cleanStyle ); 3179}; 3180 3181var cleanTransitionStyle = { 3182 transitionProperty: '', 3183 transitionDuration: '', 3184 transitionDelay: '' 3185}; 3186 3187proto.removeTransitionStyles = function() { 3188 // remove transition 3189 this.css( cleanTransitionStyle ); 3190}; 3191 3192// ----- stagger ----- // 3193 3194proto.stagger = function( delay ) { 3195 delay = isNaN( delay ) ? 0 : delay; 3196 this.staggerDelay = delay + 'ms'; 3197}; 3198 3199// ----- show/hide/remove ----- // 3200 3201// remove element from DOM 3202proto.removeElem = function() { 3203 this.element.parentNode.removeChild( this.element ); 3204 // remove display: none 3205 this.css({ display: '' }); 3206 this.emitEvent( 'remove', [ this ] ); 3207}; 3208 3209proto.remove = function() { 3210 // just remove element if no transition support or no transition 3211 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 3212 this.removeElem(); 3213 return; 3214 } 3215 3216 // start transition 3217 this.once( 'transitionEnd', function() { 3218 this.removeElem(); 3219 }); 3220 this.hide(); 3221}; 3222 3223proto.reveal = function() { 3224 delete this.isHidden; 3225 // remove display: none 3226 this.css({ display: '' }); 3227 3228 var options = this.layout.options; 3229 3230 var onTransitionEnd = {}; 3231 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 3232 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 3233 3234 this.transition({ 3235 from: options.hiddenStyle, 3236 to: options.visibleStyle, 3237 isCleaning: true, 3238 onTransitionEnd: onTransitionEnd 3239 }); 3240}; 3241 3242proto.onRevealTransitionEnd = function() { 3243 // check if still visible 3244 // during transition, item may have been hidden 3245 if ( !this.isHidden ) { 3246 this.emitEvent('reveal'); 3247 } 3248}; 3249 3250/** 3251 * get style property use for hide/reveal transition end 3252 * @param {String} styleProperty - hiddenStyle/visibleStyle 3253 * @returns {String} 3254 */ 3255proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 3256 var optionStyle = this.layout.options[ styleProperty ]; 3257 // use opacity 3258 if ( optionStyle.opacity ) { 3259 return 'opacity'; 3260 } 3261 // get first property 3262 for ( var prop in optionStyle ) { 3263 return prop; 3264 } 3265}; 3266 3267proto.hide = function() { 3268 // set flag 3269 this.isHidden = true; 3270 // remove display: none 3271 this.css({ display: '' }); 3272 3273 var options = this.layout.options; 3274 3275 var onTransitionEnd = {}; 3276 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 3277 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 3278 3279 this.transition({ 3280 from: options.visibleStyle, 3281 to: options.hiddenStyle, 3282 // keep hidden stuff hidden 3283 isCleaning: true, 3284 onTransitionEnd: onTransitionEnd 3285 }); 3286}; 3287 3288proto.onHideTransitionEnd = function() { 3289 // check if still hidden 3290 // during transition, item may have been un-hidden 3291 if ( this.isHidden ) { 3292 this.css({ display: 'none' }); 3293 this.emitEvent('hide'); 3294 } 3295}; 3296 3297proto.destroy = function() { 3298 this.css({ 3299 position: '', 3300 left: '', 3301 right: '', 3302 top: '', 3303 bottom: '', 3304 transition: '', 3305 transform: '' 3306 }); 3307}; 3308 3309return Item; 3310 3311})); 3312 3313/*! 3314 * Outlayer v2.1.0
vendor: 22,038 bytes, lines 3314-4254
3314 3315 * the brains and guts of a layout library 3316 * MIT license 3317 */ 3318 3319( function( window, factory ) { 3320 'use strict'; 3321 // universal module definition 3322 /* jshint strict: false */ /* globals define, module, require */ 3323 if ( typeof define == 'function' && define.amd ) { 3324 // AMD - RequireJS 3325 define( 'outlayer/outlayer',[ 3326 'ev-emitter/ev-emitter', 3327 'get-size/get-size', 3328 'fizzy-ui-utils/utils', 3329 './item' 3330 ], 3331 function( EvEmitter, getSize, utils, Item ) { 3332 return factory( window, EvEmitter, getSize, utils, Item); 3333 } 3334 ); 3335 } else if ( typeof module == 'object' && module.exports ) { 3336 // CommonJS - Browserify, Webpack 3337 module.exports = factory( 3338 window, 3339 require('ev-emitter'), 3340 require('get-size'), 3341 require('fizzy-ui-utils'), 3342 require('./item') 3343 ); 3344 } else { 3345 // browser global 3346 window.Outlayer = factory( 3347 window, 3348 window.EvEmitter, 3349 window.getSize, 3350 window.fizzyUIUtils, 3351 window.Outlayer.Item 3352 ); 3353 } 3354 3355}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 3356'use strict'; 3357 3358// ----- vars ----- // 3359 3360var console = window.console; 3361var jQuery = window.jQuery; 3362var noop = function() {}; 3363 3364// -------------------------- Outlayer -------------------------- // 3365 3366// globally unique identifiers 3367var GUID = 0; 3368// internal store of all Outlayer intances 3369var instances = {}; 3370 3371 3372/** 3373 * @param {Element, String} element 3374 * @param {Object} options 3375 * @constructor 3376 */ 3377function Outlayer( element, options ) { 3378 var queryElement = utils.getQueryElement( element ); 3379 if ( !queryElement ) { 3380 if ( console ) { 3381 console.error( 'Bad element for ' + this.constructor.namespace + 3382 ': ' + ( queryElement || element ) ); 3383 } 3384 return; 3385 } 3386 this.element = queryElement; 3387 // add jQuery 3388 if ( jQuery ) { 3389 this.$element = jQuery( this.element ); 3390 } 3391 3392 // options 3393 this.options = utils.extend( {}, this.constructor.defaults ); 3394 this.option( options ); 3395 3396 // add id for Outlayer.getFromElement 3397 var id = ++GUID; 3398 this.element.outlayerGUID = id; // expando 3399 instances[ id ] = this; // associate via id 3400 3401 // kick it off 3402 this._create(); 3403 3404 var isInitLayout = this._getOption('initLayout'); 3405 if ( isInitLayout ) { 3406 this.layout(); 3407 } 3408} 3409 3410// settings are for internal use only 3411Outlayer.namespace = 'outlayer'; 3412Outlayer.Item = Item; 3413 3414// default options 3415Outlayer.defaults = { 3416 containerStyle: { 3417 position: 'relative' 3418 }, 3419 initLayout: true, 3420 originLeft: true, 3421 originTop: true, 3422 resize: true, 3423 resizeContainer: true, 3424 // item options 3425 transitionDuration: '0.4s', 3426 hiddenStyle: { 3427 opacity: 0, 3428 transform: 'scale(0.001)' 3429 }, 3430 visibleStyle: { 3431 opacity: 1, 3432 transform: 'scale(1)' 3433 } 3434}; 3435 3436var proto = Outlayer.prototype; 3437// inherit EvEmitter 3438utils.extend( proto, EvEmitter.prototype ); 3439 3440/** 3441 * set options 3442 * @param {Object} opts 3443 */ 3444proto.option = function( opts ) { 3445 utils.extend( this.options, opts ); 3446}; 3447 3448/** 3449 * get backwards compatible option value, check old name 3450 */ 3451proto._getOption = function( option ) { 3452 var oldOption = this.constructor.compatOptions[ option ]; 3453 return oldOption && this.options[ oldOption ] !== undefined ? 3454 this.options[ oldOption ] : this.options[ option ]; 3455}; 3456 3457Outlayer.compatOptions = { 3458 // currentName: oldName 3459 initLayout: 'isInitLayout', 3460 horizontal: 'isHorizontal', 3461 layoutInstant: 'isLayoutInstant', 3462 originLeft: 'isOriginLeft', 3463 originTop: 'isOriginTop', 3464 resize: 'isResizeBound', 3465 resizeContainer: 'isResizingContainer' 3466}; 3467 3468proto._create = function() { 3469 // get items from children 3470 this.reloadItems(); 3471 // elements that affect layout, but are not laid out 3472 this.stamps = []; 3473 this.stamp( this.options.stamp ); 3474 // set container style 3475 utils.extend( this.element.style, this.options.containerStyle ); 3476 3477 // bind resize method 3478 var canBindResize = this._getOption('resize'); 3479 if ( canBindResize ) { 3480 this.bindResize(); 3481 } 3482}; 3483 3484// goes through all children again and gets bricks in proper order 3485proto.reloadItems = function() { 3486 // collection of item elements 3487 this.items = this._itemize( this.element.children ); 3488}; 3489 3490 3491/** 3492 * turn elements into Outlayer.Items to be used in layout 3493 * @param {Array or NodeList or HTMLElement} elems 3494 * @returns {Array} items - collection of new Outlayer Items 3495 */ 3496proto._itemize = function( elems ) { 3497 3498 var itemElems = this._filterFindItemElements( elems ); 3499 var Item = this.constructor.Item; 3500 3501 // create new Outlayer Items for collection 3502 var items = []; 3503 for ( var i=0; i < itemElems.length; i++ ) { 3504 var elem = itemElems[i]; 3505 var item = new Item( elem, this ); 3506 items.push( item ); 3507 } 3508 3509 return items; 3510}; 3511 3512/** 3513 * get item elements to be used in layout 3514 * @param {Array or NodeList or HTMLElement} elems 3515 * @returns {Array} items - item elements 3516 */ 3517proto._filterFindItemElements = function( elems ) { 3518 return utils.filterFindElements( elems, this.options.itemSelector ); 3519}; 3520 3521/** 3522 * getter method for getting item elements 3523 * @returns {Array} elems - collection of item elements 3524 */ 3525proto.getItemElements = function() { 3526 return this.items.map( function( item ) { 3527 return item.element; 3528 }); 3529}; 3530 3531// ----- init & layout ----- // 3532 3533/** 3534 * lays out all items 3535 */ 3536proto.layout = function() { 3537 this._resetLayout(); 3538 this._manageStamps(); 3539 3540 // don't animate first layout 3541 var layoutInstant = this._getOption('layoutInstant'); 3542 var isInstant = layoutInstant !== undefined ? 3543 layoutInstant : !this._isLayoutInited; 3544 this.layoutItems( this.items, isInstant ); 3545 3546 // flag for initalized 3547 this._isLayoutInited = true; 3548}; 3549 3550// _init is alias for layout 3551proto._init = proto.layout; 3552 3553/** 3554 * logic before any new layout 3555 */ 3556proto._resetLayout = function() { 3557 this.getSize(); 3558}; 3559 3560 3561proto.getSize = function() { 3562 this.size = getSize( this.element ); 3563}; 3564 3565/** 3566 * get measurement from option, for columnWidth, rowHeight, gutter 3567 * if option is String -> get element from selector string, & get size of element 3568 * if option is Element -> get size of element 3569 * else use option as a number 3570 * 3571 * @param {String} measurement 3572 * @param {String} size - width or height 3573 * @private 3574 */ 3575proto._getMeasurement = function( measurement, size ) { 3576 var option = this.options[ measurement ]; 3577 var elem; 3578 if ( !option ) { 3579 // default to 0 3580 this[ measurement ] = 0; 3581 } else { 3582 // use option as an element 3583 if ( typeof option == 'string' ) { 3584 elem = this.element.querySelector( option ); 3585 } else if ( option instanceof HTMLElement ) { 3586 elem = option; 3587 } 3588 // use size of element, if element 3589 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 3590 } 3591}; 3592 3593/** 3594 * layout a collection of item elements 3595 * @api public 3596 */ 3597proto.layoutItems = function( items, isInstant ) { 3598 items = this._getItemsForLayout( items ); 3599 3600 this._layoutItems( items, isInstant ); 3601 3602 this._postLayout(); 3603}; 3604 3605/** 3606 * get the items to be laid out 3607 * you may want to skip over some items 3608 * @param {Array} items 3609 * @returns {Array} items 3610 */ 3611proto._getItemsForLayout = function( items ) { 3612 return items.filter( function( item ) { 3613 return !item.isIgnored; 3614 }); 3615}; 3616 3617/** 3618 * layout items 3619 * @param {Array} items 3620 * @param {Boolean} isInstant 3621 */ 3622proto._layoutItems = function( items, isInstant ) { 3623 this._emitCompleteOnItems( 'layout', items ); 3624 3625 if ( !items || !items.length ) { 3626 // no items, emit event with empty array 3627 return; 3628 } 3629 3630 var queue = []; 3631 3632 items.forEach( function( item ) { 3633 // get x/y object from method 3634 var position = this._getItemLayoutPosition( item ); 3635 // enqueue 3636 position.item = item; 3637 position.isInstant = isInstant || item.isLayoutInstant; 3638 queue.push( position ); 3639 }, this ); 3640 3641 this._processLayoutQueue( queue ); 3642}; 3643 3644/** 3645 * get item layout position 3646 * @param {Outlayer.Item} item 3647 * @returns {Object} x and y position 3648 */ 3649proto._getItemLayoutPosition = function( /* item */ ) { 3650 return { 3651 x: 0, 3652 y: 0 3653 }; 3654}; 3655 3656/** 3657 * iterate over array and position each item 3658 * Reason being - separating this logic prevents 'layout invalidation' 3659 * thx @paul_irish 3660 * @param {Array} queue 3661 */ 3662proto._processLayoutQueue = function( queue ) { 3663 this.updateStagger(); 3664 queue.forEach( function( obj, i ) { 3665 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 3666 }, this ); 3667}; 3668 3669// set stagger from option in milliseconds number 3670proto.updateStagger = function() { 3671 var stagger = this.options.stagger; 3672 if ( stagger === null || stagger === undefined ) { 3673 this.stagger = 0; 3674 return; 3675 } 3676 this.stagger = getMilliseconds( stagger ); 3677 return this.stagger; 3678}; 3679 3680/** 3681 * Sets position of item in DOM 3682 * @param {Outlayer.Item} item 3683 * @param {Number} x - horizontal position 3684 * @param {Number} y - vertical position 3685 * @param {Boolean} isInstant - disables transitions 3686 */ 3687proto._positionItem = function( item, x, y, isInstant, i ) { 3688 if ( isInstant ) { 3689 // if not transition, just set CSS 3690 item.goTo( x, y ); 3691 } else { 3692 item.stagger( i * this.stagger ); 3693 item.moveTo( x, y ); 3694 } 3695}; 3696 3697/** 3698 * Any logic you want to do after each layout, 3699 * i.e. size the container 3700 */ 3701proto._postLayout = function() { 3702 this.resizeContainer(); 3703}; 3704 3705proto.resizeContainer = function() { 3706 var isResizingContainer = this._getOption('resizeContainer'); 3707 if ( !isResizingContainer ) { 3708 return; 3709 } 3710 var size = this._getContainerSize(); 3711 if ( size ) { 3712 this._setContainerMeasure( size.width, true ); 3713 this._setContainerMeasure( size.height, false ); 3714 } 3715}; 3716 3717/** 3718 * Sets width or height of container if returned 3719 * @returns {Object} size 3720 * @param {Number} width 3721 * @param {Number} height 3722 */ 3723proto._getContainerSize = noop; 3724 3725/** 3726 * @param {Number} measure - size of width or height 3727 * @param {Boolean} isWidth 3728 */ 3729proto._setContainerMeasure = function( measure, isWidth ) { 3730 if ( measure === undefined ) { 3731 return; 3732 } 3733 3734 var elemSize = this.size; 3735 // add padding and border width if border box 3736 if ( elemSize.isBorderBox ) { 3737 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 3738 elemSize.borderLeftWidth + elemSize.borderRightWidth : 3739 elemSize.paddingBottom + elemSize.paddingTop + 3740 elemSize.borderTopWidth + elemSize.borderBottomWidth; 3741 } 3742 3743 measure = Math.max( measure, 0 ); 3744 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 3745}; 3746 3747/** 3748 * emit eventComplete on a collection of items events 3749 * @param {String} eventName 3750 * @param {Array} items - Outlayer.Items 3751 */ 3752proto._emitCompleteOnItems = function( eventName, items ) { 3753 var _this = this; 3754 function onComplete() { 3755 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 3756 } 3757 3758 var count = items.length; 3759 if ( !items || !count ) { 3760 onComplete(); 3761 return; 3762 } 3763 3764 var doneCount = 0; 3765 function tick() { 3766 doneCount++; 3767 if ( doneCount == count ) { 3768 onComplete(); 3769 } 3770 } 3771 3772 // bind callback 3773 items.forEach( function( item ) { 3774 item.once( eventName, tick ); 3775 }); 3776}; 3777 3778/** 3779 * emits events via EvEmitter and jQuery events 3780 * @param {String} type - name of event 3781 * @param {Event} event - original event 3782 * @param {Array} args - extra arguments 3783 */ 3784proto.dispatchEvent = function( type, event, args ) { 3785 // add original event to arguments 3786 var emitArgs = event ? [ event ].concat( args ) : args; 3787 this.emitEvent( type, emitArgs ); 3788 3789 if ( jQuery ) { 3790 // set this.$element 3791 this.$element = this.$element || jQuery( this.element ); 3792 if ( event ) { 3793 // create jQuery event 3794 var $event = jQuery.Event( event ); 3795 $event.type = type; 3796 this.$element.trigger( $event, args ); 3797 } else { 3798 // just trigger with type if no event available 3799 this.$element.trigger( type, args ); 3800 } 3801 } 3802}; 3803 3804// -------------------------- ignore & stamps -------------------------- // 3805 3806 3807/** 3808 * keep item in collection, but do not lay it out 3809 * ignored items do not get skipped in layout 3810 * @param {Element} elem 3811 */ 3812proto.ignore = function( elem ) { 3813 var item = this.getItem( elem ); 3814 if ( item ) { 3815 item.isIgnored = true; 3816 } 3817}; 3818 3819/** 3820 * return item to layout collection 3821 * @param {Element} elem 3822 */ 3823proto.unignore = function( elem ) { 3824 var item = this.getItem( elem ); 3825 if ( item ) { 3826 delete item.isIgnored; 3827 } 3828}; 3829 3830/** 3831 * adds elements to stamps 3832 * @param {NodeList, Array, Element, or String} elems 3833 */ 3834proto.stamp = function( elems ) { 3835 elems = this._find( elems ); 3836 if ( !elems ) { 3837 return; 3838 } 3839 3840 this.stamps = this.stamps.concat( elems ); 3841 // ignore 3842 elems.forEach( this.ignore, this ); 3843}; 3844 3845/** 3846 * removes elements to stamps 3847 * @param {NodeList, Array, or Element} elems 3848 */ 3849proto.unstamp = function( elems ) { 3850 elems = this._find( elems ); 3851 if ( !elems ){ 3852 return; 3853 } 3854 3855 elems.forEach( function( elem ) { 3856 // filter out removed stamp elements 3857 utils.removeFrom( this.stamps, elem ); 3858 this.unignore( elem ); 3859 }, this ); 3860}; 3861 3862/** 3863 * finds child elements 3864 * @param {NodeList, Array, Element, or String} elems 3865 * @returns {Array} elems 3866 */ 3867proto._find = function( elems ) { 3868 if ( !elems ) { 3869 return; 3870 } 3871 // if string, use argument as selector string 3872 if ( typeof elems == 'string' ) { 3873 elems = this.element.querySelectorAll( elems ); 3874 } 3875 elems = utils.makeArray( elems ); 3876 return elems; 3877}; 3878 3879proto._manageStamps = function() { 3880 if ( !this.stamps || !this.stamps.length ) { 3881 return; 3882 } 3883 3884 this._getBoundingRect(); 3885 3886 this.stamps.forEach( this._manageStamp, this ); 3887}; 3888 3889// update boundingLeft / Top 3890proto._getBoundingRect = function() { 3891 // get bounding rect for container element 3892 var boundingRect = this.element.getBoundingClientRect(); 3893 var size = this.size; 3894 this._boundingRect = { 3895 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 3896 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 3897 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 3898 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 3899 }; 3900}; 3901 3902/** 3903 * @param {Element} stamp 3904**/ 3905proto._manageStamp = noop; 3906 3907/** 3908 * get x/y position of element relative to container element 3909 * @param {Element} elem 3910 * @returns {Object} offset - has left, top, right, bottom 3911 */ 3912proto._getElementOffset = function( elem ) { 3913 var boundingRect = elem.getBoundingClientRect(); 3914 var thisRect = this._boundingRect; 3915 var size = getSize( elem ); 3916 var offset = { 3917 left: boundingRect.left - thisRect.left - size.marginLeft, 3918 top: boundingRect.top - thisRect.top - size.marginTop, 3919 right: thisRect.right - boundingRect.right - size.marginRight, 3920 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 3921 }; 3922 return offset; 3923}; 3924 3925// -------------------------- resize -------------------------- // 3926 3927// enable event handlers for listeners 3928// i.e. resize -> onresize 3929proto.handleEvent = utils.handleEvent; 3930 3931/** 3932 * Bind layout to window resizing 3933 */ 3934proto.bindResize = function() { 3935 window.addEventListener( 'resize', this ); 3936 this.isResizeBound = true; 3937}; 3938 3939/** 3940 * Unbind layout to window resizing 3941 */ 3942proto.unbindResize = function() { 3943 window.removeEventListener( 'resize', this ); 3944 this.isResizeBound = false; 3945}; 3946 3947proto.onresize = function() { 3948 this.resize(); 3949}; 3950 3951utils.debounceMethod( Outlayer, 'onresize', 100 ); 3952 3953proto.resize = function() { 3954 // don't trigger if size did not change 3955 // or if resize was unbound. See #9 3956 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 3957 return; 3958 } 3959 3960 this.layout(); 3961}; 3962 3963/** 3964 * check if layout is needed post layout 3965 * @returns Boolean 3966 */ 3967proto.needsResizeLayout = function() { 3968 var size = getSize( this.element ); 3969 // check that this.size and size are there 3970 // IE8 triggers resize on body size change, so they might not be 3971 var hasSizes = this.size && size; 3972 return hasSizes && size.innerWidth !== this.size.innerWidth; 3973}; 3974 3975// -------------------------- methods -------------------------- // 3976 3977/** 3978 * add items to Outlayer instance 3979 * @param {Array or NodeList or Element} elems 3980 * @returns {Array} items - Outlayer.Items 3981**/ 3982proto.addItems = function( elems ) { 3983 var items = this._itemize( elems ); 3984 // add items to collection 3985 if ( items.length ) { 3986 this.items = this.items.concat( items ); 3987 } 3988 return items; 3989}; 3990 3991/** 3992 * Layout newly-appended item elements 3993 * @param {Array or NodeList or Element} elems 3994 */ 3995proto.appended = function( elems ) { 3996 var items = this.addItems( elems ); 3997 if ( !items.length ) { 3998 return; 3999 } 4000 // layout and reveal just the new items 4001 this.layoutItems( items, true ); 4002 this.reveal( items ); 4003}; 4004 4005/** 4006 * Layout prepended elements 4007 * @param {Array or NodeList or Element} elems 4008 */ 4009proto.prepended = function( elems ) { 4010 var items = this._itemize( elems ); 4011 if ( !items.length ) { 4012 return; 4013 } 4014 // add items to beginning of collection 4015 var previousItems = this.items.slice(0); 4016 this.items = items.concat( previousItems ); 4017 // start new layout 4018 this._resetLayout(); 4019 this._manageStamps(); 4020 // layout new stuff without transition 4021 this.layoutItems( items, true ); 4022 this.reveal( items ); 4023 // layout previous items 4024 this.layoutItems( previousItems ); 4025}; 4026 4027/** 4028 * reveal a collection of items 4029 * @param {Array of Outlayer.Items} items 4030 */ 4031proto.reveal = function( items ) { 4032 this._emitCompleteOnItems( 'reveal', items ); 4033 if ( !items || !items.length ) { 4034 return; 4035 } 4036 var stagger = this.updateStagger(); 4037 items.forEach( function( item, i ) { 4038 item.stagger( i * stagger ); 4039 item.reveal(); 4040 }); 4041}; 4042 4043/** 4044 * hide a collection of items 4045 * @param {Array of Outlayer.Items} items 4046 */ 4047proto.hide = function( items ) { 4048 this._emitCompleteOnItems( 'hide', items ); 4049 if ( !items || !items.length ) { 4050 return; 4051 } 4052 var stagger = this.updateStagger(); 4053 items.forEach( function( item, i ) { 4054 item.stagger( i * stagger ); 4055 item.hide(); 4056 }); 4057}; 4058 4059/** 4060 * reveal item elements 4061 * @param {Array}, {Element}, {NodeList} items 4062 */ 4063proto.revealItemElements = function( elems ) { 4064 var items = this.getItems( elems ); 4065 this.reveal( items ); 4066}; 4067 4068/** 4069 * hide item elements 4070 * @param {Array}, {Element}, {NodeList} items 4071 */ 4072proto.hideItemElements = function( elems ) { 4073 var items = this.getItems( elems ); 4074 this.hide( items ); 4075}; 4076 4077/** 4078 * get Outlayer.Item, given an Element 4079 * @param {Element} elem 4080 * @param {Function} callback 4081 * @returns {Outlayer.Item} item 4082 */ 4083proto.getItem = function( elem ) { 4084 // loop through items to get the one that matches 4085 for ( var i=0; i < this.items.length; i++ ) { 4086 var item = this.items[i]; 4087 if ( item.element == elem ) { 4088 // return item 4089 return item; 4090 } 4091 } 4092}; 4093 4094/** 4095 * get collection of Outlayer.Items, given Elements 4096 * @param {Array} elems 4097 * @returns {Array} items - Outlayer.Items 4098 */ 4099proto.getItems = function( elems ) { 4100 elems = utils.makeArray( elems ); 4101 var items = []; 4102 elems.forEach( function( elem ) { 4103 var item = this.getItem( elem ); 4104 if ( item ) { 4105 items.push( item ); 4106 } 4107 }, this ); 4108 4109 return items; 4110}; 4111 4112/** 4113 * remove element(s) from instance and DOM 4114 * @param {Array or NodeList or Element} elems 4115 */ 4116proto.remove = function( elems ) { 4117 var removeItems = this.getItems( elems ); 4118 4119 this._emitCompleteOnItems( 'remove', removeItems ); 4120 4121 // bail if no items to remove 4122 if ( !removeItems || !removeItems.length ) { 4123 return; 4124 } 4125 4126 removeItems.forEach( function( item ) { 4127 item.remove(); 4128 // remove item from collection 4129 utils.removeFrom( this.items, item ); 4130 }, this ); 4131}; 4132 4133// ----- destroy ----- // 4134 4135// remove and disable Outlayer instance 4136proto.destroy = function() { 4137 // clean up dynamic styles 4138 var style = this.element.style; 4139 style.height = ''; 4140 style.position = ''; 4141 style.width = ''; 4142 // destroy items 4143 this.items.forEach( function( item ) { 4144 item.destroy(); 4145 }); 4146 4147 this.unbindResize(); 4148 4149 var id = this.element.outlayerGUID; 4150 delete instances[ id ]; // remove reference to instance by id 4151 delete this.element.outlayerGUID; 4152 // remove data for jQuery 4153 if ( jQuery ) { 4154 jQuery.removeData( this.element, this.constructor.namespace ); 4155 } 4156 4157}; 4158 4159// -------------------------- data -------------------------- // 4160 4161/** 4162 * get Outlayer instance from element 4163 * @param {Element} elem 4164 * @returns {Outlayer} 4165 */ 4166Outlayer.data = function( elem ) { 4167 elem = utils.getQueryElement( elem ); 4168 var id = elem && elem.outlayerGUID; 4169 return id && instances[ id ]; 4170}; 4171 4172 4173// -------------------------- create Outlayer class -------------------------- // 4174 4175/** 4176 * create a layout class 4177 * @param {String} namespace 4178 */ 4179Outlayer.create = function( namespace, options ) { 4180 // sub-class Outlayer 4181 var Layout = subclass( Outlayer ); 4182 // apply new options and compatOptions 4183 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 4184 utils.extend( Layout.defaults, options ); 4185 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 4186 4187 Layout.namespace = namespace; 4188 4189 Layout.data = Outlayer.data; 4190 4191 // sub-class Item 4192 Layout.Item = subclass( Item ); 4193 4194 // -------------------------- declarative -------------------------- // 4195 4196 utils.htmlInit( Layout, namespace ); 4197 4198 // -------------------------- jQuery bridge -------------------------- // 4199 4200 // make into jQuery plugin 4201 if ( jQuery && jQuery.bridget ) { 4202 jQuery.bridget( namespace, Layout ); 4203 } 4204 4205 return Layout; 4206}; 4207 4208function subclass( Parent ) { 4209 function SubClass() { 4210 Parent.apply( this, arguments ); 4211 } 4212 4213 SubClass.prototype = Object.create( Parent.prototype ); 4214 SubClass.prototype.constructor = SubClass; 4215 4216 return SubClass; 4217} 4218 4219// ----- helpers ----- // 4220 4221// how many milliseconds are in each unit 4222var msUnits = { 4223 ms: 1, 4224 s: 1000 4225}; 4226 4227// munge time-like parameter into millisecond number 4228// '0.4s' -> 40 4229function getMilliseconds( time ) { 4230 if ( typeof time == 'number' ) { 4231 return time; 4232 } 4233 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 4234 var num = matches && matches[1]; 4235 var unit = matches && matches[2]; 4236 if ( !num.length ) { 4237 return 0; 4238 } 4239 num = parseFloat( num ); 4240 var mult = msUnits[ unit ] || 1; 4241 return num * mult; 4242} 4243 4244// ----- fin ----- // 4245 4246// back in global 4247Outlayer.Item = Item; 4248 4249return Outlayer; 4250 4251})); 4252 4253/** 4254 *
vendor: 23,322 bytes, lines 4254-5129
4254Isotope Item 4255**/ 4256 4257( function( window, factory ) { 4258 // universal module definition 4259 /* jshint strict: false */ /*globals define, module, require */ 4260 if ( typeof define == 'function' && define.amd ) { 4261 // AMD 4262 define( 'isotope/js/item',[ 4263 'outlayer/outlayer' 4264 ], 4265 factory ); 4266 } else if ( typeof module == 'object' && module.exports ) { 4267 // CommonJS 4268 module.exports = factory( 4269 require('outlayer') 4270 ); 4271 } else { 4272 // browser global 4273 window.Isotope = window.Isotope || {}; 4274 window.Isotope.Item = factory( 4275 window.Outlayer 4276 ); 4277 } 4278 4279}( window, function factory( Outlayer ) { 4280'use strict'; 4281 4282// -------------------------- Item -------------------------- // 4283 4284// sub-class Outlayer Item 4285function Item() { 4286 Outlayer.Item.apply( this, arguments ); 4287} 4288 4289var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 4290 4291var _create = proto._create; 4292proto._create = function() { 4293 // assign id, used for original-order sorting 4294 this.id = this.layout.itemGUID++; 4295 _create.call( this ); 4296 this.sortData = {}; 4297}; 4298 4299proto.updateSortData = function() { 4300 if ( this.isIgnored ) { 4301 return; 4302 } 4303 // default sorters 4304 this.sortData.id = this.id; 4305 // for backward compatibility 4306 this.sortData['original-order'] = this.id; 4307 this.sortData.random = Math.random(); 4308 // go thru getSortData obj and apply the sorters 4309 var getSortData = this.layout.options.getSortData; 4310 var sorters = this.layout._sorters; 4311 for ( var key in getSortData ) { 4312 var sorter = sorters[ key ]; 4313 this.sortData[ key ] = sorter( this.element, this ); 4314 } 4315}; 4316 4317var _destroy = proto.destroy; 4318proto.destroy = function() { 4319 // call super 4320 _destroy.apply( this, arguments ); 4321 // reset display, #741 4322 this.css({ 4323 display: '' 4324 }); 4325}; 4326 4327return Item; 4328 4329})); 4330 4331/** 4332 * Isotope LayoutMode 4333 */ 4334 4335( function( window, factory ) { 4336 // universal module definition 4337 /* jshint strict: false */ /*globals define, module, require */ 4338 if ( typeof define == 'function' && define.amd ) { 4339 // AMD 4340 define( 'isotope/js/layout-mode',[ 4341 'get-size/get-size', 4342 'outlayer/outlayer' 4343 ], 4344 factory ); 4345 } else if ( typeof module == 'object' && module.exports ) { 4346 // CommonJS 4347 module.exports = factory( 4348 require('get-size'), 4349 require('outlayer') 4350 ); 4351 } else { 4352 // browser global 4353 window.Isotope = window.Isotope || {}; 4354 window.Isotope.LayoutMode = factory( 4355 window.getSize, 4356 window.Outlayer 4357 ); 4358 } 4359 4360}( window, function factory( getSize, Outlayer ) { 4361 'use strict'; 4362 4363 // layout mode class 4364 function LayoutMode( isotope ) { 4365 this.isotope = isotope; 4366 // link properties 4367 if ( isotope ) { 4368 this.options = isotope.options[ this.namespace ]; 4369 this.element = isotope.element; 4370 this.items = isotope.filteredItems; 4371 this.size = isotope.size; 4372 } 4373 } 4374 4375 var proto = LayoutMode.prototype; 4376 4377 /** 4378 * some methods should just defer to default Outlayer method 4379 * and reference the Isotope instance as `this` 4380 **/ 4381 var facadeMethods = [ 4382 '_resetLayout', 4383 '_getItemLayoutPosition', 4384 '_manageStamp', 4385 '_getContainerSize', 4386 '_getElementOffset', 4387 'needsResizeLayout', 4388 '_getOption' 4389 ]; 4390 4391 facadeMethods.forEach( function( methodName ) { 4392 proto[ methodName ] = function() { 4393 return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); 4394 }; 4395 }); 4396 4397 // ----- ----- // 4398 4399 // for horizontal layout modes, check vertical size 4400 proto.needsVerticalResizeLayout = function() { 4401 // don't trigger if size did not change 4402 var size = getSize( this.isotope.element ); 4403 // check that this.size and size are there 4404 // IE8 triggers resize on body size change, so they might not be 4405 var hasSizes = this.isotope.size && size; 4406 return hasSizes && size.innerHeight != this.isotope.size.innerHeight; 4407 }; 4408 4409 // ----- measurements ----- // 4410 4411 proto._getMeasurement = function() { 4412 this.isotope._getMeasurement.apply( this, arguments ); 4413 }; 4414 4415 proto.getColumnWidth = function() { 4416 this.getSegmentSize( 'column', 'Width' ); 4417 }; 4418 4419 proto.getRowHeight = function() { 4420 this.getSegmentSize( 'row', 'Height' ); 4421 }; 4422 4423 /** 4424 * get columnWidth or rowHeight 4425 * segment: 'column' or 'row' 4426 * size 'Width' or 'Height' 4427 **/ 4428 proto.getSegmentSize = function( segment, size ) { 4429 var segmentName = segment + size; 4430 var outerSize = 'outer' + size; 4431 // columnWidth / outerWidth // rowHeight / outerHeight 4432 this._getMeasurement( segmentName, outerSize ); 4433 // got rowHeight or columnWidth, we can chill 4434 if ( this[ segmentName ] ) { 4435 return; 4436 } 4437 // fall back to item of first element 4438 var firstItemSize = this.getFirstItemSize(); 4439 this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || 4440 // or size of container 4441 this.isotope.size[ 'inner' + size ]; 4442 }; 4443 4444 proto.getFirstItemSize = function() { 4445 var firstItem = this.isotope.filteredItems[0]; 4446 return firstItem && firstItem.element && getSize( firstItem.element ); 4447 }; 4448 4449 // ----- methods that should reference isotope ----- // 4450 4451 proto.layout = function() { 4452 this.isotope.layout.apply( this.isotope, arguments ); 4453 }; 4454 4455 proto.getSize = function() { 4456 this.isotope.getSize(); 4457 this.size = this.isotope.size; 4458 }; 4459 4460 // -------------------------- create -------------------------- // 4461 4462 LayoutMode.modes = {}; 4463 4464 LayoutMode.create = function( namespace, options ) { 4465 4466 function Mode() { 4467 LayoutMode.apply( this, arguments ); 4468 } 4469 4470 Mode.prototype = Object.create( proto ); 4471 Mode.prototype.constructor = Mode; 4472 4473 // default options 4474 if ( options ) { 4475 Mode.options = options; 4476 } 4477 4478 Mode.prototype.namespace = namespace; 4479 // register in Isotope 4480 LayoutMode.modes[ namespace ] = Mode; 4481 4482 return Mode; 4483 }; 4484 4485 return LayoutMode; 4486 4487})); 4488 4489/*! 4490 * Masonry v4.1.0 4491 * Cascading grid layout library 4492 * http://masonry.desandro.com 4493 * MIT License 4494 * by David DeSandro 4495 */ 4496 4497( function( window, factory ) { 4498 // universal module definition 4499 /* jshint strict: false */ /*globals define, module, require */ 4500 if ( typeof define == 'function' && define.amd ) { 4501 // AMD 4502 define( 'masonry/masonry',[ 4503 'outlayer/outlayer', 4504 'get-size/get-size' 4505 ], 4506 factory ); 4507 } else if ( typeof module == 'object' && module.exports ) { 4508 // CommonJS 4509 module.exports = factory( 4510 require('outlayer'), 4511 require('get-size') 4512 ); 4513 } else { 4514 // browser global 4515 window.Masonry = factory( 4516 window.Outlayer, 4517 window.getSize 4518 ); 4519 } 4520 4521}( window, function factory( Outlayer, getSize ) { 4522 4523 4524 4525// -------------------------- masonryDefinition -------------------------- // 4526 4527 // create an Outlayer layout class 4528 var Masonry = Outlayer.create('masonry'); 4529 // isFitWidth -> fitWidth 4530 Masonry.compatOptions.fitWidth = 'isFitWidth'; 4531 4532 Masonry.prototype._resetLayout = function() { 4533 this.getSize(); 4534 this._getMeasurement( 'columnWidth', 'outerWidth' ); 4535 this._getMeasurement( 'gutter', 'outerWidth' ); 4536 this.measureColumns(); 4537 4538 // reset column Y 4539 this.colYs = []; 4540 for ( var i=0; i < this.cols; i++ ) { 4541 this.colYs.push( 0 ); 4542 } 4543 4544 this.maxY = 0; 4545 }; 4546 4547 Masonry.prototype.measureColumns = function() { 4548 this.getContainerWidth(); 4549 // if columnWidth is 0, default to outerWidth of first item 4550 if ( !this.columnWidth ) { 4551 var firstItem = this.items[0]; 4552 var firstItemElem = firstItem && firstItem.element; 4553 // columnWidth fall back to item of first element 4554 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 4555 // if first elem has no width, default to size of container 4556 this.containerWidth; 4557 } 4558 4559 var columnWidth = this.columnWidth += this.gutter; 4560 4561 // calculate columns 4562 var containerWidth = this.containerWidth + this.gutter; 4563 var cols = containerWidth / columnWidth; 4564 // fix rounding errors, typically with gutters 4565 var excess = columnWidth - containerWidth % columnWidth; 4566 // if overshoot is less than a pixel, round up, otherwise floor it 4567 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 4568 cols = Math[ mathMethod ]( cols ); 4569 this.cols = Math.max( cols, 1 ); 4570 }; 4571 4572 Masonry.prototype.getContainerWidth = function() { 4573 // container is parent if fit width 4574 var isFitWidth = this._getOption('fitWidth'); 4575 var container = isFitWidth ? this.element.parentNode : this.element; 4576 // check that this.size and size are there 4577 // IE8 triggers resize on body size change, so they might not be 4578 var size = getSize( container ); 4579 this.containerWidth = size && size.innerWidth; 4580 }; 4581 4582 Masonry.prototype._getItemLayoutPosition = function( item ) { 4583 item.getSize(); 4584 // how many columns does this brick span 4585 var remainder = item.size.outerWidth % this.columnWidth; 4586 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 4587 // round if off by 1 pixel, otherwise use ceil 4588 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 4589 colSpan = Math.min( colSpan, this.cols ); 4590 4591 var colGroup = this._getColGroup( colSpan ); 4592 // get the minimum Y value from the columns 4593 var minimumY = Math.min.apply( Math, colGroup ); 4594 var shortColIndex = colGroup.indexOf( minimumY ); 4595 4596 // position the brick 4597 var position = { 4598 x: this.columnWidth * shortColIndex, 4599 y: minimumY 4600 }; 4601 4602 // apply setHeight to necessary columns 4603 var setHeight = minimumY + item.size.outerHeight; 4604 var setSpan = this.cols + 1 - colGroup.length; 4605 for ( var i = 0; i < setSpan; i++ ) { 4606 this.colYs[ shortColIndex + i ] = setHeight; 4607 } 4608 4609 return position; 4610 }; 4611 4612 /** 4613 * @param {Number} colSpan - number of columns the element spans 4614 * @returns {Array} colGroup 4615 */ 4616 Masonry.prototype._getColGroup = function( colSpan ) { 4617 if ( colSpan < 2 ) { 4618 // if brick spans only one column, use all the column Ys 4619 return this.colYs; 4620 } 4621 4622 var colGroup = []; 4623 // how many different places could this brick fit horizontally 4624 var groupCount = this.cols + 1 - colSpan; 4625 // for each group potential horizontal position 4626 for ( var i = 0; i < groupCount; i++ ) { 4627 // make an array of colY values for that one group 4628 var groupColYs = this.colYs.slice( i, i + colSpan ); 4629 // and get the max value of the array 4630 colGroup[i] = Math.max.apply( Math, groupColYs ); 4631 } 4632 return colGroup; 4633 }; 4634 4635 Masonry.prototype._manageStamp = function( stamp ) { 4636 var stampSize = getSize( stamp ); 4637 var offset = this._getElementOffset( stamp ); 4638 // get the columns that this stamp affects 4639 var isOriginLeft = this._getOption('originLeft'); 4640 var firstX = isOriginLeft ? offset.left : offset.right; 4641 var lastX = firstX + stampSize.outerWidth; 4642 var firstCol = Math.floor( firstX / this.columnWidth ); 4643 firstCol = Math.max( 0, firstCol ); 4644 var lastCol = Math.floor( lastX / this.columnWidth ); 4645 // lastCol should not go over if multiple of columnWidth #425 4646 lastCol -= lastX % this.columnWidth ? 0 : 1; 4647 lastCol = Math.min( this.cols - 1, lastCol ); 4648 // set colYs to bottom of the stamp 4649 4650 var isOriginTop = this._getOption('originTop'); 4651 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 4652 stampSize.outerHeight; 4653 for ( var i = firstCol; i <= lastCol; i++ ) { 4654 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 4655 } 4656 }; 4657 4658 Masonry.prototype._getContainerSize = function() { 4659 this.maxY = Math.max.apply( Math, this.colYs ); 4660 var size = { 4661 height: this.maxY 4662 }; 4663 4664 if ( this._getOption('fitWidth') ) { 4665 size.width = this._getContainerFitWidth(); 4666 } 4667 4668 return size; 4669 }; 4670 4671 Masonry.prototype._getContainerFitWidth = function() { 4672 var unusedCols = 0; 4673 // count unused columns 4674 var i = this.cols; 4675 while ( --i ) { 4676 if ( this.colYs[i] !== 0 ) { 4677 break; 4678 } 4679 unusedCols++; 4680 } 4681 // fit container to columns that have been used 4682 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 4683 }; 4684 4685 Masonry.prototype.needsResizeLayout = function() { 4686 var previousWidth = this.containerWidth; 4687 this.getContainerWidth(); 4688 return previousWidth != this.containerWidth; 4689 }; 4690 4691 return Masonry; 4692 4693})); 4694 4695/*! 4696 * Masonry layout mode 4697 * sub-classes Masonry 4698 * http://masonry.desandro.com 4699 */ 4700 4701( function( window, factory ) { 4702 // universal module definition 4703 /* jshint strict: false */ /*globals define, module, require */ 4704 if ( typeof define == 'function' && define.amd ) { 4705 // AMD 4706 define( 'isotope/js/layout-modes/masonry',[ 4707 '../layout-mode', 4708 'masonry/masonry' 4709 ], 4710 factory ); 4711 } else if ( typeof module == 'object' && module.exports ) { 4712 // CommonJS 4713 module.exports = factory( 4714 require('../layout-mode'), 4715 require('masonry-layout') 4716 ); 4717 } else { 4718 // browser global 4719 factory( 4720 window.Isotope.LayoutMode, 4721 window.Masonry 4722 ); 4723 } 4724 4725}( window, function factory( LayoutMode, Masonry ) { 4726'use strict'; 4727 4728// -------------------------- masonryDefinition -------------------------- // 4729 4730 // create an Outlayer layout class 4731 var MasonryMode = LayoutMode.create('masonry'); 4732 4733 var proto = MasonryMode.prototype; 4734 4735 var keepModeMethods = { 4736 _getElementOffset: true, 4737 layout: true, 4738 _getMeasurement: true 4739 }; 4740 4741 // inherit Masonry prototype 4742 for ( var method in Masonry.prototype ) { 4743 // do not inherit mode methods 4744 if ( !keepModeMethods[ method ] ) { 4745 proto[ method ] = Masonry.prototype[ method ]; 4746 } 4747 } 4748 4749 var measureColumns = proto.measureColumns; 4750 proto.measureColumns = function() { 4751 // set items, used if measuring first item 4752 this.items = this.isotope.filteredItems; 4753 measureColumns.call( this ); 4754 }; 4755 4756 // point to mode options for fitWidth 4757 var _getOption = proto._getOption; 4758 proto._getOption = function( option ) { 4759 if ( option == 'fitWidth' ) { 4760 return this.options.isFitWidth !== undefined ? 4761 this.options.isFitWidth : this.options.fitWidth; 4762 } 4763 return _getOption.apply( this.isotope, arguments ); 4764 }; 4765 4766 return MasonryMode; 4767 4768})); 4769 4770/** 4771 * fitRows layout mode 4772 */ 4773 4774( function( window, factory ) { 4775 // universal module definition 4776 /* jshint strict: false */ /*globals define, module, require */ 4777 if ( typeof define == 'function' && define.amd ) { 4778 // AMD 4779 define( 'isotope/js/layout-modes/fit-rows',[ 4780 '../layout-mode' 4781 ], 4782 factory ); 4783 } else if ( typeof exports == 'object' ) { 4784 // CommonJS 4785 module.exports = factory( 4786 require('../layout-mode') 4787 ); 4788 } else { 4789 // browser global 4790 factory( 4791 window.Isotope.LayoutMode 4792 ); 4793 } 4794 4795}( window, function factory( LayoutMode ) { 4796'use strict'; 4797 4798var FitRows = LayoutMode.create('fitRows'); 4799 4800var proto = FitRows.prototype; 4801 4802proto._resetLayout = function() { 4803 this.x = 0; 4804 this.y = 0; 4805 this.maxY = 0; 4806 this._getMeasurement( 'gutter', 'outerWidth' ); 4807}; 4808 4809proto._getItemLayoutPosition = function( item ) { 4810 item.getSize(); 4811 4812 var itemWidth = item.size.outerWidth + this.gutter; 4813 // if this element cannot fit in the current row 4814 var containerWidth = this.isotope.size.innerWidth + this.gutter; 4815 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 4816 this.x = 0; 4817 this.y = this.maxY; 4818 } 4819 4820 var position = { 4821 x: this.x, 4822 y: this.y 4823 }; 4824 4825 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 4826 this.x += itemWidth; 4827 4828 return position; 4829}; 4830 4831proto._getContainerSize = function() { 4832 return { height: this.maxY }; 4833}; 4834 4835return FitRows; 4836 4837})); 4838 4839/** 4840 * vertical layout mode 4841 */ 4842 4843( function( window, factory ) { 4844 // universal module definition 4845 /* jshint strict: false */ /*globals define, module, require */ 4846 if ( typeof define == 'function' && define.amd ) { 4847 // AMD 4848 define( 'isotope/js/layout-modes/vertical',[ 4849 '../layout-mode' 4850 ], 4851 factory ); 4852 } else if ( typeof module == 'object' && module.exports ) { 4853 // CommonJS 4854 module.exports = factory( 4855 require('../layout-mode') 4856 ); 4857 } else { 4858 // browser global 4859 factory( 4860 window.Isotope.LayoutMode 4861 ); 4862 } 4863 4864}( window, function factory( LayoutMode ) { 4865'use strict'; 4866 4867var Vertical = LayoutMode.create( 'vertical', { 4868 horizontalAlignment: 0 4869}); 4870 4871var proto = Vertical.prototype; 4872 4873proto._resetLayout = function() { 4874 this.y = 0; 4875}; 4876 4877proto._getItemLayoutPosition = function( item ) { 4878 item.getSize(); 4879 var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) * 4880 this.options.horizontalAlignment; 4881 var y = this.y; 4882 this.y += item.size.outerHeight; 4883 return { x: x, y: y }; 4884}; 4885 4886proto._getContainerSize = function() { 4887 return { height: this.y }; 4888}; 4889 4890return Vertical; 4891 4892})); 4893 4894/*! 4895 * Isotope v3.0.1 4896 * 4897 * Licensed GPLv3 for open source use 4898 * or Isotope Commercial License for commercial use 4899 * 4900 * http://isotope.metafizzy.co 4901 * Copyright 2016 Metafizzy 4902 */ 4903 4904( function( window, factory ) { 4905 // universal module definition 4906 /* jshint strict: false */ /*globals define, module, require */ 4907 if ( typeof define == 'function' && define.amd ) { 4908 // AMD 4909 define( [ 4910 'outlayer/outlayer', 4911 'get-size/get-size', 4912 'desandro-matches-selector/matches-selector', 4913 'fizzy-ui-utils/utils', 4914 'isotope/js/item', 4915 'isotope/js/layout-mode', 4916 // include default layout modes 4917 'isotope/js/layout-modes/masonry', 4918 'isotope/js/layout-modes/fit-rows', 4919 'isotope/js/layout-modes/vertical' 4920 ], 4921 function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) { 4922 return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ); 4923 }); 4924 } else if ( typeof module == 'object' && module.exports ) { 4925 // CommonJS 4926 module.exports = factory( 4927 window, 4928 require('outlayer'), 4929 require('get-size'), 4930 require('desandro-matches-selector'), 4931 require('fizzy-ui-utils'), 4932 require('isotope/js/item'), 4933 require('isotope/js/layout-mode'), 4934 // include default layout modes 4935 require('isotope/js/layout-modes/masonry'), 4936 require('isotope/js/layout-modes/fit-rows'), 4937 require('isotope/js/layout-modes/vertical') 4938 ); 4939 } else { 4940 // browser global 4941 window.Isotope = factory( 4942 window, 4943 window.Outlayer, 4944 window.getSize, 4945 window.matchesSelector, 4946 window.fizzyUIUtils, 4947 window.Isotope.Item, 4948 window.Isotope.LayoutMode 4949 ); 4950 } 4951 4952}( window, function factory( window, Outlayer, getSize, matchesSelector, utils, 4953 Item, LayoutMode ) { 4954 4955 4956 4957// -------------------------- vars -------------------------- // 4958 4959var jQuery = window.jQuery; 4960 4961// -------------------------- helpers -------------------------- // 4962 4963var trim = String.prototype.trim ? 4964 function( str ) { 4965 return str.trim(); 4966 } : 4967 function( str ) { 4968 return str.replace( /^\s+|\s+$/g, '' ); 4969 }; 4970 4971// -------------------------- isotopeDefinition -------------------------- // 4972 4973 // create an Outlayer layout class 4974 var Isotope = Outlayer.create( 'isotope', { 4975 layoutMode: 'masonry', 4976 isJQueryFiltering: true, 4977 sortAscending: true 4978 }); 4979 4980 Isotope.Item = Item; 4981 Isotope.LayoutMode = LayoutMode; 4982 4983 var proto = Isotope.prototype; 4984 4985 proto._create = function() { 4986 this.itemGUID = 0; 4987 // functions that sort items 4988 this._sorters = {}; 4989 this._getSorters(); 4990 // call super 4991 Outlayer.prototype._create.call( this ); 4992 4993 // create layout modes 4994 this.modes = {}; 4995 // start filteredItems with all items 4996 this.filteredItems = this.items; 4997 // keep of track of sortBys 4998 this.sortHistory = [ 'original-order' ]; 4999 // create from registered layout modes 5000 for ( var name in LayoutMode.modes ) { 5001 this._initLayoutMode( name ); 5002 } 5003 }; 5004 5005 proto.reloadItems = function() { 5006 // reset item ID counter 5007 this.itemGUID = 0; 5008 // call super 5009 Outlayer.prototype.reloadItems.call( this ); 5010 }; 5011 5012 proto._itemize = function() { 5013 var items = Outlayer.prototype._itemize.apply( this, arguments ); 5014 // assign ID for original-order 5015 for ( var i=0; i < items.length; i++ ) { 5016 var item = items[i]; 5017 item.id = this.itemGUID++; 5018 } 5019 this._updateItemsSortData( items ); 5020 return items; 5021 }; 5022 5023 5024 // -------------------------- layout -------------------------- // 5025 5026 proto._initLayoutMode = function( name ) { 5027 var Mode = LayoutMode.modes[ name ]; 5028 // set mode options 5029 // HACK extend initial options, back-fill in default options 5030 var initialOpts = this.options[ name ] || {}; 5031 this.options[ name ] = Mode.options ? 5032 utils.extend( Mode.options, initialOpts ) : initialOpts; 5033 // init layout mode instance 5034 this.modes[ name ] = new Mode( this ); 5035 }; 5036 5037 5038 proto.layout = function() { 5039 // if first time doing layout, do all magic 5040 if ( !this._isLayoutInited && this._getOption('initLayout') ) { 5041 this.arrange(); 5042 return; 5043 } 5044 this._layout(); 5045 }; 5046 5047 // private method to be used in layout() & magic() 5048 proto._layout = function() { 5049 // don't animate first layout 5050 var isInstant = this._getIsInstant(); 5051 // layout flow 5052 this._resetLayout(); 5053 this._manageStamps(); 5054 this.layoutItems( this.filteredItems, isInstant ); 5055 5056 // flag for initalized 5057 this._isLayoutInited = true; 5058 }; 5059 5060 // filter + sort + layout 5061 proto.arrange = function( opts ) { 5062 // set any options pass 5063 this.option( opts ); 5064 this._getIsInstant(); 5065 // filter, sort, and layout 5066 5067 // filter 5068 var filtered = this._filter( this.items ); 5069 this.filteredItems = filtered.matches; 5070 5071 this._bindArrangeComplete(); 5072 5073 if ( this._isInstant ) { 5074 this._noTransition( this._hideReveal, [ filtered ] ); 5075 } else { 5076 this._hideReveal( filtered ); 5077 } 5078 5079 this._sort(); 5080 this._layout(); 5081 }; 5082 // alias to _init for main plugin method 5083 proto._init = proto.arrange; 5084 5085 proto._hideReveal = function( filtered ) { 5086 this.reveal( filtered.needReveal ); 5087 this.hide( filtered.needHide ); 5088 }; 5089 5090 // HACK 5091 // Don't animate/transition first layout 5092 // Or don't animate/transition other layouts 5093 proto._getIsInstant = function() { 5094 var isLayoutInstant = this._getOption('layoutInstant'); 5095 var isInstant = isLayoutInstant !== undefined ? isLayoutInstant : 5096 !this._isLayoutInited; 5097 this._isInstant = isInstant; 5098 return isInstant; 5099 }; 5100 5101 // listen for layoutComplete, hideComplete and revealComplete 5102 // to trigger arrangeComplete 5103 proto._bindArrangeComplete = function() { 5104 // listen for 3 events to trigger arrangeComplete 5105 var isLayoutComplete, isHideComplete, isRevealComplete; 5106 var _this = this; 5107 function arrangeParallelCallback() { 5108 if ( isLayoutComplete && isHideComplete && isRevealComplete ) { 5109 _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] ); 5110 } 5111 } 5112 this.once( 'layoutComplete', function() { 5113 isLayoutComplete = true; 5114 arrangeParallelCallback(); 5115 }); 5116 this.once( 'hideComplete', function() { 5117 isHideComplete = true; 5118 arrangeParallelCallback(); 5119 }); 5120 this.once( 'revealComplete', function() { 5121 isRevealComplete = true; 5122 arrangeParallelCallback(); 5123 }); 5124 }; 5125 5126 // -------------------------- filter -------------------------- // 5127 5128 proto._filter = function( items ) { 5129 var filter = this.options.filter;
vendor: 10,963 bytes, lines 5130-5517
5130 filter = filter || '*'; 5131 var matches = []; 5132 var hiddenMatched = []; 5133 var visibleUnmatched = []; 5134 5135 var test = this._getFilterTest( filter ); 5136 5137 // test each item 5138 for ( var i=0; i < items.length; i++ ) { 5139 var item = items[i]; 5140 if ( item.isIgnored ) { 5141 continue; 5142 } 5143 // add item to either matched or unmatched group 5144 var isMatched = test( item ); 5145 // item.isFilterMatched = isMatched; 5146 // add to matches if its a match 5147 if ( isMatched ) { 5148 matches.push( item ); 5149 } 5150 // add to additional group if item needs to be hidden or revealed 5151 if ( isMatched && item.isHidden ) { 5152 hiddenMatched.push( item ); 5153 } else if ( !isMatched && !item.isHidden ) { 5154 visibleUnmatched.push( item ); 5155 } 5156 } 5157 5158 // return collections of items to be manipulated 5159 return { 5160 matches: matches, 5161 needReveal: hiddenMatched, 5162 needHide: visibleUnmatched 5163 }; 5164 }; 5165 5166 // get a jQuery, function, or a matchesSelector test given the filter 5167 proto._getFilterTest = function( filter ) { 5168 if ( jQuery && this.options.isJQueryFiltering ) { 5169 // use jQuery 5170 return function( item ) { 5171 return jQuery( item.element ).is( filter ); 5172 }; 5173 } 5174 if ( typeof filter == 'function' ) { 5175 // use filter as function 5176 return function( item ) { 5177 return filter( item.element ); 5178 }; 5179 } 5180 // default, use filter as selector string 5181 return function( item ) { 5182 return matchesSelector( item.element, filter ); 5183 }; 5184 }; 5185 5186 // -------------------------- sorting -------------------------- // 5187 5188 /** 5189 * @params {Array} elems 5190 * @public 5191 */ 5192 proto.updateSortData = function( elems ) { 5193 // get items 5194 var items; 5195 if ( elems ) { 5196 elems = utils.makeArray( elems ); 5197 items = this.getItems( elems ); 5198 } else { 5199 // update all items if no elems provided 5200 items = this.items; 5201 } 5202 5203 this._getSorters(); 5204 this._updateItemsSortData( items ); 5205 }; 5206 5207 proto._getSorters = function() { 5208 var getSortData = this.options.getSortData; 5209 for ( var key in getSortData ) { 5210 var sorter = getSortData[ key ]; 5211 this._sorters[ key ] = mungeSorter( sorter ); 5212 } 5213 }; 5214 5215 /** 5216 * @params {Array} items - of Isotope.Items 5217 * @private 5218 */ 5219 proto._updateItemsSortData = function( items ) { 5220 // do not update if no items 5221 var len = items && items.length; 5222 5223 for ( var i=0; len && i < len; i++ ) { 5224 var item = items[i]; 5225 item.updateSortData(); 5226 } 5227 }; 5228 5229 // ----- munge sorter ----- // 5230 5231 // encapsulate this, as we just need mungeSorter 5232 // other functions in here are just for munging 5233 var mungeSorter = ( function() { 5234 // add a magic layer to sorters for convienent shorthands 5235 // `.foo-bar` will use the text of .foo-bar querySelector 5236 // `[foo-bar]` will use attribute 5237 // you can also add parser 5238 // `.foo-bar parseInt` will parse that as a number 5239 function mungeSorter( sorter ) { 5240 // if not a string, return function or whatever it is 5241 if ( typeof sorter != 'string' ) { 5242 return sorter; 5243 } 5244 // parse the sorter string 5245 var args = trim( sorter ).split(' '); 5246 var query = args[0]; 5247 // check if query looks like [an-attribute] 5248 var attrMatch = query.match( /^\[(.+)\]$/ ); 5249 var attr = attrMatch && attrMatch[1]; 5250 var getValue = getValueGetter( attr, query ); 5251 // use second argument as a parser 5252 var parser = Isotope.sortDataParsers[ args[1] ]; 5253 // parse the value, if there was a parser 5254 sorter = parser ? function( elem ) { 5255 return elem && parser( getValue( elem ) ); 5256 } : 5257 // otherwise just return value 5258 function( elem ) { 5259 return elem && getValue( elem ); 5260 }; 5261 5262 return sorter; 5263 } 5264 5265 // get an attribute getter, or get text of the querySelector 5266 function getValueGetter( attr, query ) { 5267 // if query looks like [foo-bar], get attribute 5268 if ( attr ) { 5269 return function getAttribute( elem ) { 5270 return elem.getAttribute( attr ); 5271 }; 5272 } 5273 5274 // otherwise, assume its a querySelector, and get its text 5275 return function getChildText( elem ) { 5276 var child = elem.querySelector( query ); 5277 return child && child.textContent; 5278 }; 5279 } 5280 5281 return mungeSorter; 5282 })(); 5283 5284 // parsers used in getSortData shortcut strings 5285 Isotope.sortDataParsers = { 5286 'parseInt': function( val ) { 5287 return parseInt( val, 10 ); 5288 }, 5289 'parseFloat': function( val ) { 5290 return parseFloat( val ); 5291 } 5292 }; 5293 5294 // ----- sort method ----- // 5295 5296 // sort filteredItem order 5297 proto._sort = function() { 5298 var sortByOpt = this.options.sortBy; 5299 if ( !sortByOpt ) { 5300 return; 5301 } 5302 // concat all sortBy and sortHistory 5303 var sortBys = [].concat.apply( sortByOpt, this.sortHistory ); 5304 // sort magic 5305 var itemSorter = getItemSorter( sortBys, this.options.sortAscending ); 5306 this.filteredItems.sort( itemSorter ); 5307 // keep track of sortBy History 5308 if ( sortByOpt != this.sortHistory[0] ) { 5309 // add to front, oldest goes in last 5310 this.sortHistory.unshift( sortByOpt ); 5311 } 5312 }; 5313 5314 // returns a function used for sorting 5315 function getItemSorter( sortBys, sortAsc ) { 5316 return function sorter( itemA, itemB ) { 5317 // cycle through all sortKeys 5318 for ( var i = 0; i < sortBys.length; i++ ) { 5319 var sortBy = sortBys[i]; 5320 var a = itemA.sortData[ sortBy ]; 5321 var b = itemB.sortData[ sortBy ]; 5322 if ( a > b || a < b ) { 5323 // if sortAsc is an object, use the value given the sortBy key 5324 var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc; 5325 var direction = isAscending ? 1 : -1; 5326 return ( a > b ? 1 : -1 ) * direction; 5327 } 5328 } 5329 return 0; 5330 }; 5331 } 5332 5333 // -------------------------- methods -------------------------- // 5334 5335 // get layout mode 5336 proto._mode = function() { 5337 var layoutMode = this.options.layoutMode; 5338 var mode = this.modes[ layoutMode ]; 5339 if ( !mode ) { 5340 // TODO console.error 5341 throw new Error( 'No layout mode: ' + layoutMode ); 5342 } 5343 // HACK sync mode's options 5344 // any options set after init for layout mode need to be synced 5345 mode.options = this.options[ layoutMode ]; 5346 return mode; 5347 }; 5348 5349 proto._resetLayout = function() { 5350 // trigger original reset layout 5351 Outlayer.prototype._resetLayout.call( this ); 5352 this._mode()._resetLayout(); 5353 }; 5354 5355 proto._getItemLayoutPosition = function( item ) { 5356 return this._mode()._getItemLayoutPosition( item ); 5357 }; 5358 5359 proto._manageStamp = function( stamp ) { 5360 this._mode()._manageStamp( stamp ); 5361 }; 5362 5363 proto._getContainerSize = function() { 5364 return this._mode()._getContainerSize(); 5365 }; 5366 5367 proto.needsResizeLayout = function() { 5368 return this._mode().needsResizeLayout(); 5369 }; 5370 5371 // -------------------------- adding & removing -------------------------- // 5372 5373 // HEADS UP overwrites default Outlayer appended 5374 proto.appended = function( elems ) { 5375 var items = this.addItems( elems ); 5376 if ( !items.length ) { 5377 return; 5378 } 5379 // filter, layout, reveal new items 5380 var filteredItems = this._filterRevealAdded( items ); 5381 // add to filteredItems 5382 this.filteredItems = this.filteredItems.concat( filteredItems ); 5383 }; 5384 5385 // HEADS UP overwrites default Outlayer prepended 5386 proto.prepended = function( elems ) { 5387 var items = this._itemize( elems ); 5388 if ( !items.length ) { 5389 return; 5390 } 5391 // start new layout 5392 this._resetLayout(); 5393 this._manageStamps(); 5394 // filter, layout, reveal new items 5395 var filteredItems = this._filterRevealAdded( items ); 5396 // layout previous items 5397 this.layoutItems( this.filteredItems ); 5398 // add to items and filteredItems 5399 this.filteredItems = filteredItems.concat( this.filteredItems ); 5400 this.items = items.concat( this.items ); 5401 }; 5402 5403 proto._filterRevealAdded = function( items ) { 5404 var filtered = this._filter( items ); 5405 this.hide( filtered.needHide ); 5406 // reveal all new items 5407 this.reveal( filtered.matches ); 5408 // layout new items, no transition 5409 this.layoutItems( filtered.matches, true ); 5410 return filtered.matches; 5411 }; 5412 5413 /** 5414 * Filter, sort, and layout newly-appended item elements 5415 * @param {Array or NodeList or Element} elems 5416 */ 5417 proto.insert = function( elems ) { 5418 var items = this.addItems( elems ); 5419 if ( !items.length ) { 5420 return; 5421 } 5422 // append item elements 5423 var i, item; 5424 var len = items.length; 5425 for ( i=0; i < len; i++ ) { 5426 item = items[i]; 5427 this.element.appendChild( item.element ); 5428 } 5429 // filter new stuff 5430 var filteredInsertItems = this._filter( items ).matches; 5431 // set flag 5432 for ( i=0; i < len; i++ ) { 5433 items[i].isLayoutInstant = true; 5434 } 5435 this.arrange(); 5436 // reset flag 5437 for ( i=0; i < len; i++ ) { 5438 delete items[i].isLayoutInstant; 5439 } 5440 this.reveal( filteredInsertItems ); 5441 }; 5442 5443 var _remove = proto.remove; 5444 proto.remove = function( elems ) { 5445 elems = utils.makeArray( elems ); 5446 var removeItems = this.getItems( elems ); 5447 // do regular thing 5448 _remove.call( this, elems ); 5449 // bail if no items to remove 5450 var len = removeItems && removeItems.length; 5451 // remove elems from filteredItems 5452 for ( var i=0; len && i < len; i++ ) { 5453 var item = removeItems[i]; 5454 // remove item from collection 5455 utils.removeFrom( this.filteredItems, item ); 5456 } 5457 }; 5458 5459 proto.shuffle = function() { 5460 // update random sortData 5461 for ( var i=0; i < this.items.length; i++ ) { 5462 var item = this.items[i]; 5463 item.sortData.random = Math.random(); 5464 } 5465 this.options.sortBy = 'random'; 5466 this._sort(); 5467 this._layout(); 5468 }; 5469 5470 /** 5471 * trigger fn without transition 5472 * kind of hacky to have this in the first place 5473 * @param {Function} fn 5474 * @param {Array} args 5475 * @returns ret 5476 * @private 5477 */ 5478 proto._noTransition = function( fn, args ) { 5479 // save transitionDuration before disabling 5480 var transitionDuration = this.options.transitionDuration; 5481 // disable transition 5482 this.options.transitionDuration = 0; 5483 // do it 5484 var returnValue = fn.apply( this, args ); 5485 // re-enable transition for reveal 5486 this.options.transitionDuration = transitionDuration; 5487 return returnValue; 5488 }; 5489 5490 // ----- helper methods ----- // 5491 5492 /** 5493 * getter method for getting filtered item elements 5494 * @returns {Array} elems - collection of item elements 5495 */ 5496 proto.getFilteredItemElements = function() { 5497 return this.filteredItems.map( function( item ) { 5498 return item.element; 5499 }); 5500 }; 5501 5502 // ----- ----- // 5503 5504 return Isotope; 5505 5506})); 5507; 5508/*! 5509 * Setup Isotope Grid 5510 * 5511 * JavaScript specific to posts displayed in a grid templates 5512 * 5513 * Initiates Isotope, handles sorting and triggers lazy-loading for images 5514 * 5515 * @package Altofocus 5516 */ 5517
5518/* global loadedPosts */ 5519( function( $ ) { 5520 5521 // Define initial variable for Isotope 5522 var $body = $( document.body ), 5523 $isotopeWrap = $( '.hfeed:not(.error404, .search-no-results) #main' ), 5524 isoOptions = { 5525 layoutMode: 'masonry', 5526 itemSelector: '.grid-item', 5527 masonry: { 5528 columnWidth: '.grid-sizer', 5529 gutter: '.gutter-sizer' 5530 }, 5531 percentPosition: true 5532 }; 5533 5534 /** 5535 * Debounce script 5536 */ 5537 function altofocus_debounce(func, wait, immediate) { 5538 var timeout; 5539 return function() { 5540 5541 var context = this, 5542 args = arguments; 5543 5544 var later = function() { 5545 timeout = null; 5546 if (!immediate) { 5547 func.apply(context, args); 5548 } 5549 }; 5550 5551 var callNow = immediate && !timeout; 5552 clearTimeout(timeout); 5553 timeout = setTimeout(later, wait); 5554 if (callNow) { 5555 func.apply(context, args); 5556 } 5557 }; 5558 } 5559 5560 /** 5561 * Init Isotope 5562 * 5563 * - Add Isotope class 5564 * - Add empty grid sizing elements for resposnive isotope sizing 5565 */ 5566 function initIsotope() { 5567 5568 // Init Isotope 5569 $isotopeWrap 5570 .append( "<div class=\'grid-sizer\'></div><div class=\'gutter-sizer\'></div>" ); 5571 } 5572 5573 /** 5574 * Run Isotope 5575 */ 5576 function runIsotope() { 5577 5578 $isotopeWrap.imagesLoaded().fail( function() { 5579 5580 // broken images 5581 // console.log('All images loaded but at least one is broken'); 5582 5583 // Initialize Isotope 5584 $isotopeWrap.isotope( isoOptions ); 5585 5586 } ).done( function() { 5587 5588 // Initialize Isotope 5589 $isotopeWrap.isotope( isoOptions ); 5590 5591 } ); 5592 5593 // jQuery 5594 $isotopeWrap.on( 'layoutComplete', function() { 5595 5596 $isotopeWrap.addClass( "has-isotope" ); 5597 } ); 5598 } 5599 5600 /** 5601 * Triggers re-layout on Isotope wrapper after infinite scroll has loaded new posts 5602 */ 5603 function reLayoutIsotope( loadedPosts ) { 5604 5605 // Set array for newly added post IDs 5606 var newPostIds = []; 5607 5608 // If new posts have been loaded from Infinite Scroll, attach them to the isotope wrapper and lay them out 5609 // note: loadedPosts variable is set globally in altofocus_infinite_scroll_render(). See jetpack.php 5610 if ( typeof loadedPosts !== 'undefined' ) { 5611 5612 // Create post IDs from IS results and push into post ID array 5613 $.each( JSON.parse(loadedPosts), function( index, value ) { 5614 5615 var $appendedPost = '#post-'+ value; 5616 5617 newPostIds.push( $appendedPost ); 5618 5619 }); 5620 5621 // Place infinite scroll results into a jQuery object 5622 var $newPostObj = $( newPostIds.join( ", " ) ), 5623 $appendedPosts = $( $newPostObj ); 5624 5625 // Get each new post, add it to Isotope, and relayout Isotope 5626 $appendedPosts 5627 5628 // Hide newly loaded posts to prevent animation jumping 5629 .hide() 5630 5631 // Get each post with an image and without 5632 .each( function() { 5633 5634 var $this = $( this ); 5635 5636 // Cue posts with images separately to account for varying image load times 5637 if ( $this.find( "img" ).length > 0 ) { 5638 5639 // Make sure images are loaded before laying them out 5640 $this.imagesLoaded() 5641 5642 // After image load completes, append newly loaded posts to Isotope wrapper and lay them out 5643 .done( altofocus_debounce( function() { 5644 5645 $isotopeWrap 5646 5647 // Append this post 5648 .append( $this ) 5649 5650 // Layout this post 5651 .isotope( 'appended', $this ); 5652 5653 }, 200, 1 ) ); 5654 5655 // Append and layout posts without images normally 5656 } else { 5657 5658 $isotopeWrap 5659 5660 // Append this post 5661 .append( $this ) 5662 5663 // Layout this post 5664 .isotope( 'appended', $this ); 5665 } 5666 5667 }); 5668 } 5669 } 5670 5671 /** 5672 * Document calls 5673 */ 5674 $( document ) 5675 .ready( initIsotope ) 5676 .ready( function() { 5677 5678 /** 5679 * Relayout Isotope on post-load (Infinite Scroll) 5680 */ 5681 $body.on( 'post-load', function() { 5682 var loadedPosts = $('#infinite-ids').attr('data'); 5683 reLayoutIsotope( loadedPosts ); 5684 $('#infinite-ids').remove(); 5685 }); 5686 5687 /** 5688 * Window calls 5689 */ 5690 $( window ) 5691 .load( runIsotope ); 5692 } ); 5693 5694} )( jQuery ); 5695; 5696/*! 5697 * Script for AltoFocus 5698 * 5699 * @package Altofocus 5700 */ 5701 5702/* global altoFocusFlexSliderText */ 5703( function( $ ) { 5704 5705 /** 5706 * Set variables 5707 */ 5708 var body, 5709 $wrapper = $( '.js body' ), 5710 $widgetlist = $( '.widget > ul' ).not( '.widget_wpcom_social_media_icons_widget > ul, .widget_author_grid > ul, .jetpack_widget_social_icons > ul' ), 5711 $gallery_slider = $( '.flexslider' ); 5712 5713 /** 5714 * Debounce script 5715 */ 5716 function altofocus_debounce(func, wait, immediate) { 5717 var timeout; 5718 return function() { 5719 5720 var context = this, 5721 args = arguments; 5722 5723 var later = function() { 5724 timeout = null; 5725 if (!immediate) {
5726 func.apply(context, args); 5727 } 5728 }; 5729 5730 var callNow = immediate && !timeout; 5731 clearTimeout(timeout); 5732 timeout = setTimeout(later, wait); 5733 if (callNow) { 5734 func.apply(context, args); 5735 } 5736 }; 5737 } 5738 5739 /** 5740 * Stick header to window when scrolling passes the masthead height threshold 5741 */ 5742 function stickyPageHeader() { 5743 5744 // get the amount the window has scrolled 5745 var scroll = $( this ).scrollTop(), 5746 header_height = $( '#masthead' ).outerHeight(), 5747 $page_header = $( '.hfeed .page-header' ); 5748 5749 // add the 'fixed' class to the header menu based on the window position 5750 if ( scroll >= header_height ) { 5751 5752 $page_header.addClass( 'sticky' ); 5753 5754 } else { 5755 5756 $page_header.removeClass( 'sticky' ); 5757 } 5758 } 5759 5760 /** 5761 * Split widget lists 5762 */ 5763 function initColumnLists() { 5764 5765 $widgetlist.columnlist({ 5766 size : 2, 5767 'class' : 'widget-list', 5768 incrementClass : 'widget-list-' 5769 }); 5770 } 5771 5772 /** 5773 * Init Gallery Slider 5774 */ 5775 function initGallerySlider() { 5776 5777 // Determine text direction 5778 var $text_direction = true; 5779 if ( $( 'html' ).attr( 'dir' ) === 'rtl' ) { 5780 5781 $text_direction = false; 5782 } 5783 5784 $gallery_slider.flexslider({ 5785 // options 5786 animation: "slide", 5787 selector: ".slides > .slide", 5788 smoothHeight: true, 5789 slideshow: false, 5790 rtl: $text_direction, 5791 prevText: '<span class="screen-reader-text">'+ altoFocusFlexSliderText.previous +'</span> <span class="meta-nav" aria-hidden="true"><svg class="arrow-icon left-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect class="rectangle" x="0" y="0" width="40" height="40" /><polyline class="arrow" points="27,6 13,20 27,34" /></svg></span>', 5792 nextText: '<span class="screen-reader-text">'+ altoFocusFlexSliderText.next +'</span> <span class="meta-nav" aria-hidden="true"><svg class="arrow-icon right-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect class="rectangle" x="0" y="0" width="40" height="40" /><polyline class="arrow" points="13 34 27 20 13 6" /></svg></span>', 5793 }); 5794 } 5795 5796 /* 5797 * Fade in page 5798 * - only if js is enabled 5799 */ 5800 function fadeInPage() { 5801 5802 $wrapper.animate({ 5803 opacity: 1, 5804 }, 100); 5805 } 5806 5807 /** 5808 * Execute functions 5809 */ 5810 $( document ) 5811 .ready( initColumnLists ) 5812 .ready( initGallerySlider ) 5813 .ready( fadeInPage ) 5814 .ready( function() { 5815 5816 body = $( document.body ); 5817 5818 window.addEventListener( 'scroll', altofocus_debounce( stickyPageHeader, 20, 1 ) ); 5819 5820 } ); 5821 5822})(jQuery); 5823; 5824/** 5825 * File skip-link-focus-fix.js. 5826 * 5827 * Helps with accessibility for keyboard only users. 5828 * 5829 * Learn more: https://git.io/vWdr2 5830 */ 5831( function() { 5832 5833 var isWebkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1, 5834 isOpera = navigator.userAgent.toLowerCase().indexOf( 'opera' ) > -1, 5835 isIe = navigator.userAgent.toLowerCase().indexOf( 'msie' ) > -1; 5836 5837 if ( ( isWebkit || isOpera || isIe ) && document.getElementById && window.addEventListener ) { 5838 5839 window.addEventListener( 'hashchange', function() { 5840 5841 var id = location.hash.substring( 1 ), 5842 element; 5843 5844 if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { 5845 5846 return; 5847 } 5848 5849 element = document.getElementById( id ); 5850 5851 if ( element ) { 5852 5853 if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { 5854 5855 element.tabIndex = -1; 5856 } 5857 5858 element.focus(); 5859 } 5860 }, false ); 5861 } 5862})(); 5863; 5864!function(){"use strict";var e,t={noop:function(){},texturize:function(e){return(e=(e=(e=(e+="").replace(/'/g,"’").replace(/'/g,"’")).replace(/"/g,"”").replace(/"/g,"”").replace(/"/g,"”").replace(/[\u201D]/g,"”")).replace(/([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g,'$1="$2"')).trim()},applyReplacements:function(e,t){if(e)return t?e.replace(/{(\d+)}/g,function(e,r){return void 0!==t[r]?t[r]:e}):e},getBackgroundImage:function(e){var t=document.createElement("canvas"),r=t.getContext&&t.getContext("2d");if(e){r.filter="blur(20px) ",r.drawImage(e,0,0);var o=t.toDataURL("image/png");return t=null,o}}},r=function(){function e(e,t){return Element.prototype.matches?e.matches(t):Element.prototype.msMatchesSelector?e.msMatchesSelector(t):void 0}function r(e,t,r,o){if(!e)return o();e.jpCarouselCancelFade&&e.jpCarouselCancelFade(),e.classList.remove("jp-carousel-fade"),e.style.removeProperty("display"),e.style.opacity=t,e.style.pointerEvents="none",e.offsetWidth,e.classList.add("jp-carousel-fade"),e.style.opacity=r;var a=1e3*parseFloat(getComputedStyle(e).transitionDuration)||0,n=setTimeout(function(){e.jpCarouselCancelFade=null,e.style.removeProperty("pointer-events"),o()},a+50);e.jpCarouselCancelFade=function(){clearTimeout(n),e.jpCarouselCancelFade=null}}return{closest:function(t,r){if(t.closest)return t.closest(r);var o=t;do{if(e(o,r))return o;o=o.parentElement||o.parentNode}while(null!==o&&1===o.nodeType);return null},matches:e,hide:function(e){e&&(e.style.display="none")},show:function(e){e&&(e.style.display="block")},fadeIn:function(e,o){r(e,0,1,o=o||t.noop)},fadeOut:function(e,o){o=o||t.noop,r(e,1,0,function(){e&&(e.style.display="none"),o()})},scrollToElement:function(e,t,r){if(!e||!t)return r?r():void 0;var o=t.querySelector(".jp-carousel-info-extra");o&&(o.style.minHeight=window.innerHeight-64+"px");var a=!0,n=Date.now(),i=t.scrollTop,l=Math.max(0,e.offsetTop-Math.max(0,window.innerHeight-function(e){var t=e.querySelector(".jp-carousel-info-footer"),r=e.querySelector(".jp-carousel-info-extra"),o=e.querySelector(".jp-carousel-info-content-wrapper");if(t&&r&&o){var a=window.getComputedStyle(r),n=parseInt(a.paddingTop,10)+parseInt(a.paddingBottom,10);return n=isNaN(n)?0:n,o.offsetHeight+t.offsetHeight+n}return 0}(t)))-t.scrollTop;function s(){a=!1}
5864l=Math.min(l,t.scrollHeight-window.innerHeight),t.addEventListener("wheel",s),function e(){var c,u=Date.now(),d=(c=(u-n)/300)<.5?2*c*c:1-Math.pow(-2*c+2,2)/2,m=(d=d>1?1:d)*l;if(t.scrollTop=i+m,u<=n+300&&a)return requestAnimationFrame(e);r&&r(),o&&(o.style.minHeight=""),a=!1,t.removeEventListener("wheel",s)}()},getJSONAttribute:function(e,t){if(e&&e.hasAttribute(t))try{return JSON.parse(e.getAttribute(t))}catch{return}},convertToPlainText:function(e){var t=document.createElement("div");return t.textContent=e,t.innerHTML},stripHTML:function(e){var t=document.createElement("div");return t.innerHTML=e.replace(/<[^>]*>?/gm,""),t.textContent},emitEvent:function(e,t,r){var o;try{o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:r||null})}catch{(o=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,r||null)}e.dispatchEvent(o)},isTouch:function(){return"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch},prefersReducedMotion:function(){return!!window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}}}();function o(){var o,a,n,i,l={},s={},c="",u=!1,d="div.gallery, div.tiled-gallery, ul.wp-block-gallery, ul.blocks-gallery-grid, figure.wp-block-gallery.has-nested-images, div.wp-block-jetpack-tiled-gallery, a.single-image-gallery",m=".gallery-item, .tiled-gallery-item, .blocks-gallery-item, .tiled-gallery__item",p=m+", .wp-block-image",g={},h="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.stat?wpcom.carousel.stat:t.noop,f="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.pageview?wpcom.carousel.pageview:t.noop;function v(t){if(!u)switch(t.which){case 38:t.preventDefault(),g.overlay.scrollTop-=100;break;case 40:t.preventDefault(),g.overlay.scrollTop+=100;break;case 39:t.preventDefault(),e.slideNext();break;case 37:case 8:t.preventDefault(),e.slidePrev();break;case 27:t.preventDefault(),k()}}function y(){u=!0}function w(){u=!1}function S(e){e.role="button",e.tabIndex=0,e.ariaLabel=jetpackCarouselStrings.image_label}function j(){g.overlay||(g.overlay=document.querySelector(".jp-carousel-overlay"),g.container=g.overlay.querySelector(".jp-carousel-wrap"),g.gallery=g.container.querySelector(".jp-carousel"),g.info=g.overlay.querySelector(".jp-carousel-info"),g.caption=g.info.querySelector(".jp-carousel-caption"),g.commentField=g.overlay.querySelector("#jp-carousel-comment-form-comment-field"),g.emailField=g.overlay.querySelector("#jp-carousel-comment-form-email-field"),g.authorField=g.overlay.querySelector("#jp-carousel-comment-form-author-field"),g.urlField=g.overlay.querySelector("#jp-carousel-comment-form-url-field"),window.innerWidth<=760&&Math.round(window.innerWidth/760*110)<40&&r.isTouch(),[g.commentField,g.emailField,g.authorField,g.urlField].forEach(function(e){e&&(e.addEventListener("focus",y),e.addEventListener("blur",w))}),g.overlay.addEventListener("click",function(e){var t,o,a=e.target,n=!!r.closest(a,".jp-carousel-close-hint"),i=!!window.matchMedia("(max-device-width: 760px)").matches;a===g.overlay?i||k():n?k():a.classList.contains("jp-carousel-image-download")?h("download_original_click"):a.classList.contains("jp-carousel-comment-login")?(t=g.currentSlide,o=t?t.attrs.attachmentId:"0",window.location.href=jetpackCarouselStrings.login_url+"%23jp-carousel-"+o):r.closest(a,"#jp-carousel-comment-form-container")?function(e){var t=e.target,o=r.getJSONAttribute(g.container,"data-carousel-extra")||{},a=g.currentSlide.attrs.attachmentId,n=document.querySelector("#jp-carousel-comment-form-submit-and-info-wrapper"),i=document.querySelector("#jp-carousel-comment-form-spinner"),s=document.querySelector("#jp-carousel-comment-form-button-submit"),c=document.querySelector("#jp-carousel-comment-form");if(g.commentField&&g.commentField.getAttribute("id")===t.getAttribute("id"))y(),r.show(n);else if(r.matches(t,'input[type="submit"]')){e.preventDefault(),e.stopPropagation(),r.show(i),c.classList.add("jp-carousel-is-disabled");var u={action:"post_attachment_comment",nonce:jetpackCarouselStrings.nonce,blog_id:o.blog_id,id:a,comment:g.commentField.value};if(!u.comment.length)return void b(jetpackCarouselStrings.no_comment_text,!1);if(1!==Number(jetpackCarouselStrings.is_logged_in)&&(u.email=g.emailField.value,u.author=g.authorField.value,u.url=g.urlField.value,1===Number(jetpackCarouselStrings.require_name_email))){if(!u.email.length||!u.email.match("@"))return void b(jetpackCarouselStrings.no_comment_email,!1);if(!u.author.length)return void b(jetpackCarouselStrings.no_comment_author,!1)}var d=new XMLHttpRequest;d.open("POST",jetpackCarouselStrings.ajaxurl,!0),d.setRequestHeader("X-Requested-With","XMLHttpRequest"),d.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),d.onreadystatechange=function(){if(this.readyState===XMLHttpRequest.DONE&&this.status>=200&&this.status<300){var e;try{e=JSON.parse(this.response)}catch{return void b(jetpackCarouselStrings.comment_post_error,!1)}if("approved"===e.comment_status){b(jetpackCarouselStrings.comment_approved,!0);var t=function(e){for(var t=0;t<g.slides.length;t++)if(g.slides[t].attrs.attachmentId===e)return g.slides[t];return null}(a);t&&(t.attrs.commentsCount=(parseInt(t.attrs.commentsCount,10)||0)+1)}else"unapproved"===e.comment_status?b(jetpackCarouselStrings.comment_unapproved,!0):b(jetpackCarouselStrings.comment_post_error,!1);W(),delete l[a],_(a,void 0,!0),s.value=jetpackCarouselStrings.post_comment,r.hide(i),c.classList.remove("jp-carousel-is-disabled")}else b(jetpackCarouselStrings.comment_post_error,!1)};var m=[];for(var p in u)if(p){var h=encodeURIComponent(p)+"="+encodeURIComponent(u[p]);m.push(h.replace(/%20/g,"+"))}var f=m.join("&");d.send(f)}}(e):(r.closest(a,".jp-carousel-photo-icons-container")||a.classList.contains("jp-carousel-photo-title"))&&function(e){e.preventDefault();var t=e.target,o=g.info.querySelector(".jp-carousel-info-extra"),a=g.info.querySelector(".jp-carousel-image-meta"),n=g.info.querySelector(".jp-carousel-comments-wrapper"),i=g.info.querySelector(".jp-carousel-icon-info"),s=g.info.querySelector(".jp-carousel-icon-comments");function c(){s&&s.classList.remove("jp-carousel-selected"),i.classList.toggle("jp-carousel-selected"),n&&n.classList.remove("jp-carousel-show"),a&&(a.classList.toggle("jp-carousel-show"),a.classList.contains("jp-carousel-show")?o.classList.add("jp-carousel-show"):o.classList.remove("jp-carousel-show"))}function u(){if(i&&i.classList.remove("jp-carousel-selected"),s.classList.toggle("jp-carousel-selected"),a&&a.classList.remove("jp-carousel-show"),n)if(n.classList.toggle("jp-carousel-show"),n.classList.contains("jp-carousel-show")){o.classList.add("jp-carousel-show");var e=g.currentSlide;if(e){var t=l[e.attrs.attachmentId];t?t.hasMore&&T(e.attrs.attachmentId,t.nextOffset):_(e.attrs.attachmentId)}}else o.classList.remove("jp-carousel-show")}(r.closest(t,".jp-carousel-icon-info")||t.classList.contains("jp-carousel-photo-title"))&&(a&&a.classList.contains("jp-carousel-show")?r.scrollToElement(g.overlay,g.overlay,c):(c(),r.scrollToElement(g.info,g.overlay))),r.closest(t,".jp-carousel-icon-comments")&&(n&&n.classList.contains("jp-carousel-show")?r.scrollToElement(g.overlay,g.overlay,u):(u(),r.scrollToElement(g.info,g.overlay)))}(e)}),window.addEventListener("keydown",v),g.overlay.addEventListener("jp_carousel.afterOpen",function(){w(),g.slides.length<=1||(g.slides.length<=5?r.show(g.info.querySelector(".jp-swiper-pagination")):r.show(g.info.querySelector(".jp-carousel-pagination")))}),g.overlay.addEventListener("jp_carousel.beforeClose",function(){y(),document.documentElement.style.removeProperty("height"),e&&e.enable(),r.hide(g.info.querySelector(".jp-swiper-pagination")),r.hide(g.info.querySelector(".jp-carousel-pagination"))}),g.overlay.addEventListener("jp_carousel.afterClose",function(){window.history.pushState?history.pushState("",document.title,window.location.pathname+window.location.search):window.location.href="",c="",g.isOpen=!1}),g.overlay.addEventListener("touchstart",function(e){e.touches.length>1&&e.preventDefault()}))}function b(e,t){var o=g.overlay.querySelector("#jp-carousel-comment-post-results"),a="jp-carousel-comment-post-"+(t?"success":"error");o.innerHTML='<span class="'+a+'">'+e+"</span>",r.hide(g.overlay.querySelector("#jp-carousel-comment-form-spinner")),g.overlay.querySelector("#jp-carousel-comment-form").classList.remove("jp-carousel-is-disabled"),r.show(o)}function L(){var e=document.querySelectorAll("a img[data-attachment-id]");Array.prototype.forEach.call(e,function(e){var t=e.parentElement,o=t.parentElement;if(!o.classList.contains("gallery-icon")&&!r.closest(o,m)&&t.hasAttribute("href")){var a=!1;t.getAttribute("href").split("?")[0]===e.getAttribute("data-orig-file").split("?")[0]&&1===Number(jetpackCarouselStrings.single_image_gallery_media_file)&&(a=!0),t.getAttribute("href")===e.getAttribute("data-permalink")&&(a=!0),a&&(S(e),t.classList.add("single-image-gallery"),t.setAttribute("data-carousel-extra",JSON.stringify({blog_id:Number(jetpackCarouselStrings.blog_id)})))}})}function x(t,r){g.isOpen?(C(r),e.slideTo(r+1)):z(t,{startIndex:r})}function C(e){(!e||e<0||e>g.slides.length)&&(e=0),g.currentSlide=g.slides[e];var a,n,i=g.currentSlide,s=i.attrs.attachmentId;M(g.slides[e]),function(e){var t=[],r=g.slides.length;if(r>1){var o=e>0?e-1:r-1;t.push(o);var a=e<r-1?e+1:0;t.push(a)}t.forEach(function(e){var t=g.slides[e];t&&(M(t),1!==Number(jetpackCarouselStrings.display_background_image)||t.backgroundImage||F(t))})}(e),1!==Number(jetpackCarouselStrings.display_background_image)||g.slides[e].backgroundImage||F(g.slides[e]),r.hide(g.caption),function(e){var t,o,a,n,i,l,s;if(n=g.overlay.querySelector(".jp-carousel-photo-caption"),i=g.overlay.querySelector(".jp-carousel-caption"),l=g.overlay.querySelector(".jp-carousel-photo-title"),s=g.overlay.querySelector(".jp-carousel-photo-description"),r.hide(n),r.hide(i),r.hide(l),r.hide(s),t=A(e.caption)||"",o=A(e.title)||"",a=A(e.desc)||"",(t||o||a)&&(t&&(n.innerHTML=t,i.innerHTML=t,r.show(n),r.show(i)),r.stripHTML(t)===r.stripHTML(o)&&(o=""),r.stripHTML(t)===r.stripHTML(a)&&(a=""),r.stripHTML(o)===r.stripHTML(a)&&(a=""),a&&(s.innerHTML=a,r.show(s),o||t||(n.textContent=r.stripHTML(a),r.show(n))),o)){var c=r.stripHTML(o);l.textContent=c,t||(n.textContent=c,i.textContent=c,r.show(n)),r.show(l)}}
5864({caption:i.attrs.caption,title:i.attrs.title,desc:i.attrs.desc}),function(e){if(!e||1!==Number(jetpackCarouselStrings.display_exif))return!1;var t=g.info.querySelector(".jp-carousel-image-meta");if(!t)return!1;var r="";for(var o in e){var a=e[o],n=jetpackCarouselStrings.meta_data||[];if(0!==parseFloat(a)&&a.length&&-1!==n.indexOf(o)){switch(o){case"focal_length":a+="mm";break;case"shutter_speed":a=E(a);break;case"aperture":a="f/"+a}r+="<li><h5>"+jetpackCarouselStrings[o]+"</h5>"+a+"</li>"}}var i=t.querySelector("ul.jp-carousel-image-exif");if(""!==r){if(!i){(i=document.createElement("ul")).className="jp-carousel-image-exif";var l=t.querySelector(".jp-carousel-title-and-caption");l&&l.nextSibling?t.insertBefore(i,l.nextSibling):t.insertBefore(i,t.firstChild)}i.innerHTML=r,i.style.removeProperty("display")}else i&&i.parentNode.removeChild(i)}(g.slides[e].attrs.imageMeta),function(e){if(!e)return!1;var r,o=[e.attrs.origWidth,e.attrs.origHeight],a=document.createElement("a");a.href=e.attrs.src.replace(/\?.+$/,""),r=null!==a.hostname.match(/^i[\d]{1}\.wp\.com$/i)?a.href:e.attrs.origFile.replace(/\?.+$/,"");var n=g.info.querySelector(".jp-carousel-download-text"),i=g.info.querySelector(".jp-carousel-image-download");n.innerHTML=t.applyReplacements(jetpackCarouselStrings.download_original,o),i.setAttribute("href",r),i.style.removeProperty("display")}(i),1===Number(jetpackCarouselStrings.display_comments)&&(a=g.slides[e].attrs.commentsOpened,n=g.info.querySelector("#jp-carousel-comment-form-container"),1===parseInt(a,10)?r.fadeIn(n):r.fadeOut(n),function(e){var t=e.attrs.attachmentId,a=g.info.querySelector(".jp-carousel-comments"),n=l[t];if(clearInterval(o),r.hide(g.info.querySelector("#jp-carousel-comments-loading")),n)return a.innerHTML=n.html,H(n.count),r.show(a),void(n.hasMore&&I()&&T(t,n.nextOffset));a.innerHTML="",r.hide(a),H(parseInt(e.attrs.commentsCount,10)||0),I()&&_(t)}(i),r.hide(g.info.querySelector("#jp-carousel-comment-post-results")));var u=g.info.querySelector(".jp-carousel-pagination");if(u&&g.slides.length>5){var d=e+1;u.innerHTML="<span>"+d+" / "+g.slides.length+"</span>"}jetpackCarouselStrings.stats&&g.isOpen&&((new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?"+jetpackCarouselStrings.stats+"&post="+encodeURIComponent(s)+"&rand="+Math.random()),g.isOpen&&f(s),c="#jp-carousel-"+s,window.location.hash=c}function k(){document.body.style.overflow=a,document.documentElement.style.overflow=n,W(),y(),r.emitEvent(g.overlay,"jp_carousel.beforeClose"),window.scrollTo(window.scrollX||window.pageXOffset||0,i||0),g.isOpen=!1,e.destroy(),g.slides=[],l={},s={},g.currentSlide=void 0,g.gallery.innerHTML="",r.fadeOut(g.overlay,function(){r.emitEvent(g.overlay,"jp_carousel.afterClose")})}function q(e){if("object"!=typeof e&&(e={}),void 0===e.origFile)return"";if(void 0===e.origWidth||void 0===e.maxWidth)return e.origFile;if(!e.largeFile)return e.origFile;var t=document.createElement("a");t.href=e.largeFile;var r=/^i[0-2]\.wp\.com$/i.test(t.hostname),o=function(e,t,r){var o,a=r?e.replace(/.*=([\d]+%2C[\d]+).*$/,"$1"):e.replace(/.*-([\d]+x[\d]+)\..+$/,"$1");return"9999"===(o=a!==e?r?a.split("%2C"):a.split("x"):[t,0])[0]&&(o[0]="0"),"9999"===o[1]&&(o[1]="0"),o}(e.largeFile,e.origWidth,r),a=parseInt(o[0],10),n=parseInt(o[1],10);e.origMaxWidth=e.maxWidth,e.origMaxHeight=e.maxHeight,void 0!==window.devicePixelRatio&&window.devicePixelRatio>1&&(e.maxWidth=e.maxWidth*window.devicePixelRatio,e.maxHeight=e.maxHeight*window.devicePixelRatio);var i=e.zoomHeadroom||1;if(i>1&&(e.maxWidth=e.maxWidth*i,e.maxHeight=e.maxHeight*i),a>=e.maxWidth||n>=e.maxHeight)return e.largeFile;if(r){if(-1===e.largeFile.lastIndexOf("?"))return e.largeFile;var l=function(e){var t;try{t=new URL(e)}catch(t){return e}var r=["quality","ssl","filter","brightness","contrast","colorize","smooth"],o=Array.from(t.searchParams.entries());return t.search="",o.forEach(([e,o])=>{r.includes(e)&&t.searchParams.append(e,o)}),t}(e.largeFile);return(e.origWidth>e.maxWidth||e.origHeight>e.maxHeight)&&(e.origMaxWidth=e.maxWidth,e.origMaxHeight=e.maxHeight,l.searchParams.set("fit",e.origMaxWidth+","+e.origMaxHeight)),l.toString()}return e.origFile}function E(e){return e>=1?Math.round(10*e)/10+"s":"1/"+Math.round(1/e)+"s"}
5864function A(e){return!e.match(" ")&&e.match("_")?"":e}function I(){var e=g.info.querySelector(".jp-carousel-comments-wrapper");return!!e&&e.classList.contains("jp-carousel-show")}function H(e){var t=g.info.querySelector(".jp-carousel-icon-comments .jp-carousel-has-comments-indicator");t&&(e>0?(t.innerText=e,t.classList.add("jp-carousel-show")):t.classList.remove("jp-carousel-show"))}function T(e,t){clearInterval(o),o=setInterval(function(){g.container.scrollTop+150>window.innerHeight&&(clearInterval(o),_(e,t))},300)}function _(e,t,a){var n=void 0===t;if(clearInterval(o),e&&g.currentSlide&&g.currentSlide.attrs.attachmentId===e&&(!s[e]||a)){(!t||t<1)&&(t=0);var i=g.info.querySelector(".jp-carousel-comments"),c=g.info.querySelector("#jp-carousel-comments-loading");r.show(c),n&&(r.hide(i),i.innerHTML="");var u=new XMLHttpRequest;s[e]=u;var d=function(){return s[e]===u},m=jetpackCarouselStrings.ajaxurl+"?action=get_attachment_comments&nonce="+jetpackCarouselStrings.nonce+"&id="+e+"&offset="+t;u.open("GET",m),u.setRequestHeader("X-Requested-With","XMLHttpRequest");var p=function(){r.fadeIn(i),r.fadeOut(c)};u.onload=function(){if(d()&&(delete s[e],g.currentSlide&&g.currentSlide.attrs.attachmentId===e)){var o,a=u.status>=200&&u.status<300;try{o=JSON.parse(u.responseText)}catch{}if(a&&o&&Array.isArray(o)){n&&(i.innerHTML="");for(var m=0;m<o.length;m++){var h=o[m];if(!i.querySelector("#jp-carousel-comment-"+h.id)){var f=document.createElement("div");f.classList.add("jp-carousel-comment"),f.setAttribute("id","jp-carousel-comment-"+h.id),f.innerHTML='<div class="comment-gravatar">'+h.gravatar_markup+'</div><div class="comment-content"><div class="comment-author">'+h.author_markup+'</div><div class="comment-date">'+h.date_gmt+"</div>"+h.content+"</div>",i.appendChild(f)}}var v=o.length>=10,y=t+10;v&&T(e,y);var w=i.querySelectorAll(".jp-carousel-comment").length,S=Math.max(parseInt(g.currentSlide.attrs.commentsCount,10)||0,w);o.length>0&&(r.show(i),H(S)),l[e]={html:i.innerHTML,count:S,hasMore:v,nextOffset:y},r.hide(c)}else p()}},u.onerror=function(){d()&&(delete s[e],g.currentSlide&&g.currentSlide.attrs.attachmentId===e&&p())},u.send()}}function M(e){var t=e.attrs,r=e.el.querySelector("img");if(!r.hasAttribute("data-loaded"))if(r.setAttribute("itemprop","image"),r.setAttribute("data-loaded",1),t.previewImage&&t.previewImage!==t.src){r.src=t.previewImage,r.style.filter="blur(8px)";var o=new window.Image;o.addEventListener("load",function(){r.hasAttribute("data-zoom-loaded")||(r.src=t.src),r.style.filter=""},{once:!0}),o.addEventListener("error",function(){r.style.filter=""},{once:!0}),o.src=t.src}else r.src=t.src}function F(e){var t=e.attrs.originalElement;if(t)if(t.complete&&0!==t.naturalHeight)O(e,t);else{var r=function(){t.removeEventListener("error",o),O(e,t)},o=function(){t.removeEventListener("load",r)};t.addEventListener("load",r,{once:!0}),t.addEventListener("error",o,{once:!0})}}function O(e,r){var o=t.getBackgroundImage(r);o&&(e.backgroundImage=o,e.el.style.backgroundImage="url("+o+")",e.el.style.backgroundSize="cover",e.el.style.backgroundPosition="center")}function W(){g.commentField&&(g.commentField.value="")}function N(e,o){g.slides=[];var a={width:window.innerWidth,height:window.innerHeight-64};0!==o&&null!==e[o].getAttribute("data-gallery-src")&&((new Image).src=e[o].getAttribute("data-gallery-src")),Array.prototype.forEach.call(e,function(e,o){var n=r.closest(e,"a"),i=e.getAttribute("data-orig-file")||e.getAttribute("src-orig"),l=e.getAttribute("data-attachment-id")||e.getAttribute("data-id")||"0",s=document.querySelector('img[data-attachment-id="'+l+'"] + figcaption');s=s?s.innerHTML:e.getAttribute("data-image-caption");var c={originalElement:e,attachmentId:l,commentsOpened:e.getAttribute("data-comments-opened")||"0",commentsCount:e.getAttribute("data-comments-count")||"0",imageMeta:r.getJSONAttribute(e,"data-image-meta")||{},title:e.getAttribute("data-image-title")||"",desc:e.getAttribute("data-image-description")||"",largeFile:e.getAttribute("data-large-file")||"",origFile:i||"",thumbSize:{width:e.naturalWidth,height:e.naturalHeight},caption:s||"",permalink:n&&n.getAttribute("href"),src:i||e.getAttribute("src")||""},u=r.closest(e,".tiled-gallery-item"),d=u&&u.querySelector(".tiled-gallery-caption"),m=d&&d.innerHTML;m&&(c.caption=m);var p=function(e){var t=e.getAttribute("data-orig-size")||"";if(t){var r=t.split(",");return{width:parseInt(r[0],10),height:parseInt(r[1],10)}}return{width:e.getAttribute("data-original-width")||e.getAttribute("width")||void 0,height:e.getAttribute("data-original-height")||e.getAttribute("height")||void 0}}(e);if(c.origWidth=p.width||c.thumbSize.width,c.origHeight=p.height||c.thumbSize.height,"undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.generateImgSrc)c.src=wpcom.carousel.generateImgSrc(e,a);else{var h=function(e){return{origFile:c.src,origWidth:c.origWidth,origHeight:c.origHeight,maxWidth:a.width,maxHeight:a.height,largeFile:c.largeFile,zoomHeadroom:e}};c.zoomSrc=q(h(2)),c.src=q(h(1))}if(e.setAttribute("data-gallery-src",c.src),"0"!==c.attachmentId){c.title=t.texturize(c.title),c.desc=t.texturize(c.desc),c.caption=t.texturize(c.caption);var f=new Image,v=document.createElement("div");v.classList.add("swiper-slide"),v.setAttribute("itemprop","associatedMedia"),v.setAttribute("itemscope",""),v.setAttribute("itemtype","https://schema.org/ImageObject");var y=document.createElement("div");y.classList.add("swiper-zoom-container"),g.gallery.appendChild(v),v.appendChild(y),y.appendChild(f),v.setAttribute("data-attachment-id",c.attachmentId),v.setAttribute("data-permalink",c.permalink),v.setAttribute("data-orig-file",c.origFile),c.previewImage=e.currentSrc||e.getAttribute("src")||"";var w={el:v,attrs:c,index:o};g.slides.push(w)}})}function z(e,t){if(!window.JetpackSwiper){var o=document.querySelector("#jp-carousel-loading-overlay");r.show(o);var a=document.createElement("script");return a.id="jetpack-carousel-swiper-js",a.src=window.jetpackSwiperLibraryPath.url,a.async=!0,a.onload=function(){r.hide(o),R(e,t)},a.onerror=function(){r.hide(o)},void document.head.appendChild(a)}R(e,t)}function R(t,o){var c,u={imgSelector:".gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id], img[data-attachment-id], img[data-id]",startIndex:0},d=r.getJSONAttribute(t,"data-carousel-extra");if(!d)return;const m=t.querySelectorAll(u.imgSelector);if(m.length&&(j(),!g.isOpen)){for(var p in g.isOpen=!0,a=getComputedStyle(document.body).overflow,document.body.style.overflow="hidden",n=getComputedStyle(document.documentElement).overflow,document.documentElement.style.overflow="hidden",i=window.scrollY||window.pageYOffset||0,g.container.setAttribute("data-carousel-extra",JSON.stringify(d)),h(["open","view_image"]),o||{})u[p]=o[p];-1===u.startIndex&&(u.startIndex=0),r.emitEvent(g.overlay,"jp_carousel.beforeOpen"),g.gallery.innerHTML="",l={},s={},g.overlay.style.opacity=1,g.overlay.style.display="block",N(m,u.startIndex),(e=new window.JetpackSwiper(".jp-carousel-swiper-container",{centeredSlides:!0,speed:r.prefersReducedMotion()?0:250,zoom:!0,loop:g.slides.length>1,enabled:g.slides.length>1,pagination:{el:".jp-swiper-pagination",clickable:!0},navigation:{nextEl:".jp-swiper-button-next",prevEl:".jp-swiper-button-prev"},initialSlide:u.startIndex,on:{init:function(){C(u.startIndex)}},preventClicks:!1,preventClicksPropagation:!1,preventInteractionOnTransition:!r.isTouch(),threshold:5})).on("slideChange",function(e){g.isOpen&&(C(e.realIndex),g.overlay.classList.remove("jp-carousel-hide-control
5864s"))}),e.on("zoomChange",function(e,t){t>1&&(function(e){if(e&&e.attrs.zoomSrc&&e.attrs.zoomSrc!==e.attrs.src){var t=e.el.querySelector("img");t&&!t.hasAttribute("data-zoom-loaded")&&(t.setAttribute("data-zoom-loaded",1),t.src=e.attrs.zoomSrc)}}(g.currentSlide),g.overlay.classList.add("jp-carousel-hide-controls")),1===t&&g.overlay.classList.remove("jp-carousel-hide-controls")}),e.on("doubleTap",function(e){if(clearTimeout(c),1===e.zoom.scale)var t=setTimeout(function(){g.overlay.classList.remove("jp-carousel-hide-controls"),clearTimeout(t)},150)}),e.on("tap",function(){e.zoom.scale>1&&(c=setTimeout(function(){g.overlay.classList.toggle("jp-carousel-hide-controls")},150))}),r.fadeIn(g.overlay,function(){r.emitEvent(g.overlay,"jp_carousel.afterOpen")})}}function P(e){if("click"!==e.type){if("keydown"===e.type){const t=document.activeElement.parentElement,r=t&&t.classList.contains("tiled-gallery__item");" "!==e.key&&"Enter"!==e.key||!r||$(e)}}else $(e)}function D(e){return(e||"").split("?")[0].replace(/\/$/,"")}function J(e){"A"===e.tagName&&(e=e.querySelector("img")||e);var t=e.parentElement,o=t?t.parentElement:null,a=null;if(o&&o.classList.contains("wp-block-image")?a=t.getAttribute("href"):t&&t.classList.contains("wp-block-image")&&t.querySelector(":scope > a")&&(a=t.querySelector(":scope > a").getAttribute("href")),a){var n=D(a),i=D(e.getAttribute("data-orig-file")),l=D(e.getAttribute("data-permalink"));if(n!==i&&n!==l)return!1}return!(t&&t.classList.contains("gallery-caption")||r.matches(t,"figcaption"))}function $(e){if(window.CSS&&window.CSS.supports&&window.CSS.supports("display","grid")){var t,o=e.target,a=r.closest(o,d);if(a){if(!(t=a)||!t.getAttribute("data-carousel-extra"))return;if(!J(o))return;document.documentElement.style.height="auto",e.preventDefault(),e.stopPropagation();var n=r.closest(o,p),i=Array.prototype.indexOf.call(a.querySelectorAll(p),n);z(a,{startIndex:i})}}}document.body.addEventListener("click",P),document.body.addEventListener("keydown",P),document.querySelectorAll(m+"img").forEach(function(e){J(e)&&S(e)}),1===Number(jetpackCarouselStrings.single_image_gallery)&&(L(),document.body.addEventListener("is.post-load",function(){L()})),window.addEventListener("hashchange",function(){var e=/jp-carousel-(\d+)/;if(window.location.hash&&e.test(window.location.hash)){if(window.location.hash!==c||!g.isOpen)if(window.location.hash&&g.gallery&&!g.isOpen&&history.back)history.back();else{c=window.location.hash;for(var t=window.location.hash.match(e),r=parseInt(t[1],10),o=document.querySelectorAll(d),a=0;a<o.length;a++){for(var n,i=o[a],l=i.querySelectorAll("img"),s=0;s<l.length;s++)if(parseInt(l[s].getAttribute("data-attachment-id"),10)===r||parseInt(l[s].getAttribute("data-id"),10)===r){n=s;break}if(void 0!==n){x(i,n);break}}}}else g.isOpen&&k()}),window.location.hash&&r.emitEvent(window,"hashchange")}"loading"!==document.readyState?o():document.addEventListener("DOMContentLoaded",o)}();;
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.