1/* global wpcom_reblog */ 2 3var jetpackLikesWidgetBatch = []; 4var jetpackLikesMasterReady = false; 5 6// Due to performance problems on pages with a large number of widget iframes that need to be loaded, 7// we are limiting the processing at any instant to unloaded widgets that are currently in viewport, 8// plus this constant that will allow processing of widgets above and bellow the current fold. 9// This aim of it is to improve the UX and hide the transition from unloaded to loaded state from users. 10var jetpackLikesLookAhead = 2000; // pixels 11 12// Keeps track of loaded comment likes widget so we can unload them when they are scrolled out of view. 13var jetpackCommentLikesLoadedWidgets = []; 14 15var jetpackLikesDocReadyPromise = new Promise( resolve => { 16 if ( document.readyState !== 'loading' ) { 17 resolve(); 18 } else { 19 window.addEventListener( 'DOMContentLoaded', () => resolve() ); 20 } 21} ); 22 23function JetpackLikesPostMessage( message, target ) { 24 if ( typeof message === 'string' ) { 25 try { 26 message = JSON.parse( message ); 27 } catch ( e ) { 28 return; 29 } 30 } 31 32 if ( target && typeof target.postMessage === 'function' ) { 33 try { 34 target.postMessage( 35 JSON.stringify( { 36 type: 'likesMessage', 37 data: message, 38 } ), 39 '*' 40 ); 41 } catch ( e ) { 42 return; 43 } 44 } 45} 46 47function JetpackLikesBatchHandler() { 48 const requests = []; 49 document.querySelectorAll( 'div.jetpack-likes-widget-unloaded' ).forEach( widget => { 50 if ( jetpackLikesWidgetBatch.indexOf( widget.id ) > -1 ) { 51 return; 52 } 53 54 if ( ! jetpackIsScrolledIntoView( widget ) ) { 55 return; 56 } 57 58 jetpackLikesWidgetBatch.push( widget.id ); 59 60 var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/, 61 match = regex.exec( widget.id ), 62 info; 63 64 if ( ! match || match.length !== 5 ) { 65 return; 66 } 67 68 info = { 69 blog_id: match[ 2 ], 70 width: widget.width, 71 }; 72 73 if ( 'post' === match[ 1 ] ) { 74 info.post_id = match[ 3 ]; 75 } else if ( 'comment' === match[ 1 ] ) { 76 info.comment_id = match[ 3 ]; 77 } 78 79 info.obj_id = match[ 4 ]; 80 81 requests.push( info ); 82 } ); 83 84 if ( requests.length > 0 ) { 85 JetpackLikesPostMessage( 86 { event: 'initialBatch', requests: requests }, 87 window.frames[ 'likes-master' ] 88 ); 89 } 90} 91 92function JetpackLikesMessageListener( event ) { 93 let message = event && event.data; 94 if ( typeof message === 'string' ) { 95 try { 96 message = JSON.parse( message ); 97 } catch ( err ) { 98 return; 99 } 100 } 101 102 const type = message && message.type; 103 const data = message && message.data; 104 105 if ( type !== 'likesMessage' || typeof data.event === 'undefined' ) { 106 return; 107 } 108 109 // We only allow messages from one origin 110 const allowedOrigin = 'https://widgets.wp.com'; 111 if ( allowedOrigin !== event.origin ) { 112 return; 113 } 114 115 switch ( data.event ) { 116 case 'masterReady': 117 jetpackLikesDocReadyPromise.then( () => { 118 jetpackLikesMasterReady = true; 119 120 const stylesData = { 121 event: 'injectStyles', 122 }; 123 const sdTextColor = document.querySelector( '.sd-text-color' ); 124 const sdLinkColor = document.querySelector( '.sd-link-color' ); 125 const sdTextColorStyles = ( sdTextColor && getComputedStyle( sdTextColor ) ) || {}; 126 const sdLinkColorStyles = ( sdLinkColor && getComputedStyle( sdLinkColor ) ) || {}; 127 128 // enable reblogs if they are enabled for the page 129 if ( document.body.classList.contains( 'jetpack-reblog-enabled' ) ) { 130 JetpackLikesPostMessage( { event: 'reblogsEnabled' }, window.frames[ 'likes-master' ] ); 131 } 132 133 stylesData.textStyles = { 134 color: sdTextColorStyles[ 'color' ],
135 fontFamily: sdTextColorStyles[ 'font-family' ], 136 fontSize: sdTextColorStyles[ 'font-size' ], 137 direction: sdTextColorStyles[ 'direction' ], 138 fontWeight: sdTextColorStyles[ 'font-weight' ], 139 fontStyle: sdTextColorStyles[ 'font-style' ], 140 textDecoration: sdTextColorStyles[ 'text-decoration' ], 141 }; 142 143 stylesData.linkStyles = { 144 color: sdLinkColorStyles[ 'color' ], 145 fontFamily: sdLinkColorStyles[ 'font-family' ], 146 fontSize: sdLinkColorStyles[ 'font-size' ], 147 textDecoration: sdLinkColorStyles[ 'text-decoration' ], 148 fontWeight: sdLinkColorStyles[ 'font-weight' ], 149 fontStyle: sdLinkColorStyles[ 'font-style' ], 150 }; 151 152 JetpackLikesPostMessage( stylesData, window.frames[ 'likes-master' ] ); 153 154 JetpackLikesBatchHandler(); 155 } ); 156 157 break; 158 159 // We're keeping this for planned future follow ups. 160 // @see: https://github.com/Automattic/jetpack/pull/42361#discussion_r1995338815 161 case 'showLikeWidget': 162 break; 163 164 // We're keeping this for planned future follow ups. 165 // @see: https://github.com/Automattic/jetpack/pull/42361#discussion_r1995338815 166 case 'showCommentLikeWidget': 167 break; 168 169 case 'killCommentLikes': 170 // If kill switch for comment likes is enabled remove all widgets wrappers and `Loading...` placeholders. 171 document 172 .querySelectorAll( '.jetpack-comment-likes-widget-wrapper' ) 173 .forEach( wrapper => wrapper.remove() ); 174 break; 175 176 case 'clickReblogFlair': 177 if ( wpcom_reblog && typeof wpcom_reblog.toggle_reblog_box_flair === 'function' ) { 178 wpcom_reblog.toggle_reblog_box_flair( data.obj_id, data.post_id ); 179 } 180 break; 181 182 case 'hideOtherGravatars': { 183 hideLikersPopover(); 184 break; 185 } 186 187 case 'showOtherGravatars': { 188 const container = document.querySelector( '#likes-other-gravatars' ); 189 190 if ( ! container ) { 191 break; 192 } 193 194 const list = container.querySelector( 'ul' ); 195 196 container.style.display = 'none'; 197 list.innerHTML = ''; 198 199 container 200 .querySelectorAll( '.likes-text span' ) 201 .forEach( item => ( item.textContent = data.totalLikesLabel ) ); 202 203 ( data.likers || [] ).forEach( async ( liker, index ) => { 204 if ( liker.profile_URL.substr( 0, 4 ) !== 'http' ) { 205 // We only display gravatars with http or https schema 206 return; 207 } 208 209 const element = document.createElement( 'li' ); 210 list.append( element ); 211 212 element.innerHTML = ` 213 <a href="${ encodeURI( liker.profile_URL ) }" rel="nofollow" target="_parent" class="wpl-liker"> 214 <img src="${ encodeURI( liker.avatar_URL ) }" 215 alt="" 216 style="width: 28px; height: 28px;" /> 217 <span></span> 218 </a> 219 `; 220 221 222 // Add some extra attributes through native methods, to ensure strings are sanitized. 223 element.classList.add( liker.css_class ); 224 element.querySelector( 'img' ).alt = data.avatarAltTitle.replace( '%s', liker.name ); 225 element.querySelector( 'span' ).innerText = liker.name; 226 227 if ( index === data.likers.length - 1 ) { 228 element.addEventListener( 'keydown', ( e ) => { 229 if ( e.key === 'Tab' && ! e.shiftKey ) { 230 e.preventDefault(); 231 hideLikersPopover(); 232 233 JetpackLikesPostMessage( 234 { event: 'focusLikesCount', parent: data.parent }, 235 window.frames[ 'likes-master' ] 236 ); 237 } 238 } ); 239 } 240 } ); 241 242 const positionPopup = function() { 243 const containerStyle = getComputedStyle(container); 244 const isRtl = containerStyle.direction === 'rtl'; 245 246 const el = document.querySelector( `*[name='${ data.parent }']` ); 247 const rect = el.getBoundingClientRect(); 248 const win = el.ownerDocument.defaultView; 249 250 const offset = { 251 top: rect.top + win.pageYOffset, 252 left: rect.left + win.pageXOffset, 253 }; 254 255 // don't display yet or we get skewed window.innerWidth later 256 container.style.display = 'none'; 257 258 let containerLeft = 0; 259 container.style.top = offset.top + data.position.top - 1 + 'px'; 260 261 if ( isRtl ) { 262 const visibleAvatarsCount = data && data.likers ? Math.min( data.likers.length, 5 ) : 0; 263 // 24px is the width of the avatar + 4px is the padding between avatars 264 containerLeft = offset.left + data.position.left + 24 * visibleAvatarsCount + 4; 265 container.style.transform = 'translateX(-100%)'; 266 } else { 267 containerLeft = offset.left + data.position.left; 268 } 269 container.style.left = containerLeft + 'px'; 270 271 // Container width - padding
272 const initContainerWidth = data.width - 20; 273 const rowLength = Math.floor( initContainerWidth / 37 ); 274 // # of rows + (avatar + avatar padding) + text above + container padding 275 let height = Math.ceil( data.likers.length / rowLength ) * 37 + 17 + 22; 276 if ( height > 204 ) { 277 height = 204; 278 } 279 280 // If the popup is overflows viewport width, we should show it on the next line 281 // Push it offscreen to calculated rendered width 282 const windowWidth = win.innerWidth; 283 container.style.left = '-9999px'; 284 container.style.display = 'block'; 285 286 // If the popup exceeds the viewport width, 287 // flip the position of the popup. 288 const containerWidth = container.offsetWidth; 289 const containerRight = containerLeft + containerWidth; 290 291 if ( containerRight > windowWidth && ! isRtl) { 292 containerLeft = rect.left + rect.width - containerWidth; 293 } else if ( containerLeft - containerWidth < 0 && isRtl ) { 294 container.style.transform = 'none'; 295 containerLeft = rect.left; 296 } 297 // Set the container left 298 container.style.left = containerLeft + 'px'; 299 300 container.setAttribute( 'aria-hidden', 'false' ); 301 } 302 303 positionPopup(); 304 container.focus(); 305 306 const debounce = function( func, wait ) { 307 var timeout; 308 return function() { 309 var context = this; 310 var args = arguments; 311 clearTimeout( timeout ); 312 timeout = setTimeout( function() { 313 func.apply( context, args ); 314 }, wait ); 315 }; 316 }; 317 318 const debouncedPositionPopup = debounce( positionPopup, 100 ); 319 320 // Keep a reference of this function in the element itself 321 // so that we can destroy it later 322 container.__resizeHandler = debouncedPositionPopup; 323 324 // When window is resized, resize the popup. 325 window.addEventListener( "resize", debouncedPositionPopup ); 326 } 327 } 328} 329 330window.addEventListener( 'message', JetpackLikesMessageListener ); 331 332function hideLikersPopover() { 333 const container = document.querySelector( '#likes-other-gravatars' ); 334 335 if ( container ) { 336 container.style.display = 'none'; 337 container.setAttribute( 'aria-hidden', 'true' ); 338 339 // Remove the resize event listener and cleanup. 340 const resizeHandler = container.__resizeHandler; 341 if ( resizeHandler ) { 342 window.removeEventListener( "resize", resizeHandler ); 343 delete container.__resizeHandler; 344 } 345 } 346} 347 348document.addEventListener( 'click', hideLikersPopover ); 349 350function JetpackLikesWidgetQueueHandler() { 351 var wrapperID; 352 353 if ( ! jetpackLikesMasterReady ) { 354 setTimeout( JetpackLikesWidgetQueueHandler, 500 ); 355 return; 356 } 357 358 // Restore widgets to initial unloaded state when they are scrolled out of view. 359 jetpackUnloadScrolledOutWidgets(); 360 361 var unloadedWidgetsInView = jetpackGetUnloadedWidgetsInView(); 362 363 if ( unloadedWidgetsInView.length > 0 ) { 364 // Grab any unloaded widgets for a batch request 365 JetpackLikesBatchHandler(); 366 } 367 368 for ( var i = 0, length = unloadedWidgetsInView.length; i <= length - 1; i++ ) { 369 wrapperID = unloadedWidgetsInView[ i ].id; 370 371 if ( ! wrapperID ) { 372 continue; 373 } 374 375 jetpackLoadLikeWidgetIframe( wrapperID ); 376 } 377} 378 379function jetpackLoadLikeWidgetIframe( wrapperID ) { 380 if ( typeof wrapperID === 'undefined' ) { 381 return; 382 } 383 384 const wrapper = document.querySelector( '#' + wrapperID ); 385 wrapper.querySelectorAll( 'iframe' ).forEach( iFrame => iFrame.remove() ); 386 387 const placeholder = wrapper.querySelector( '.likes-widget-placeholder' ); 388 389 // Post like iframe 390 if ( placeholder && placeholder.classList.contains( 'post-likes-widget-placeholder' ) ) { 391 const postLikesFrame = document.createElement( 'iframe' ); 392 393 postLikesFrame.classList.add( 'post-likes-widget', 'jetpack-likes-widget' ); 394 postLikesFrame.name = wrapper.dataset.name; 395 postLikesFrame.src = wrapper.dataset.src; 396 postLikesFrame.height = '55px'; 397 postLikesFrame.width = '100%'; 398 postLikesFrame.frameBorder = '0'; 399 postLikesFrame.scrolling = 'no'; 400 postLikesFrame.title = wrapper.dataset.title; 401 402 placeholder.after( postLikesFrame ); 403 } 404 405 // Comment like iframe 406 if ( placeholder.classList.contains( 'comment-likes-widget-placeholder' ) ) { 407 const commentLikesFrame = document.createElement( 'iframe' ); 408 409 commentLikesFrame.class = 'comment-likes-widget-frame jetpack-likes-widget-frame'; 410 commentLikesFrame.name = wrapper.dataset.name; 411 commentLikesFrame.src = wrapper.dataset.src; 412 commentLikesFrame.height = '18px'; 413 commentLikesFrame.width = '100%'; 414 commentLikesFrame.frameBorder = '0'; 415 commentLikesFrame.scrolling = 'no'; 416 417 wrapper.querySelector( '.comment-like-feedback' ).after( commentLikesFrame ); 418 419 jetpackCommentLikesLoadedWidgets.push( commentLikesFrame ); 420 } 421 422 wrapper.classList.remove( 'jetpack-likes-widget-unloaded' ); 423 wrapper.classList.add( 'jetpack-likes-widget-loading' ); 424 425 wrapper.querySelector( 'iframe' ).addEventListener( 'load', e => { 426 JetpackLikesPostMessage( 427 { event: 'loadLikeWidget', name: e.target.name, width: e.target.width }, 428 window.frames[ 'likes-master' ] 429 ); 430 431 wrapper.classList.remove( 'jetpack-likes-widget-loading' ); 432 wrapper.classList.add( 'jetpack-likes-widget-loaded' ); 433 } ); 434} 435 436function jetpackGetUnloadedWidgetsInView() { 437 const unloadedWidgets = document.querySelectorAll( 'div.jetpack-likes-widget-unloaded' ); 438 439 return [ ...unloadedWidgets ].filter( item => jetpackIsScrolledIntoView( item ) ); 440} 441 442function jetpackIsScrolledIntoView( element ) { 443 const top = element.getBoundingClientRect().top; 444 const bottom = element.getBoundingClientRect().bottom; 445
446 // Allow some slack above and bellow the fold with jetpackLikesLookAhead, 447 // with the aim of hiding the transition from unloaded to loaded widget from users. 448 return top + jetpackLikesLookAhead >= 0 && bottom <= window.innerHeight + jetpackLikesLookAhead; 449} 450 451function jetpackUnloadScrolledOutWidgets() { 452 for ( let i = jetpackCommentLikesLoadedWidgets.length - 1; i >= 0; i-- ) { 453 const currentWidgetIframe = jetpackCommentLikesLoadedWidgets[ i ]; 454 455 if ( ! jetpackIsScrolledIntoView( currentWidgetIframe ) ) { 456 const widgetWrapper = 457 currentWidgetIframe && 458 currentWidgetIframe.parentElement && 459 currentWidgetIframe.parentElement.parentElement; 460 461 // Restore parent class to 'unloaded' so this widget can be picked up by queue manager again if needed. 462 widgetWrapper.classList.remove( 'jetpack-likes-widget-loaded' ); 463 widgetWrapper.classList.remove( 'jetpack-likes-widget-loading' ); 464 widgetWrapper.classList.add( 'jetpack-likes-widget-unloaded' ); 465 466 // Bring back the loading placeholder into view. 467 widgetWrapper 468 .querySelectorAll( '.comment-likes-widget-placeholder' ) 469 .forEach( item => ( item.style.display = 'block' ) ); 470 471 // Remove it from the list of loaded widgets. 472 jetpackCommentLikesLoadedWidgets.splice( i, 1 ); 473 474 // Remove comment like widget iFrame. 475 currentWidgetIframe.remove(); 476 } 477 } 478} 479 480var jetpackWidgetsDelayedExec = function ( after, fn ) { 481 var timer; 482 return function () { 483 clearTimeout( timer ); 484 timer = setTimeout( fn, after ); 485 }; 486}; 487 488var jetpackOnScrollStopped = jetpackWidgetsDelayedExec( 250, JetpackLikesWidgetQueueHandler ); 489 490// Load initial batch of widgets, prior to any scrolling events. 491JetpackLikesWidgetQueueHandler(); 492 493// Add event listener to execute queue handler after scroll. 494window.addEventListener( 'scroll', jetpackOnScrollStopped, true ); 495; 496(()=>{(function(){var Scroller,stats,type,text,totop,loading_text,isIE=-1!==navigator.userAgent.
496search("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
496inite"/></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.
496settings.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)})()})();; 497!function(e){var o={};function n(t){if(o[t])return o[t].exports;var r=o[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:t})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,o){if(1&o&&(e=n(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var r in e)n.d(t,r,function(o){return e[o]}.bind(null,r));return t},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},n.p="",n(n.s=273)}({273:function(e,o){!function(){"use strict";let e,o;function n(e){return new Promise((o,n)=>{const t=document.createElement("script");t.onload=()=>o(),t.onerror=e=>n(e),t.src=e,document.body.appendChild(t)})}function t(){if(e)return e;const o=window.wpcom_coblocks_js;return e=n(o.coblocks_lightbox_js),e}function r(){if(o)return o;window.wpcomJQueryUsageLoggerDisabled=!0;const e=window.wpcom_coblocks_js,t=window.jQuery?Promise.resolve():n(e.jquery_core_js).then(()=>n(e.jquery_migrate_js)),r=t.then(()=>window.imagesLoaded?Promise.resolve():n(e.imagesloaded_js)),c=t.then(()=>window.Masonry?Promise.resolve():n(e.masonry_js)),u=Promise.all([t,r,c]).then(()=>n(e.coblocks_masonry_js));return o=u,o}function c(){document.querySelector(".wp-block-coblocks-gallery-masonry")&&r(),document.querySelector(".has-lightbox")&&t(),document.body.classList.contains("block-editor-page")&&(r(),t())}"loading"!==document.readyState?c():document.addEventListener("DOMContentLoaded",c)}()}});; 498/*! 499 * requestAnimationFrame polyfill 500 * http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 501 * http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating 502 * Test a CSS media type/query in JS. 503 * Authors Erik Möller. fixes from Paul Irish and Tino Zijdel 504 * MIT license 505 */ 506 507(function() { 508 var lastTime = 0; 509 var vendors = ['ms', 'moz', 'webkit', 'o']; 510 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 511 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 512 window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 513 || window[vendors[x]+'CancelRequestAnimationFrame']; 514 } 515 516 if (!window.requestAnimationFrame) 517 window.requestAnimationFrame = function(callback, element) { 518 var currTime = new Date().getTime(); 519 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 520 var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 521 timeToCall); 522 lastTime = currTime + timeToCall; 523 return id; 524 }; 525 526 if (!window.cancelAnimationFrame) 527 window.cancelAnimationFrame = function(id) { 528 clearTimeout(id); 529 }; 530}()); 531 532/*! 533 * matchMedia() polyfill 534 * https://github.com/paulirish/matchMedia.js 535 * Test a CSS media type/query in JS. 536 * Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license 537 */ 538 539window.matchMedia || (window.matchMedia = function() { 540 "use strict"; 541 542 // For browsers that support matchMedium api such as IE 9 and webkit 543 var styleMedia = (window.styleMedia || window.media); 544 545 // For those that don't support matchMedium 546 if (!styleMedia) { 547 var style = document.createElement('style'), 548 script = document.getElementsByTagName('script')[0], 549 info = null; 550 551 style.type = 'text/css'; 552 style.id = 'matchmediajs-test'; 553 554 script.parentNode.insertBefore(style, script); 555 556 // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers 557 info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; 558 559 styleMedia = { 560 matchMedium: function(media) { 561 var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; 562 563 // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers 564 if (style.styleSheet) { 565 style.styleSheet.cssText = text; 566 } else { 567 style.textContent = text; 568 } 569 570 // Test if media query is true or false 571 return info.width === '1px'; 572 } 573 }; 574 } 575 576 return function(media) { 577 return { 578 matches: styleMedia.matchMedium(media || 'all'), 579 media: media || 'all' 580 }; 581 }; 582}()); 583 584/*! 585 * matchMedia() polyfill addListener/removeListener extension. 586 * https://github.com/paulirish/matchMedia.js 587 * Test a CSS media type/query in JS. 588 * Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license 589 */ 590 591(function(){ 592 // Bail out for browsers that have addListener support 593 if (window.matchMedia && window.matchMedia('all').addListener) { 594 return false;
595 } 596 597 var localMatchMedia = window.matchMedia, 598 hasMediaQueries = localMatchMedia('only all').matches, 599 isListening = false, 600 timeoutID = 0, // setTimeout for debouncing 'handleChange' 601 queries = [], // Contains each 'mql' and associated 'listeners' if 'addListener' is used 602 handleChange = function(evt) { 603 // Debounce 604 clearTimeout(timeoutID); 605 606 timeoutID = setTimeout(function() { 607 for (var i = 0, il = queries.length; i < il; i++) { 608 var mql = queries[i].mql, 609 listeners = queries[i].listeners || [], 610 matches = localMatchMedia(mql.media).matches; 611 612 // Update mql.matches value and call listeners 613 // Fire listeners only if transitioning to or from matched state 614 if (matches !== mql.matches) { 615 mql.matches = matches; 616 617 for (var j = 0, jl = listeners.length; j < jl; j++) { 618 listeners[j].call(window, mql); 619 } 620 } 621 } 622 }, 30); 623 }; 624 625 window.matchMedia = function(media) { 626 var mql = localMatchMedia(media), 627 listeners = [], 628 index = 0; 629 630 mql.addListener = function(listener) { 631 // Changes would not occur to css media type so return now (Affects IE <= 8) 632 if (!hasMediaQueries) { 633 return; 634 } 635 636 // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8) 637 // There should only ever be 1 resize listener running for performance 638 if (!isListening) { 639 isListening = true; 640 window.addEventListener('resize', handleChange, true); 641 } 642 643 // Push object only if it has not been pushed already 644 if (index === 0) { 645 index = queries.push({ 646 mql : mql, 647 listeners : listeners 648 }); 649 } 650 651 listeners.push(listener); 652 }; 653 654 mql.removeListener = function(listener) { 655 for (var i = 0, il = listeners.length; i < il; i++){ 656 if (listeners[i] === listener){ 657 listeners.splice(i, 1); 658 } 659 } 660 }; 661 662 return mql; 663 }; 664}()); 665 666/*! 667 * Minimal classList shim for IE 9 668 * https://gist.github.com/devongovett/1381839 669 * By Devon Govett 670 * MIT LICENSE 671 */ 672 673if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') { 674 Object.defineProperty(HTMLElement.prototype, 'classList', { 675 get: function() { 676 var self = this; 677 function update(fn) { 678 return function(value) { 679 var classes = self.className.split(/\s+/), 680 index = classes.indexOf(value); 681 682 fn(classes, index, value); 683 self.className = classes.join(" "); 684 } 685 } 686 687 var ret = { 688 add: update(function(classes, index, value) { 689 ~index || classes.push(value); 690 }), 691 692 remove: update(function(classes, index) { 693 ~index && classes.splice(index, 1); 694 }), 695 696 toggle: update(function(classes, index, value) { 697 ~index ? classes.splice(index, 1) : classes.push(value); 698 }), 699 700 contains: function(value) { 701 return !!~self.className.split(/\s+/).indexOf(value); 702 }, 703 704 item: function(i) { 705 return self.className.split(/\s+/)[i] || null; 706 } 707 }; 708 709 Object.defineProperty(ret, 'length', { 710 get: function() { 711 return self.className.split(/\s+/).length; 712 } 713 }); 714 715 return ret; 716 } 717 }); 718} 719; 720/* Modernizr 2.8.3 (Custom Build) | MIT & BSD 721 * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradiu
vendor: 26,463 bytes, lines 721-1593
721s-boxshadow-flexbox-flexboxlegacy-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-printshiv-mq-cssclasses-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load 722 */ 723;window.Modernizr = (function( window, document, undefined ) { 724 725 var version = '2.8.3', 726 727 Modernizr = {}, 728 729 enableClasses = true, 730 731 docElement = document.documentElement, 732 733 mod = 'modernizr', 734 modElem = document.createElement(mod), 735 mStyle = modElem.style, 736 737 inputElem = document.createElement('input') , 738 739 smile = ':)', 740 741 toString = {}.toString, 742 743 prefixes = ' -webkit- -moz- -o- -ms- '.split(' '), 744 745 746 747 omPrefixes = 'Webkit Moz O ms', 748 749 cssomPrefixes = omPrefixes.split(' '), 750 751 domPrefixes = omPrefixes.toLowerCase().split(' '), 752 753 ns = {'svg': 'http://www.w3.org/2000/svg'}, 754 755 tests = {}, 756 inputs = {}, 757 attrs = {}, 758 759 classes = [], 760 761 slice = classes.slice, 762 763 featureName, 764 765 766 injectElementWithStyles = function( rule, callback, nodes, testnames ) { 767 768 var style, ret, node, docOverflow, 769 div = document.createElement('div'), 770 body = document.body, 771 fakeBody = body || document.createElement('body'); 772 773 if ( parseInt(nodes, 10) ) { 774 while ( nodes-- ) { 775 node = document.createElement('div'); 776 node.id = testnames ? testnames[nodes] : mod + (nodes + 1); 777 div.appendChild(node); 778 } 779 } 780 781 style = ['­','<style id="s', mod, '">', rule, '</style>'].join(''); 782 div.id = mod; 783 (body ? div : fakeBody).innerHTML += style; 784 fakeBody.appendChild(div); 785 if ( !body ) { 786 fakeBody.style.background = ''; 787 fakeBody.style.overflow = 'hidden'; 788 docOverflow = docElement.style.overflow; 789 docElement.style.overflow = 'hidden'; 790 docElement.appendChild(fakeBody); 791 } 792 793 ret = callback(div, rule); 794 if ( !body ) { 795 fakeBody.parentNode.removeChild(fakeBody); 796 docElement.style.overflow = docOverflow; 797 } else { 798 div.parentNode.removeChild(div); 799 } 800 801 return !!ret; 802 803 }, 804 805 testMediaQuery = function( mq ) { 806 807 var matchMedia = window.matchMedia || window.msMatchMedia; 808 if ( matchMedia ) { 809 return matchMedia(mq) && matchMedia(mq).matches || false; 810 } 811 812 var bool; 813 814 injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) { 815 bool = (window.getComputedStyle ? 816 getComputedStyle(node, null) : 817 node.currentStyle)['position'] == 'absolute'; 818 }); 819 820 return bool; 821 822 }, 823 824 825 isEventSupported = (function() { 826 827 var TAGNAMES = { 828 'select': 'input', 'change': 'input', 829 'submit': 'form', 'reset': 'form', 830 'error': 'img', 'load': 'img', 'abort': 'img' 831 }; 832 833 function isEventSupported( eventName, element ) { 834 835 element = element || document.createElement(TAGNAMES[eventName] || 'div'); 836 eventName = 'on' + eventName; 837 838 var isSupported = eventName in element; 839 840 if ( !isSupported ) { 841 if ( !element.setAttribute ) { 842 element = document.createElement('div'); 843 } 844 if ( element.setAttribute && element.removeAttribute ) { 845 element.setAttribute(eventName, ''); 846 isSupported = is(element[eventName], 'function'); 847 848 if ( !is(element[eventName], 'undefined') ) { 849 element[eventName] = undefined; 850 } 851 element.removeAttribute(eventName); 852 } 853 } 854 855 element = null; 856 return isSupported; 857 } 858 return isEventSupported; 859 })(), 860 861 862 _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp; 863 864 if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) { 865 hasOwnProp = function (object, property) { 866 return _hasOwnProperty.call(object, property); 867 }; 868 } 869 else { 870 hasOwnProp = function (object, property) { 871 return ((property in object) && is(object.constructor.prototype[property], 'undefined')); 872 }; 873 } 874 875 876 if (!Function.prototype.bind) { 877 Function.prototype.bind = function bind(that) { 878 879 var target = this; 880 881 if (typeof target != "function") { 882 throw new TypeError(); 883 } 884 885 var args = slice.call(arguments, 1), 886 bound = function () { 887 888 if (this instanceof bound) { 889 890 var F = function(){}; 891 F.prototype = target.prototype; 892 var self = new F(); 893 894 var result = target.apply( 895 self, 896 args.concat(slice.call(arguments)) 897 ); 898 if (Object(result) === result) { 899 return result; 900 } 901 return self; 902 903 } else { 904 905 return target.apply( 906 that, 907 args.concat(slice.call(arguments)) 908 ); 909 910 } 911 912 }; 913 914 return bound; 915 }; 916 } 917 918 function setCss( str ) { 919 mStyle.cssText = str; 920 } 921 922 function setCssAll( str1, str2 ) { 923 return setCss(prefixes.join(str1 + ';') + ( str2 || '' )); 924 } 925 926 function is( obj, type ) { 927 return typeof obj === type; 928 } 929 930 function contains( str, substr ) { 931 return !!~('' + str).indexOf(substr); 932 } 933 934 function testProps( props, prefixed ) { 935 for ( var i in props ) { 936 var prop = props[i]; 937 if ( !contains(prop, "-") && mStyle[prop] !== undefined ) { 938 return prefixed == 'pfx' ? prop : true; 939 } 940 } 941 return false; 942 } 943 944 function testDOMProps( props, obj, elem ) { 945 for ( var i in props ) { 946 var item = obj[props[i]]; 947 if ( item !== undefined) { 948 949 if (elem === false) return props[i]; 950 951 if (is(item, 'function')){ 952 return item.bind(elem || obj); 953 } 954 955 return item; 956 } 957 } 958 return false; 959 } 960 961 function testPropsAll( prop, prefixed, elem ) { 962 963 var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), 964 props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); 965 966 if(is(prefixed, "string") || is(prefixed, "undefined")) { 967 return testProps(props, prefixed); 968 969 } else { 970 props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); 971 return testDOMProps(props, prefixed, elem); 972 } 973 } tests['flexbox'] = function() { 974 return testPropsAll('flexWrap'); 975 }; 976 977 978 tests['flexboxlegacy'] = function() { 979 return testPropsAll('boxDirection'); 980 }; 981 982 983 tests['canvas'] = function() { 984 var elem = document.createElement('canvas'); 985 return !!(elem.getContext && elem.getContext('2d')); 986 }; 987 988 tests['canvastext'] = function() { 989 return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function')); 990 }; 991 992 993 994 tests['webgl'] = function() { 995 return !!window.WebGLRenderingContext; 996 }; 997 998 999 tests['touch'] = function() { 1000 var bool; 1001 1002 if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { 1003 bool = true; 1004 } else { 1005 injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) { 1006 bool = node.offsetTop === 9; 1007 }); 1008 } 1009 1010 return bool; 1011 }; 1012 1013 1014 1015 tests['geolocation'] = function() { 1016 return 'geolocation' in navigator; 1017 }; 1018 1019 1020 tests['postmessage'] = function() { 1021 return !!window.postMessage; 1022 }; 1023 1024 1025 tests['websqldatabase'] = function() { 1026 return !!window.openDatabase; 1027 }; 1028 1029 tests['indexedDB'] = function() { 1030 return !!testPropsAll("indexedDB", window); 1031 }; 1032 1033 tests['hashchange'] = function() { 1034 return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7); 1035 }; 1036 1037 tests['history'] = function() { 1038 return !!(window.history && history.pushState); 1039 }; 1040 1041 tests['draganddrop'] = function() { 1042 var div = document.createElement('div'); 1043 return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div); 1044 }; 1045 1046 tests['websockets'] = function() { 1047 return 'WebSocket' in window || 'MozWebSocket' in window; 1048 }; 1049 1050 1051 tests['rgba'] = function() { 1052 setCss('background-color:rgba(150,255,150,.5)'); 1053 1054 return contains(mStyle.backgroundColor, 'rgba'); 1055 }; 1056 1057 tests['hsla'] = function() { 1058 setCss('background-color:hsla(120,40%,100%,.5)'); 1059 1060 return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla'); 1061 }; 1062 1063 tests['multiplebgs'] = function() { 1064 setCss('background:url(https://),url(https://),red url(https://)'); 1065 1066 return (/(url\s*\(.*?){3}/).test(mStyle.background); 1067 }; tests['backgroundsize'] = function() { 1068 return testPropsAll('backgroundSize'); 1069 }; 1070 1071 tests['borderimage'] = function() { 1072 return testPropsAll('borderImage'); 1073 }; 1074 1075 1076 1077 tests['borderradius'] = function() { 1078 return testPropsAll('borderRadius'); 1079 }; 1080 1081 tests['boxshadow'] = function() { 1082 return testPropsAll('boxShadow'); 1083 }; 1084 1085 tests['textshadow'] = function() { 1086 return document.createElement('div').style.textShadow === ''; 1087 }; 1088 1089 1090 tests['opacity'] = function() { 1091 setCssAll('opacity:.55'); 1092 1093 return (/^0.55$/).test(mStyle.opacity); 1094 }; 1095 1096 1097 tests['cssanimations'] = function() { 1098 return testPropsAll('animationName'); 1099 }; 1100 1101 1102 tests['csscolumns'] = function() { 1103 return testPropsAll('columnCount'); 1104 }; 1105 1106 1107 tests['cssgradients'] = function() { 1108 var str1 = 'background-image:', 1109 str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));', 1110 str3 = 'linear-gradient(left top,#9f9, white);'; 1111 1112 setCss( 1113 (str1 + '-webkit- '.split(' ').join(str2 + str1) + 1114 prefixes.join(str3 + str1)).slice(0, -str1.length) 1115 ); 1116 1117 return contains(mStyle.backgroundImage, 'gradient'); 1118 }; 1119 1120 1121 tests['cssreflections'] = function() { 1122 return testPropsAll('boxReflect'); 1123 }; 1124 1125 1126 tests['csstransforms'] = function() { 1127 return !!testPropsAll('transform'); 1128 }; 1129 1130 1131 tests['csstransforms3d'] = function() { 1132 1133 var ret = !!testPropsAll('perspective'); 1134 1135 if ( ret && 'webkitPerspective' in docElement.style ) { 1136 1137 injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) { 1138 ret = node.offsetLeft === 9 && node.offsetHeight === 3; 1139 }); 1140 } 1141 return ret; 1142 }; 1143 1144 1145 tests['csstransitions'] = function() { 1146 return testPropsAll('transition'); 1147 }; 1148 1149 1150 1151 tests['fontface'] = function() { 1152 var bool; 1153 1154 injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) { 1155 var style = document.getElementById('smodernizr'), 1156 sheet = style.sheet || style.styleSheet, 1157 cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : ''; 1158 1159 bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0; 1160 }); 1161 1162 return bool; 1163 }; 1164 1165 tests['generatedcontent'] = function() { 1166 var bool; 1167 1168 injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) { 1169 bool = node.offsetHeight >= 3; 1170 }); 1171 1172 return bool; 1173 }; 1174 tests['video'] = function() { 1175 var elem = document.createElement('video'), 1176 bool = false; 1177 1178 try { 1179 if ( bool = !!elem.canPlayType ) { 1180 bool = new Boolean(bool); 1181 bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,''); 1182 1183 bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,''); 1184 1185 bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,''); 1186 } 1187 1188 } catch(e) { } 1189 1190 return bool; 1191 }; 1192 1193 tests['audio'] = function() { 1194 var elem = document.createElement('audio'), 1195 bool = false; 1196 1197 try { 1198 if ( bool = !!elem.canPlayType ) { 1199 bool = new Boolean(bool); 1200 bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,''); 1201 bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,''); 1202 1203 bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,''); 1204 bool.m4a = ( elem.canPlayType('audio/x-m4a;') || 1205 elem.canPlayType('audio/aac;')) .replace(/^no$/,''); 1206 } 1207 } catch(e) { } 1208 1209 return bool; 1210 }; 1211 1212 1213 tests['localstorage'] = function() { 1214 try { 1215 localStorage.setItem(mod, mod); 1216 localStorage.removeItem(mod); 1217 return true; 1218 } catch(e) { 1219 return false; 1220 } 1221 }; 1222 1223 tests['sessionstorage'] = function() { 1224 try { 1225 sessionStorage.setItem(mod, mod); 1226 sessionStorage.removeItem(mod); 1227 return true; 1228 } catch(e) { 1229 return false; 1230 } 1231 }; 1232 1233 1234 tests['webworkers'] = function() { 1235 return !!window.Worker; 1236 }; 1237 1238 1239 tests['applicationcache'] = function() { 1240 return !!window.applicationCache; 1241 }; 1242 1243 1244 tests['svg'] = function() { 1245 return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect; 1246 }; 1247 1248 tests['inlinesvg'] = function() { 1249 var div = document.createElement('div'); 1250 div.innerHTML = '<svg/>'; 1251 return (div.firstChild && div.firstChild.namespaceURI) == ns.svg; 1252 }; 1253 1254 tests['smil'] = function() { 1255 return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate'))); 1256 }; 1257 1258 1259 tests['svgclippaths'] = function() { 1260 return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath'))); 1261 }; 1262 1263 function webforms() { 1264 Modernizr['input'] = (function( props ) { 1265 for ( var i = 0, len = props.length; i < len; i++ ) { 1266 attrs[ props[i] ] = !!(props[i] in inputElem); 1267 } 1268 if (attrs.list){ 1269 attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement); 1270 } 1271 return attrs; 1272 })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ')); 1273 Modernizr['inputtypes'] = (function(props) { 1274 1275 for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) { 1276 1277 inputElem.setAttribute('type', inputElemType = props[i]); 1278 bool = inputElem.type !== 'text'; 1279 1280 if ( bool ) { 1281 1282 inputElem.value = smile; 1283 inputElem.style.cssText = 'position:absolute;visibility:hidden;'; 1284 1285 if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) { 1286 1287 docElement.appendChild(inputElem); 1288 defaultView = document.defaultView; 1289 1290 bool = defaultView.getComputedStyle && 1291 defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' && 1292 (inputElem.offsetHeight !== 0); 1293 1294 docElement.removeChild(inputElem); 1295 1296 } else if ( /^(search|tel)$/.test(inputElemType) ){ 1297 } else if ( /^(url|email)$/.test(inputElemType) ) { 1298 bool = inputElem.checkValidity && inputElem.checkValidity() === false; 1299 1300 } else { 1301 bool = inputElem.value != smile; 1302 } 1303 } 1304 1305 inputs[ props[i] ] = !!bool; 1306 } 1307 return inputs; 1308 })('search tel url email datetime date month week time datetime-local number range color'.split(' ')); 1309 } 1310 for ( var feature in tests ) { 1311 if ( hasOwnProp(tests, feature) ) { 1312 featureName = feature.toLowerCase(); 1313 Modernizr[featureName] = tests[feature](); 1314 1315 classes.push((Modernizr[featureName] ? '' : 'no-') + featureName); 1316 } 1317 } 1318 1319 Modernizr.input || webforms(); 1320 1321 1322 Modernizr.addTest = function ( feature, test ) { 1323 if ( typeof feature == 'object' ) { 1324 for ( var key in feature ) { 1325 if ( hasOwnProp( feature, key ) ) { 1326 Modernizr.addTest( key, feature[ key ] ); 1327 } 1328 } 1329 } else { 1330 1331 feature = feature.toLowerCase(); 1332 1333 if ( Modernizr[feature] !== undefined ) { 1334 return Modernizr; 1335 } 1336 1337 test = typeof test == 'function' ? test() : test; 1338 1339 if (typeof enableClasses !== "undefined" && enableClasses) { 1340 docElement.className += ' ' + (test ? '' : 'no-') + feature; 1341 } 1342 Modernizr[feature] = test; 1343 1344 } 1345 1346 return Modernizr; 1347 }; 1348 1349 1350 setCss(''); 1351 modElem = inputElem = null; 1352 1353 1354 Modernizr._version = version; 1355 1356 Modernizr._prefixes = prefixes; 1357 Modernizr._domPrefixes = domPrefixes; 1358 Modernizr._cssomPrefixes = cssomPrefixes; 1359 1360 Modernizr.mq = testMediaQuery; 1361 1362 Modernizr.hasEvent = isEventSupported; 1363 1364 Modernizr.testProp = function(prop){ 1365 return testProps([prop]); 1366 }; 1367 1368 Modernizr.testAllProps = testPropsAll; 1369 1370 1371 Modernizr.testStyles = injectElementWithStyles; docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') + 1372 1373 (enableClasses ? ' js ' + classes.join(' ') : ''); 1374 1375 return Modernizr; 1376 1377})(this, this.document); 1378/** 1379* @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 1380*/ 1381;(function(window, document) { 1382/*jshint evil:true */ 1383 /** version */ 1384 var version = '3.7.0'; 1385 1386 /** Preset options */ 1387 var options = window.html5 || {}; 1388 1389 /** Used to skip problem elements */ 1390 var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; 1391 1392 /** Not all elements can be cloned in IE **/ 1393 var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; 1394 1395 /** Detect whether the browser supports default html5 styles */ 1396 var supportsHtml5Styles; 1397 1398 /** Name of the expando, to work with multiple documents or to re-shiv one document */ 1399 var expando = '_html5shiv'; 1400 1401 /** The id for the the documents expando */ 1402 var expanID = 0; 1403 1404 /** Cached data for each document */ 1405 var expandoData = {}; 1406 1407 /** Detect whether the browser supports unknown elements */ 1408 var supportsUnknownElements; 1409 1410 (function() { 1411 try { 1412 var a = document.createElement('a'); 1413 a.innerHTML = '<xyz></xyz>'; 1414 //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles 1415 supportsHtml5Styles = ('hidden' in a); 1416 1417 supportsUnknownElements = a.childNodes.length == 1 || (function() { 1418 // assign a false positive if unable to shiv 1419 (document.createElement)('a'); 1420 var frag = document.createDocumentFragment(); 1421 return ( 1422 typeof frag.cloneNode == 'undefined' || 1423 typeof frag.createDocumentFragment == 'undefined' || 1424 typeof frag.createElement == 'undefined' 1425 ); 1426 }()); 1427 } catch(e) { 1428 // assign a false positive if detection fails => unable to shiv 1429 supportsHtml5Styles = true; 1430 supportsUnknownElements = true; 1431 } 1432 1433 }()); 1434 1435 /*--------------------------------------------------------------------------*/ 1436 1437 /** 1438 * Creates a style sheet with the given CSS text and adds it to the document. 1439 * @private 1440 * @param {Document} ownerDocument The document. 1441 * @param {String} cssText The CSS text. 1442 * @returns {StyleSheet} The style element. 1443 */ 1444 function addStyleSheet(ownerDocument, cssText) { 1445 var p = ownerDocument.createElement('p'), 1446 parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; 1447 1448 p.innerHTML = 'x<style>' + cssText + '</style>'; 1449 return parent.insertBefore(p.lastChild, parent.firstChild); 1450 } 1451 1452 /** 1453 * Returns the value of `html5.elements` as an array. 1454 * @private 1455 * @returns {Array} An array of shived element node names. 1456 */ 1457 function getElements() { 1458 var elements = html5.elements; 1459 return typeof elements == 'string' ? elements.split(' ') : elements; 1460 } 1461 1462 /** 1463 * Returns the data associated to the given document 1464 * @private 1465 * @param {Document} ownerDocument The document. 1466 * @returns {Object} An object of data. 1467 */ 1468 function getExpandoData(ownerDocument) { 1469 var data = expandoData[ownerDocument[expando]]; 1470 if (!data) { 1471 data = {}; 1472 expanID++; 1473 ownerDocument[expando] = expanID; 1474 expandoData[expanID] = data; 1475 } 1476 return data; 1477 } 1478 1479 /** 1480 * returns a shived element for the given nodeName and document 1481 * @memberOf html5 1482 * @param {String} nodeName name of the element 1483 * @param {Document} ownerDocument The context document. 1484 * @returns {Object} The shived element. 1485 */ 1486 function createElement(nodeName, ownerDocument, data){ 1487 if (!ownerDocument) { 1488 ownerDocument = document; 1489 } 1490 if(supportsUnknownElements){ 1491 return ownerDocument.createElement(nodeName); 1492 } 1493 if (!data) { 1494 data = getExpandoData(ownerDocument); 1495 } 1496 var node; 1497 1498 if (data.cache[nodeName]) { 1499 node = data.cache[nodeName].cloneNode(); 1500 } else if (saveClones.test(nodeName)) { 1501 node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); 1502 } else { 1503 node = data.createElem(nodeName); 1504 } 1505 1506 // Avoid adding some elements to fragments in IE < 9 because 1507 // * Attributes like `name` or `type` cannot be set/changed once an element 1508 // is inserted into a document/fragment 1509 // * Link elements with `src` attributes that are inaccessible, as with 1510 // a 403 response, will cause the tab/window to crash 1511 // * Script elements appended to fragments will execute when their `src` 1512 // or `text` property is set 1513 return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; 1514 } 1515 1516 /** 1517 * returns a shived DocumentFragment for the given document 1518 * @memberOf html5 1519 * @param {Document} ownerDocument The context document. 1520 * @returns {Object} The shived DocumentFragment. 1521 */ 1522 function createDocumentFragment(ownerDocument, data){ 1523 if (!ownerDocument) { 1524 ownerDocument = document; 1525 } 1526 if(supportsUnknownElements){ 1527 return ownerDocument.createDocumentFragment(); 1528 } 1529 data = data || getExpandoData(ownerDocument); 1530 var clone = data.frag.cloneNode(), 1531 i = 0, 1532 elems = getElements(), 1533 l = elems.length; 1534 for(;i<l;i++){ 1535 clone.createElement(elems[i]); 1536 } 1537 return clone; 1538 } 1539 1540 /** 1541 * Shivs the `createElement` and `createDocumentFragment` methods of the document. 1542 * @private 1543 * @param {Document|DocumentFragment} ownerDocument The document. 1544 * @param {Object} data of the document. 1545 */ 1546 function shivMethods(ownerDocument, data) { 1547 if (!data.cache) { 1548 data.cache = {}; 1549 data.createElem = ownerDocument.createElement; 1550 data.createFrag = ownerDocument.createDocumentFragment; 1551 data.frag = data.createFrag(); 1552 } 1553 1554 1555 ownerDocument.createElement = function(nodeName) { 1556 //abort shiv 1557 if (!html5.shivMethods) { 1558 return data.createElem(nodeName); 1559 } 1560 return createElement(nodeName, ownerDocument, data); 1561 }; 1562 1563 ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + 1564 'var n=f.cloneNode(),c=n.createElement;' + 1565 'h.shivMethods&&(' + 1566 // unroll the `createElement` calls 1567 getElements().join().replace(/\w+/g, function(nodeName) { 1568 data.createElem(nodeName); 1569 data.frag.createElement(nodeName); 1570 return 'c("' + nodeName + '")'; 1571 }) + 1572 ');return n}' 1573 )(html5, data.frag); 1574 } 1575 1576 /*--------------------------------------------------------------------------*/ 1577 1578 /** 1579 * Shivs the given document. 1580 * @memberOf html5 1581 * @param {Document} ownerDocument The document to shiv. 1582 * @returns {Document} The shived document. 1583 */ 1584 function shivDocument(ownerDocument) { 1585 if (!ownerDocument) { 1586 ownerDocument = document; 1587 } 1588 var data = getExpandoData(ownerDocument); 1589 1590 if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { 1591 data.hasCSS = !!addStyleSheet(ownerDocument, 1592 // corrects block display not defined in IE6/7/8/9 1593 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
1593play:block}' + 1594 // adds styling not present in IE6/7/8/9 1595 'mark{background:#FF0;color:#000}' + 1596 // hides non-rendered elements 1597 'template{display:none}' 1598 ); 1599 } 1600 if (!supportsUnknownElements) { 1601 shivMethods(ownerDocument, data); 1602 } 1603 return ownerDocument; 1604 } 1605 1606 /*--------------------------------------------------------------------------*/ 1607 1608 /** 1609 * The `html5` object is exposed so that more elements can be shived and 1610 * existing shiving can be detected on iframes. 1611 * @type Object 1612 * @example 1613 * 1614 * // options can be changed before the script is included 1615 * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; 1616 */ 1617 var html5 = { 1618 1619 /** 1620 * An array or space separated string of node names of the elements to shiv. 1621 * @memberOf html5 1622 * @type Array|String 1623 */ 1624 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video', 1625 1626 /** 1627 * current version of html5shiv 1628 */ 1629 'version': version, 1630 1631 /** 1632 * A flag to indicate that the HTML5 style sheet should be inserted. 1633 * @memberOf html5 1634 * @type Boolean 1635 */ 1636 'shivCSS': (options.shivCSS !== false), 1637 1638 /** 1639 * Is equal to true if a browser supports creating unknown/HTML5 elements 1640 * @memberOf html5 1641 * @type boolean 1642 */ 1643 'supportsUnknownElements': supportsUnknownElements, 1644 1645 /** 1646 * A flag to indicate that the document's `createElement` and `createDocumentFragment` 1647 * methods should be overwritten. 1648 * @memberOf html5 1649 * @type Boolean 1650 */ 1651 'shivMethods': (options.shivMethods !== false), 1652 1653 /** 1654 * A string to describe the type of `html5` object ("default" or "default print"). 1655 * @memberOf html5
vendor: 6,618 bytes, lines 1656-1878
1656 * @type String 1657 */ 1658 'type': 'default', 1659 1660 // shivs the document according to the specified `html5` object options 1661 'shivDocument': shivDocument, 1662 1663 //creates a shived element 1664 createElement: createElement, 1665 1666 //creates a shived documentFragment 1667 createDocumentFragment: createDocumentFragment 1668 }; 1669 1670 /*--------------------------------------------------------------------------*/ 1671 1672 // expose html5 1673 window.html5 = html5; 1674 1675 // shiv the document 1676 shivDocument(document); 1677 1678 /*------------------------------- Print Shiv -------------------------------*/ 1679 1680 /** Used to filter media types */ 1681 var reMedia = /^$|\b(?:all|print)\b/; 1682 1683 /** Used to namespace printable elements */ 1684 var shivNamespace = 'html5shiv'; 1685 1686 /** Detect whether the browser supports shivable style sheets */ 1687 var supportsShivableSheets = !supportsUnknownElements && (function() { 1688 // assign a false negative if unable to shiv 1689 var docEl = document.documentElement; 1690 return !( 1691 typeof document.namespaces == 'undefined' || 1692 typeof document.parentWindow == 'undefined' || 1693 typeof docEl.applyElement == 'undefined' || 1694 typeof docEl.removeNode == 'undefined' || 1695 typeof window.attachEvent == 'undefined' 1696 ); 1697 }()); 1698 1699 /*--------------------------------------------------------------------------*/ 1700 1701 /** 1702 * Wraps all HTML5 elements in the given document with printable elements. 1703 * (eg. the "header" element is wrapped with the "html5shiv:header" element) 1704 * @private 1705 * @param {Document} ownerDocument The document. 1706 * @returns {Array} An array wrappers added. 1707 */ 1708 function addWrappers(ownerDocument) { 1709 var node, 1710 nodes = ownerDocument.getElementsByTagName('*'), 1711 index = nodes.length, 1712 reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'), 1713 result = []; 1714 1715 while (index--) { 1716 node = nodes[index]; 1717 if (reElements.test(node.nodeName)) { 1718 result.push(node.applyElement(createWrapper(node))); 1719 } 1720 } 1721 return result; 1722 } 1723 1724 /** 1725 * Creates a printable wrapper for the given element. 1726 * @private 1727 * @param {Element} element The element. 1728 * @returns {Element} The wrapper. 1729 */ 1730 function createWrapper(element) { 1731 var node, 1732 nodes = element.attributes, 1733 index = nodes.length, 1734 wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName); 1735 1736 // copy element attributes to the wrapper 1737 while (index--) { 1738 node = nodes[index]; 1739 node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue); 1740 } 1741 // copy element styles to the wrapper 1742 wrapper.style.cssText = element.style.cssText; 1743 return wrapper; 1744 } 1745 1746 /** 1747 * Shivs the given CSS text. 1748 * (eg. header{} becomes html5shiv\:header{}) 1749 * @private 1750 * @param {String} cssText The CSS text to shiv. 1751 * @returns {String} The shived CSS text. 1752 */ 1753 function shivCssText(cssText) { 1754 var pair, 1755 parts = cssText.split('{'), 1756 index = parts.length, 1757 reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'), 1758 replacement = '$1' + shivNamespace + '\\:$2'; 1759 1760 while (index--) { 1761 pair = parts[index] = parts[index].split('}'); 1762 pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement); 1763 parts[index] = pair.join('}'); 1764 } 1765 return parts.join('{'); 1766 } 1767 1768 /** 1769 * Removes the given wrappers, leaving the original elements. 1770 * @private 1771 * @params {Array} wrappers An array of printable wrappers. 1772 */ 1773 function removeWrappers(wrappers) { 1774 var index = wrappers.length; 1775 while (index--) { 1776 wrappers[index].removeNode(); 1777 } 1778 } 1779 1780 /*--------------------------------------------------------------------------*/ 1781 1782 /** 1783 * Shivs the given document for print. 1784 * @memberOf html5 1785 * @param {Document} ownerDocument The document to shiv. 1786 * @returns {Document} The shived document. 1787 */ 1788 function shivPrint(ownerDocument) { 1789 var shivedSheet, 1790 wrappers, 1791 data = getExpandoData(ownerDocument), 1792 namespaces = ownerDocument.namespaces, 1793 ownerWindow = ownerDocument.parentWindow; 1794 1795 if (!supportsShivableSheets || ownerDocument.printShived) { 1796 return ownerDocument; 1797 } 1798 if (typeof namespaces[shivNamespace] == 'undefined') { 1799 namespaces.add(shivNamespace); 1800 } 1801 1802 function removeSheet() { 1803 clearTimeout(data._removeSheetTimer); 1804 if (shivedSheet) { 1805 shivedSheet.removeNode(true); 1806 } 1807 shivedSheet= null; 1808 } 1809 1810 ownerWindow.attachEvent('onbeforeprint', function() { 1811 1812 removeSheet(); 1813 1814 var imports, 1815 length, 1816 sheet, 1817 collection = ownerDocument.styleSheets, 1818 cssText = [], 1819 index = collection.length, 1820 sheets = Array(index); 1821 1822 // convert styleSheets collection to an array 1823 while (index--) { 1824 sheets[index] = collection[index]; 1825 } 1826 // concat all style sheet CSS text 1827 while ((sheet = sheets.pop())) { 1828 // IE does not enforce a same origin policy for external style sheets... 1829 // but has trouble with some dynamically created stylesheets 1830 if (!sheet.disabled && reMedia.test(sheet.media)) { 1831 1832 try { 1833 imports = sheet.imports; 1834 length = imports.length; 1835 } catch(er){ 1836 length = 0; 1837 } 1838 1839 for (index = 0; index < length; index++) { 1840 sheets.push(imports[index]); 1841 } 1842 1843 try { 1844 cssText.push(sheet.cssText); 1845 } catch(er){} 1846 } 1847 } 1848 1849 // wrap all HTML5 elements with printable elements and add the shived style sheet 1850 cssText = shivCssText(cssText.reverse().join('')); 1851 wrappers = addWrappers(ownerDocument); 1852 shivedSheet = addStyleSheet(ownerDocument, cssText); 1853 1854 }); 1855 1856 ownerWindow.attachEvent('onafterprint', function() { 1857 // remove wrappers, leaving the original elements, and remove the shived style sheet 1858 removeWrappers(wrappers); 1859 clearTimeout(data._removeSheetTimer); 1860 data._removeSheetTimer = setTimeout(removeSheet, 500); 1861 }); 1862 1863 ownerDocument.printShived = true; 1864 return ownerDocument; 1865 } 1866 1867 /*--------------------------------------------------------------------------*/ 1868 1869 // expose API 1870 html5.type += ' print'; 1871 html5.shivPrint = shivPrint; 1872 1873 // shiv for print 1874 shivPrint(document); 1875 1876}(this, document)); 1877/*yepnope1.5.4|WTFPL*/ 1878(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}
vendor: 4,833 bytes, lines 1878-1932
1878function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document); 1879Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0));}; 1880; 1881; 1882/*! 1883 * imagesLoaded PACKAGED v3.1.8 1884 * JavaScript is all like "You images are done yet or what?" 1885 * MIT License 1886 */ 1887 1888 1889/*! 1890 * EventEmitter v4.2.6 - git.io/ee 1891 * Oliver Caldwell 1892 * MIT license 1893 * @preserve 1894 */ 1895 1896(function () { 1897 1898 1899 /** 1900 * Class for managing events. 1901 * Can be extended to provide event functionality in other classes. 1902 * 1903 * @class EventEmitter Manages event registering and emitting. 1904 */ 1905 function EventEmitter() {} 1906 1907 // Shortcuts to improve speed and size 1908 var proto = EventEmitter.prototype; 1909 var exports = this; 1910 var originalGlobalValue = exports.EventEmitter; 1911 1912 /** 1913 * Finds the index of the listener for the event in it's storage array. 1914 * 1915 * @param {Function[]} listeners Array of listeners to search through. 1916 * @param {Function} listener Method to look for. 1917 * @return {Number} Index of the specified listener, -1 if not found 1918 * @api private 1919 */ 1920 function indexOfListener(listeners, listener) { 1921 var i = listeners.length; 1922 while (i--) { 1923 if (listeners[i].listener === listener) { 1924 return i; 1925 } 1926 } 1927 1928 return -1; 1929 } 1930 1931 /** 1932 * Alias a method while keeping the context correct, to allow for over
vendor: 11,346 bytes, lines 1932-2240
1932writing of target method. 1933 * 1934 * @param {String} name The name of the target method. 1935 * @return {Function} The aliased method 1936 * @api private 1937 */ 1938 function alias(name) { 1939 return function aliasClosure() { 1940 return this[name].apply(this, arguments); 1941 }; 1942 } 1943 1944 /** 1945 * Returns the listener array for the specified event. 1946 * Will initialise the event object and listener arrays if required. 1947 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. 1948 * Each property in the object response is an array of listener functions. 1949 * 1950 * @param {String|RegExp} evt Name of the event to return the listeners from. 1951 * @return {Function[]|Object} All listener functions for the event. 1952 */ 1953 proto.getListeners = function getListeners(evt) { 1954 var events = this._getEvents(); 1955 var response; 1956 var key; 1957 1958 // Return a concatenated array of all matching events if 1959 // the selector is a regular expression. 1960 if (typeof evt === 'object') { 1961 response = {}; 1962 for (key in events) { 1963 if (events.hasOwnProperty(key) && evt.test(key)) { 1964 response[key] = events[key]; 1965 } 1966 } 1967 } 1968 else { 1969 response = events[evt] || (events[evt] = []); 1970 } 1971 1972 return response; 1973 }; 1974 1975 /** 1976 * Takes a list of listener objects and flattens it into a list of listener functions. 1977 * 1978 * @param {Object[]} listeners Raw listener objects. 1979 * @return {Function[]} Just the listener functions. 1980 */ 1981 proto.flattenListeners = function flattenListeners(listeners) { 1982 var flatListeners = []; 1983 var i; 1984 1985 for (i = 0; i < listeners.length; i += 1) { 1986 flatListeners.push(listeners[i].listener); 1987 } 1988 1989 return flatListeners; 1990 }; 1991 1992 /** 1993 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. 1994 * 1995 * @param {String|RegExp} evt Name of the event to return the listeners from. 1996 * @return {Object} All listener functions for an event in an object. 1997 */ 1998 proto.getListenersAsObject = function getListenersAsObject(evt) { 1999 var listeners = this.getListeners(evt); 2000 var response; 2001 2002 if (listeners instanceof Array) { 2003 response = {}; 2004 response[evt] = listeners; 2005 } 2006 2007 return response || listeners; 2008 }; 2009 2010 /** 2011 * Adds a listener function to the specified event. 2012 * The listener will not be added if it is a duplicate. 2013 * If the listener returns true then it will be removed after it is called. 2014 * If you pass a regular expression as the event name then the listener will be added to all events that match it. 2015 * 2016 * @param {String|RegExp} evt Name of the event to attach the listener to. 2017 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 2018 * @return {Object} Current instance of EventEmitter for chaining. 2019 */ 2020 proto.addListener = function addListener(evt, listener) { 2021 var listeners = this.getListenersAsObject(evt); 2022 var listenerIsWrapped = typeof listener === 'object'; 2023 var key; 2024 2025 for (key in listeners) { 2026 if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { 2027 listeners[key].push(listenerIsWrapped ? listener : { 2028 listener: listener, 2029 once: false 2030 }); 2031 } 2032 } 2033 2034 return this; 2035 }; 2036 2037 /** 2038 * Alias of addListener 2039 */ 2040 proto.on = alias('addListener'); 2041 2042 /** 2043 * Semi-alias of addListener. It will add a listener that will be 2044 * automatically removed after it's first execution. 2045 * 2046 * @param {String|RegExp} evt Name of the event to attach the listener to. 2047 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 2048 * @return {Object} Current instance of EventEmitter for chaining. 2049 */ 2050 proto.addOnceListener = function addOnceListener(evt, listener) { 2051 return this.addListener(evt, { 2052 listener: listener, 2053 once: true 2054 }); 2055 }; 2056 2057 /** 2058 * Alias of addOnceListener. 2059 */ 2060 proto.once = alias('addOnceListener'); 2061 2062 /** 2063 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. 2064 * You need to tell it what event names should be matched by a regex. 2065 * 2066 * @param {String} evt Name of the event to create. 2067 * @return {Object} Current instance of EventEmitter for chaining. 2068 */ 2069 proto.defineEvent = function defineEvent(evt) { 2070 this.getListeners(evt); 2071 return this; 2072 }; 2073 2074 /** 2075 * Uses defineEvent to define multiple events. 2076 * 2077 * @param {String[]} evts An array of event names to define. 2078 * @return {Object} Current instance of EventEmitter for chaining. 2079 */ 2080 proto.defineEvents = function defineEvents(evts) { 2081 for (var i = 0; i < evts.length; i += 1) { 2082 this.defineEvent(evts[i]); 2083 } 2084 return this; 2085 }; 2086 2087 /** 2088 * Removes a listener function from the specified event. 2089 * When passed a regular expression as the event name, it will remove the listener from all events that match it. 2090 * 2091 * @param {String|RegExp} evt Name of the event to remove the listener from. 2092 * @param {Function} listener Method to remove from the event. 2093 * @return {Object} Current instance of EventEmitter for chaining. 2094 */ 2095 proto.removeListener = function removeListener(evt, listener) { 2096 var listeners = this.getListenersAsObject(evt); 2097 var index; 2098 var key; 2099 2100 for (key in listeners) { 2101 if (listeners.hasOwnProperty(key)) { 2102 index = indexOfListener(listeners[key], listener); 2103 2104 if (index !== -1) { 2105 listeners[key].splice(index, 1); 2106 } 2107 } 2108 } 2109 2110 return this; 2111 }; 2112 2113 /** 2114 * Alias of removeListener 2115 */ 2116 proto.off = alias('removeListener'); 2117 2118 /** 2119 * Adds listeners in bulk using the manipulateListeners method. 2120 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. 2121 * You can also pass it a regular expression to add the array of listeners to all events that match it. 2122 * Yeah, this function does quite a bit. That's probably a bad thing. 2123 * 2124 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. 2125 * @param {Function[]} [listeners] An optional array of listener functions to add. 2126 * @return {Object} Current instance of EventEmitter for chaining. 2127 */ 2128 proto.addListeners = function addListeners(evt, listeners) { 2129 // Pass through to manipulateListeners 2130 return this.manipulateListeners(false, evt, listeners); 2131 }; 2132 2133 /** 2134 * Removes listeners in bulk using the manipulateListeners method. 2135 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 2136 * You can also pass it an event name and an array of listeners to be removed. 2137 * You can also pass it a regular expression to remove the listeners from all events that match it. 2138 * 2139 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. 2140 * @param {Function[]} [listeners] An optional array of listener functions to remove. 2141 * @return {Object} Current instance of EventEmitter for chaining. 2142 */ 2143 proto.removeListeners = function removeListeners(evt, listeners) { 2144 // Pass through to manipulateListeners 2145 return this.manipulateListeners(true, evt, listeners); 2146 }; 2147 2148 /** 2149 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. 2150 * The first argument will determine if the listeners are removed (true) or added (false). 2151 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 2152 * You can also pass it an event name and an array of listeners to be added/removed. 2153 * You can also pass it a regular expression to manipulate the listeners of all events that match it. 2154 * 2155 * @param {Boolean} remove True if you want to remove listeners, false if you want to add. 2156 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. 2157 * @param {Function[]} [listeners] An optional array of listener functions to add/remove. 2158 * @return {Object} Current instance of EventEmitter for chaining. 2159 */ 2160 proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { 2161 var i; 2162 var value; 2163 var single = remove ? this.removeListener : this.addListener; 2164 var multiple = remove ? this.removeListeners : this.addListeners; 2165 2166 // If evt is an object then pass each of it's properties to this method 2167 if (typeof evt === 'object' && !(evt instanceof RegExp)) { 2168 for (i in evt) { 2169 if (evt.hasOwnProperty(i) && (value = evt[i])) { 2170 // Pass the single listener straight through to the singular method 2171 if (typeof value === 'function') { 2172 single.call(this, i, value); 2173 } 2174 else { 2175 // Otherwise pass back to the multiple function 2176 multiple.call(this, i, value); 2177 } 2178 } 2179 } 2180 } 2181 else { 2182 // So evt must be a string 2183 // And listeners must be an array of listeners 2184 // Loop over it and pass each one to the multiple method 2185 i = listeners.length; 2186 while (i--) { 2187 single.call(this, evt, listeners[i]); 2188 } 2189 } 2190 2191 return this; 2192 }; 2193 2194 /** 2195 * Removes all listeners from a specified event. 2196 * If you do not specify an event then all listeners will be removed. 2197 * That means every event will be emptied. 2198 * You can also pass a regex to remove all events that match it. 2199 * 2200 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. 2201 * @return {Object} Current instance of EventEmitter for chaining. 2202 */ 2203 proto.removeEvent = function removeEvent(evt) { 2204 var type = typeof evt; 2205 var events = this._getEvents(); 2206 var key; 2207 2208 // Remove different things depending on the state of evt 2209 if (type === 'string') { 2210 // Remove all listeners for the specified event 2211 delete events[evt]; 2212 } 2213 else if (type === 'object') { 2214 // Remove all events matching the regex. 2215 for (key in events) { 2216 if (events.hasOwnProperty(key) && evt.test(key)) { 2217 delete events[key]; 2218 } 2219 } 2220 } 2221 else { 2222 // Remove all listeners in all events 2223 delete this._events; 2224 } 2225 2226 return this; 2227 }; 2228 2229 /** 2230 * Alias of removeEvent. 2231 * 2232 * Added to mirror the node API. 2233 */ 2234 proto.removeAllListeners = alias('removeEvent'); 2235 2236 /** 2237 * Emits an event of your choice. 2238 * When emitted, every listener attached to that event will be executed. 2239 * If you pass the optional argument array then those arguments will be passed to every listener upon execution. 2240 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
2241 * So they will not arrive within the array on the other side, they will be separate. 2242 * You can also pass a regular expression to emit to all events that match it. 2243 * 2244 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 2245 * @param {Array} [args] Optional array of arguments to be passed to each listener. 2246 * @return {Object} Current instance of EventEmitter for chaining. 2247 */ 2248 proto.emitEvent = function emitEvent(evt, args) { 2249 var listeners = this.getListenersAsObject(evt); 2250 var listener; 2251 var i; 2252 var key; 2253 var response; 2254 2255 for (key in listeners) { 2256 if (listeners.hasOwnProperty(key)) { 2257 i = listeners[key].length; 2258 2259 while (i--) { 2260 // If the listener returns true then it shall be removed from the event 2261 // The function is executed either with a basic call or an apply if there is an args array 2262 listener = listeners[key][i]; 2263 2264 if (listener.once === true) { 2265 this.removeListener(evt, listener.listener); 2266 } 2267 2268 response = listener.listener.apply(this, args || []); 2269 2270 if (response === this._getOnceReturnValue()) { 2271 this.removeListener(evt, listener.listener); 2272 } 2273 } 2274 } 2275 } 2276 2277 return this; 2278 }; 2279 2280 /** 2281 * Alias of emitEvent 2282 */ 2283 proto.trigger = alias('emitEvent'); 2284 2285 /** 2286 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. 2287 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. 2288 * 2289 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 2290 * @param {...*} Optional additional arguments to be passed to each listener. 2291 * @return {Object} Current instance of EventEmitter for chaining. 2292 */ 2293 proto.emit = function emit(evt) { 2294 var args = Array.prototype.slice.call(arguments, 1); 2295 return this.emitEvent(evt, args); 2296 }; 2297 2298 /** 2299 * Sets the current value to check against when executing listeners. If a 2300 * listeners return value matches the one set here then it will be removed 2301 * after execution. This value defaults to true. 2302 * 2303 * @param {*} value The new value to check for when executing listeners. 2304 * @return {Object} Current instance of EventEmitter for chaining. 2305 */ 2306 proto.setOnceReturnValue = function setOnceReturnValue(value) { 2307 this._onceReturnValue = value; 2308 return this; 2309 }; 2310 2311 /** 2312 * Fetches the current value to check against when executing listeners. If 2313 * the listeners return value matches this one then it should be removed 2314 * automatically. It will return true by default. 2315 * 2316 * @return {*|Boolean} The current value to check for or the default, true. 2317 * @api private 2318 */ 2319 proto._getOnceReturnValue = function _getOnceReturnValue() { 2320 if (this.hasOwnProperty('_onceReturnValue')) { 2321 return this._onceReturnValue; 2322 } 2323 else { 2324 return true; 2325 } 2326 }; 2327 2328 /** 2329 * Fetches the events object and creates one if required. 2330 * 2331 * @return {Object} The events storage object. 2332 * @api private 2333 */ 2334 proto._getEvents = function _getEvents() { 2335 return this._events || (this._events = {}); 2336 }; 2337 2338 /** 2339 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. 2340 * 2341 * @return {Function} Non conflicting EventEmitter class. 2342 */ 2343 EventEmitter.noConflict = function noConflict() { 2344 exports.EventEmitter = originalGlobalValue; 2345 return EventEmitter; 2346 }; 2347 2348 // Expose the class either via AMD, CommonJS or the global object 2349 if (typeof define === 'function' && define.amd) { 2350 define('eventEmitter/EventEmitter',[],function () { 2351 return EventEmitter; 2352 }); 2353 } 2354 else if (typeof module === 'object' && module.exports){ 2355 module.exports = EventEmitter; 2356 } 2357 else { 2358 this.EventEmitter = EventEmitter; 2359 } 2360}.call(this)); 2361 2362/*! 2363 * eventie v1.0.4 2364 * event binding helper 2365 * eventie.bind( elem, 'click', myFn ) 2366 * eventie.unbind( elem, 'click', myFn ) 2367 */ 2368 2369/*jshint browser: true, undef: true, unused: true */ 2370/*global define: false */ 2371 2372( function( window ) { 2373 2374 2375 2376var docElem = document.documentElement; 2377 2378var bind = function() {}; 2379 2380function getIEEvent( obj ) { 2381 var event = window.event; 2382 // add event.target 2383 event.target = event.target || event.srcElement || obj; 2384 return event; 2385} 2386 2387if ( docElem.addEventListener ) { 2388 bind = function( obj, type, fn ) { 2389 obj.addEventListener( type, fn, false ); 2390 }; 2391} else if ( docElem.attachEvent ) { 2392 bind = function( obj, type, fn ) { 2393 obj[ type + fn ] = fn.handleEvent ? 2394 function() { 2395 var event = getIEEvent( obj ); 2396 fn.handleEvent.call( fn, event ); 2397 } : 2398 function() { 2399 var event = getIEEvent( obj ); 2400 fn.call( obj, event ); 2401 }; 2402 obj.attachEvent( "on" + type, obj[ type + fn ] ); 2403 }; 2404} 2405 2406var unbind = function() {}; 2407 2408if ( docElem.removeEventListener ) { 2409 unbind = function( obj, type, fn ) { 2410 obj.removeEventListener( type, fn, false ); 2411 }; 2412} else if ( docElem.detachEvent ) { 2413 unbind = function( obj, type, fn ) { 2414 obj.detachEvent( "on" + type, obj[ type + fn ] ); 2415 try { 2416 delete obj[ type + fn ]; 2417 } catch ( err ) { 2418 // can't delete window object properties 2419 obj[ type + fn ] = undefined; 2420 } 2421 }; 2422} 2423 2424var eventie = { 2425 bind: bind, 2426 unbind: unbind 2427}; 2428 2429// transport 2430if ( typeof define === 'function' && define.amd ) { 2431 // AMD 2432 define( 'eventie/eventie',eventie ); 2433} else { 2434 // browser global 2435 window.eventie = eventie; 2436} 2437 2438})( this ); 2439 2440/*! 2441 * imagesLoaded v3.1.8 2442 * JavaScript is all like "You images are done yet or what?" 2443 * MIT License 2444 */ 2445 2446( function( window, factory ) { 2447 // universal module definition 2448 2449 /*global define: false, module: false, require: false */ 2450 2451 if ( typeof define === 'function' && define.amd ) { 2452 // AMD 2453 define( [ 2454 'eventEmitter/EventEmitter', 2455 'eventie/eventie' 2456 ], function( EventEmitter, eventie ) { 2457 return factory( window, EventEmitter, eventie ); 2458 }); 2459 } else if ( typeof exports === 'object' ) { 2460 // CommonJS 2461 module.exports = factory( 2462 window, 2463 require('wolfy87-eventemitter'), 2464 require('eventie') 2465 ); 2466 } else { 2467 // browser global 2468 window.imagesLoaded = factory( 2469 window, 2470 window.EventEmitter, 2471 window.eventie 2472 ); 2473 } 2474 2475})( window, 2476 2477// -------------------------- factory -------------------------- // 2478 2479function factory( window, EventEmitter, eventie ) { 2480 2481 2482 2483var $ = window.jQuery; 2484var console = window.console; 2485var hasConsole = typeof console !== 'undefined'; 2486 2487// -------------------------- helpers -------------------------- // 2488 2489// extend objects 2490function extend( a, b ) { 2491 for ( var prop in b ) { 2492 a[ prop ] = b[ prop ]; 2493 } 2494 return a; 2495} 2496 2497var objToString = Object.prototype.toString; 2498function isArray( obj ) { 2499 return objToString.call( obj ) === '[object Array]'; 2500} 2501 2502// turn element or nodeList into an array 2503function makeArray( obj ) { 2504 var ary = []; 2505 if ( isArray( obj ) ) { 2506 // use object if already an array 2507 ary = obj; 2508 } else if ( typeof obj.length === 'number' ) { 2509 // convert nodeList to array 2510 for ( var i=0, len = obj.length; i < len; i++ ) { 2511 ary.push( obj[i] ); 2512 } 2513 } else { 2514 // array of single index 2515 ary.push( obj ); 2516 } 2517 return ary; 2518} 2519 2520 // -------------------------- imagesLoaded -------------------------- // 2521 2522 /** 2523 * @param {Array, Element, NodeList, String} elem 2524 * @param {Object or Function} options - if function, use as callback 2525 * @param {Function} onAlways - callback function 2526 */ 2527 function ImagesLoaded( elem, options, onAlways ) { 2528 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 2529 if ( !( this instanceof ImagesLoaded ) ) { 2530 return new ImagesLoaded( elem, options ); 2531 } 2532 // use elem as selector string 2533 if ( typeof elem === 'string' ) { 2534 elem = document.querySelectorAll( elem ); 2535 } 2536 2537 this.elements = makeArray( elem ); 2538 this.options = extend( {}, this.options ); 2539 2540 if ( typeof options === 'function' ) { 2541 onAlways = options; 2542 } else { 2543 extend( this.options, options ); 2544 } 2545 2546 if ( onAlways ) { 2547 this.on( 'always', onAlways ); 2548 } 2549 2550 this.getImages(); 2551 2552 if ( $ ) { 2553 // add jQuery Deferred object 2554 this.jqDeferred = new $.Deferred(); 2555 } 2556 2557 // HACK check async to allow time to bind listeners 2558 var _this = this; 2559 setTimeout( function() { 2560 _this.check(); 2561 }); 2562 } 2563 2564 ImagesLoaded.prototype = new EventEmitter(); 2565 2566 ImagesLoaded.prototype.options = {}; 2567 2568 ImagesLoaded.prototype.getImages = function() { 2569 this.images = []; 2570 2571 // filter & find items if we have an item selector 2572 for ( var i=0, len = this.elements.length; i < len; i++ ) { 2573 var elem = this.elements[i]; 2574 // filter siblings 2575 if ( elem.nodeName === 'IMG' ) { 2576 this.addImage( elem ); 2577 } 2578 // find children 2579 // no non-element nodes, #143 2580 var nodeType = elem.nodeType; 2581 if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) { 2582 continue; 2583 } 2584 var childElems = elem.querySelectorAll('img'); 2585 // concat childElems to filterFound array 2586 for ( var j=0, jLen = childElems.length; j < jLen; j++ ) { 2587 var img = childElems[j]; 2588 this.addImage( img ); 2589 } 2590 } 2591 }; 2592 2593 /** 2594 * @param {Image} img 2595 */ 2596 ImagesLoaded.prototype.addImage = function( img ) { 2597 var loadingImage = new LoadingImage( img ); 2598 this.images.push( loadingImage ); 2599 }; 2600
2601 ImagesLoaded.prototype.check = function() { 2602 var _this = this; 2603 var checkedCount = 0; 2604 var length = this.images.length; 2605 this.hasAnyBroken = false; 2606 // complete if no images 2607 if ( !length ) { 2608 this.complete(); 2609 return; 2610 } 2611 2612 function onConfirm( image, message ) { 2613 if ( _this.options.debug && hasConsole ) { 2614 console.log( 'confirm', image, message ); 2615 } 2616 2617 _this.progress( image ); 2618 checkedCount++; 2619 if ( checkedCount === length ) { 2620 _this.complete(); 2621 } 2622 return true; // bind once 2623 } 2624 2625 for ( var i=0; i < length; i++ ) { 2626 var loadingImage = this.images[i]; 2627 loadingImage.on( 'confirm', onConfirm ); 2628 loadingImage.check(); 2629 } 2630 }; 2631 2632 ImagesLoaded.prototype.progress = function( image ) { 2633 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 2634 // HACK - Chrome triggers event before object properties have changed. #83 2635 var _this = this; 2636 setTimeout( function() { 2637 _this.emit( 'progress', _this, image ); 2638 if ( _this.jqDeferred && _this.jqDeferred.notify ) { 2639 _this.jqDeferred.notify( _this, image ); 2640 } 2641 }); 2642 }; 2643 2644 ImagesLoaded.prototype.complete = function() { 2645 var eventName = this.hasAnyBroken ? 'fail' : 'done'; 2646 this.isComplete = true; 2647 var _this = this; 2648 // HACK - another setTimeout so that confirm happens after progress 2649 setTimeout( function() { 2650 _this.emit( eventName, _this ); 2651 _this.emit( 'always', _this ); 2652 if ( _this.jqDeferred ) { 2653 var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve'; 2654 _this.jqDeferred[ jqMethod ]( _this ); 2655 } 2656 }); 2657 }; 2658 2659 // -------------------------- jquery -------------------------- // 2660 2661 if ( $ ) { 2662 $.fn.imagesLoaded = function( options, callback ) { 2663 var instance = new ImagesLoaded( this, options, callback ); 2664 return instance.jqDeferred.promise( $(this) ); 2665 }; 2666 } 2667 2668 2669 // -------------------------- -------------------------- // 2670 2671 function LoadingImage( img ) { 2672 this.img = img; 2673 } 2674 2675 LoadingImage.prototype = new EventEmitter(); 2676 2677 LoadingImage.prototype.check = function() { 2678 // first check cached any previous images that have same src 2679 var resource = cache[ this.img.src ] || new Resource( this.img.src ); 2680 if ( resource.isConfirmed ) { 2681 this.confirm( resource.isLoaded, 'cached was confirmed' ); 2682 return; 2683 } 2684 2685 // If complete is true and browser supports natural sizes, 2686 // try to check for image status manually. 2687 if ( this.img.complete && this.img.naturalWidth !== undefined ) { 2688 // report based on naturalWidth 2689 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 2690 return; 2691 } 2692 2693 // If none of the checks above matched, simulate loading on detached element. 2694 var _this = this; 2695 resource.on( 'confirm', function( resrc, message ) { 2696 _this.confirm( resrc.isLoaded, message ); 2697 return true; 2698 }); 2699 2700 resource.check(); 2701 }; 2702 2703 LoadingImage.prototype.confirm = function( isLoaded, message ) { 2704 this.isLoaded = isLoaded; 2705 this.emit( 'confirm', this, message ); 2706 }; 2707 2708 // -------------------------- Resource -------------------------- // 2709 2710 // Resource checks each src, only once 2711 // separate class from LoadingImage to prevent memory leaks. See #115 2712 2713 var cache = {}; 2714 2715 function Resource( src ) { 2716 this.src = src; 2717 // add to cache 2718 cache[ src ] = this; 2719 } 2720 2721 Resource.prototype = new EventEmitter(); 2722 2723 Resource.prototype.check = function() { 2724 // only trigger checking once 2725 if ( this.isChecked ) { 2726 return; 2727 } 2728 // simulate loading on detached element 2729 var proxyImage = new Image(); 2730 eventie.bind( proxyImage, 'load', this ); 2731 eventie.bind( proxyImage, 'error', this ); 2732 proxyImage.src = this.src; 2733 // set flag 2734 this.isChecked = true; 2735 }; 2736 2737 // ----- events ----- // 2738 2739 // trigger specified handler for event type 2740 Resource.prototype.handleEvent = function( event ) { 2741 var method = 'on' + event.type; 2742 if ( this[ method ] ) { 2743 this[ method ]( event ); 2744 } 2745 }; 2746 2747 Resource.prototype.onload = function( event ) { 2748 this.confirm( true, 'onload' ); 2749 this.unbindProxyEvents( event ); 2750 }; 2751 2752 Resource.prototype.onerror = function( event ) { 2753 this.confirm( false, 'onerror' ); 2754 this.unbindProxyEvents( event ); 2755 }; 2756 2757 // ----- confirm ----- // 2758 2759 Resource.prototype.confirm = function( isLoaded, message ) { 2760 this.isConfirmed = true; 2761 this.isLoaded = isLoaded;
2762 this.emit( 'confirm', this, message ); 2763 }; 2764 2765 Resource.prototype.unbindProxyEvents = function( event ) { 2766 eventie.unbind( event.target, 'load', this ); 2767 eventie.unbind( event.target, 'error', this ); 2768 }; 2769 2770 // ----- ----- // 2771 2772 return ImagesLoaded; 2773 2774}); 2775; 2776/*! 2777Waypoints - 4.0.1 2778Copyright © 2011-2016 Caleb Troughton 2779Licensed under the MIT license. 2780https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 2781*/ 2782(function() { 2783 'use strict' 2784 2785 var keyCounter = 0 2786 var allWaypoints = {} 2787 2788 /* http://imakewebthings.com/waypoints/api/waypoint */ 2789 function Waypoint(options) { 2790 if (!options) { 2791 throw new Error('No options passed to Waypoint constructor') 2792 } 2793 if (!options.element) { 2794 throw new Error('No element option passed to Waypoint constructor') 2795 } 2796 if (!options.handler) { 2797 throw new Error('No handler option passed to Waypoint constructor') 2798 } 2799 2800 this.key = 'waypoint-' + keyCounter 2801 this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) 2802 this.element = this.options.element 2803 this.adapter = new Waypoint.Adapter(this.element) 2804 this.callback = options.handler 2805 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 2806 this.enabled = this.options.enabled 2807 this.triggerPoint = null 2808 this.group = Waypoint.Group.findOrCreate({ 2809 name: this.options.group, 2810 axis: this.axis 2811 }) 2812 this.context = Waypoint.Context.findOrCreateByElement(this.options.context) 2813 2814 if (Waypoint.offsetAliases[this.options.offset]) { 2815 this.options.offset = Waypoint.offsetAliases[this.options.offset] 2816 } 2817 this.group.add(this) 2818 this.context.add(this) 2819 allWaypoints[this.key] = this 2820 keyCounter += 1 2821 } 2822 2823 /* Private */ 2824 Waypoint.prototype.queueTrigger = function(direction) { 2825 this.group.queueTrigger(this, direction) 2826 } 2827 2828 /* Private */ 2829 Waypoint.prototype.trigger = function(args) { 2830 if (!this.enabled) { 2831 return 2832 } 2833 if (this.callback) { 2834 this.callback.apply(this, args) 2835 } 2836 } 2837 2838 /* Public */ 2839 /* http://imakewebthings.com/waypoints/api/destroy */ 2840 Waypoint.prototype.destroy = function() { 2841 this.context.remove(this) 2842 this.group.remove(this) 2843 delete allWaypoints[this.key] 2844 } 2845 2846 /* Public */ 2847 /* http://imakewebthings.com/waypoints/api/disable */ 2848 Waypoint.prototype.disable = function() { 2849 this.enabled = false 2850 return this 2851 } 2852 2853 /* Public */ 2854 /* http://imakewebthings.com/waypoints/api/enable */ 2855 Waypoint.prototype.enable = function() { 2856 this.context.refresh() 2857 this.enabled = true 2858 return this 2859 } 2860 2861 /* Public */ 2862 /* http://imakewebthings.com/waypoints/api/next */ 2863 Waypoint.prototype.next = function() { 2864 return this.group.next(this) 2865 } 2866 2867 /* Public */ 2868 /* http://imakewebthings.com/waypoints/api/previous */ 2869 Waypoint.prototype.previous = function() { 2870 return this.group.previous(this) 2871 } 2872 2873 /* Private */ 2874 Waypoint.invokeAll = function(method) { 2875 var allWaypointsArray = []
2876 for (var waypointKey in allWaypoints) { 2877 allWaypointsArray.push(allWaypoints[waypointKey]) 2878 } 2879 for (var i = 0, end = allWaypointsArray.length; i < end; i++) { 2880 allWaypointsArray[i][method]() 2881 } 2882 } 2883 2884 /* Public */ 2885 /* http://imakewebthings.com/waypoints/api/destroy-all */ 2886 Waypoint.destroyAll = function() { 2887 Waypoint.invokeAll('destroy') 2888 } 2889 2890 /* Public */ 2891 /* http://imakewebthings.com/waypoints/api/disable-all */ 2892 Waypoint.disableAll = function() { 2893 Waypoint.invokeAll('disable') 2894 } 2895 2896 /* Public */ 2897 /* http://imakewebthings.com/waypoints/api/enable-all */ 2898 Waypoint.enableAll = function() { 2899 Waypoint.Context.refreshAll() 2900 for (var waypointKey in allWaypoints) { 2901 allWaypoints[waypointKey].enabled = true 2902 } 2903 return this 2904 } 2905 2906 /* Public */ 2907 /* http://imakewebthings.com/waypoints/api/refresh-all */ 2908 Waypoint.refreshAll = function() { 2909 Waypoint.Context.refreshAll() 2910 } 2911 2912 /* Public */ 2913 /* http://imakewebthings.com/waypoints/api/viewport-height */ 2914 Waypoint.viewportHeight = function() { 2915 return window.innerHeight || document.documentElement.clientHeight 2916 } 2917 2918 /* Public */ 2919 /* http://imakewebthings.com/waypoints/api/viewport-width */ 2920 Waypoint.viewportWidth = function() { 2921 return document.documentElement.clientWidth 2922 } 2923 2924 Waypoint.adapters = [] 2925 2926 Waypoint.defaults = { 2927 context: window, 2928 continuous: true, 2929 enabled: true, 2930 group: 'default', 2931 horizontal: false, 2932 offset: 0 2933 } 2934 2935 Waypoint.offsetAliases = { 2936 'bottom-in-view': function() { 2937 return this.context.innerHeight() - this.adapter.outerHeight() 2938 }, 2939 'right-in-view': function() { 2940 return this.context.innerWidth() - this.adapter.outerWidth() 2941 } 2942 } 2943 2944 window.Waypoint = Waypoint 2945}()) 2946;(function() { 2947 'use strict' 2948 2949 function requestAnimationFrameShim(callback) { 2950 window.setTimeout(callback, 1000 / 60) 2951 } 2952 2953 var keyCounter = 0 2954 var contexts = {} 2955 var Waypoint = window.Waypoint 2956 var oldWindowLoad = window.onload 2957 2958 /* http://imakewebthings.com/waypoints/api/context */ 2959 function Context(element) { 2960 this.element = element 2961 this.Adapter = Waypoint.Adapter 2962 this.adapter = new this.Adapter(element) 2963 this.key = 'waypoint-context-' + keyCounter 2964 this.didScroll = false 2965 this.didResize = false 2966 this.oldScroll = { 2967 x: this.adapter.scrollLeft(), 2968 y: this.adapter.scrollTop() 2969 } 2970 this.waypoints = { 2971 vertical: {}, 2972 horizontal: {} 2973 } 2974 2975 element.waypointContextKey = this.key 2976 contexts[element.waypointContextKey] = this 2977 keyCounter += 1 2978 if (!Waypoint.windowContext) { 2979 Waypoint.windowContext = true 2980 Waypoint.windowContext = new Context(window) 2981 } 2982 2983 this.createThrottledScrollHandler() 2984 this.createThrottledResizeHandler() 2985 } 2986 2987 /* Private */ 2988 Context.prototype.add = function(waypoint) { 2989 var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' 2990 this.waypoints[axis][waypoint.key] = waypoint 2991 this.refresh() 2992 } 2993 2994 /* Private */ 2995 Context.prototype.checkEmpty = function() { 2996 var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) 2997 var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) 2998 var isWindow = this.element == this.element.window 2999 if (horizontalEmpty && verticalEmpty && !isWindow) { 3000 this.adapter.off('.waypoints') 3001 delete contexts[this.key] 3002 } 3003 } 3004 3005 /* Private */ 3006 Context.prototype.createThrottledResizeHandler = function() { 3007 var self = this 3008 3009 function resizeHandler() { 3010 self.handleResize() 3011 self.didResize = false 3012 } 3013 3014 this.adapter.on('resize.waypoints', function() { 3015 if (!self.didResize) { 3016 self.didResize = true 3017 Waypoint.requestAnimationFrame(resizeHandler) 3018 } 3019 }) 3020 } 3021 3022 /* Private */ 3023 Context.prototype.createThrottledScrollHandler = function() { 3024 var self = this 3025 function scrollHandler() { 3026 self.handleScroll() 3027 self.didScroll = false 3028 } 3029 3030 this.adapter.on('scroll.waypoints', function() { 3031 if (!self.didScroll || Waypoint.isTouch) { 3032 self.didScroll = true 3033 Waypoint.requestAnimationFrame(scrollHandler) 3034 } 3035 }) 3036 } 3037 3038 /* Private */ 3039 Context.prototype.handleResize = function() { 3040 Waypoint.Context.refreshAll() 3041 } 3042 3043 /* Private */ 3044 Context.prototype.handleScroll = function() { 3045 var triggeredGroups = {} 3046 var axes = { 3047 horizontal: { 3048 newScroll: this.adapter.scrollLeft(), 3049 oldScroll: this.oldScroll.x, 3050 forward: 'right', 3051 backward: 'left' 3052 }, 3053 vertical: { 3054 newScroll: this.adapter.scrollTop(), 3055 oldScroll: this.oldScroll.y, 3056 forward: 'down', 3057 backward: 'up' 3058 } 3059 } 3060 3061 for (var axisKey in axes) { 3062 var axis = axes[axisKey] 3063 var isForward = axis.newScroll > axis.oldScroll 3064 var direction = isForward ? axis.forward : axis.backward 3065
3066 for (var waypointKey in this.waypoints[axisKey]) { 3067 var waypoint = this.waypoints[axisKey][waypointKey] 3068 if (waypoint.triggerPoint === null) { 3069 continue 3070 } 3071 var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint 3072 var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint 3073 var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint 3074 var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint 3075 if (crossedForward || crossedBackward) { 3076 waypoint.queueTrigger(direction) 3077 triggeredGroups[waypoint.group.id] = waypoint.group 3078 } 3079 } 3080 } 3081 3082 for (var groupKey in triggeredGroups) { 3083 triggeredGroups[groupKey].flushTriggers() 3084 } 3085 3086 this.oldScroll = { 3087 x: axes.horizontal.newScroll, 3088 y: axes.vertical.newScroll 3089 } 3090 } 3091 3092 /* Private */ 3093 Context.prototype.innerHeight = function() { 3094 /*eslint-disable eqeqeq */ 3095 if (this.element == this.element.window) { 3096 return Waypoint.viewportHeight() 3097 } 3098 /*eslint-enable eqeqeq */ 3099 return this.adapter.innerHeight() 3100 } 3101 3102 /* Private */ 3103 Context.prototype.remove = function(waypoint) { 3104 delete this.waypoints[waypoint.axis][waypoint.key] 3105 this.checkEmpty() 3106 } 3107 3108 /* Private */ 3109 Context.prototype.innerWidth = function() { 3110 /*eslint-disable eqeqeq */ 3111 if (this.element == this.element.window) { 3112 return Waypoint.viewportWidth() 3113 } 3114 /*eslint-enable eqeqeq */ 3115 return this.adapter.innerWidth() 3116 } 3117 3118 /* Public */ 3119 /* http://imakewebthings.com/waypoints/api/context-destroy */ 3120 Context.prototype.destroy = function() { 3121 var allWaypoints = [] 3122 for (var axis in this.waypoints) {
3123 for (var waypointKey in this.waypoints[axis]) { 3124 allWaypoints.push(this.waypoints[axis][waypointKey]) 3125 } 3126 } 3127 for (var i = 0, end = allWaypoints.length; i < end; i++) { 3128 allWaypoints[i].destroy() 3129 } 3130 } 3131 3132 /* Public */ 3133 /* http://imakewebthings.com/waypoints/api/context-refresh */ 3134 Context.prototype.refresh = function() { 3135 /*eslint-disable eqeqeq */ 3136 var isWindow = this.element == this.element.window 3137 /*eslint-enable eqeqeq */ 3138 var contextOffset = isWindow ? undefined : this.adapter.offset() 3139 var triggeredGroups = {} 3140 var axes 3141 3142 this.handleScroll() 3143 axes = { 3144 horizontal: { 3145 contextOffset: isWindow ? 0 : contextOffset.left, 3146 contextScroll: isWindow ? 0 : this.oldScroll.x, 3147 contextDimension: this.innerWidth(), 3148 oldScroll: this.oldScroll.x, 3149 forward: 'right', 3150 backward: 'left', 3151 offsetProp: 'left' 3152 }, 3153 vertical: { 3154 contextOffset: isWindow ? 0 : contextOffset.top, 3155 contextScroll: isWindow ? 0 : this.oldScroll.y, 3156 contextDimension: this.innerHeight(), 3157 oldScroll: this.oldScroll.y, 3158 forward: 'down', 3159 backward: 'up', 3160 offsetProp: 'top' 3161 } 3162 } 3163 3164 for (var axisKey in axes) { 3165 var axis = axes[axisKey]
3166 for (var waypointKey in this.waypoints[axisKey]) { 3167 var waypoint = this.waypoints[axisKey][waypointKey] 3168 var adjustment = waypoint.options.offset 3169 var oldTriggerPoint = waypoint.triggerPoint 3170 var elementOffset = 0 3171 var freshWaypoint = oldTriggerPoint == null 3172 var contextModifier, wasBeforeScroll, nowAfterScroll 3173 var triggeredBackward, triggeredForward 3174 3175 if (waypoint.element !== waypoint.element.window) { 3176 elementOffset = waypoint.adapter.offset()[axis.offsetProp] 3177 } 3178 3179 if (typeof adjustment === 'function') { 3180 adjustment = adjustment.apply(waypoint) 3181 } 3182 else if (typeof adjustment === 'string') { 3183 adjustment = parseFloat(adjustment) 3184 if (waypoint.options.offset.indexOf('%') > - 1) { 3185 adjustment = Math.ceil(axis.contextDimension * adjustment / 100) 3186 } 3187 } 3188 3189 contextModifier = axis.contextScroll - axis.contextOffset 3190 waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment) 3191 wasBeforeScroll = oldTriggerPoint < axis.oldScroll 3192 nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll 3193 triggeredBackward = wasBeforeScroll && nowAfterScroll 3194 triggeredForward = !wasBeforeScroll && !nowAfterScroll 3195 3196 if (!freshWaypoint && triggeredBackward) { 3197 waypoint.queueTrigger(axis.backward) 3198 triggeredGroups[waypoint.group.id] = waypoint.group 3199 } 3200 else if (!freshWaypoint && triggeredForward) { 3201 waypoint.queueTrigger(axis.forward) 3202 triggeredGroups[waypoint.group.id] = waypoint.group 3203 } 3204 else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { 3205 waypoint.queueTrigger(axis.forward) 3206 triggeredGroups[waypoint.group.id] = waypoint.group 3207 } 3208 } 3209 } 3210 3211 Waypoint.requestAnimationFrame(function() { 3212 for (var groupKey in triggeredGroups) { 3213 triggeredGroups[groupKey].flushTriggers() 3214 } 3215 }) 3216 3217 return this 3218 } 3219 3220 /* Private */ 3221 Context.findOrCreateByElement = function(element) { 3222 return Context.findByElement(element) || new Context(element) 3223 } 3224 3225 /* Private */ 3226 Context.refreshAll = function() { 3227 for (var contextId in contexts) { 3228 contexts[contextId].refresh() 3229 } 3230 } 3231 3232 /* Public */ 3233 /* http://imakewebthings.com/waypoints/api/context-find-by-element */ 3234 Context.findByElement = function(element) { 3235 return contexts[element.waypointContextKey] 3236 } 3237 3238 window.onload = function() { 3239 if (oldWindowLoad) { 3240 oldWindowLoad() 3241 } 3242 Context.refreshAll() 3243 } 3244 3245 3246 Waypoint.requestAnimationFrame = function(callback) { 3247 var requestFn = window.requestAnimationFrame || 3248 window.mozRequestAnimationFrame || 3249 window.webkitRequestAnimationFrame || 3250 requestAnimationFrameShim 3251 requestFn.call(window, callback) 3252 } 3253 Waypoint.Context = Context 3254}()) 3255;(function() { 3256 'use strict' 3257 3258 function byTriggerPoint(a, b) { 3259 return a.triggerPoint - b.triggerPoint 3260 } 3261 3262 function byReverseTriggerPoint(a, b) { 3263 return b.triggerPoint - a.triggerPoint 3264 } 3265 3266 var groups = { 3267 vertical: {}, 3268 horizontal: {} 3269 } 3270 var Waypoint = window.Waypoint 3271 3272 /* http://imakewebthings.com/waypoints/api/group */ 3273 function Group(options) { 3274 this.name = options.name 3275 this.axis = options.axis 3276 this.id = this.name + '-' + this.axis 3277 this.waypoints = [] 3278 this.clearTriggerQueues() 3279 groups[this.axis][this.name] = this 3280 } 3281 3282 /* Private */ 3283 Group.prototype.add = function(waypoint) { 3284 this.waypoints.push(waypoint) 3285 } 3286 3287 /* Private */ 3288 Group.prototype.clearTriggerQueues = function() { 3289 this.triggerQueues = { 3290 up: [], 3291 down: [], 3292 left: [], 3293 right: [] 3294 } 3295 } 3296 3297 /* Private */ 3298 Group.prototype.flushTriggers = function() { 3299 for (var direction in this.triggerQueues) { 3300 var waypoints = this.triggerQueues[direction] 3301 var reverse = direction === 'up' || direction === 'left' 3302 waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) 3303 for (var i = 0, end = waypoints.length; i < end; i += 1) { 3304 var waypoint = waypoints[i] 3305 if (waypoint.options.continuous || i === waypoints.length - 1) { 3306 waypoint.trigger([direction]) 3307 } 3308 } 3309 } 3310 this.clearTriggerQueues() 3311 } 3312 3313 /* Private */ 3314 Group.prototype.next = function(waypoint) { 3315 this.waypoints.sort(byTriggerPoint) 3316 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 3317 var isLast = index === this.waypoints.length - 1 3318 return isLast ? null : this.waypoints[index + 1] 3319 } 3320 3321 /* Private */ 3322 Group.prototype.previous = function(waypoint) { 3323 this.waypoints.sort(byTriggerPoint) 3324 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 3325 return index ? this.waypoints[index - 1] : null 3326 } 3327 3328 /* Private */ 3329 Group.prototype.queueTrigger = function(waypoint, direction) { 3330 this.triggerQueues[direction].push(waypoint) 3331 } 3332 3333 /* Private */ 3334 Group.prototype.remove = function(waypoint) { 3335 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 3336 if (index > -1) { 3337 this.waypoints.splice(index, 1) 3338 } 3339 } 3340 3341 /* Public */ 3342 /* http://imakewebthings.com/waypoints/api/first */ 3343 Group.prototype.first = function() { 3344 return this.waypoints[0] 3345 } 3346 3347 /* Public */ 3348 /* http://imakewebthings.com/waypoints/api/last */ 3349 Group.prototype.last = function() { 3350 return this.waypoints[this.waypoints.length - 1] 3351 } 3352 3353 /* Private */ 3354 Group.findOrCreate = function(options) { 3355 return groups[options.axis][options.name] || new Group(options) 3356 } 3357 3358 Waypoint.Group = Group 3359}()) 3360;(function() { 3361 'use strict' 3362 3363 var $ = window.jQuery 3364 var Waypoint = window.Waypoint 3365 3366 function JQueryAdapter(element) { 3367 this.$element = $(element) 3368 } 3369 3370 $.each([
3371 'innerHeight', 3372 'innerWidth', 3373 'off', 3374 'offset', 3375 'on', 3376 'outerHeight', 3377 'outerWidth', 3378 'scrollLeft', 3379 'scrollTop' 3380 ], function(i, method) { 3381 JQueryAdapter.prototype[method] = function() { 3382 var args = Array.prototype.slice.call(arguments) 3383 return this.$element[method].apply(this.$element, args) 3384 } 3385 }) 3386 3387 $.each([ 3388 'extend', 3389 'inArray', 3390 'isEmptyObject' 3391 ], function(i, method) { 3392 JQueryAdapter[method] = $[method] 3393 }) 3394 3395 Waypoint.adapters.push({ 3396 name: 'jquery', 3397 Adapter: JQueryAdapter 3398 }) 3399 Waypoint.Adapter = JQueryAdapter 3400}()) 3401;(function() { 3402 'use strict' 3403 3404 var Waypoint = window.Waypoint 3405 3406 function createExtension(framework) { 3407 return function() { 3408 var waypoints = [] 3409 var overrides = arguments[0] 3410 3411 if (framework.isFunction(arguments[0])) { 3412 overrides = framework.extend({}, arguments[1]) 3413 overrides.handler = arguments[0] 3414 } 3415 3416 this.each(function() { 3417 var options = framework.extend({}, overrides, { 3418 element: this 3419 }) 3420 if (typeof options.context === 'string') { 3421 options.context = framework(this).closest(options.context)[0] 3422 } 3423 waypoints.push(new Waypoint(options)) 3424 }) 3425 3426 return waypoints 3427 } 3428 } 3429 3430 if (window.jQuery) { 3431 window.jQuery.fn.waypoint = createExtension(window.jQuery) 3432 } 3433 if (window.Zepto) { 3434 window.Zepto.fn.waypoint = createExtension(window.Zepto) 3435 } 3436}()) 3437;; 3438/*! 3439Waypoints Sticky Element Shortcut - 4.0.1 3440Copyright © 2011-2016 Caleb Troughton 3441Licensed under the MIT license. 3442https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 3443*/ 3444(function() { 3445 'use strict' 3446 3447 var $ = window.jQuery 3448 var Waypoint = window.Waypoint 3449 3450 /* http://imakewebthings.com/waypoints/shortcuts/sticky-elements */ 3451 function Sticky(options) { 3452 this.options = $.extend({}, Waypoint.defaults, Sticky.defaults, options) 3453 this.element = this.options.element 3454 this.$element = $(this.element) 3455 this.createWrapper() 3456 this.createWaypoint() 3457 } 3458 3459 /* Private */ 3460 Sticky.prototype.createWaypoint = function() { 3461 var originalHandler = this.options.handler 3462 3463 this.waypoint = new Waypoint($.extend({}, this.options, { 3464 element: this.wrapper, 3465 handler: $.proxy(function(direction) { 3466 var shouldBeStuck = this.options.direction.indexOf(direction) > -1 3467 var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : '' 3468 3469 this.$wrapper.height(wrapperHeight) 3470 this.$element.toggleClass(this.options.stuckClass, shouldBeStuck) 3471 3472 if (originalHandler) { 3473 originalHandler.call(this, direction) 3474 } 3475 }, this) 3476 })) 3477 } 3478 3479 /* Private */ 3480 Sticky.prototype.createWrapper = function() { 3481 if (this.options.wrapper) { 3482 this.$element.wrap(this.options.wrapper) 3483 } 3484 this.$wrapper = this.$element.parent() 3485 this.wrapper = this.$wrapper[0] 3486 } 3487 3488 /* Public */ 3489 Sticky.prototype.destroy = function() { 3490 if (this.$element.parent()[0] === this.wrapper) { 3491 this.waypoint.destroy() 3492 this.$element.removeClass(this.options.stuckClass) 3493 if (this.options.wrapper) { 3494 this.$element.unwrap() 3495 } 3496 } 3497 } 3498 3499 Sticky.defaults = { 3500 wrapper: '<div class="sticky-wrapper" />', 3501 stuckClass: 'stuck', 3502 direction: 'down right' 3503 } 3504
3505 Waypoint.Sticky = Sticky 3506}()) 3507; 3508 3509/** 3510 * Waypoints Sticky Element Handlers to make the menu sticky 3511 * 3512 * Copyright (c) 2013-2018 DesignOrbital.com 3513 * License: GNU General Public License v2 or later 3514 * http://www.gnu.org/licenses/gpl-2.0.html 3515 */ 3516 3517( function( $ ) { 3518 3519 // Document Ready 3520 $( document ).ready( function() { 3521 3522 // Sticky Menu Setup 3523 new Waypoint.Sticky( { 3524 element: $( '.main-navigation' )[0], 3525 wrapper: '<div class="main-navigation-sticky-wrapper waypoint" />', 3526 stuckClass: 'stuck' 3527 } ); 3528 3529 } ); 3530 3531} )( jQuery ); 3532; 3533/*! 3534 * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it 3535 * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js 3536 * License: MIT 3537 */ 3538 3539(function(window, document) { 3540 3541 'use strict'; 3542 3543 /* exported features */ 3544 3545 var features = { 3546 bind : !!(function(){}.bind), 3547 classList : 'classList' in document.documentElement, 3548 rAF : !!(window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame) 3549 }; 3550 window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; 3551 3552 /** 3553 * Handles debouncing of events via requestAnimationFrame 3554 * @see http://www.html5rocks.com/en/tutorials/speed/animations/ 3555 * @param {Function} callback The callback to handle whichever event 3556 */ 3557 function Debouncer (callback) { 3558 this.callback = callback; 3559 this.ticking = false; 3560 } 3561 Debouncer.prototype = { 3562 constructor : Debouncer, 3563 3564 /** 3565 * dispatches the event to the supplied callback 3566 * @private 3567 */ 3568 update : function() { 3569 this.callback && this.callback(); 3570 this.ticking = false; 3571 }, 3572 3573 /** 3574 * ensures events don't get stacked 3575 * @private 3576 */ 3577 requestTick : function() { 3578 if(!this.ticking) { 3579 requestAnimationFrame(this.rafCallback || (this.rafCallback = this.update.bind(this))); 3580 this.ticking = true; 3581 } 3582 }, 3583 3584 /** 3585 * Attach this as the event listeners 3586 */ 3587 handleEvent : function() { 3588 this.requestTick(); 3589 } 3590 }; 3591 /** 3592 * Check if object is part of the DOM 3593 * @constructor 3594 * @param {Object} obj element to check 3595 */ 3596 function isDOMElement(obj) { 3597 return obj && typeof window !== 'undefined' && (obj === window || obj.nodeType); 3598 } 3599 3600 /** 3601 * Helper function for extending objects 3602 */ 3603 function extend (object /*, objectN ... */) { 3604 if(arguments.length <= 0) { 3605 throw new Error('Missing arguments in extend function'); 3606 } 3607 3608 var result = object || {}, 3609 key, 3610 i; 3611 3612 for (i = 1; i < arguments.length; i++) { 3613 var replacement = arguments[i] || {}; 3614 3615 for (key in replacement) { 3616 // Recurse into object except if the object is a DOM element 3617 if(typeof result[key] === 'object' && ! isDOMElement(result[key])) { 3618 result[key] = extend(result[key], replacement[key]); 3619 } 3620 else { 3621 result[key] = result[key] || replacement[key]; 3622 } 3623 } 3624 } 3625 3626 return result; 3627 } 3628 3629 /** 3630 * Helper function for normalizing tolerance option to object format 3631 */ 3632 function normalizeTolerance (t) { 3633 return t === Object(t) ? t : { down : t, up : t }; 3634 } 3635 3636 /** 3637 * UI enhancement for fixed headers. 3638 * Hides header when scrolling down 3639 * Shows header when scrolling up 3640 * @constructor 3641 * @param {DOMElement} elem the header element 3642 * @param {Object} options options for the widget 3643 */ 3644 function Headroom (elem, options) { 3645 options = extend(options, Headroom.options); 3646 3647 this.lastKnownScrollY = 0; 3648 this.elem = elem; 3649 this.debouncer = new Debouncer(this.update.bind(this)); 3650 this.tolerance = normalizeTolerance(options.tolerance); 3651 this.classes = options.classes; 3652 this.offset = options.offset; 3653 this.scroller = options.scroller; 3654 this.initialised = false; 3655 this.onPin = options.onPin; 3656 this.onUnpin = options.onUnpin; 3657 this.onTop = options.onTop; 3658 this.onNotTop = options.onNotTop; 3659 } 3660 Headroom.prototype = { 3661 constructor : Headroom, 3662 3663 /** 3664 * Initialises the widget 3665 */ 3666 init : function() { 3667 if(!Headroom.cutsTheMustard) { 3668 return; 3669 } 3670 3671 this.elem.classList.add(this.classes.initial); 3672 3673 // defer event registration to handle browser 3674 // potentially restoring previous scroll position 3675 setTimeout(this.attachEvent.bind(this), 100); 3676 3677 return this; 3678 }, 3679 3680 /** 3681 * Unattaches events and removes any classes that were added 3682 */ 3683 destroy : function() { 3684 var classes = this.classes; 3685
3686 this.initialised = false; 3687 this.elem.classList.remove(classes.unpinned, classes.pinned, classes.top, classes.initial); 3688 this.scroller.removeEventListener('scroll', this.debouncer, false); 3689 }, 3690 3691 /** 3692 * Attaches the scroll event 3693 * @private 3694 */ 3695 attachEvent : function() { 3696 if(!this.initialised){ 3697 this.lastKnownScrollY = this.getScrollY(); 3698 this.initialised = true; 3699 this.scroller.addEventListener('scroll', this.debouncer, false); 3700 3701 this.debouncer.handleEvent(); 3702 } 3703 }, 3704 3705 /** 3706 * Unpins the header if it's currently pinned 3707 */ 3708 unpin : function() { 3709 var classList = this.elem.classList, 3710 classes = this.classes; 3711 3712 if(classList.contains(classes.pinned) || !classList.contains(classes.unpinned)) { 3713 classList.add(classes.unpinned); 3714 classList.remove(classes.pinned); 3715 this.onUnpin && this.onUnpin.call(this); 3716 } 3717 }, 3718 3719 /** 3720 * Pins the header if it's currently unpinned 3721 */ 3722 pin : function() { 3723 var classList = this.elem.classList, 3724 classes = this.classes; 3725 3726 if(classList.contains(classes.unpinned)) { 3727 classList.remove(classes.unpinned); 3728 classList.add(classes.pinned); 3729 this.onPin && this.onPin.call(this); 3730 } 3731 }, 3732 3733 /** 3734 * Handles the top states 3735 */ 3736 top : function() { 3737 var classList = this.elem.classList, 3738 classes = this.classes; 3739 3740 if(!classList.contains(classes.top)) { 3741 classList.add(classes.top); 3742 classList.remove(classes.notTop); 3743 this.onTop && this.onTop.call(this); 3744 } 3745 }, 3746 3747 /** 3748 * Handles the not top state 3749 */ 3750 notTop : function() { 3751 var classList = this.elem.classList, 3752 classes = this.classes; 3753 3754 if(!classList.contains(classes.notTop)) { 3755 classList.add(classes.notTop); 3756 classList.remove(classes.top); 3757 this.onNotTop && this.onNotTop.call(this); 3758 } 3759 }, 3760 3761 /** 3762 * Gets the Y scroll position 3763 * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY 3764 * @return {Number} pixels the page has scrolled along the Y-axis 3765 */ 3766 getScrollY : function() { 3767 return (this.scroller.pageYOffset !== undefined) 3768 ? this.scroller.pageYOffset 3769 : (this.scroller.scrollTop !== undefined) 3770 ? this.scroller.scrollTop 3771 : (document.documentElement || document.body.parentNode || document.body).scrollTop; 3772 }, 3773 3774 /** 3775 * Gets the height of the viewport 3776 * @see http://andylangton.co.uk/blog/development/get-viewport-size-width-and-height-javascript 3777 * @return {int} the height of the viewport in pixels 3778 */ 3779 getViewportHeight : function () { 3780 return window.innerHeight 3781 || document.documentElement.clientHeight 3782 || document.body.clientHeight; 3783 }, 3784 3785 /** 3786 * Gets the height of the document 3787 * @see http://james.padolsey.com/javascript/get-document-height-cross-browser/ 3788 * @return {int} the height of the document in pixels 3789 */ 3790 getDocumentHeight : function () { 3791 var body = document.body, 3792 documentElement = document.documentElement; 3793 3794 return Math.max( 3795 body.scrollHeight, documentElement.scrollHeight, 3796 body.offsetHeight, documentElement.offsetHeight, 3797 body.clientHeight, documentElement.clientHeight 3798 ); 3799 }, 3800 3801 /** 3802 * Gets the height of the DOM element 3803 * @param {Object} elm the element to calculate the height of which 3804 * @return {int} the height of the element in pixels 3805 */ 3806 getElementHeight : function (elm) { 3807 return Math.max( 3808 elm.scrollHeight, 3809 elm.offsetHeight, 3810 elm.clientHeight 3811 ); 3812 }, 3813 3814 /** 3815 * Gets the height of the scroller element 3816 * @return {int} the height of the scroller element in pixels 3817 */ 3818 getScrollerHeight : function () { 3819 return (this.scroller === window || this.scroller === document.body) 3820 ? this.getDocumentHeight() 3821 : this.getElementHeight(this.scroller); 3822 }, 3823 3824 /** 3825 * determines if the scroll position is outside of document boundaries 3826 * @param {int} currentScrollY the current y scroll position 3827 * @return {bool} true if out of bounds, false otherwise 3828 */ 3829 isOutOfBounds : function (currentScrollY) { 3830 var pastTop = currentScrollY < 0,
3831 pastBottom = currentScrollY + this.getViewportHeight() > this.getScrollerHeight(); 3832 3833 return pastTop || pastBottom; 3834 }, 3835 3836 /** 3837 * determines if the tolerance has been exceeded 3838 * @param {int} currentScrollY the current scroll y position 3839 * @return {bool} true if tolerance exceeded, false otherwise 3840 */ 3841 toleranceExceeded : function (currentScrollY, direction) { 3842 return Math.abs(currentScrollY-this.lastKnownScrollY) >= this.tolerance[direction]; 3843 }, 3844 3845 /** 3846 * determine if it is appropriate to unpin 3847 * @param {int} currentScrollY the current y scroll position 3848 * @param {bool} toleranceExceeded has the tolerance been exceeded? 3849 * @return {bool} true if should unpin, false otherwise 3850 */ 3851 shouldUnpin : function (currentScrollY, toleranceExceeded) { 3852 var scrollingDown = currentScrollY > this.lastKnownScrollY, 3853 pastOffset = currentScrollY >= this.offset; 3854 3855 return scrollingDown && pastOffset && toleranceExceeded; 3856 }, 3857 3858 /** 3859 * determine if it is appropriate to pin 3860 * @param {int} currentScrollY the current y scroll position 3861 * @param {bool} toleranceExceeded has the tolerance been exceeded? 3862 * @return {bool} true if should pin, false otherwise 3863 */ 3864 shouldPin : function (currentScrollY, toleranceExceeded) { 3865 var scrollingUp = currentScrollY < this.lastKnownScrollY, 3866 pastOffset = currentScrollY <= this.offset; 3867 3868 return (scrollingUp && toleranceExceeded) || pastOffset; 3869 }, 3870 3871 /** 3872 * Handles updating the state of the widget 3873 */ 3874 update : function() { 3875 var currentScrollY = this.getScrollY(), 3876 scrollDirection = currentScrollY > this.lastKnownScrollY ? 'down' : 'up', 3877 toleranceExceeded = this.toleranceExceeded(currentScrollY, scrollDirection); 3878 3879 if(this.isOutOfBounds(currentScrollY)) { // Ignore bouncy scrolling in OSX 3880 return; 3881 } 3882 3883 if (currentScrollY <= this.offset ) { 3884 this.top(); 3885 } else { 3886 this.notTop(); 3887 } 3888 3889 if(this.shouldUnpin(currentScrollY, toleranceExceeded)) { 3890 this.unpin(); 3891 } 3892 else if(this.shouldPin(currentScrollY, toleranceExceeded)) { 3893 this.pin(); 3894 } 3895 3896 this.lastKnownScrollY = currentScrollY; 3897 } 3898 }; 3899 /** 3900 * Default options 3901 * @type {Object} 3902 */ 3903 Headroom.options = { 3904 tolerance : { 3905 up : 0, 3906 down : 0 3907 }, 3908 offset : 0, 3909 scroller: window, 3910 classes : { 3911 pinned : 'headroom--pinned', 3912 unpinned : 'headroom--unpinned', 3913 top : 'headroom--top', 3914 notTop : 'headroom--not-top', 3915 initial : 'headroom' 3916 } 3917 }; 3918 Headroom.cutsTheMustard = typeof features !== 'undefined' && features.rAF && features.bind && features.classList; 3919 3920 window.Headroom = Headroom; 3921 3922}(window, document)); 3923 3924/*! 3925 * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it 3926 * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js 3927 * License: MIT 3928 */ 3929 3930(function($) { 3931 3932 if(!$) { 3933 return; 3934 } 3935 3936 //////////// 3937 // Plugin // 3938 //////////// 3939 3940 $.fn.headroom = function(option) { 3941 return this.each(function() { 3942 var $this = $(this), 3943 data = $this.data('headroom'), 3944 options = typeof option === 'object' && option; 3945 3946 options = $.extend(true, {}, Headroom.options, options); 3947 3948 if (!data) { 3949 data = new Headroom(this, options); 3950 data.init(); 3951 $this.data('headroom', data); 3952 } 3953 if (typeof option === 'string') { 3954 data[option](); 3955 } 3956 }); 3957 }; 3958 3959 ////////////// 3960 // Data API // 3961 ////////////// 3962 3963 $('[data-headroom]').each(function() { 3964 var $this = $(this); 3965 $this.headroom($this.data()); 3966 }); 3967 3968}(window.Zepto || window.jQuery)); 3969 3970/*! 3971 * Headroom Handlers to show the menu on scroll up 3972 * 3973 * Copyright (c) 2013-2015 DesignOrbital.com 3974 * License: GNU General Public License v2 or later 3975 * http://www.gnu.org/licenses/gpl-2.0.html 3976 */ 3977 3978( function( $ ) { 3979 3980 // Document Ready 3981 $( document ).ready( function() { 3982 3983 var anemoneOffset = 600; 3984 if ( $( 'body' ).hasClass( 'site-hero-small' ) ) { 3985 anemoneOffset = 400; 3986 } 3987 3988 // Sticky Menu 3989 $( '.main-navigation' ).headroom ( { 3990 3991 // vertical offset in px before element is first unpinned 3992 offset : anemoneOffset, 3993 // scroll tolerance in px before state changes 3994 tolerance: { 3995 down : 10, 3996 up : 20 3997 }, 3998 classes : { 3999 // when element is initialised 4000 initial : 'headroom', 4001 // when scrolling up 4002 pinned : 'headroom-pinned', 4003 // when scrolling down 4004 unpinned : 'headroom-unpinned', 4005 // when above offset 4006 top : 'headroom-top', 4007 // when below offset 4008 notTop : 'headroom-not-top' 4009 } 4010 4011 } ); 4012 4013 } ); 4014 4015} )( jQuery ); 4016; 4017/*! 4018 * Search Curtain v1.0 4019 * Contains handlers for the search overlay 4020 * 4021 * Copyright (c) 2013-2015 DesignOrbital.com 4022 * License: GNU General Public License v2 or later 4023 * http://www.gnu.org/licenses/gpl-2.0.html 4024 */ 4025 4026( function( $ ) { 4027 4028 var anemoneSearch = { 4029 4030 // Search Curtain 4031 searchCurtainInit: function() { 4032 4033 // Elements 4034 var scw = $( '.search-curtain-wrapper' ); 4035 var sc = $( '.search-curtain' ); 4036 4037 // Search Curtain Open 4038 $( '.toggle-search' ).off( 'click' ).on( 'click', function( e ) { 4039 4040 // Prevent Default 4041 e.preventDefault(); 4042 e.stopPropagation(); 4043 4044 // ToggleClass 4045 scw.toggleClass( 'show' ); 4046 setTimeout( function() { 4047 sc.toggleClass( 'show' ); 4048 }, 150 ); 4049 4050 } ); 4051 4052 // Search Curtain Close 4053 $( '.search-curtain-close' ).off( 'click' ).on( 'click', function( e ) { 4054 4055 // Prevent Default 4056 e.preventDefault(); 4057 e.stopPropagation(); 4058 4059 // Search Curtian Close 4060 anemoneSearch.searchCurtainCloseInit(); 4061 4062 } ); 4063 4064 }, 4065 4066 // Search Curtain Close 4067 searchCurtainCloseInit: function() { 4068 4069 // Elements 4070 var scw = $( '.search-curtain-wrapper' ); 4071 var sc = $( '.search-curtain' ); 4072 4073 // Close the search curtain, when user interacts with 4074 // the sidebar, responisve menu or esc key 4075 if( scw.hasClass( 'show' ) ) { 4076 4077 // ToggleClass 4078 sc.toggleClass( 'show' ); 4079 setTimeout( function() { 4080 scw.toggleClass( 'show' ); 4081 }, 150 ); 4082 4083 } 4084 4085 } 4086 4087 }; 4088 4089 // Document Ready 4090 $( document ).ready( function() { 4091 4092 // Search Curtain 4093 anemoneSearch.searchCurtainInit(); 4094 4095 } ); 4096 4097 // Document Keyup 4098 $( document ).keyup( function( e ) { 4099 4100 // Escape Key 4101 if ( e.keyCode === 27 ) { 4102 4103 // Make the escape key to close the search curtain 4104 anemoneSearch.searchCurtainCloseInit(); 4105 4106 } 4107 4108 } ); 4109 4110} )( jQuery ); 4111; 4112/*! 4113 * Sticky Sidebar v1.0
4114 * Contains handlers for the sticky sidebar 4115 * 4116 * Copyright (c) 2013-2015 DesignOrbital.com 4117 * License: GNU General Public License v2 or later 4118 * http://www.gnu.org/licenses/gpl-2.0.html 4119 */ 4120 4121( function( $ ) { 4122 4123 $.fn.anemoneStickySidebar = function( options ) { 4124 4125 // Defaults 4126 var defaults = { 4127 content: '.site-content', 4128 offset: 20 4129 }; 4130 4131 // Settings 4132 var settings = $.extend( {}, defaults, options ); 4133 4134 // Selector Cache 4135 var $this = $( this ); 4136 var $window = $( window ); 4137 var $content = $( settings.content ); 4138 4139 // Sticky Sidebar Vars 4140 var sticky, reloadTimer, offsetCalibration = 0, reloadTicking = false, contentBottom, contentBottomActual, contentBottomVirtual, sidebarBottom, latestKnownScrollYBottom; 4141 var sidebarStaticTriggered = true, sidebarFixedTriggered = false, sidebarPinnedTriggered = false; 4142 4143 // rAF logic Vars 4144 var latestKnownScrollY = 0, ticking = false; 4145 4146 /** 4147 * Sticky Sidebar Methods 4148 */ 4149 4150 // Sticky Sidebar Init 4151 function stickySidebarInit() { 4152 4153 // Reset 4154 stickySidebarReset(); 4155 4156 // Attach Events 4157 $window 4158 .on ( 'scroll.anemoneStickySidebar', onScroll ) 4159 .on ( 'resize.anemoneStickySidebar', onResize ); 4160 4161 // Infinite Scroll Post Load 4162 $( document.body ).on( 'post-load', onPostLoad ); 4163 4164 // Update 4165 update(); 4166 4167 } 4168 4169 /** 4170 * Callback for resize event 4171 */ 4172 function onResize() { 4173 stickySidebarReloadTimer( 250 ); 4174 } 4175 4176 /** 4177 * Callback for Infinite Scroll Post Load 4178 */ 4179 function onPostLoad() { 4180 stickySidebarReloadTimer( 1500 ); 4181 } 4182 4183 /** 4184 * rAF logic 4185 * http://www.html5rocks.com/en/tutorials/speed/animations/ 4186 * https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY 4187 */ 4188 4189 /** 4190 * Callback for our scroll event - just 4191 * keeps track of the last scroll value 4192 */ 4193 function onScroll() { 4194 requestTick(); 4195 } 4196 4197 /** 4198 * Calls rAF if it's not already 4199 * been done already 4200 */ 4201 function requestTick() { 4202 if( ! ticking ) { 4203 requestAnimationFrame( update ); 4204 } 4205 ticking = true; 4206 } 4207 4208 /** 4209 * Our animation callback 4210 */ 4211 function update() { 4212 4213 // scrollY 4214 latestKnownScrollY = window.pageYOffset; 4215 4216 // Sticky Sidebar 4217 stickySidebarUpdate(); 4218 4219 // allow further rAFs to be called 4220 ticking = false; 4221 4222 } 4223 4224 /** 4225 * Sticky Sidebar Reset 4226 * Reset Calulations, Bind Events and Other Things 4227 */ 4228 function stickySidebarReset() { 4229 4230 // Reset Style Attribute 4231 $this.removeAttr( 'style' ); 4232 4233 // Reset Vars 4234 sticky = { 4235 4236 'windowWidth': $window.width(), 4237 'windowHeight': $window.height(), 4238 'contentHeight': $content.height(), 4239 'contentTop': $content.offset().top, 4240 'sidebarWidth': $this.outerWidth( true ), 4241 'sidebarHeight': $this.height(), 4242 'sidebarTop': $this.offset().top, 4243 'sidebarLeft': $this.offset().left 4244 4245 }; 4246 4247 // Offset Calibration w.r.t Admin Bar and WordPress.com Demo Site Bar 4248 if ( $( 'body' ).hasClass( 'demo-site', 'admin-bar' ) ) { 4249 offsetCalibration = 112; 4250 } else if ( $( 'body' ).hasClass( 'admin-bar' ) ) { 4251 offsetCalibration = 32; 4252 } else if ( $( 'body' ).hasClass( 'demo-site' ) ) { 4253 offsetCalibration = 80; 4254 } 4255 4256 if ( sticky.windowWidth <= 782 ) { 4257 4258 if ( $( 'body' ).hasClass( 'demo-site', 'admin-bar' ) ) { 4259 offsetCalibration = 126; 4260 } else if ( $( 'body' ).hasClass( 'admin-bar' ) ) { 4261 offsetCalibration = 46; 4262 } else if ( $( 'body' ).hasClass( 'demo-site' ) ) { 4263 offsetCalibration = 80; 4264 } 4265 4266 } 4267 4268 // Content and Sidebar Bottoms 4269 contentBottomActual = sticky.contentHeight + sticky.contentTop; 4270 contentBottomVirtual = contentBottomActual + ( sticky.windowHeight - sticky.sidebarHeight ); 4271 sidebarBottom = sticky.sidebarHeight + sticky.sidebarTop; 4272 4273 // Content Bottom for our Logic 4274 contentBottom = contentBottomActual; 4275 // If Window height is greater than Sidebar height 4276 if ( sticky.windowHeight >= sticky.sidebarHeight ) { 4277 contentBottom = contentBottomVirtual; 4278 } 4279 4280 // Sidebar Flags 4281 sidebarStaticTriggered = true; 4282 sidebarFixedTriggered = false;
4283 sidebarPinnedTriggered = false; 4284 4285 } 4286 4287 // Sidebar Reload 4288 function stickySidebarReload() { 4289 4290 // Reset 4291 stickySidebarReset(); 4292 4293 // Update 4294 update(); 4295 4296 } 4297 4298 // Sticky Sidebar Reload With Timer 4299 function stickySidebarReloadTimer( delay ) { 4300 4301 if ( ! reloadTicking ) { 4302 4303 // Reload Timer 4304 clearTimeout( reloadTimer ); 4305 reloadTimer = setTimeout( function() { 4306 4307 // Reload 4308 stickySidebarReload(); 4309 4310 // allow further reloads to be called 4311 reloadTicking = false; 4312 4313 }, delay ); 4314 4315 } 4316 4317 reloadTicking = true; 4318 4319 } 4320 4321 // Sidebar Reset 4322 function sidebarReset() { 4323 4324 // CSS 4325 $this.css( { 4326 position: '', 4327 width: '', 4328 top: '', 4329 left: '' 4330 } ); 4331 4332 // Sidebar Flags 4333 sidebarStaticTriggered = true; 4334 sidebarFixedTriggered = false; 4335 sidebarPinnedTriggered = false; 4336 4337 } 4338 4339 // Sticky Sidebar Update 4340 function stickySidebarUpdate() { 4341 4342 // Basic Validation 4343 if ( sticky.windowWidth <= 767 || sticky.sidebarHeight >= sticky.contentHeight ) { 4344 return; 4345 } 4346 4347 /** 4348 * Enhanced Validation 4349 * For the widgets which may change sidebar height in late execuation 4350 * e.g. Post Carousel etc 4351 */ 4352 4353 if ( $this.height() !== sticky.sidebarHeight ) { 4354 stickySidebarReloadTimer( 250 ); 4355 return; 4356 } 4357 4358 // ScrollY Bottom 4359 latestKnownScrollYBottom = latestKnownScrollY + sticky.windowHeight; 4360 4361 /** 4362 * Sticky Sidebar Breakpoints 4363 * Reset Sidebar 4364 * Fixed Sidebar 4365 * Pinned Sidebar 4366 */ 4367 4368 // Reset Sidebar 4369 if ( latestKnownScrollY <= sticky.sidebarTop && false === sidebarStaticTriggered ) { 4370 4371 // Sidebar Reset 4372 sidebarReset(); 4373 4374 } 4375 4376 // Fixed Sidebar 4377 else if ( latestKnownScrollY > sticky.sidebarTop && latestKnownScrollYBottom < contentBottom && latestKnownScrollYBottom > sidebarBottom ) { 4378 4379 // If Sidebar height is greater than window height 4380 if ( sticky.sidebarHeight >= sticky.windowHeight && false === sidebarFixedTriggered ) { 4381 4382 // CSS 4383 $this.css( { 4384 4385 position: 'fixed', 4386 width: sticky.sidebarWidth, 4387 top: ( sticky.windowHeight - sticky.sidebarHeight ) - settings.offset, 4388 left: sticky.sidebarLeft, 4389 4390 } ); 4391 4392 } else if ( false === sidebarFixedTriggered ) { 4393 4394 // CSS 4395 $this.css( { 4396 4397 position: 'fixed', 4398 width: sticky.sidebarWidth, 4399 top: settings.offset + offsetCalibration, 4400 left: sticky.sidebarLeft 4401 4402 } ); 4403 4404 } 4405 4406 // Sidebar Flags 4407 sidebarStaticTriggered = false; 4408 sidebarFixedTriggered = true; 4409 sidebarPinnedTriggered = false; 4410 4411 } 4412 4413 // Pinned Sidebar 4414 else if ( latestKnownScrollY > sticky.sidebarTop && latestKnownScrollYBottom > contentBottom ) { 4415 4416 if ( false === sidebarPinnedTriggered ) { 4417 4418 // CSS 4419 $this.css( { 4420 4421 position: '', 4422 width: '', 4423 top: ( contentBottomActual - sidebarBottom ) - settings.offset, 4424 left: '' 4425 4426 } ); 4427 4428 } 4429 4430 // Sidebar Flags 4431 sidebarStaticTriggered = false; 4432 sidebarFixedTriggered = false; 4433 sidebarPinnedTriggered = true; 4434 4435 } 4436 4437 else { 4438 4439 if ( false === sidebarStaticTriggered ) { 4440 // Sidebar Reset 4441 sidebarReset(); 4442 } 4443 } 4444 4445 } 4446 4447 /** 4448 * Sticky Sidebar Ride 4449 */ 4450 4451 return $this.each( function () { 4452 stickySidebarInit(); 4453 } ); 4454 4455 }; 4456 4457 // Windows Load 4458 $( window ).load( function() { 4459 4460 var anemoneSidebarTimer; 4461 var $sidebar = $( '.sidebar' ); 4462 4463 // Sticky Sidebar 4464 if ( $sidebar.length ) { 4465 // Images Loaded 4466 $sidebar.imagesLoaded( function() { 4467 4468 // Reload Timer 4469 clearTimeout( anemoneSidebarTimer ); 4470 anemoneSidebarTimer = setTimeout( function() { 4471 $sidebar.anemoneStickySidebar(); 4472 }, 1000 ); 4473 4474 }); 4475 } 4476 4477 } ); 4478 4479} )( jQuery ); 4480; 4481/*! 4482 * scrollup v2.4.0 4483 * Url: http://markgoodyear.com/labs/scrollup/ 4484 * Copyright (c) Mark Goodyear @markgdyr http://markgoodyear.com 4485 * License: MIT 4486 */ 4487 4488(function ($, window, document) { 4489 'use strict'; 4490 4491 // Main function 4492 $.fn.scrollUp = function (options) { 4493 4494 // Ensure that only one scrollUp exists 4495 if (!$.data(document.body, 'scrollUp')) { 4496 $.data(document.body, 'scrollUp', true); 4497 $.fn.scrollUp.init(options); 4498 } 4499 }; 4500 4501 // Init 4502 $.fn.scrollUp.init = function (options) { 4503 4504 // Define vars 4505 var o = $.fn.scrollUp.settings = $.extend({}, $.fn.scrollUp.defaults, options), 4506 triggerVisible = false, 4507 animIn, animOut, animSpeed, scrollDis, scrollEvent, scrollTarget, $self; 4508 4509 // Create element 4510 if (o.scrollTrigger) { 4511 $self = $(o.scrollTrigger); 4512 } else { 4513 $self = $('<a/>', { 4514 id: o.scrollName, 4515 href: '#top' 4516 }); 4517 } 4518 4519 // Set scrollTitle if there is one 4520 if (o.scrollTitle) { 4521 $self.attr('title', o.scrollTitle); 4522 } 4523 4524 $self.appendTo('body'); 4525 4526 // If not using an image display text 4527 if (!(o.scrollImg || o.scrollTrigger)) { 4528 $self.html(o.scrollText); 4529 } 4530 4531 // Minimum CSS to make the magic happen 4532 $self.css({ 4533 display: 'none', 4534 position: 'fixed', 4535 zIndex: o.zIndex 4536 }); 4537 4538 // Active point overlay 4539 if (o.activeOverlay) { 4540 $('<div/>', { 4541 id: o.scrollName + '-active' 4542 }).css({ 4543 position: 'absolute', 4544 'top': o.scrollDistance + 'px', 4545 width: '100%', 4546 borderTop: '1px dotted' + o.activeOverlay, 4547 zIndex: o.zIndex 4548 }).appendTo('body'); 4549 } 4550 4551 // Switch animation type 4552 switch (o.animation) { 4553 case 'fade': 4554 animIn = 'fadeIn'; 4555 animOut = 'fadeOut'; 4556 animSpeed = o.animationSpeed; 4557 break; 4558 4559 case 'slide': 4560 animIn = 'slideDown'; 4561 animOut = 'slideUp'; 4562 animSpeed = o.animationSpeed; 4563 break; 4564 4565 default: 4566 animIn = 'show'; 4567 animOut = 'hide'; 4568 animSpeed = 0; 4569 } 4570 4571 // If from top or bottom 4572 if (o.scrollFrom === 'top') { 4573 scrollDis = o.scrollDistance; 4574 } else { 4575 scrollDis = $(document).height() - $(window).height() - o.scrollDistance; 4576 } 4577 4578 // Scroll function 4579 scrollEvent = $(window).scroll(function () { 4580 if ($(window).scrollTop() > scrollDis) { 4581 if (!triggerVisible) { 4582 $self[animIn](animSpeed); 4583 triggerVisible = true; 4584 } 4585 } else { 4586 if (triggerVisible) { 4587 $self[animOut](animSpeed); 4588 triggerVisible = false;
4589 } 4590 } 4591 }); 4592 4593 if (o.scrollTarget) { 4594 if (typeof o.scrollTarget === 'number') { 4595 scrollTarget = o.scrollTarget; 4596 } else if (typeof o.scrollTarget === 'string') { 4597 scrollTarget = Math.floor($(o.scrollTarget).offset().top); 4598 } 4599 } else { 4600 scrollTarget = 0; 4601 } 4602 4603 // To the top 4604 $self.click(function (e) { 4605 e.preventDefault(); 4606 4607 $('html, body').animate({ 4608 scrollTop: scrollTarget 4609 }, o.scrollSpeed, o.easingType); 4610 }); 4611 }; 4612 4613 // Defaults 4614 $.fn.scrollUp.defaults = { 4615 scrollName: 'scrollUp', // Element ID 4616 scrollDistance: 300, // Distance from top/bottom before showing element (px) 4617 scrollFrom: 'top', // 'top' or 'bottom' 4618 scrollSpeed: 300, // Speed back to top (ms) 4619 easingType: 'linear', // Scroll to top easing (see http://easings.net/) 4620 animation: 'fade', // Fade, slide, none 4621 animationSpeed: 200, // Animation in speed (ms) 4622 scrollTrigger: false, // Set a custom triggering element. Can be an HTML string or jQuery object 4623 scrollTarget: false, // Set a custom target element for scrolling to. Can be element or number 4624 scrollText: 'Scroll to top', // Text for element, can contain HTML 4625 scrollTitle: false, // Set a custom <a> title if required. Defaults to scrollText 4626 scrollImg: false, // Set true to use image 4627 activeOverlay: false, // Set CSS color to display scrollUp active point, e.g '#00FFFF' 4628 zIndex: 2147483647 // Z-Index for the overlay 4629 }; 4630 4631 // Destroy scrollUp plugin and clean all modifications to the DOM 4632 $.fn.scrollUp.destroy = function (scrollEvent) { 4633 $.removeData(document.body, 'scrollUp'); 4634 $('#' + $.fn.scrollUp.settings.scrollName).remove(); 4635 $('#' + $.fn.scrollUp.settings.scrollName + '-active').remove(); 4636 4637 // If 1.7 or above use the new .off() 4638 if ($.fn.jquery.split('.')[1] >= 7) { 4639 $(window).off('scroll', scrollEvent); 4640 4641 // Else use the old .unbind() 4642 } else { 4643 $(window).unbind('scroll', scrollEvent); 4644 } 4645 }; 4646 4647 $.scrollUp = $.fn.scrollUp; 4648 4649})(jQuery, window, document); 4650 4651/*! 4652 * ScrollUp Handlers for back to top 4653 * 4654 * Copyright (c) 2013-2015 DesignOrbital.com 4655 * License: GNU General Public License v2 or later 4656 * http://www.gnu.org/licenses/gpl-2.0.html 4657 */ 4658 4659( function( $ ) { 4660 4661 // Document Ready 4662 $( document ).ready( function() { 4663 4664 // Scroll Up 4665 $.scrollUp({ 4666 scrollDistance: 1000, 4667 scrollFrom: 'bottom', 4668 scrollSpeed: 1500, 4669 animation: 'slide', 4670 scrollText: '<span></span>', 4671 zIndex: 99950 4672 }); 4673 4674 } ); 4675 4676} )( jQuery ); 4677; 4678/*! 4679 * enquire.js v2.1.2 - Awesome Media Queries in JavaScript 4680 * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/enquire.js 4681 * License: MIT (http://www.opensource.org/licenses/mit-license.php) 4682 */ 4683 4684;(function (name, context, factory) { 4685 var matchMedia = window.matchMedia; 4686 4687 if (typeof module !== 'undefined' && module.exports) { 4688 module.exports = factory(matchMedia); 4689 } 4690 else if (typeof define === 'function' && define.amd) { 4691 define(function() { 4692 return (context[name] = factory(matchMedia)); 4693 }); 4694 } 4695 else { 4696 context[name] = factory(matchMedia); 4697 } 4698}('enquire', this, function (matchMedia) { 4699 4700 'use strict'; 4701 4702 /*jshint unused:false */ 4703 /** 4704 * Helper function for iterating over a collection 4705 * 4706 * @param collection 4707 * @param fn 4708 */ 4709 function each(collection, fn) { 4710 var i = 0, 4711 length = collection.length, 4712 cont; 4713 4714 for(i; i < length; i++) { 4715 cont = fn(collection[i], i); 4716 if(cont === false) { 4717 break; //allow early exit 4718 } 4719 } 4720 } 4721 4722 /** 4723 * Helper function for determining whether target object is an array 4724 * 4725 * @param target the object under test 4726 * @return {Boolean} true if array, false otherwise 4727 */ 4728 function isArray(target) { 4729 return Object.prototype.toString.apply(target) === '[object Array]'; 4730 } 4731 4732 /** 4733 * Helper function for determining whether target object is a function 4734 * 4735 * @param target the object under test 4736 * @return {Boolean} true if function, false otherwise 4737 */ 4738 function isFunction(target) { 4739 return typeof target === 'function'; 4740 } 4741 4742 /** 4743 * Delegate to handle a media query being matched and unmatched. 4744 * 4745 * @param {object} options 4746 * @param {function} options.match callback for when the media query is matched 4747 * @param {function} [options.unmatch] callback for when the media query is unmatched 4748 * @param {function} [options.setup] one-time callback triggered the first time a query is matched 4749 * @param {boolean} [options.deferSetup=false] should the setup callback be run immediately, rather than first time query is matched? 4750 * @constructor 4751 */ 4752 function QueryHandler(options) { 4753 this.options = options; 4754 !options.deferSetup && this.setup(); 4755 } 4756 QueryHandler.prototype = { 4757 4758 /** 4759 * coordinates setup of the handler 4760 * 4761 * @function 4762 */ 4763 setup : function() { 4764 if(this.options.setup) { 4765 this.options.setup(); 4766 }
vendor: 4,487 bytes, lines 4767-4902
4767 this.initialised = true; 4768 }, 4769 4770 /** 4771 * coordinates setup and triggering of the handler 4772 * 4773 * @function 4774 */ 4775 on : function() { 4776 !this.initialised && this.setup(); 4777 this.options.match && this.options.match(); 4778 }, 4779 4780 /** 4781 * coordinates the unmatch event for the handler 4782 * 4783 * @function 4784 */ 4785 off : function() { 4786 this.options.unmatch && this.options.unmatch(); 4787 }, 4788 4789 /** 4790 * called when a handler is to be destroyed. 4791 * delegates to the destroy or unmatch callbacks, depending on availability. 4792 * 4793 * @function 4794 */ 4795 destroy : function() { 4796 this.options.destroy ? this.options.destroy() : this.off(); 4797 }, 4798 4799 /** 4800 * determines equality by reference. 4801 * if object is supplied compare options, if function, compare match callback 4802 * 4803 * @function 4804 * @param {object || function} [target] the target for comparison 4805 */ 4806 equals : function(target) { 4807 return this.options === target || this.options.match === target; 4808 } 4809 4810 }; 4811 /** 4812 * Represents a single media query, manages it's state and registered handlers for this query 4813 * 4814 * @constructor 4815 * @param {string} query the media query string 4816 * @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design 4817 */ 4818 function MediaQuery(query, isUnconditional) { 4819 this.query = query; 4820 this.isUnconditional = isUnconditional; 4821 this.handlers = []; 4822 this.mql = matchMedia(query); 4823 4824 var self = this; 4825 this.listener = function(mql) { 4826 self.mql = mql; 4827 self.assess(); 4828 }; 4829 this.mql.addListener(this.listener); 4830 } 4831 MediaQuery.prototype = { 4832 4833 /** 4834 * add a handler for this query, triggering if already active 4835 * 4836 * @param {object} handler 4837 * @param {function} handler.match callback for when query is activated 4838 * @param {function} [handler.unmatch] callback for when query is deactivated 4839 * @param {function} [handler.setup] callback for immediate execution when a query handler is registered 4840 * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched? 4841 */ 4842 addHandler : function(handler) { 4843 var qh = new QueryHandler(handler); 4844 this.handlers.push(qh); 4845 4846 this.matches() && qh.on(); 4847 }, 4848 4849 /** 4850 * removes the given handler from the collection, and calls it's destroy methods 4851 * 4852 * @param {object || function} handler the handler to remove 4853 */ 4854 removeHandler : function(handler) { 4855 var handlers = this.handlers; 4856 each(handlers, function(h, i) { 4857 if(h.equals(handler)) { 4858 h.destroy(); 4859 return !handlers.splice(i,1); //remove from array and exit each early 4860 } 4861 }); 4862 }, 4863 4864 /** 4865 * Determine whether the media query should be considered a match 4866 * 4867 * @return {Boolean} true if media query can be considered a match, false otherwise 4868 */ 4869 matches : function() { 4870 return this.mql.matches || this.isUnconditional; 4871 }, 4872 4873 /** 4874 * Clears all handlers and unbinds events 4875 */ 4876 clear : function() { 4877 each(this.handlers, function(handler) { 4878 handler.destroy(); 4879 }); 4880 this.mql.removeListener(this.listener); 4881 this.handlers.length = 0; //clear array 4882 }, 4883 4884 /* 4885 * Assesses the query, turning on all handlers if it matches, turning them off if it doesn't match 4886 */ 4887 assess : function() { 4888 var action = this.matches() ? 'on' : 'off'; 4889 4890 each(this.handlers, function(handler) { 4891 handler[action](); 4892 }); 4893 } 4894 }; 4895 /** 4896 * Allows for registration of query handlers. 4897 * Manages the query handler's state and is responsible for wiring up browser events 4898 * 4899 * @constructor 4900 */ 4901 function MediaQueryDispatch () { 4902 if(!matchMedia) {
4903 throw new Error('matchMedia not present, legacy browsers require a polyfill'); 4904 } 4905 4906 this.queries = {}; 4907 this.browserIsIncapable = !matchMedia('only all').matches; 4908 } 4909 4910 MediaQueryDispatch.prototype = { 4911 4912 /** 4913 * Registers a handler for the given media query 4914 * 4915 * @param {string} q the media query 4916 * @param {object || Array || Function} options either a single query handler object, a function, or an array of query handlers 4917 * @param {function} options.match fired when query matched 4918 * @param {function} [options.unmatch] fired when a query is no longer matched 4919 * @param {function} [options.setup] fired when handler first triggered 4920 * @param {boolean} [options.deferSetup=false] whether setup should be run immediately or deferred until query is first matched 4921 * @param {boolean} [shouldDegrade=false] whether this particular media query should always run on incapable browsers 4922 */ 4923 register : function(q, options, shouldDegrade) { 4924 var queries = this.queries, 4925 isUnconditional = shouldDegrade && this.browserIsIncapable; 4926 4927 if(!queries[q]) { 4928 queries[q] = new MediaQuery(q, isUnconditional); 4929 } 4930 4931 //normalise to object in an array 4932 if(isFunction(options)) { 4933 options = { match : options }; 4934 } 4935 if(!isArray(options)) { 4936 options = [options]; 4937 } 4938 each(options, function(handler) { 4939 if (isFunction(handler)) { 4940 handler = { match : handler }; 4941 } 4942 queries[q].addHandler(handler); 4943 }); 4944 4945 return this; 4946 }, 4947 4948 /** 4949 * unregisters a query and all it's handlers, or a specific handler for a query 4950 * 4951 * @param {string} q the media query to target 4952 * @param {object || function} [handler] specific handler to unregister 4953 */ 4954 unregister : function(q, handler) { 4955 var query = this.queries[q]; 4956 4957 if(query) { 4958 if(handler) { 4959 query.removeHandler(handler); 4960 } 4961 else { 4962 query.clear(); 4963 delete this.queries[q]; 4964 } 4965 } 4966 4967 return this; 4968 } 4969 }; 4970 4971 return new MediaQueryDispatch(); 4972 4973})); 4974; 4975/** 4976 * hoverIntent is similar to jQuery's built-in "hover" method except that 4977 * instead of firing the handlerIn function immediately, hoverIntent checks 4978 * to see if the user's mouse has slowed down (beneath the sensitivity 4979 * threshold) before firing the event. The handlerOut function is only 4980 * called after a matching handlerIn. 4981 * 4982 * hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+ 4983 * http://cherne.net/brian/resources/jquery.hoverIntent.html 4984 * 4985 * You may use hoverIntent under the terms of the MIT license. Basically that 4986 * means you are free to use hoverIntent as long as this header is left intact. 4987 * Copyright 2007, 2013 Brian Cherne 4988 * 4989 * // basic usage ... just like .hover() 4990 * .hoverIntent( handlerIn, handlerOut ) 4991 * .hoverIntent( handlerInOut ) 4992 * 4993 * // basic usage ... with event delegation! 4994 * .hoverIntent( handlerIn, handlerOut, selector ) 4995 * .hoverIntent( handlerInOut, selector ) 4996 * 4997 * // using a basic configuration object 4998 * .hoverIntent( config ) 4999 * 5000 * @param handlerIn function OR configuration object 5001 * @param handlerOut function OR selector for delegation OR undefined 5002 * @param selector selector OR undefined 5003 * @author Brian Cherne <brian(at)cherne(dot)net> 5004 **/ 5005(function($) { 5006 $.fn.hoverIntent = function(handlerIn,handlerOut,selector) { 5007 5008 // default configuration values 5009 var cfg = { 5010 interval: 100, 5011 sensitivity: 7, 5012 timeout: 0 5013 }; 5014 5015 if ( typeof handlerIn === "object" ) { 5016 cfg = $.extend(cfg, handlerIn ); 5017 } else if ($.isFunction(handlerOut)) { 5018 cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } ); 5019 } else { 5020 cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } ); 5021 } 5022 5023 // instantiate variables 5024 // cX, cY = current X and Y position of mouse, updated by mousemove event 5025 // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval 5026 var cX, cY, pX, pY; 5027 5028 // A private function for getting mouse position 5029 var track = function(ev) { 5030 cX = ev.pageX; 5031 cY = ev.pageY; 5032 }; 5033 5034 // A private function for comparing current and previous mouse position 5035 var compare = function(ev,ob) { 5036 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 5037 // compare mouse positions to see if they've crossed the threshold 5038 if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { 5039 $(ob).off("mousemove.hoverIntent",track); 5040 // set hoverIntent state to true (so mouseOut can be called) 5041 ob.hoverIntent_s = 1; 5042 return cfg.over.apply(ob,[ev]); 5043 } else {
5044 // set previous coordinates for next time 5045 pX = cX; pY = cY; 5046 // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) 5047 ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); 5048 } 5049 }; 5050 5051 // A private function for delaying the mouseOut function 5052 var delay = function(ev,ob) { 5053 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 5054 ob.hoverIntent_s = 0; 5055 return cfg.out.apply(ob,[ev]); 5056 }; 5057 5058 // A private function for handling mouse 'hovering' 5059 var handleHover = function(e) { 5060 // copy objects to be passed into t (required for event object to be passed in IE) 5061 var ev = jQuery.extend({},e); 5062 var ob = this; 5063 5064 // cancel hoverIntent timer if it exists 5065 if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } 5066 5067 // if e.type == "mouseenter" 5068 if (e.type == "mouseenter") { 5069 // set "previous" X and Y position based on initial entry point 5070 pX = ev.pageX; pY = ev.pageY; 5071 // update "current" X and Y position based on mousemove 5072 $(ob).on("mousemove.hoverIntent",track); 5073 // start polling interval (self-calling timeout) to compare mouse coordinates over time 5074 if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} 5075 5076 // else e.type == "mouseleave" 5077 } else { 5078 // unbind expensive mousemove event 5079 $(ob).off("mousemove.hoverIntent",track); 5080 // if hoverIntent state is true, then call the mouseOut function after the specified delay 5081 if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} 5082 } 5083 }; 5084 5085 // listen for mouseenter and mouseleave 5086 return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector); 5087 }; 5088})(jQuery); 5089; 5090/*! 5091 * jQuery Superfish Menu Plugin - v1.7.5 5092 * Copyright (c) 2014 Joel Birch 5093 * 5094 * Dual licensed under the MIT and GPL licenses: 5095 * http://www.opensource.org/licenses/mit-license.php 5096 * http://www.gnu.org/licenses/gpl.html 5097 */ 5098 5099;(function ($, w) { 5100 "use strict"; 5101 5102 var methods = (function () { 5103 // private properties and methods go here 5104 var c = { 5105 bcClass: 'sf-breadcrumb', 5106 menuClass: 'sf-js-enabled', 5107 anchorClass: 'sf-with-ul', 5108 menuArrowClass: 'sf-arrows' 5109 }, 5110 ios = (function () { 5111 var ios = /iPhone|iPad|iPod/i.test(navigator.userAgent); 5112 if (ios) { 5113 // iOS clicks only bubble as far as body children 5114 $(w).load(function () { 5115 $('body').children().on('click', $.noop); 5116 }); 5117 } 5118 return ios; 5119 })(), 5120 wp7 = (function () { 5121 var style = document.documentElement.style; 5122 return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent)); 5123 })(), 5124 unprefixedPointerEvents = (function () { 5125 return (!!w.PointerEvent); 5126 })(), 5127 toggleMenuClasses = function ($menu, o) { 5128 var classes = c.menuClass; 5129 if (o.cssArrows) { 5130 classes += ' ' + c.menuArrowClass; 5131 } 5132 $menu.toggleClass(classes); 5133 }, 5134 setPathToCurrent = function ($menu, o) { 5135 return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels) 5136 .addClass(o.hoverClass + ' ' + c.bcClass) 5137 .filter(function () { 5138 return ($(this).children(o.popUpSelector).hide().show().length); 5139 }).removeClass(o.pathClass); 5140 }, 5141 toggleAnchorClass = function ($li) { 5142 $li.children('a').toggleClass(c.anchorClass); 5143 }, 5144 toggleTouchAction = function ($menu) { 5145 var msTouchAction = $menu.css('ms-touch-action'); 5146 var touchAction = $menu.css('touch-action'); 5147 touchAction = touchAction || msTouchAction; 5148 touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y'; 5149 $menu.css({ 5150 'ms-touch-action': touchAction, 5151 'touch-action': touchAction 5152 }); 5153 }, 5154 applyHandlers = function ($menu, o) { 5155 var targets = 'li:has(' + o.popUpSelector + ')'; 5156 if ($.fn.hoverIntent && !o.disableHI) { 5157 $menu.hoverIntent(over, out, targets); 5158 } 5159 else { 5160 $menu 5161 .on('mouseenter.superfish', targets, over)
vendor: 4,773 bytes, lines 5162-5337
5162 .on('mouseleave.superfish', targets, out); 5163 } 5164 var touchevent = 'MSPointerDown.superfish'; 5165 if (unprefixedPointerEvents) { 5166 touchevent = 'pointerdown.superfish'; 5167 } 5168 if (!ios) { 5169 touchevent += ' touchend.superfish'; 5170 } 5171 if (wp7) { 5172 touchevent += ' mousedown.superfish'; 5173 } 5174 $menu 5175 .on('focusin.superfish', 'li', over) 5176 .on('focusout.superfish', 'li', out) 5177 .on(touchevent, 'a', o, touchHandler); 5178 }, 5179 touchHandler = function (e) { 5180 var $this = $(this), 5181 $ul = $this.siblings(e.data.popUpSelector); 5182 5183 if ($ul.length > 0 && $ul.is(':hidden')) { 5184 $this.one('click.superfish', false); 5185 if (e.type === 'MSPointerDown' || e.type === 'pointerdown') { 5186 $this.trigger('focus'); 5187 } else { 5188 $.proxy(over, $this.parent('li'))(); 5189 } 5190 } 5191 }, 5192 over = function () { 5193 var $this = $(this), 5194 o = getOptions($this); 5195 clearTimeout(o.sfTimer); 5196 $this.siblings().superfish('hide').end().superfish('show'); 5197 }, 5198 out = function () { 5199 var $this = $(this), 5200 o = getOptions($this); 5201 if (ios) { 5202 $.proxy(close, $this, o)(); 5203 } 5204 else { 5205 clearTimeout(o.sfTimer); 5206 o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay); 5207 } 5208 }, 5209 close = function (o) { 5210 o.retainPath = ($.inArray(this[0], o.$path) > -1); 5211 this.superfish('hide'); 5212 5213 if (!this.parents('.' + o.hoverClass).length) { 5214 o.onIdle.call(getMenu(this)); 5215 if (o.$path.length) { 5216 $.proxy(over, o.$path)(); 5217 } 5218 } 5219 }, 5220 getMenu = function ($el) { 5221 return $el.closest('.' + c.menuClass); 5222 }, 5223 getOptions = function ($el) { 5224 return getMenu($el).data('sf-options'); 5225 }; 5226 5227 return { 5228 // public methods 5229 hide: function (instant) { 5230 if (this.length) { 5231 var $this = this, 5232 o = getOptions($this); 5233 if (!o) { 5234 return this; 5235 } 5236 var not = (o.retainPath === true) ? o.$path : '', 5237 $ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector), 5238 speed = o.speedOut; 5239 5240 if (instant) { 5241 $ul.show(); 5242 speed = 0; 5243 } 5244 o.retainPath = false; 5245 o.onBeforeHide.call($ul); 5246 $ul.stop(true, true).animate(o.animationOut, speed, function () { 5247 var $this = $(this); 5248 o.onHide.call($this); 5249 }); 5250 } 5251 return this; 5252 }, 5253 show: function () { 5254 var o = getOptions(this); 5255 if (!o) { 5256 return this; 5257 } 5258 var $this = this.addClass(o.hoverClass), 5259 $ul = $this.children(o.popUpSelector); 5260 5261 o.onBeforeShow.call($ul); 5262 $ul.stop(true, true).animate(o.animation, o.speed, function () { 5263 o.onShow.call($ul); 5264 }); 5265 return this; 5266 }, 5267 destroy: function () { 5268 return this.each(function () { 5269 var $this = $(this), 5270 o = $this.data('sf-options'), 5271 $hasPopUp; 5272 if (!o) { 5273 return false; 5274 } 5275 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 5276 clearTimeout(o.sfTimer); 5277 toggleMenuClasses($this, o); 5278 toggleAnchorClass($hasPopUp); 5279 toggleTouchAction($this); 5280 // remove event handlers 5281 $this.off('.superfish').off('.hoverIntent'); 5282 // clear animation's inline display style 5283 $hasPopUp.children(o.popUpSelector).attr('style', function (i, style) { 5284 return style.replace(/display[^;]+;?/g, ''); 5285 }); 5286 // reset 'current' path classes 5287 o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass); 5288 $this.find('.' + o.hoverClass).removeClass(o.hoverClass); 5289 o.onDestroy.call($this); 5290 $this.removeData('sf-options'); 5291 }); 5292 }, 5293 init: function (op) { 5294 return this.each(function () { 5295 var $this = $(this); 5296 if ($this.data('sf-options')) { 5297 return false; 5298 } 5299 var o = $.extend({}, $.fn.superfish.defaults, op), 5300 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 5301 o.$path = setPathToCurrent($this, o); 5302 5303 $this.data('sf-options', o); 5304 5305 toggleMenuClasses($this, o); 5306 toggleAnchorClass($hasPopUp); 5307 toggleTouchAction($this); 5308 applyHandlers($this, o); 5309 5310 $hasPopUp.not('.' + c.bcClass).superfish('hide', true); 5311 5312 o.onInit.call(this); 5313 }); 5314 } 5315 }; 5316 })(); 5317 5318 $.fn.superfish = function (method, args) { 5319 if (methods[method]) { 5320 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 5321 } 5322 else if (typeof method === 'object' || ! method) { 5323 return methods.init.apply(this, arguments); 5324 } 5325 else { 5326 return $.error('Method ' + method + ' does not exist on jQuery.fn.superfish'); 5327 } 5328 }; 5329 5330 $.fn.superfish.defaults = { 5331 popUpSelector: 'ul,.sf-mega', // within menu context 5332 hoverClass: 'sfHover', 5333 pathClass: 'overrideThisToUse', 5334 pathLevels: 1, 5335 delay: 800, 5336 animation: {opacity: 'show'}, 5337 animationOut: {opacity: 'hide'},
5338 speed: 'normal', 5339 speedOut: 'fast', 5340 cssArrows: true, 5341 disableHI: false, 5342 onInit: $.noop, 5343 onBeforeShow: $.noop, 5344 onShow: $.noop, 5345 onBeforeHide: $.noop, 5346 onHide: $.noop, 5347 onIdle: $.noop, 5348 onDestroy: $.noop 5349 }; 5350 5351})(jQuery, window); 5352; 5353/*! 5354 * Custom v1.0 5355 * Contains handlers for the different site functions 5356 * 5357 * Copyright (c) 2013-2015 DesignOrbital.com 5358 * License: GNU General Public License v2 or later 5359 * http://www.gnu.org/licenses/gpl-2.0.html 5360 */ 5361 5362/* global enquire:true */ 5363 5364( function( $ ) { 5365 5366 var anemone = { 5367 5368 // Menu 5369 menuInit: function() { 5370 5371 // Superfish Menu 5372 $( 'ul.sf-menu' ).superfish( { 5373 delay: 1500, 5374 animation: { opacity : 'show', height : 'show' }, 5375 speed: 'fast', 5376 autoArrows: false, 5377 cssArrows: true 5378 } ); 5379 5380 }, 5381 5382 // Responsive Menu 5383 responsiveMenuInit: function() { 5384 5385 // Clone the Primary Menu and remove classes from clone to prevent css issues 5386 var $primaryMenuClone = $( '.primary-menu' ).clone().removeAttr( 'class' ).addClass( 'primary-menu-responsive' ); 5387 $primaryMenuClone.removeAttr( 'style' ).find( '*' ).each( function( i,e ) { 5388 $( e ).removeAttr( 'style' ); 5389 } ); 5390 5391 // Insert the cloned menu before the site content 5392 $( '<div class="site-primary-menu-responsive" />' ).insertBefore( '.site-content' ); 5393 $primaryMenuClone.appendTo( '.site-primary-menu-responsive' ); 5394 5395 // Add dropdown toggle that display child menu items. 5396 $( '.site-primary-menu-responsive .page_item_has_children > a, .site-primary-menu-responsive .menu-item-has-children > a' ).append( '<button class="dropdown-toggle" aria-expanded="false"/>' ); 5397 $( '.site-primary-menu-responsive .dropdown-toggle' ).off( 'click' ).on( 'click', function( e ) { 5398 e.preventDefault(); 5399 $( this ).toggleClass( 'toggle-on' ); 5400 $( this ).parent().next( '.children, .sub-menu' ).toggleClass( 'toggle-on' ); 5401 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false'); 5402 } ); 5403 5404 }, 5405 5406 // Open Slide Panel - Responsive Mobile Menu 5407 slidePanelInit: function() { 5408 5409 // Elements 5410 var menuResponsive = $( '.site-primary-menu-responsive' ); 5411 var overlayEffect = $( '.overlay-effect' ); 5412 5413 // Responsive Menu Slide 5414 $( '.toggle-menu' ).off( 'click' ).on( 'click', function( e ) { 5415 5416 // Prevent Default 5417 e.preventDefault(); 5418 e.stopPropagation(); 5419 5420 // ToggleClass 5421 menuResponsive.toggleClass( 'show' ); 5422 overlayEffect.toggleClass( 'open' ); 5423 5424 } ); 5425 5426 // Overlay Slide Close 5427 overlayEffect.off( 'click' ).on( 'click', function() { 5428 anemone.slidePanelCloseInit(); 5429 } ); 5430 5431 }, 5432 5433 // Close Slide Panel 5434 slidePanelCloseInit: function() { 5435 5436 // Elements 5437 var menuResponsive = $( '.site-primary-menu-responsive' ); 5438 var overlayEffect = $( '.overlay-effect' ); 5439 5440 // Slide Panel Close Logic 5441 if( overlayEffect.hasClass( 'open' ) ) { 5442 5443 // For Menu 5444 if( menuResponsive.hasClass( 'show' ) ) { 5445 menuResponsive.toggleClass( 'show' ); 5446 } 5447 5448 // Toggle Overlay Slide 5449 overlayEffect.toggleClass( 'open' ); 5450 5451 } 5452 5453 }, 5454 5455 // Widget Logic 5456 widgetLogicInit: function() { 5457 5458 // Social Menu Widget 5459 $( '.widget_nav_menu > div[class^="menu-social-"] > ul > li > a' ).wrapInner( '<span class="screen-reader-text"></span>' ); 5460 5461 // Custom Menu Widget 5462 $( '.widget_nav_menu .menu-item-has-children > a' ).append( '<span class="custom-menu-toggle" aria-expanded="false"></span>' ); 5463 $( '.widget_nav_menu .custom-menu-toggle' ).off( 'click' ).on( 'click', function( e ) { 5464 e.preventDefault(); 5465 $( this ).toggleClass( 'toggle-on' ); 5466 $( this ).parent().next( '.sub-menu' ).toggleClass( 'toggle-on' ); 5467 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); 5468 } ); 5469 5470 // Pages Widget 5471 $( '.widget_pages .page_item_has_children > a' ).append( '<span class="page-toggle" aria-expanded="false"></span>' ); 5472 $( '.widget_pages .page-toggle' ).off( 'click' ).on( 'click', function( e ) { 5473 e.preventDefault(); 5474 $( this ).toggleClass( 'toggle-on' ); 5475 $( this ).parent().next( '.children' ).toggleClass( 'toggle-on' ); 5476 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); 5477 } ); 5478 5479 // Categories Widget 5480 $( '.widget_categories' ).find( '.children' ).parent().addClass( 'category_item_has_children' ); 5481 $( '.widget_categories .category_item_has_children > a' ).append( '<span class="category-toggle" aria-expanded="false"></span>' ); 5482 $( '.widget_categories .category-toggle' ).off( 'click' ).on( 'click', function( e ) { 5483 e.preventDefault(); 5484 $( this ).toggleClass( 'toggle-on' ); 5485 $( this ).parent().next( '.children' ).toggleClass( 'toggle-on' ); 5486 $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); 5487 } ); 5488 5489 }, 5490 5491 // Media Queries 5492 mqInit: function() { 5493 5494 enquire 5495 .register( 'screen and ( min-width: 768px )' , { 5496 5497 match : function() { 5498 5499 // Site Bar 5500 setTimeout( function() { 5501 5502 if ( $( 'body' ).hasClass( 'has-header-social-menu' ) ) { 5503 var siteBarMargin = ( $( '.site-header' ).height() / 2 ) - 18; 5504 $( '.site-bar' ).css( 'margin-top', siteBarMargin + 'px' ).fadeIn( 500 ); 5505 } 5506 5507 }, 500 ); 5508 5509 } 5510 5511 }) 5512 .register( 'screen and ( max-width: 767px )' , { 5513 5514 deferSetup : true, 5515 setup : function() { 5516 5517 // Responsive Menu 5518 anemone.responsiveMenuInit(); 5519 5520 }, 5521 match : function() { 5522 5523 // Sliding Panels for Menu 5524 anemone.slidePanelInit(); 5525 5526 // Responsive Tables 5527 $( '.single .entry-content, .page .entry-content' ).find( 'table' ).wrap( '<div class="table-responsive"></div>' ); 5528 5529 }, 5530 unmatch : function() { 5531 5532 // Responsive Menu Close 5533 anemone.slidePanelCloseInit(); 5534 5535 // Responsive Tables Undo 5536 $( '.single .entry-content, .page .entry-content' ).find( 'table' ).unwrap( '<div class="table-responsive"></div>' ); 5537 5538 } 5539 5540 }); 5541 5542 } 5543 5544 }; 5545 5546 // Document Ready 5547 $( document ).ready( function() { 5548 5549 // Menu 5550 anemone.menuInit(); 5551 5552 // Sliding Panels for Menu and Sidebar 5553 anemone.slidePanelInit(); 5554 5555 // Widget Logic 5556 anemone.widgetLogicInit(); 5557 5558 // Media Queries 5559 anemone.mqInit(); 5560 5561 } ); 5562 5563 // Document Keyup 5564 $( document ).keyup( function( e ) { 5565 5566 // Escape Key 5567 if ( e.keyCode === 27 ) { 5568 5569 // Make the escape key to close the slide panel 5570 anemone.slidePanelCloseInit(); 5571 5572 } 5573 5574 } ); 5575 5576} )( jQuery ); 5577; 5578/* global FB, jpfbembed */ 5579( function ( window ) { 5580 var facebookEmbed = function () { 5581 var fbroot, src, newScript, firstScript; 5582 5583 if ( 'undefined' !== typeof FB && FB.XFBML ) {
5584 FB.XFBML.parse(); 5585 } else { 5586 fbroot = document.createElement( 'div' ); 5587 fbroot.id = 'fb-root'; 5588 document.getElementsByTagName( 'body' )[ 0 ].appendChild( fbroot ); 5589 5590 src = '//connect.facebook.net/' + jpfbembed.locale + '/sdk.js#xfbml=1'; 5591 if ( jpfbembed.appid ) { 5592 src += '&appId=' + jpfbembed.appid; 5593 } 5594 src += '&version=v2.3'; 5595 5596 newScript = document.createElement( 'script' ); 5597 newScript.setAttribute( 'src', src ); 5598 firstScript = document.querySelector( 'script' ); 5599 firstScript.parentNode.insertBefore( newScript, firstScript ); 5600 } 5601 }; 5602 5603 window.fbAsyncInit = function () { 5604 FB.init( { 5605 appId: jpfbembed.appid, 5606 version: 'v2.3', 5607 } ); 5608 5609 FB.XFBML.parse(); 5610 }; 5611 5612 if ( 'undefined' !== typeof infiniteScroll ) { 5613 document.body.addEventListener( 'post-load', facebookEmbed ); 5614 } 5615 5616 facebookEmbed(); 5617} )( window ); 5618; 5619!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}l=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.
5619info.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)}}
5619({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"}
5619function 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
5619s"))}),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.