1(()=>{(function(){var Scroller,stats,type,text,totop,loading_text,isIE=-1!==navigator.userAgent.search("MSIE");if(isIE){var IEVersion=navigator.userAgent.match(/MSIE\s?(\d+)\.?\d*;/);IEVersion=parseInt(IEVersion[1])}function fullscreenState(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement?1:0}"https:"===document.location.protocol&&(infiniteScroll.settings.ajaxurl=infiniteScroll.settings.ajaxurl.replace("http://","https://")),Scroller=function(e){var t=this;this.id=e.id,this.body=document.body,this.window=window,this.element=document.getElementById(e.id),this.wrapperClass=e.wrapper_class,this.ready=!0,this.disabled=!1,this.page=1,this.offset=e.offset,this.currentday=e.currentday,this.order=e.order,this.throttle=!1,this.click_handle=e.click_handle,this.google_analytics=e.google_analytics,this.history=e.history,this.origURL=window.location.href,this.handle=document.createElement("div"),this.handle.setAttribute("id","infinite-handle");var n=document.createElement("span"),i=document.createElement("button");i.textContent=text,n.appendChild(i),this.handle.appendChild(n),this.footer={el:document.getElementById("infinite-footer"),wrap:e.footer},this.checkViewportOnLoadBound=t.checkViewportOnLoad.bind(this),this.wpMediaelement=null,"scroll"===type?(this.window.addEventListener("scroll",function(){t.throttle=!0}),t.gotop(),setInterval(function(){t.throttle&&(t.throttle=!1,t.thefooter(),t.refresh(),t.determineURL())},250),t.ensureFilledViewport(),this.body.addEventListener("is.post-load",t.checkViewportOnLoadBound)):"click"===type&&(this.click_handle&&this.element.appendChild(this.handle),this.handle.addEventListener("click",function(){t.click_handle&&t.handle.parentNode.removeChild(t.handle),t.refresh()})),this.body.addEventListener("is.post-load",t.initializeMejs)},Scroller.prototype.getScrollTop=function(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},Scroller.prototype.extend=function(e){e=e||{};for(var t=1;t<arguments.length;t++)if(arguments[t])for(var n in arguments[t])Object.hasOwn(arguments[t],n)&&(e[n]=arguments[t][n]);return e},Scroller.prototype.check=function(){return this.measure(this.element,[this.wrapperClass]).bottom<2*this.window.innerHeight},Scroller.prototype.render=function(e){var t=Array.prototype.slice.call(e.fragment.childNodes);for(this.body.classList.add("infinity-success");t.length>0;){var n=t.shift();this.element.appendChild(n)}this.trigger(this.body,"is.post-load",{jqueryEventName:"post-load",data:e}),this.ready=!0},Scroller.prototype.query=function(){return{page:this.page+this.offset,currentday:this.currentday,order:this.order,scripts:window.infiniteScroll.settings.scripts,styles:window.infiniteScroll.settings.styles,query_args:window.infiniteScroll.settings.query_args,query_before:window.infiniteScroll.settings.query_before,last_post_date:window.infiniteScroll.settings.last_post_date}},Scroller.prototype.animate=function(e,t){var n=performance.now();requestAnimationFrame(function i(o){var r=Math.min(1,(o-n)/t);e(r),r<1&&requestAnimationFrame(i)})},Scroller.prototype.gotop=function(){var e=document.getElementById("infinity-blog-title"),t=this;e&&(e.setAttribute("title",totop),e.addEventListener("click",function(e){var n=t.window.pageYOffset;e.preventDefault(),t.animate(function(e){var t=n-n*e;document.documentElement.scrollTop=document.body.scrollTop=t},200)}))},Scroller.prototype.thefooter=function(){var e,t,n,i,o=this;if(this.footer&&this.footer.el){if("string"==typeof this.footer.wrap){try{t=(t=document.getElementById(this.footer.wrap).getBoundingClientRect()).width}catch{t=0}t>479&&(e=this.footer.el.querySelector(".container"))&&(e.style.width=t+"px")}n=parseInt(o.footer.el.style.bottom||-50,10),i=this.window.pageYOffset>=350?0:-50,n!==i&&o.animate(function(e){var t=n+(i-n)*e;o.footer.el.style.bottom=t+"px",1===e&&(n=i)},200)}},Scroller.prototype.urlEncodeJSON=function(e,t){var n,i,o=[];for(var r in e)n=encodeURIComponent(r),i=t?t+"["+n+"]":n,"object"==typeof e[r]?!Array.isArray(e[r])||e[r].length>0?o.push(this.urlEncodeJSON(e[r],i)):o.push(i+"[]="):o.push(i+"="+encodeURIComponent(e[r]));return o.join("&")},Scroller.prototype.refresh=function(){var self=this,query,xhr,loader,customized;if(!this.disabled&&this.ready&&this.check())return this.ready=!1,this.click_handle&&(loader||(document.getElementById("infinite-aria").textContent=loading_text,loader=document.createElement("div"),loader.classList.add("infinite-loader"),loader.setAttribute("role","progress"),loader.innerHTML='<svg class="jetpack-spinner infinite-loader-spinner spinner" width="28" height="28" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><circle cx="50" cy="50" r="46" fill="none" stroke="#ddd" stroke-width="8"/><path d="M 50 4 A 46 46 0 0 1 96 50" fill="none" stroke="currentColor" stroke-width="8" stroke-linecap="round"><animateTransform attributeName="transform" type="rotate" dur="1.4s" from="0 50 50" to="360 50 50" repeatCount="indef
1inite"/></path></svg>'),this.element.appendChild(loader)),query=self.extend({action:"infinite_scroll"},this.query()),"undefined"!=typeof wp&&wp.customize&&wp.customize.settings.theme&&(customized={},query.wp_customize="on",query.theme=wp.customize.settings.theme.stylesheet,wp.customize.each(function(e){e._dirty&&(customized[e.id]=e())}),query.customized=JSON.stringify(customized),query.nonce=wp.customize.settings.nonce.preview),xhr=new XMLHttpRequest,xhr.open("POST",infiniteScroll.settings.ajaxurl,!0),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),xhr.send(self.urlEncodeJSON(query)),xhr.onerror=function(){self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader),self.ready=!0},xhr.onload=function(){var response=JSON.parse(xhr.responseText),httpCheck=xhr.status>=200&&xhr.status<300,responseCheck=void 0!==response.html;if(response&&httpCheck&&responseCheck){if(self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader),response.scripts&&Array.isArray(response.scripts)&&response.scripts.forEach(function(e){var t=e.footer?"body":"head";window.infiniteScroll.settings.scripts.push(e.handle),e.extra_data&&self.appendInlineScript(e.extra_data,t),e.before_handle&&self.appendInlineScript(e.before_handle,t);var n=document.createElement("script");n.type="text/javascript",n.src=e.src,n.id=e.handle,n.async=!1,e.after_handle&&(n.onload=function(){self.appendInlineScript(e.after_handle,t)}),"wp-mediaelement"===e.handle&&self.body.removeEventListener("is.post-load",self.initializeMejs),"wp-mediaelement"===e.handle&&"undefined"==typeof mejs?(self.wpMediaelement={},self.wpMediaelement.tag=n,self.wpMediaelement.element=t,setTimeout(self.maybeLoadMejs.bind(self),250)):document.getElementsByTagName(t)[0].appendChild(n)}),response.styles&&Array.isArray(response.styles)&&response.styles.forEach(function(item){window.infiniteScroll.settings.styles.push(item.handle);var style=document.createElement("link");style.rel="stylesheet",style.href=item.src,style.id=item.handle+"-css",!item.conditional||isIE&&eval(item.conditional.replace(/%ver/g,IEVersion))||(style=!1),style&&document.getElementsByTagName("head")[0].appendChild(style)}),response.fragment=document.createElement("div"),response.fragment.innerHTML=response.html,self.page++,stats&&((new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?"+stats+"&post=0&baba="+Math.random()),"object"==typeof response.postflair&&"object"==typeof WPCOM_sharing_counts&&(WPCOM_sharing_counts=self.extend(WPCOM_sharing_counts,response.postflair)),self.render.call(self,response),"click"===type?(infiniteScroll.settings.wrapper&&document.querySelector("#infinite-view-"+(self.page+self.offset-1)+" a:first-of-type").focus({preventScroll:!0}),response.lastbatch?self.click_handle?(self.body.classList.add("infinity-end"),self.body.classList.remove("infinity-success")):self.trigger(this.body,"infinite-scroll-posts-end"):self.click_handle?self.element.appendChild(self.handle):self.trigger(this.body,"infinite-scroll-posts-more")):response.lastbatch&&(self.disabled=!0,self.body.classList.add("infinity-end"),self.body.classList.remove("infinity-success")),response.currentday&&(self.currentday=response.currentday),self.google_analytics){var ga_url=self.history.path.replace(/%d/,self.page);"object"==typeof _gaq&&_gaq.push(["_trackPageview",ga_url]),"function"==typeof ga&&ga("send","pageview",ga_url)}}else self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader)},xhr},Scroller.prototype.appendInlineScript=function(e,t){var n=document.createElement("script"),i=document.createTextNode("//<![CDATA[ \n"+e+"\n//]]>");n.type="text/javascript",n.appendChild(i),document.getElementsByTagName(t)[0].appendChild(n)},Scroller.prototype.maybeLoadMejs=function(){null!==this.wpMediaelement&&("undefined"==typeof mejs?setTimeout(this.maybeLoadMejs.bind(this),250):(document.getElementsByTagName(this.wpMediaelement.element)[0].appendChild(this.wpMediaelement.tag),this.wpMediaelement=null,this.body.addEventListener("is.post-load",this.initializeMejs)))},Scroller.prototype.initializeMejs=function(e){if(e.detail&&e.detail.html&&(-1!==e.detail.html.indexOf("wp-audio-shortcode")||-1!==e.detail.html.indexOf("wp-video-shortcode"))&&"undefined"!=typeof mejs){var t,n={};"undefined"!=typeof _wpmejsSettings&&(n.pluginPath=_wpmejsSettings.pluginPath),n.success=function(e){var t=e.attributes.autoplay&&"false"!==e.attributes.autoplay;"flash"===e.pluginType&&t&&e.addEventListener("canplay",function(){e.play()},!1)},t=document.querySelectorAll(".wp-audio-shortcode, .wp-video-shortcode"),t=(t=Array.prototype.slice.call(t)).filter(function(e){for(;e.parentNode;){if(e.classList.contains("mejs-container"))return!1;e=e.parentNode}return!0});for(var i=0;i<t.length;i++)new MediaElementPlayer(t[i],n)}},Scroller.prototype.measure=function(e,t){t=t||[];for(var n,i,o,r=Array.prototype.slice.call(e.children),s=Number.MAX_VALUE,l=0;r.length>0;){for(n=r.shift(),o=0;o<t.length;o++)if(n.classList.contains(t[o])){r=r.concat(Array.prototype.slice.call(n.children));break}i=n.getBoundingClientRect(),s=Math.min(s,i.top),l=Math.max(l,i.bottom)}var a=Math.round(window.innerHeight/2),d=s<=a&&l>=a;return{top:s,bottom:l,height:l-s,factor:(Math.min(l,a)-Math.max(s,0))/a,isActive:d}},Scroller.prototype.ensureFilledViewport=function(){var e=this,t=e.window.innerHeight,n=e.measure(e.element,[e.wrapperClass]);e.body.removeEventListener("is.post-load",e.checkViewportOnLoadBound),0!==n.bottom&&n.bottom<t&&(e.ready=!0,e.refresh())},Scroller.prototype.checkViewportOnLoad=function(){this.ensureFilledViewport()};var previousFullScrenState=fullscreenState();Scroller.prototype.determineURL=function(){var e,t=this,n=-1,i=fullscreenState(),o=0;if(previousFullScrenState^i)previousFullScrenState=i;else{previousFullScrenState=i,e=document.querySelectorAll("."+t.wrapperClass);for(var r=0;r<e.length;r++){var s=t.measure(e[r]);if(s.isActive){n=parseInt(e[r].dataset.pageNum,10);break}s.factor>o&&(n=parseInt(e[r].dataset.pageNum,10),o=s.factor)}t.updateURL(n)}},Scroller.prototype.updateURL=function(e){if(window.history.pushState){var t=this,n=t.origURL;-1!==e&&(n=window.location.protocol+"//"+t.history.host+t.history.path.replace(/%d/,e)+t.history.parameters),window.location.href!==n&&history.pushState(null,null,n)}},Scroller.prototype.pause=function(){this.disabled=!0},Scroller.prototype.resume=function(){this.disabled=!1},Scroller.prototype.trigger=function(e,t,n){var i;(n=n||{}).jqueryEventName&&"undefined"!=typeof jQuery&&jQuery(e).trigger(n.jqueryEventName,n.data||null);try{i=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n.data||null})}catch{(i=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,n.data||null)}e.dispatchEvent(i)};var jetpackInfinityModule=function(){if("object"==typeof infiniteScroll&&(infiniteScroll.
1settings.body_class.split(" ").forEach(function(e){e&&document.body.classList.add(e)}),stats=infiniteScroll.settings.stats,type=infiniteScroll.settings.type,text=infiniteScroll.settings.text,totop=infiniteScroll.settings.totop,loading_text=infiniteScroll.settings.loading_text,infiniteScroll.scroller=new Scroller(infiniteScroll.settings),"click"===type)){var e=null;window.addEventListener("scroll",function(){e||(e=setTimeout(function(){infiniteScroll.scroller.determineURL(),e=null},250))})}};"interactive"===document.readyState||"complete"===document.readyState?jetpackInfinityModule():document.addEventListener("DOMContentLoaded",jetpackInfinityModule)})()})();; 2!function(e){var o={};function n(t){if(o[t])return o[t].exports;var r=o[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:t})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,o){if(1&o&&(e=n(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var r in e)n.d(t,r,function(o){return e[o]}.bind(null,r));return t},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},n.p="",n(n.s=273)}({273:function(e,o){!function(){"use strict";let e,o;function n(e){return new Promise((o,n)=>{const t=document.createElement("script");t.onload=()=>o(),t.onerror=e=>n(e),t.src=e,document.body.appendChild(t)})}function t(){if(e)return e;const o=window.wpcom_coblocks_js;return e=n(o.coblocks_lightbox_js),e}function r(){if(o)return o;window.wpcomJQueryUsageLoggerDisabled=!0;const e=window.wpcom_coblocks_js,t=window.jQuery?Promise.resolve():n(e.jquery_core_js).then(()=>n(e.jquery_migrate_js)),r=t.then(()=>window.imagesLoaded?Promise.resolve():n(e.imagesloaded_js)),c=t.then(()=>window.Masonry?Promise.resolve():n(e.masonry_js)),u=Promise.all([t,r,c]).then(()=>n(e.coblocks_masonry_js));return o=u,o}function c(){document.querySelector(".wp-block-coblocks-gallery-masonry")&&r(),document.querySelector(".has-lightbox")&&t(),document.body.classList.contains("block-editor-page")&&(r(),t())}"loading"!==document.readyState?c():document.addEventListener("DOMContentLoaded",c)}()}});; 3/** 4 * Bricklayer - Cascading Grid Layouts 5 * https://github.com/ademilter/bricklayer 6 * Copyright © 2016 Adem İlter 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining 9 * a copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 24 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 27 var __extends = (this && this.__extends) || function (d, b) { 28 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 29 function __() { this.constructor = d; } 30 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 31 }; 32 var Bricklayer; 33 (function (Bricklayer) { 34 // Helper Functions 35 function toArray(arrayLike) { 36 return [].slice.call(arrayLike); 37 } 38 function triggerEvent(el, eventName, data) { 39 var event; 40 try { 41 event = new CustomEvent(eventName, { detail: data }); 42 } 43 catch(err) { 44 event = document.createEvent('CustomEvent'); 45 event.initCustomEvent(eventName, true, true, data); 46 } 47 return el.dispatchEvent(event); 48 } 49 var DEFAULTS = { 50 rulerClassName: "bricklayer-column-sizer", 51 columnClassName: "bricklayer-column" 52 }; 53 var SimpleElement = (function () { 54 function SimpleElement(className) { 55 this.element = document.createElement("div"); 56 this.element.className = className; 57 } 58 SimpleElement.prototype.destroy = function () { 59 this.element.parentNode.removeChild(this.element); 60 }; 61 return SimpleElement; 62 }()); 63 var Ruler = (function (_super) { 64 __extends(Ruler, _super); 65 function Ruler() { 66 _super.apply(this, arguments); 67 } 68 Ruler.prototype.getWidth = function () { 69 this.element.setAttribute('style', "\n display: block;\n visibility: hidden !important;\n top: -1000px !important;\n "); 70 var width = this.element.offsetWidth; 71 this.element.removeAttribute('style'); 72 return width; 73 }; 74 return Ruler; 75 }(SimpleElement)); 76 var Column = (function (_super) { 77 __extends(Column, _super); 78 function Column() { 79 _super.apply(this, arguments); 80 } 81 return Column; 82 }(SimpleElement)); 83 var Container = (function () { 84 function Container(element, options) { 85 if (options === void 0) { options = DEFAULTS; } 86 this.element = element; 87 this.options = options; 88 this.build(); 89 this.buildResponsive(); 90 }
91 Container.prototype.append = function (item) { 92 var _this = this; 93 if (Array.isArray(item)) { 94 item.forEach(function (item) { return _this.append(item); }); 95 return; 96 } 97 var column = this.findMinHeightColumn(); 98 this.elements = toArray(this.elements).concat([item]); 99 this.applyPosition('append', column, item); 100 }; 101 Container.prototype.prepend = function (item) { 102 var _this = this; 103 if (Array.isArray(item)) { 104 item.forEach(function (item) { return _this.prepend(item); }); 105 return; 106 } 107 var column = this.findMinHeightColumn(); 108 this.elements = [item].concat(toArray(this.elements)); 109 this.applyPosition('prepend', column, item); 110 }; 111 Container.prototype.on = function (eventName, handler) { 112 // eventName may be: 113 // - breakpoint 114 // - afterAppend 115 // - beforeAppend 116 // - afterPrepend 117 // - beforePrepend 118 this.element.addEventListener("bricklayer." + eventName, handler); 119 return this; 120 }; 121 Container.prototype.redraw = function () { 122 var columnCount = this.columnCount; 123 this.checkColumnCount(false); 124 this.reorderElements(columnCount); 125 triggerEvent(this.element, "bricklayer.redraw", { columnCount: columnCount }); 126 }; 127 Container.prototype.destroy = function () { 128 var _this = this; 129 this.ruler.destroy(); 130 toArray(this.elements).forEach(function (el) { return _this.element.appendChild(el); }); 131 toArray(this.getColumns()).forEach(function (el) { return el.parentNode.removeChild(el); }); 132 triggerEvent(this.element, "bricklayer.destroy", {}); 133 }; 134 Container.prototype.build = function () { 135 this.ruler = new Ruler(this.options.rulerClassName); 136 this.elements = this.getElementsInOrder(); 137 this.element.insertBefore(this.ruler.element, this.element.firstChild); 138 }; 139 Container.prototype.buildResponsive = function () { 140 var _this = this; 141 window.addEventListener("resize", function (e) { return _this.checkColumnCount(); }); 142 this.checkColumnCount(); 143 this.on("breakpoint", function (e) { return _this.reorderElements(e.detail.columnCount); }); 144 if (this.columnCount >= 1) { 145 this.reorderElements(this.columnCount); 146 } 147 }; 148 Container.prototype.getColumns = function() { 149 var _this = this; 150 return Array.prototype.filter.call( _this.element.children, function( element, index, aElements ) { 151 var classNames = element.className.split( ' ' ); 152 return classNames.indexOf( _this.options.columnClassName ) > - 1; 153 } ); 154 }; 155 Container.prototype.findMinHeightColumn = function () { 156 var allColumns = toArray(this.getColumns()); 157 var heights = allColumns.map(function (column) { return column.offsetHeight; }); 158 var minHeight = Math.min.apply(null, heights); 159 return allColumns[heights.indexOf(minHeight)]; 160 }; 161 Container.prototype.getElementsInOrder = function() { 162 var _this = this; 163 return Array.prototype.filter.call( _this.element.children, function( element, index, aElements ) { 164 var classNames = element.className.split( ' ' ); 165 return classNames.indexOf( _this.options.columnClassName ) == - 1 && classNames.indexOf( _this.options.rulerClassName == - 1 ); 166 } ); 167 }; 168 Container.prototype.checkColumnCount = function (publish) { 169 if (publish === void 0) { publish = true; } 170 var columnCount = this.getColumnCount(); 171 if (this.columnCount !== columnCount) { 172 if (publish) { 173 triggerEvent(this.element, "bricklayer.breakpoint", { columnCount: columnCount }); 174 } 175 this.columnCount = columnCount; 176 } 177 }; 178 Container.prototype.reorderElements = function (columnCount) { 179 var _this = this; 180 if (columnCount === void 0) { columnCount = 1; } 181 var elements = toArray(this.elements).map(function (item) { 182 var element = item.parentNode ? item.parentNode.removeChild(item) : item; 183 return element; 184 }); 185 var columns = this.getColumns(); 186 for (var i = 0; i < columns.length; i++) { 187 columns[i].parentNode.removeChild(columns[i]); 188 } 189 for (var i = 0; i < columnCount; i++) { 190 var element = (new Column(this.options.columnClassName)).element; 191 this.element.appendChild(element); 192 }
193 elements.forEach(function (item) { 194 var column = _this.findMinHeightColumn(); 195 column.appendChild(item); 196 }); 197 }; 198 Container.prototype.getColumnCount = function () { 199 var containerWidth = this.element.offsetWidth; 200 var columnWidth = this.ruler.getWidth(); 201 if (columnWidth == 0) { 202 return 1; 203 } 204 return Math.round(containerWidth / columnWidth); 205 }; 206 Container.prototype.applyPosition = function (pos, column, item) { 207 var _this = this; 208 var trigger = function (timing) { 209 var eventName = timing + pos.charAt(0).toUpperCase() + pos.substr(1); 210 triggerEvent(_this.element, "bricklayer." + eventName, { item: item, column: column }); 211 }; 212 trigger('before'); 213 switch (pos) { 214 case 'append': 215 column.appendChild(item); 216 break; 217 case 'prepend': 218 column.insertBefore(item, column.firstChild); 219 break; 220 } 221 trigger('after'); 222 }; 223 return Container; 224 }()); 225 Bricklayer.Container = Container; 226 })(Bricklayer || (Bricklayer = {})); 227 (function (root, factory) { 228 if (typeof define === 'function' && define.amd) { 229 define(function () { return factory(); }); 230 } 231 else if (typeof window !== "undefined" && root === window) { 232 root.Bricklayer = factory(); 233 } 234 else if (typeof module === 'object' && module.exports) { 235 module.exports = factory(); 236 } 237 }(typeof window !== "undefined" ? window : this, function () { 238 return Bricklayer.Container; 239 })); 240 241},{}]},{},[1]);; 242/*! 243 * modernizr v3.3.1 244 * Build http://modernizr.com/download?-applicationcache-audio-backgroundsize-borderimage-borderradius-boxshadow-canvas-canvastext-cssanimations-csscolumns-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-flexbox-fontface-generatedcontent-geolocation-hashchange-history-hsla-indexeddb-inlinesvg-input-inputtypes-localstorage-multiplebgs-opacity-postmessage-rgba-sessionstorage-smil-svg-svgclippaths-textshadow-video-webgl-websockets-websqldatabase-webworkers-addtest-domprefixes-hasevent-mq-prefixed-prefixes-setclasses-shiv-testallprops-testprop-teststyles-dontmin 245 * 246 * Copyright (c) 247 * Faruk Ates 248 * Paul Irish 249 * Alex Sexton 250 * Ryan Seddon 251 * Patrick Kettner 252 * Stu Cox 253 * Richard Herrera 254 255 * MIT License 256 */ 257 258/* 259 * Modernizr tests which native CSS3 and HTML5 features are available in the 260 * current UA and makes the results available to you in two ways: as properties on 261 * a global `Modernizr` object, and as classes on the `<html>` element. This 262 * information allows you to progressively enhance your pages with a granular level 263 * of control over the experience. 264 */ 265 266;(function(window, document, undefined){ 267 var classes = []; 268 269 270 var tests = []; 271 272 273 /** 274 * 275 * ModernizrProto is the constructor for Modernizr 276 * 277 * @class 278 * @access public 279 */ 280 281 var ModernizrProto = { 282 // The current version, dummy 283 _version: '3.3.1', 284 285 // Any settings that don't work as separate modules 286 // can go in here as configuration. 287 _config: { 288 'classPrefix': '', 289 'enableClasses': true, 290 'enableJSClass': true, 291 'usePrefixes': true 292 }, 293 294 // Queue of tests 295 _q: [], 296 297 // Stub these for people who are listening 298 on: function(test, cb) { 299 // I don't really think people should do this, but we can 300 // safe guard it a bit. 301 // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests. 302 // This is in case people listen to synchronous tests. I would leave it out, 303 // but the code to *disallow* sync tests in the real version of this 304 // function is actually larger than this. 305 var self = this; 306 setTimeout(function() { 307 cb(self[test]); 308 }, 0); 309 }, 310 311 addTest: function(name, fn, options) { 312 tests.push({name: name, fn: fn, options: options}); 313 }, 314 315 addAsyncTest: function(fn) { 316 tests.push({name: null, fn: fn}); 317 } 318 }; 319 320 321 322 // Fake some of Object.create so we can force non test results to be non "own" properties. 323 var Modernizr = function() {}; 324 Modernizr.prototype = ModernizrProto; 325 326 // Leak modernizr globally when you `require` it rather than force it here. 327 // Overwrite name so constructor name is nicer :D 328 Modernizr = new Modernizr(); 329 330 331 /*! 332 { 333 "name": "Application Cache", 334 "property": "applicationcache", 335 "caniuse": "offline-apps", 336 "tags": ["storage", "offline"],
337 "notes": [{ 338 "name": "MDN documentation", 339 "href": "https://developer.mozilla.org/en/docs/HTML/Using_the_application_cache" 340 }], 341 "polyfills": ["html5gears"] 342 } 343 !*/ 344 /* DOC 345 Detects support for the Application Cache, for storing data to enable web-based applications run offline. 346 347 The API has been [heavily criticized](http://alistapart.com/article/application-cache-is-a-douchebag) and discussions are underway to address this. 348 */ 349 350 Modernizr.addTest('applicationcache', 'applicationCache' in window); 351 352 /*! 353 { 354 "name": "Geolocation API", 355 "property": "geolocation", 356 "caniuse": "geolocation", 357 "tags": ["media"], 358 "notes": [{ 359 "name": "MDN documentation", 360 "href": "https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation" 361 }], 362 "polyfills": [ 363 "joshuabell-polyfill", 364 "webshims", 365 "geo-location-javascript", 366 "geolocation-api-polyfill" 367 ] 368 } 369 !*/ 370 /* DOC 371 Detects support for the Geolocation API for users to provide their location to web applications. 372 */ 373 374 // geolocation is often considered a trivial feature detect... 375 // Turns out, it's quite tricky to get right: 376 // 377 // Using !!navigator.geolocation does two things we don't want. It: 378 // 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513 379 // 2. Disables page caching in WebKit: webk.it/43956 380 // 381 // Meanwhile, in Firefox < 8, an about:config setting could expose 382 // a false positive that would throw an exception: bugzil.la/688158 383 384 Modernizr.addTest('geolocation', 'geolocation' in navigator); 385 386 /*! 387 { 388 "name": "History API", 389 "property": "history", 390 "caniuse": "history", 391 "tags": ["history"], 392 "authors": ["Hay Kranen", "Alexander Farkas"], 393 "notes": [{ 394 "name": "W3C Spec", 395 "href": "https://www.w3.org/TR/html51/browsers.html#the-history-interface" 396 }, { 397 "name": "MDN documentation", 398 "href": "https://developer.mozilla.org/en-US/docs/Web/API/window.history" 399 }], 400 "polyfills": ["historyjs", "html5historyapi"] 401 } 402 !*/ 403 /* DOC 404 Detects support for the History API for manipulating the browser session history. 405 */ 406 407 Modernizr.addTest('history', function() { 408 // Issue #733 409 // The stock browser on Android 2.2 & 2.3, and 4.0.x returns positive on history support 410 // Unfortunately support is really buggy and there is no clean way to detect 411 // these bugs, so we fall back to a user agent sniff :( 412 var ua = navigator.userAgent; 413 414 // We only want Android 2 and 4.0, stock browser, and not Chrome which identifies 415 // itself as 'Mobile Safari' as well, nor Windows Phone (issue #1471). 416 if ((ua.indexOf('Android 2.') !== -1 || 417 (ua.indexOf('Android 4.0') !== -1)) && 418 ua.indexOf('Mobile Safari') !== -1 && 419 ua.indexOf('Chrome') === -1 && 420 ua.indexOf('Windows Phone') === -1) { 421 return false; 422 } 423 424 // Return the regular check 425 return (window.history && 'pushState' in window.history); 426 }); 427 428 /*! 429 { 430 "name": "postMessage", 431 "property": "postmessage", 432 "caniuse": "x-doc-messaging", 433 "notes": [{ 434 "name": "W3C Spec", 435 "href": "http://www.w3.org/TR/html5/comms.html#posting-messages" 436 }], 437 "polyfills": ["easyxdm", "postmessage-jquery"] 438 } 439 !*/ 440 /* DOC 441 Detects support for the `window.postMessage` protocol for cross-document messaging. 442 */ 443 444 Modernizr.addTest('postmessage', 'postMessage' in window); 445 446 /*! 447 { 448 "name": "SVG", 449 "property": "svg", 450 "caniuse": "svg", 451 "tags": ["svg"], 452 "authors": ["Erik Dahlstrom"], 453 "polyfills": [ 454 "svgweb", 455 "raphael", 456 "amplesdk", 457 "canvg", 458 "svg-boilerplate", 459 "sie", 460 "dojogfx", 461 "fabricjs" 462 ] 463 } 464 !*/ 465 /* DOC 466 Detects support for SVG in `<embed>` or `<object>` elements. 467 */ 468 469 Modernizr.addTest('svg', !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect); 470 471 /*! 472 { 473 "name": "WebSockets Support", 474 "property": "websockets", 475 "authors": ["Phread [fearphage]", "Mike Sherov [mikesherov]", "Burak Yigit Kaya [BYK]"], 476 "caniuse": "websockets", 477 "tags": ["html5"], 478 "warnings": [ 479 "This test will reject any old version of WebSockets even if it is not prefixed such as in Safari 5.1" 480 ],
481 "notes": [{ 482 "name": "CLOSING State and Spec", 483 "href": "https://www.w3.org/TR/websockets/#the-websocket-interface" 484 }], 485 "polyfills": [ 486 "sockjs", 487 "socketio", 488 "kaazing-websocket-gateway", 489 "websocketjs", 490 "atmosphere", 491 "graceful-websocket", 492 "portal", 493 "datachannel" 494 ] 495 } 496 !*/ 497 498 Modernizr.addTest('websockets', 'WebSocket' in window && window.WebSocket.CLOSING === 2); 499 500 /*! 501 { 502 "name": "Local Storage", 503 "property": "localstorage", 504 "caniuse": "namevalue-storage", 505 "tags": ["storage"], 506 "knownBugs": [], 507 "notes": [], 508 "warnings": [], 509 "polyfills": [ 510 "joshuabell-polyfill", 511 "cupcake", 512 "storagepolyfill", 513 "amplifyjs", 514 "yui-cacheoffline" 515 ] 516 } 517 !*/ 518 519 // In FF4, if disabled, window.localStorage should === null. 520 521 // Normally, we could not test that directly and need to do a 522 // `('localStorage' in window) && ` test first because otherwise Firefox will 523 // throw bugzil.la/365772 if cookies are disabled 524 525 // Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem 526 // will throw the exception: 527 // QUOTA_EXCEEDED_ERROR DOM Exception 22. 528 // Peculiarly, getItem and removeItem calls do not throw. 529 530 // Because we are forced to try/catch this, we'll go aggressive. 531 532 // Just FWIW: IE8 Compat mode supports these features completely: 533 // www.quirksmode.org/dom/html5.html 534 // But IE8 doesn't support either with local files 535 536 Modernizr.addTest('localstorage', function() { 537 var mod = 'modernizr'; 538 try { 539 localStorage.setItem(mod, mod); 540 localStorage.removeItem(mod); 541 return true; 542 } catch (e) { 543 return false; 544 } 545 }); 546 547 /*! 548 { 549 "name": "Session Storage", 550 "property": "sessionstorage", 551 "tags": ["storage"], 552 "polyfills": ["joshuabell-polyfill", "cupcake", "sessionstorage"] 553 } 554 !*/ 555 556 // Because we are forced to try/catch this, we'll go aggressive. 557 558 // Just FWIW: IE8 Compat mode supports these features completely: 559 // www.quirksmode.org/dom/html5.html 560 // But IE8 doesn't support either with local files 561 Modernizr.addTest('sessionstorage', function() { 562 var mod = 'modernizr'; 563 try { 564 sessionStorage.setItem(mod, mod); 565 sessionStorage.removeItem(mod); 566 return true; 567 } catch (e) { 568 return false; 569 } 570 }); 571 572 /*! 573 { 574 "name": "Web SQL Database", 575 "property": "websqldatabase", 576 "caniuse": "sql-storage", 577 "tags": ["storage"] 578 } 579 !*/ 580 581 // Chrome incognito mode used to throw an exception when using openDatabase 582 // It doesn't anymore. 583 Modernizr.addTest('websqldatabase', 'openDatabase' in window); 584 585 /*! 586 { 587 "name": "Web Workers", 588 "property": "webworkers", 589 "caniuse" : "webworkers", 590 "tags": ["performance", "workers"], 591 "notes": [{ 592 "name": "W3C Reference", 593 "href": "https://www.w3.org/TR/workers/" 594 }, { 595 "name": "HTML5 Rocks article", 596 "href": "http://www.html5rocks.com/en/tutorials/workers/basics/" 597 }, { 598 "name": "MDN documentation", 599 "href": "https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers" 600 }], 601 "polyfills": ["fakeworker", "html5shims"] 602 } 603 !*/ 604 /* DOC 605 Detects support for the basic `Worker` API from the Web Workers spec. Web Workers provide a simple means for web content to run scripts in background threads. 606 */ 607 608 Modernizr.addTest('webworkers', 'Worker' in window); 609 610 611 /** 612 * List of property values to set for css tests. See ticket #21 613 * http://git.io/vUGl4 614 * 615 * @memberof Modernizr 616 * @name Modernizr._prefixes 617 * @optionName Modernizr._prefixes 618 * @optionProp prefixes 619 * @access public 620 * @example 621 * 622 * Modernizr._prefixes is the internal list of prefixes that we test against 623 * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply 624 * an array of kebab-case vendor prefixes you can use within your code. 625 * 626 * Some common use cases include 627 * 628 * Generating all possible prefixed version of a CSS property 629 * ```js 630 * var rule = Modernizr._prefixes.join('transform: rotate(20deg); '); 631 * 632 * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);' 633 * ``` 634 * 635 * Generating all possible prefixed version of a CSS value 636 * ```js 637 * rule = 'display:' + Modernizr._prefixes.join('flex; display:') + 'flex'; 638 * 639 * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex' 640 * ``` 641 */ 642 643 // we use ['',''] rather than an empty array in order to allow a pattern of .`join()`ing prefixes to test 644 // values in feature detects to continue to work 645 var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : ['','']); 646 647 // expose these for the plugin API. Look in the source for how to join() them against your input 648 ModernizrProto._prefixes = prefixes; 649 650 651 652 /** 653 * is returns a boolean if the typeof an obj is exactly type. 654 * 655 * @access private 656 * @function is 657 * @param {*} obj - A thing we want to check the type of 658 * @param {string} type - A string to compare the typeof against 659 * @returns {boolean} 660 */ 661 662 function is(obj, type) { 663 return typeof obj === type; 664 } 665 ; 666 667 /** 668 * Run through all tests and detect their support in the current UA. 669 * 670 * @access private 671 */ 672 673 function testRunner() { 674 var featureNames; 675 var feature; 676 var aliasIdx; 677 var result; 678 var nameIdx; 679 var featureName; 680 var featureNameSplit; 681 682 for (var featureIdx in tests) { 683 if (tests.hasOwnProperty(featureIdx)) { 684 featureNames = []; 685 feature = tests[featureIdx]; 686 // run the test, throw the return value into the Modernizr, 687 // then based on that boolean, define an appropriate className 688 // and push it into an array of classes we'll join later. 689 // 690 // If there is no name, it's an 'async' test that is run, 691 // but not directly added to the object. That should 692 // be done with a post-run addTest call. 693 if (feature.name) { 694 featureNames.push(feature.name.toLowerCase()); 695 696 if (feature.options && feature.options.aliases && feature.options.aliases.length) { 697 // Add all the aliases into the names list 698 for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) { 699 featureNames.push(feature.options.aliases[aliasIdx].toLowerCase()); 700 } 701 } 702 } 703 704 // Run the test, or use the raw value if it's not a function 705 result = is(feature.fn, 'function') ? feature.fn() : feature.fn; 706 707 708 // Set each of the names on the Modernizr object 709 for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) { 710 featureName = featureNames[nameIdx];
711 // Support dot properties as sub tests. We don't do checking to make sure 712 // that the implied parent tests have been added. You must call them in 713 // order (either in the test, or make the parent test a dependency). 714 // 715 // Cap it to TWO to make the logic simple and because who needs that kind of subtesting 716 // hashtag famous last words 717 featureNameSplit = featureName.split('.'); 718 719 if (featureNameSplit.length === 1) { 720 Modernizr[featureNameSplit[0]] = result; 721 } else { 722 // cast to a Boolean, if not one already 723 /* jshint -W053 */ 724 if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { 725 Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); 726 } 727 728 Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result; 729 } 730 731 classes.push((result ? '' : 'no-') + featureNameSplit.join('-')); 732 } 733 } 734 } 735 } 736 ; 737 738 /** 739 * docElement is a convenience wrapper to grab the root element of the document 740 * 741 * @access private 742 * @returns {HTMLElement|SVGElement} The root element of the document 743 */ 744 745 var docElement = document.documentElement; 746 747 748 /** 749 * A convenience helper to check if the document we are running in is an SVG document 750 * 751 * @access private 752 * @returns {boolean} 753 */ 754 755 var isSVG = docElement.nodeName.toLowerCase() === 'svg'; 756 757 758 /** 759 * setClasses takes an array of class names and adds them to the root element 760 * 761 * @access private 762 * @function setClasses 763 * @param {string[]} classes - Array of class names 764 */ 765 766 // Pass in an and array of class names, e.g.:
767 // ['no-webp', 'borderradius', ...] 768 function setClasses(classes) { 769 var className = docElement.className; 770 var classPrefix = Modernizr._config.classPrefix || ''; 771 772 if (isSVG) { 773 className = className.baseVal; 774 } 775 776 // Change `no-js` to `js` (independently of the `enableClasses` option) 777 // Handle classPrefix on this too 778 if (Modernizr._config.enableJSClass) { 779 var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)'); 780 className = className.replace(reJS, '$1' + classPrefix + 'js$2'); 781 } 782 783 if (Modernizr._config.enableClasses) { 784 // Add the new classes 785 className += ' ' + classPrefix + classes.join(' ' + classPrefix); 786 isSVG ? docElement.className.baseVal = className : docElement.className = className; 787 } 788 789 } 790 791 ; 792 793 /** 794 * @optionName html5shiv 795 * @optionProp html5shiv 796 */ 797 798 // Take the html5 variable out of the html5shiv scope so we can return it. 799 var html5; 800 if (!isSVG) { 801 /** 802 * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 803 */ 804 ;(function(window, document) { 805 /*jshint evil:true */ 806 /** version */ 807 var version = '3.7.3'; 808 809 /** Preset options */ 810 var options = window.html5 || {}; 811 812 /** Used to skip problem elements */ 813 var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; 814 815 /** Not all elements can be cloned in IE **/ 816 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; 817 818 /** Detect whether the browser supports default html5 styles */ 819 var supportsHtml5Styles; 820 821 /** Name of the expando, to work with multiple documents or to re-shiv one document */ 822 var expando = '_html5shiv'; 823 824 /** The id for the the documents expando */ 825 var expanID = 0; 826 827 /** Cached data for each document */ 828 var expandoData = {}; 829 830 /** Detect whether the browser supports unknown elements */ 831 var supportsUnknownElements; 832 833 (function() { 834 try { 835 var a = document.createElement('a'); 836 a.innerHTML = '<xyz></xyz>'; 837 //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles 838 supportsHtml5Styles = ('hidden' in a); 839 840 supportsUnknownElements = a.childNodes.length == 1 || (function() { 841 // assign a false positive if unable to shiv 842 (document.createElement)('a'); 843 var frag = document.createDocumentFragment(); 844 return ( 845 typeof frag.cloneNode == 'undefined' || 846 typeof frag.createDocumentFragment == 'undefined' || 847 typeof frag.createElement == 'undefined' 848 ); 849 }()); 850 } catch(e) { 851 // assign a false positive if detection fails => unable to shiv 852 supportsHtml5Styles = true; 853 supportsUnknownElements = true; 854 } 855 856 }()); 857 858 /*--------------------------------------------------------------------------*/ 859 860 /** 861 * Creates a style sheet with the given CSS text and adds it to the document. 862 * @private 863 * @param {Document} ownerDocument The document. 864 * @param {String} cssText The CSS text. 865 * @returns {StyleSheet} The style element. 866 */ 867 function addStyleSheet(ownerDocument, cssText) { 868 var p = ownerDocument.createElement('p'), 869 parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; 870 871 p.innerHTML = 'x<style>' + cssText + '</style>'; 872 return parent.insertBefore(p.lastChild, parent.firstChild); 873 } 874 875 /** 876 * Returns the value of `html5.elements` as an array.
vendor: 6,804 bytes, lines 877-1034
877 * @private 878 * @returns {Array} An array of shived element node names. 879 */ 880 function getElements() { 881 var elements = html5.elements; 882 return typeof elements == 'string' ? elements.split(' ') : elements; 883 } 884 885 /** 886 * Extends the built-in list of html5 elements 887 * @memberOf html5 888 * @param {String|Array} newElements whitespace separated list or array of new element names to shiv 889 * @param {Document} ownerDocument The context document. 890 */ 891 function addElements(newElements, ownerDocument) { 892 var elements = html5.elements; 893 if(typeof elements != 'string'){ 894 elements = elements.join(' '); 895 } 896 if(typeof newElements != 'string'){ 897 newElements = newElements.join(' '); 898 } 899 html5.elements = elements +' '+ newElements; 900 shivDocument(ownerDocument); 901 } 902 903 /** 904 * Returns the data associated to the given document 905 * @private 906 * @param {Document} ownerDocument The document. 907 * @returns {Object} An object of data. 908 */ 909 function getExpandoData(ownerDocument) { 910 var data = expandoData[ownerDocument[expando]]; 911 if (!data) { 912 data = {}; 913 expanID++; 914 ownerDocument[expando] = expanID; 915 expandoData[expanID] = data; 916 } 917 return data; 918 } 919 920 /** 921 * returns a shived element for the given nodeName and document 922 * @memberOf html5 923 * @param {String} nodeName name of the element 924 * @param {Document|DocumentFragment} ownerDocument The context document. 925 * @returns {Object} The shived element. 926 */ 927 function createElement(nodeName, ownerDocument, data){ 928 if (!ownerDocument) { 929 ownerDocument = document; 930 } 931 if(supportsUnknownElements){ 932 return ownerDocument.createElement(nodeName); 933 } 934 if (!data) { 935 data = getExpandoData(ownerDocument); 936 } 937 var node; 938 939 if (data.cache[nodeName]) { 940 node = data.cache[nodeName].cloneNode(); 941 } else if (saveClones.test(nodeName)) { 942 node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); 943 } else { 944 node = data.createElem(nodeName); 945 } 946 947 // Avoid adding some elements to fragments in IE < 9 because 948 // * Attributes like `name` or `type` cannot be set/changed once an element 949 // is inserted into a document/fragment 950 // * Link elements with `src` attributes that are inaccessible, as with 951 // a 403 response, will cause the tab/window to crash 952 // * Script elements appended to fragments will execute when their `src` 953 // or `text` property is set 954 return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; 955 } 956 957 /** 958 * returns a shived DocumentFragment for the given document 959 * @memberOf html5 960 * @param {Document} ownerDocument The context document. 961 * @returns {Object} The shived DocumentFragment. 962 */ 963 function createDocumentFragment(ownerDocument, data){ 964 if (!ownerDocument) { 965 ownerDocument = document; 966 } 967 if(supportsUnknownElements){ 968 return ownerDocument.createDocumentFragment(); 969 } 970 data = data || getExpandoData(ownerDocument); 971 var clone = data.frag.cloneNode(), 972 i = 0, 973 elems = getElements(), 974 l = elems.length; 975 for(;i<l;i++){ 976 clone.createElement(elems[i]); 977 } 978 return clone; 979 } 980 981 /** 982 * Shivs the `createElement` and `createDocumentFragment` methods of the document. 983 * @private 984 * @param {Document|DocumentFragment} ownerDocument The document. 985 * @param {Object} data of the document. 986 */ 987 function shivMethods(ownerDocument, data) { 988 if (!data.cache) { 989 data.cache = {}; 990 data.createElem = ownerDocument.createElement; 991 data.createFrag = ownerDocument.createDocumentFragment; 992 data.frag = data.createFrag(); 993 } 994 995 996 ownerDocument.createElement = function(nodeName) { 997 //abort shiv 998 if (!html5.shivMethods) { 999 return data.createElem(nodeName); 1000 } 1001 return createElement(nodeName, ownerDocument, data); 1002 }; 1003 1004 ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + 1005 'var n=f.cloneNode(),c=n.createElement;' + 1006 'h.shivMethods&&(' + 1007 // unroll the `createElement` calls 1008 getElements().join().replace(/[\w\-:]+/g, function(nodeName) { 1009 data.createElem(nodeName); 1010 data.frag.createElement(nodeName); 1011 return 'c("' + nodeName + '")'; 1012 }) + 1013 ');return n}' 1014 )(html5, data.frag); 1015 } 1016 1017 /*--------------------------------------------------------------------------*/ 1018 1019 /** 1020 * Shivs the given document. 1021 * @memberOf html5 1022 * @param {Document} ownerDocument The document to shiv. 1023 * @returns {Document} The shived document. 1024 */ 1025 function shivDocument(ownerDocument) { 1026 if (!ownerDocument) { 1027 ownerDocument = document; 1028 } 1029 var data = getExpandoData(ownerDocument); 1030 1031 if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { 1032 data.hasCSS = !!addStyleSheet(ownerDocument, 1033 // corrects block display not defined in IE6/7/8/9 1034 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
1034play:block}' + 1035 // adds styling not present in IE6/7/8/9 1036 'mark{background:#FF0;color:#000}' + 1037 // hides non-rendered elements 1038 'template{display:none}' 1039 ); 1040 } 1041 if (!supportsUnknownElements) { 1042 shivMethods(ownerDocument, data); 1043 } 1044 return ownerDocument; 1045 } 1046 1047 /*--------------------------------------------------------------------------*/ 1048 1049 /** 1050 * The `html5` object is exposed so that more elements can be shived and 1051 * existing shiving can be detected on iframes. 1052 * @type Object 1053 * @example 1054 * 1055 * // options can be changed before the script is included 1056 * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; 1057 */ 1058 var html5 = { 1059 1060 /** 1061 * An array or space separated string of node names of the elements to shiv. 1062 * @memberOf html5 1063 * @type Array|String 1064 */ 1065 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video', 1066 1067 /** 1068 * current version of html5shiv 1069 */ 1070 'version': version, 1071 1072 /** 1073 * A flag to indicate that the HTML5 style sheet should be inserted. 1074 * @memberOf html5 1075 * @type Boolean 1076 */ 1077 'shivCSS': (options.shivCSS !== false), 1078 1079 /** 1080 * Is equal to true if a browser supports creating unknown/HTML5 elements 1081 * @memberOf html5 1082 * @type boolean 1083 */ 1084 'supportsUnknownElements': supportsUnknownElements, 1085 1086 /** 1087 * A flag to indicate that the document's `createElement` and `createDocumentFragment` 1088 * methods should be overwritten. 1089 * @memberOf html5 1090 * @type Boolean 1091 */ 1092 'shivMethods': (options.shivMethods !== false), 1093 1094 /** 1095 * A string to describe the type of `html5` object ("default" or "default print"). 1096 * @memberOf html5
1097 * @type String 1098 */ 1099 'type': 'default', 1100 1101 // shivs the document according to the specified `html5` object options 1102 'shivDocument': shivDocument, 1103 1104 //creates a shived element 1105 createElement: createElement, 1106 1107 //creates a shived documentFragment 1108 createDocumentFragment: createDocumentFragment, 1109 1110 //extends list of elements 1111 addElements: addElements 1112 }; 1113 1114 /*--------------------------------------------------------------------------*/ 1115 1116 // expose html5 1117 window.html5 = html5; 1118 1119 // shiv the document 1120 shivDocument(document); 1121 1122 if(typeof module == 'object' && module.exports){ 1123 module.exports = html5; 1124 } 1125 1126 }(typeof window !== "undefined" ? window : this, document)); 1127 } 1128 ; 1129 1130 /** 1131 * If the browsers follow the spec, then they would expose vendor-specific style as: 1132 * elem.style.WebkitBorderRadius 1133 * instead of something like the following, which would be technically incorrect: 1134 * elem.style.webkitBorderRadius 1135 1136 * Webkit ghosts their properties in lowercase but Opera & Moz do not. 1137 * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ 1138 * erik.eae.net/archives/2008/03/10/21.48.10/ 1139 1140 * More here: github.com/Modernizr/Modernizr/issues/issue/21 1141 * 1142 * @access private 1143 * @returns {string} The string representing the vendor-specific style properties 1144 */ 1145 1146 var omPrefixes = 'Moz O ms Webkit'; 1147 1148 1149 /** 1150 * List of JavaScript DOM values used for tests 1151 * 1152 * @memberof Modernizr 1153 * @name Modernizr._domPrefixes 1154 * @optionName Modernizr._domPrefixes 1155 * @optionProp domPrefixes 1156 * @access public 1157 * @example 1158 * 1159 * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather 1160 * than kebab-case properties, all properties are their Capitalized variant 1161 * 1162 * ```js 1163 * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ]; 1164 * ``` 1165 */ 1166 1167 var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []); 1168 ModernizrProto._domPrefixes = domPrefixes; 1169 1170 1171 /** 1172 * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support 1173 * 1174 * @author kangax 1175 * @access private 1176 * @function hasOwnProp 1177 * @param {object} object - The object to check for a property 1178 * @param {string} property - The property to check for 1179 * @returns {boolean} 1180 */ 1181 1182 // hasOwnProperty shim by kangax needed for Safari 2.0 support 1183 var hasOwnProp; 1184 1185 (function() { 1186 var _hasOwnProperty = ({}).hasOwnProperty; 1187 /* istanbul ignore else */ 1188 /* we have no way of testing IE 5.5 or safari 2, 1189 * so just assume the else gets hit */ 1190 if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) { 1191 hasOwnProp = function(object, property) { 1192 return _hasOwnProperty.call(object, property); 1193 }; 1194 } 1195 else { 1196 hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ 1197 return ((property in object) && is(object.constructor.prototype[property], 'undefined')); 1198 }; 1199 } 1200 })(); 1201 1202 1203 1204 1205 // _l tracks listeners for async tests, as well as tests that execute after the initial run 1206 ModernizrProto._l = {}; 1207 1208 /** 1209 * Modernizr.on is a way to listen for the completion of async tests. Being 1210 * asynchronous, they may not finish before your scripts run. As a result you 1211 * will get a possibly false negative `undefined` value. 1212 * 1213 * @memberof Modernizr 1214 * @name Modernizr.on 1215 * @access public 1216 * @function on 1217 * @param {string} feature - String name of the feature detect 1218 * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not 1219 * @example 1220 * 1221 * ```js 1222 * Modernizr.on('flash', function( result ) { 1223 * if (result) { 1224 * // the browser has flash 1225 * } else { 1226 * // the browser does not have flash 1227 * } 1228 * }); 1229 * ``` 1230 */ 1231 1232 ModernizrProto.on = function(feature, cb) { 1233 // Create the list of listeners if it doesn't exist 1234 if (!this._l[feature]) { 1235 this._l[feature] = []; 1236 } 1237 1238 // Push this test on to the listener list 1239 this._l[feature].push(cb); 1240 1241 // If it's already been resolved, trigger it on next tick 1242 if (Modernizr.hasOwnProperty(feature)) { 1243 // Next Tick 1244 setTimeout(function() { 1245 Modernizr._trigger(feature, Modernizr[feature]); 1246 }, 0); 1247 } 1248 }; 1249 1250 /** 1251 * _trigger is the private function used to signal test completion and run any 1252 * callbacks registered through [Modernizr.on](#modernizr-on) 1253 * 1254 * @memberof Modernizr 1255 * @name Modernizr._trigger 1256 * @access private 1257 * @function _trigger 1258 * @param {string} feature - string name of the feature detect
1259 * @param {function|boolean} [res] - A feature detection function, or the boolean = 1260 * result of a feature detection function 1261 */ 1262 1263 ModernizrProto._trigger = function(feature, res) { 1264 if (!this._l[feature]) { 1265 return; 1266 } 1267 1268 var cbs = this._l[feature]; 1269 1270 // Force async 1271 setTimeout(function() { 1272 var i, cb; 1273 for (i = 0; i < cbs.length; i++) { 1274 cb = cbs[i]; 1275 cb(res); 1276 } 1277 }, 0); 1278 1279 // Don't trigger these again 1280 delete this._l[feature]; 1281 }; 1282 1283 /** 1284 * addTest allows you to define your own feature detects that are not currently 1285 * included in Modernizr (under the covers it's the exact same code Modernizr 1286 * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result 1287 * will be added onto the Modernizr object, as well as an appropriate className set on 1288 * the html element when configured to do so 1289 * 1290 * @memberof Modernizr 1291 * @name Modernizr.addTest 1292 * @optionName Modernizr.addTest() 1293 * @optionProp addTest 1294 * @access public 1295 * @function addTest 1296 * @param {string|object} feature - The string name of the feature detect, or an 1297 * object of feature detect names and test 1298 * @param {function|boolean} test - Function returning true if feature is supported, 1299 * false if not. Otherwise a boolean representing the results of a feature detection 1300 * @example 1301 * 1302 * The most common way of creating your own feature detects is by calling 1303 * `Modernizr.addTest` with a string (preferably just lowercase, without any 1304 * punctuation), and a function you want executed that will return a boolean result 1305 * 1306 * ```js 1307 * Modernizr.addTest('itsTuesday', function() { 1308 * var d = new Date(); 1309 * return d.getDay() === 2; 1310 * }); 1311 * ``` 1312 * 1313 * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday, 1314 * and to `false` every other day of the week. One thing to notice is that the names of 1315 * feature detect functions are always lowercased when added to the Modernizr object. That 1316 * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will. 1317 * 1318 * 1319 * Since we only look at the returned value from any feature detection function, 1320 * you do not need to actually use a function. For simple detections, just passing 1321 * in a statement that will return a boolean value works just fine. 1322 * 1323 * ```js 1324 * Modernizr.addTest('hasJquery', 'jQuery' in window); 1325 * ``` 1326 * 1327 * Just like before, when the above runs `Modernizr.hasjquery` will be true if 1328 * jQuery has been included on the page. Not using a function saves a small amount 1329 * of overhead for the browser, as well as making your code much more readable. 1330 * 1331 * Finally, you also have the ability to pass in an object of feature names and 1332 * their tests. This is handy if you want to add multiple detections in one go. 1333 * The keys should always be a string, and the value can be either a boolean or 1334 * function that returns a boolean. 1335 * 1336 * ```js 1337 * var detects = { 1338 * 'hasjquery': 'jQuery' in window, 1339 * 'itstuesday': function() { 1340 * var d = new Date(); 1341 * return d.getDay() === 2; 1342 * } 1343 * } 1344 * 1345 * Modernizr.addTest(detects); 1346 * ``` 1347 * 1348 * There is really no difference between the first methods and this one, it is 1349 * just a convenience to let you write more readable code. 1350 */ 1351 1352 function addTest(feature, test) { 1353 1354 if (typeof feature == 'object') { 1355 for (var key in feature) { 1356 if (hasOwnProp(feature, key)) { 1357 addTest(key, feature[ key ]); 1358 } 1359 } 1360 } else { 1361 1362 feature = feature.toLowerCase(); 1363 var featureNameSplit = feature.split('.'); 1364 var last = Modernizr[featureNameSplit[0]]; 1365 1366 // Again, we don't check for parent test existence. Get that right, though. 1367 if (featureNameSplit.length == 2) { 1368 last = last[featureNameSplit[1]]; 1369 } 1370 1371 if (typeof last != 'undefined') { 1372 // we're going to quit if you're trying to overwrite an existing test 1373 // if we were to allow it, we'd do this: 1374 // var re = new RegExp("\\b(no-)?" + feature + "\\b"); 1375 // docElement.className = docElement.className.replace( re, '' ); 1376 // but, no rly, stuff 'em. 1377 return Modernizr; 1378 } 1379 1380 test = typeof test == 'function' ? test() : test; 1381 1382 // Set the value (this is the magic, right here). 1383 if (featureNameSplit.length == 1) { 1384 Modernizr[featureNameSplit[0]] = test; 1385 } else { 1386 // cast to a Boolean, if not one already 1387 /* jshint -W053 */ 1388 if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { 1389 Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); 1390 } 1391 1392 Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test; 1393 } 1394 1395 // Set a single class (either `feature` or `no-feature`) 1396 /* jshint -W041 */ 1397 setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]); 1398 /* jshint +W041 */ 1399 1400 // Trigger the event 1401 Modernizr._trigger(feature, test); 1402 } 1403 1404 return Modernizr; // allow chaining. 1405 } 1406 1407 // After all the tests are run, add self to the Modernizr prototype 1408 Modernizr._q.push(function() { 1409 ModernizrProto.addTest = addTest; 1410 }); 1411 1412 1413 1414 1415 /** 1416 * createElement is a convenience wrapper around document.createElement. Since we 1417 * use createElement all over the place, this allows for (slightly) smaller code 1418 * as well as abstracting away issues with creating elements in contexts other than 1419 * HTML documents (e.g. SVG documents). 1420 * 1421 * @access private 1422 * @function createElement 1423 * @returns {HTMLElement|SVGElement} An HTML or SVG element 1424 */ 1425 1426 function createElement() { 1427 if (typeof document.createElement !== 'function') { 1428 // This is the case in IE7, where the type of createElement is "object". 1429 // For this reason, we cannot call apply() as Object is not a Function. 1430 return document.createElement(arguments[0]); 1431 } else if (isSVG) {
1432 return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]); 1433 } else { 1434 return document.createElement.apply(document, arguments); 1435 } 1436 } 1437 1438 ; 1439 1440 /** 1441 * Modernizr.hasEvent() detects support for a given event 1442 * 1443 * @memberof Modernizr 1444 * @name Modernizr.hasEvent 1445 * @optionName Modernizr.hasEvent() 1446 * @optionProp hasEvent 1447 * @access public 1448 * @function hasEvent 1449 * @param {string|*} eventName - the name of an event to test for (e.g. "resize") 1450 * @param {Element|string} [element=HTMLDivElement] - is the element|document|window|tagName to test on 1451 * @returns {boolean} 1452 * @example 1453 * `Modernizr.hasEvent` lets you determine if the browser supports a supplied event. 1454 * By default, it does this detection on a div element 1455 * 1456 * ```js 1457 * hasEvent('blur') // true; 1458 * ``` 1459 * 1460 * However, you are able to give an object as a second argument to hasEvent to 1461 * detect an event on something other than a div. 1462 * 1463 * ```js 1464 * hasEvent('devicelight', window) // true; 1465 * ``` 1466 * 1467 */ 1468 1469 var hasEvent = (function() { 1470 1471 // Detect whether event support can be detected via `in`. Test on a DOM element 1472 // using the "blur" event b/c it should always exist. bit.ly/event-detection 1473 var needsFallback = !('onblur' in document.documentElement); 1474 1475 function inner(eventName, element) { 1476 1477 var isSupported; 1478 if (!eventName) { return false; } 1479 if (!element || typeof element === 'string') { 1480 element = createElement(element || 'div'); 1481 } 1482 1483 // Testing via the `in` operator is sufficient for modern browsers and IE. 1484 // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and 1485 // "resize", whereas `in` "catches" those. 1486 eventName = 'on' + eventName; 1487 isSupported = eventName in element; 1488 1489 // Fallback technique for old Firefox - bit.ly/event-detection 1490 if (!isSupported && needsFallback) { 1491 if (!element.setAttribute) { 1492 // Switch to generic element if it lacks `setAttribute`. 1493 // It could be the `document`, `window`, or something else. 1494 element = createElement('div'); 1495 } 1496 1497 element.setAttribute(eventName, ''); 1498 isSupported = typeof element[eventName] === 'function'; 1499 1500 if (element[eventName] !== undefined) { 1501 // If property was created, "remove it" by setting value to `undefined`. 1502 element[eventName] = undefined; 1503 } 1504 element.removeAttribute(eventName); 1505 } 1506 1507 return isSupported; 1508 } 1509 return inner; 1510 })(); 1511 1512 1513 ModernizrProto.hasEvent = hasEvent; 1514 1515 /*! 1516 { 1517 "name": "Hashchange event", 1518 "property": "hashchange", 1519 "caniuse": "hashchange", 1520 "tags": ["history"], 1521 "notes": [{ 1522 "name": "MDN documentation", 1523 "href": "https://developer.mozilla.org/en-US/docs/Web/API/window.onhashchange" 1524 }], 1525 "polyfills": [ 1526 "jquery-hashchange", 1527 "moo-historymanager", 1528 "jquery-ajaxy", 1529 "hasher", 1530 "shistory" 1531 ] 1532 } 1533 !*/ 1534 /* DOC 1535 Detects support for the `hashchange` event, fired when the current location fragment changes. 1536 */ 1537 1538 Modernizr.addTest('hashchange', function() { 1539 if (hasEvent('hashchange', window) === false) { 1540 return false; 1541 } 1542 1543 // documentMode logic from YUI to filter out IE8 Compat Mode 1544 // which false positives. 1545 return (document.documentMode === undefined || document.documentMode > 7); 1546 }); 1547 1548 /*! 1549 { 1550 "name" : "HTML5 Audio Element", 1551 "property": "audio", 1552 "tags" : ["html5", "audio", "media"] 1553 } 1554 !*/ 1555 /* DOC 1556 Detects the audio element 1557 */ 1558 1559 // This tests evaluates support of the audio element, as well as 1560 // testing what types of content it supports. 1561 // 1562 // We're using the Boolean constructor here, so that we can extend the value 1563 // e.g. Modernizr.audio // true 1564 // Modernizr.audio.ogg // 'probably' 1565 // 1566 // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845 1567 // thx to NielsLeenheer and zcorpan 1568 1569 // Note: in some older browsers, "no" was a return value instead of empty string. 1570 // It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2 1571 // It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5 1572 Modernizr.addTest('audio', function() { 1573 /* jshint -W053 */ 1574 var elem = createElement('audio'); 1575 var bool = false;
1576 1577 try { 1578 if (bool = !!elem.canPlayType) { 1579 bool = new Boolean(bool); 1580 bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"') .replace(/^no$/, ''); 1581 bool.mp3 = elem.canPlayType('audio/mpeg; codecs="mp3"') .replace(/^no$/, ''); 1582 bool.opus = elem.canPlayType('audio/ogg; codecs="opus"') || 1583 elem.canPlayType('audio/webm; codecs="opus"') .replace(/^no$/, ''); 1584 1585 // Mimetypes accepted: 1586 // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements 1587 // bit.ly/iphoneoscodecs 1588 bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/, ''); 1589 bool.m4a = (elem.canPlayType('audio/x-m4a;') || 1590 elem.canPlayType('audio/aac;')) .replace(/^no$/, ''); 1591 } 1592 } catch (e) { } 1593 1594 return bool; 1595 }); 1596 1597 /*! 1598 { 1599 "name": "Canvas", 1600 "property": "canvas", 1601 "caniuse": "canvas", 1602 "tags": ["canvas", "graphics"], 1603 "polyfills": ["flashcanvas", "excanvas", "slcanvas", "fxcanvas"] 1604 } 1605 !*/ 1606 /* DOC 1607 Detects support for the `<canvas>` element for 2D drawing. 1608 */ 1609 1610 // On the S60 and BB Storm, getContext exists, but always returns undefined 1611 // so we actually have to call getContext() to verify 1612 // github.com/Modernizr/Modernizr/issues/issue/97/ 1613 Modernizr.addTest('canvas', function() { 1614 var elem = createElement('canvas'); 1615 return !!(elem.getContext && elem.getContext('2d')); 1616 }); 1617 1618 /*! 1619 { 1620 "name": "Canvas text", 1621 "property": "canvastext", 1622 "caniuse": "canvas-text", 1623 "tags": ["canvas", "graphics"], 1624 "polyfills": ["canvastext"] 1625 } 1626 !*/ 1627 /* DOC 1628 Detects support for the text APIs for `<canvas>` elements. 1629 */ 1630 1631 Modernizr.addTest('canvastext', function() { 1632 if (Modernizr.canvas === false) { 1633 return false; 1634 } 1635 return typeof createElement('canvas').getContext('2d').fillText == 'function'; 1636 }); 1637 1638 /*! 1639 { 1640 "name": "HTML5 Video", 1641 "property": "video", 1642 "caniuse": "video", 1643 "tags": ["html5"], 1644 "knownBugs": [ 1645 "Without QuickTime, `Modernizr.video.h264` will be `undefined`; https://github.com/Modernizr/Modernizr/issues/546" 1646 ], 1647 "polyfills": [ 1648 "html5media", 1649 "mediaelementjs", 1650 "sublimevideo", 1651 "videojs", 1652 "leanbackplayer", 1653 "videoforeverybody" 1654 ] 1655 } 1656 !*/ 1657 /* DOC 1658 Detects support for the video element, as well as testing what types of content it supports. 1659 1660 Subproperties are provided to describe support for `ogg`, `h264` and `webm` formats, e.g.: 1661 1662 ```javascript 1663 Modernizr.video // true 1664 Modernizr.video.ogg // 'probably' 1665 ``` 1666 */ 1667 1668 // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845 1669 // thx to NielsLeenheer and zcorpan 1670 1671 // Note: in some older browsers, "no" was a return value instead of empty string. 1672 // It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2 1673 // It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5 1674 1675 Modernizr.addTest('video', function() { 1676 /* jshint -W053 */ 1677 var elem = createElement('video'); 1678 var bool = false;
1679 1680 // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224 1681 try { 1682 if (bool = !!elem.canPlayType) { 1683 bool = new Boolean(bool); 1684 bool.ogg = elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, ''); 1685 1686 // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546 1687 bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, ''); 1688 1689 bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, ''); 1690 1691 bool.vp9 = elem.canPlayType('video/webm; codecs="vp9"').replace(/^no$/, ''); 1692 1693 bool.hls = elem.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/, ''); 1694 } 1695 } catch (e) {} 1696 1697 return bool; 1698 }); 1699 1700 /*! 1701 { 1702 "name": "WebGL", 1703 "property": "webgl", 1704 "caniuse": "webgl", 1705 "tags": ["webgl", "graphics"], 1706 "polyfills": ["jebgl", "cwebgl", "iewebgl"] 1707 } 1708 !*/ 1709 1710 Modernizr.addTest('webgl', function() { 1711 var canvas = createElement('canvas'); 1712 var supports = 'probablySupportsContext' in canvas ? 'probablySupportsContext' : 'supportsContext'; 1713 if (supports in canvas) { 1714 return canvas[supports]('webgl') || canvas[supports]('experimental-webgl'); 1715 } 1716 return 'WebGLRenderingContext' in window; 1717 }); 1718 1719 /*! 1720 { 1721 "name": "CSS Gradients", 1722 "caniuse": "css-gradients", 1723 "property": "cssgradients", 1724 "tags": ["css"], 1725 "knownBugs": ["False-positives on webOS (https://github.com/Modernizr/Modernizr/issues/202)"], 1726 "notes": [{ 1727 "name": "Webkit Gradient Syntax", 1728 "href": "https://webkit.org/blog/175/introducing-css-gradients/" 1729 },{ 1730 "name": "Linear Gradient Syntax", 1731 "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient" 1732 },{ 1733 "name": "W3C Gradient Spec", 1734 "href": "https://drafts.csswg.org/css-images-3/#gradients" 1735 }] 1736 } 1737 !*/ 1738 1739 1740 Modernizr.addTest('cssgradients', function() { 1741 1742 var str1 = 'background-image:'; 1743 var str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));'; 1744 var css = ''; 1745 var angle; 1746 1747 for (var i = 0, len = prefixes.length - 1; i < len; i++) { 1748 angle = (i === 0 ? 'to ' : ''); 1749 css += str1 + prefixes[i] + 'linear-gradient(' + angle + 'left top, #9f9, white);'; 1750 } 1751 1752 if (Modernizr._config.usePrefixes) { 1753 // legacy webkit syntax (FIXME: remove when syntax not in use anymore) 1754 css += str1 + '-webkit-' + str2; 1755 } 1756 1757 var elem = createElement('a'); 1758 var style = elem.style; 1759 style.cssText = css; 1760 1761 // IE6 returns undefined so cast to string 1762 return ('' + style.backgroundImage).indexOf('gradient') > -1; 1763 }); 1764 1765 /*! 1766 {
1767 "name": "CSS Multiple Backgrounds", 1768 "caniuse": "multibackgrounds", 1769 "property": "multiplebgs", 1770 "tags": ["css"] 1771 } 1772 !*/ 1773 1774 // Setting multiple images AND a color on the background shorthand property 1775 // and then querying the style.background property value for the number of 1776 // occurrences of "url(" is a reliable method for detecting ACTUAL support for this! 1777 1778 Modernizr.addTest('multiplebgs', function() { 1779 var style = createElement('a').style; 1780 style.cssText = 'background:url(https://),url(https://),red url(https://)'; 1781 1782 // If the UA supports multiple backgrounds, there should be three occurrences 1783 // of the string "url(" in the return value for elemStyle.background 1784 return (/(url\s*\(.*?){3}/).test(style.background); 1785 }); 1786 1787 /*! 1788 { 1789 "name": "CSS Opacity", 1790 "caniuse": "css-opacity", 1791 "property": "opacity", 1792 "tags": ["css"] 1793 } 1794 !*/ 1795 1796 // Browsers that actually have CSS Opacity implemented have done so 1797 // according to spec, which means their return values are within the 1798 // range of [0.0,1.0] - including the leading zero. 1799 1800 Modernizr.addTest('opacity', function() { 1801 var style = createElement('a').style; 1802 style.cssText = prefixes.join('opacity:.55;'); 1803 1804 // The non-literal . in this regex is intentional: 1805 // German Chrome returns this value as 0,55 1806 // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632 1807 return (/^0.55$/).test(style.opacity); 1808 }); 1809 1810 /*! 1811 { 1812 "name": "CSS rgba", 1813 "caniuse": "css3-colors", 1814 "property": "rgba", 1815 "tags": ["css"], 1816 "notes": [{ 1817 "name": "CSSTricks Tutorial", 1818 "href": "https://css-tricks.com/rgba-browser-support/" 1819 }] 1820 } 1821 !*/ 1822 1823 Modernizr.addTest('rgba', function() { 1824 var style = createElement('a').style; 1825 style.cssText = 'background-color:rgba(150,255,150,.5)'; 1826 1827 return ('' + style.backgroundColor).indexOf('rgba') > -1; 1828 }); 1829 1830 /*! 1831 { 1832 "name": "Inline SVG", 1833 "property": "inlinesvg", 1834 "caniuse": "svg-html5", 1835 "tags": ["svg"], 1836 "notes": [{ 1837 "name": "Test page", 1838 "href": "https://paulirish.com/demo/inline-svg" 1839 }, { 1840 "name": "Test page and results", 1841 "href": "https://codepen.io/eltonmesquita/full/GgXbvo/" 1842 }], 1843 "polyfills": ["inline-svg-polyfill"], 1844 "knownBugs": ["False negative on some Chromia browsers."] 1845 } 1846 !*/ 1847 /* DOC 1848 Detects support for inline SVG in HTML (not within XHTML). 1849 */ 1850 1851 Modernizr.addTest('inlinesvg', function() { 1852 var div = createElement('div'); 1853 div.innerHTML = '<svg/>'; 1854 return (typeof SVGRect != 'undefined' && div.firstChild && div.firstChild.namespaceURI) == 'http://www.w3.org/2000/svg'; 1855 }); 1856 1857 1858 /** 1859 * cssToDOM takes a kebab-case string and converts it to camelCase 1860 * e.g. box-sizing -> boxSizing 1861 * 1862 * @access private 1863 * @function cssToDOM 1864 * @param {string} name - String name of kebab-case prop we want to convert 1865 * @returns {string} The camelCase version of the supplied name 1866 */ 1867 1868 function cssToDOM(name) { 1869 return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) { 1870 return m1 + m2.toUpperCase(); 1871 }).replace(/^-/, ''); 1872 } 1873 ; 1874 1875 /** 1876 * since we have a fairly large number of input tests that don't mutate the input 1877 * we create a single element that can be shared with all of those tests for a 1878 * minor perf boost 1879 * 1880 * @access private 1881 * @returns {HTMLInputElement} 1882 */ 1883 var inputElem = createElement('input'); 1884 1885 /*! 1886 { 1887 "name": "Input attributes", 1888 "property": "input", 1889 "tags": ["forms"], 1890 "authors": ["Mike Taylor"], 1891 "notes": [{ 1892 "name": "WHATWG spec", 1893 "href": "https://html.spec.whatwg.org/multipage/forms.html#input-type-attr-summary" 1894 }], 1895 "knownBugs": ["Some blackberry devices report false positive for input.multiple"] 1896 } 1897 !*/ 1898 /* DOC 1899 Detects support for HTML5 `<input>` element attributes and exposes Boolean subproperties with the results: 1900 1901 ```javascript 1902 Modernizr.input.autocomplete 1903 Modernizr.input.autofocus 1904 Modernizr.input.list 1905 Modernizr.input.max 1906 Modernizr.input.min 1907 Modernizr.input.multiple 1908 Modernizr.input.pattern 1909 Modernizr.input.placeholder 1910 Modernizr.input.required 1911 Modernizr.input.step 1912 ``` 1913 */ 1914 1915 // Run through HTML5's new input attributes to see if the UA understands any. 1916 // Mike Taylr has created a comprehensive resource for testing these attributes 1917 // when applied to all input types: 1918 // miketaylr.com/code/input-type-attr.html 1919 1920 // Only input placeholder is tested while textarea's placeholder is not. 1921 // Currently Safari 4 and Opera 11 have support only for the input placeholder 1922 // Both tests are available in feature-detects/forms-placeholder.js 1923 1924 var inputattrs = 'autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '); 1925 var attrs = {}; 1926 1927 Modernizr.input = (function(props) { 1928 for (var i = 0, len = props.length; i < len; i++) { 1929 attrs[ props[i] ] = !!(props[i] in inputElem); 1930 } 1931 if (attrs.list) { 1932 // safari false positive's on datalist: webk.it/74252 1933 // see also github.com/Modernizr/Modernizr/issues/146 1934 attrs.list = !!(createElement('datalist') && window.HTMLDataListElement); 1935 } 1936 return attrs; 1937 })(inputattrs); 1938 1939 /*! 1940 { 1941 "name": "Form input types", 1942 "property": "inputtypes", 1943 "caniuse": "forms", 1944 "tags": ["forms"], 1945 "authors": ["Mike Taylor"],
1946 "polyfills": [ 1947 "jquerytools", 1948 "webshims", 1949 "h5f", 1950 "webforms2", 1951 "nwxforms", 1952 "fdslider", 1953 "html5slider", 1954 "galleryhtml5forms", 1955 "jscolor", 1956 "html5formshim", 1957 "selectedoptionsjs", 1958 "formvalidationjs" 1959 ] 1960 } 1961 !*/ 1962 /* DOC 1963 Detects support for HTML5 form input types and exposes Boolean subproperties with the results: 1964 1965 ```javascript 1966 Modernizr.inputtypes.color 1967 Modernizr.inputtypes.date 1968 Modernizr.inputtypes.datetime 1969 Modernizr.inputtypes['datetime-local'] 1970 Modernizr.inputtypes.email 1971 Modernizr.inputtypes.month 1972 Modernizr.inputtypes.number 1973 Modernizr.inputtypes.range 1974 Modernizr.inputtypes.search 1975 Modernizr.inputtypes.tel 1976 Modernizr.inputtypes.time 1977 Modernizr.inputtypes.url 1978 Modernizr.inputtypes.week 1979 ``` 1980 */ 1981 1982 // Run through HTML5's new input types to see if the UA understands any. 1983 // This is put behind the tests runloop because it doesn't return a 1984 // true/false like all the other tests; instead, it returns an object 1985 // containing each input type with its corresponding true/false value 1986 1987 // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/ 1988 var inputtypes = 'search tel url email datetime date month week time datetime-local number range color'.split(' '); 1989 var inputs = {}; 1990 1991 Modernizr.inputtypes = (function(props) { 1992 var len = props.length; 1993 var smile = '1)'; 1994 var inputElemType; 1995 var defaultView; 1996 var bool; 1997 1998 for (var i = 0; i < len; i++) { 1999 2000 inputElem.setAttribute('type', inputElemType = props[i]); 2001 bool = inputElem.type !== 'text' && 'style' in inputElem; 2002 2003 // We first check to see if the type we give it sticks.. 2004 // If the type does, we feed it a textual value, which shouldn't be valid. 2005 // If the value doesn't stick, we know there's input sanitization which infers a custom UI 2006 if (bool) { 2007 2008 inputElem.value = smile; 2009 inputElem.style.cssText = 'position:absolute;visibility:hidden;'; 2010 2011 if (/^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined) { 2012 2013 docElement.appendChild(inputElem); 2014 defaultView = document.defaultView; 2015 2016 // Safari 2-4 allows the smiley as a value, despite making a slider 2017 bool = defaultView.getComputedStyle && 2018 defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' && 2019 // Mobile android web browser has false positive, so must 2020 // check the height to see if the widget is actually there. 2021 (inputElem.offsetHeight !== 0); 2022 2023 docElement.removeChild(inputElem); 2024 2025 } else if (/^(search|tel)$/.test(inputElemType)) { 2026 // Spec doesn't define any special parsing or detectable UI 2027 // behaviors so we pass these through as true 2028 2029 // Interestingly, opera fails the earlier test, so it doesn't 2030 // even make it here. 2031 2032 } else if (/^(url|email)$/.test(inputElemType)) { 2033 // Real url and email support comes with prebaked validation. 2034 bool = inputElem.checkValidity && inputElem.checkValidity() === false; 2035 2036 } else { 2037 // If the upgraded input compontent rejects the :) text, we got a winner 2038 bool = inputElem.value != smile; 2039 } 2040 } 2041 2042 inputs[ props[i] ] = !!bool; 2043 } 2044 return inputs; 2045 })(inputtypes); 2046 2047 2048 2049 /** 2050 * contains checks to see if a string contains another string 2051 * 2052 * @access private 2053 * @function contains 2054 * @param {string} str - The string we want to check for substrings 2055 * @param {string} substr - The substring we want to search the first string for 2056 * @returns {boolean} 2057 */ 2058 2059 function contains(str, substr) {
2060 return !!~('' + str).indexOf(substr); 2061 } 2062 2063 ; 2064 /*! 2065 { 2066 "name": "CSS HSLA Colors", 2067 "caniuse": "css3-colors", 2068 "property": "hsla", 2069 "tags": ["css"] 2070 } 2071 !*/ 2072 2073 Modernizr.addTest('hsla', function() { 2074 var style = createElement('a').style; 2075 style.cssText = 'background-color:hsla(120,40%,100%,.5)'; 2076 return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla'); 2077 }); 2078 2079 /*! 2080 { 2081 "name": "CSS Supports", 2082 "property": "supports", 2083 "caniuse": "css-featurequeries", 2084 "tags": ["css"], 2085 "builderAliases": ["css_supports"], 2086 "notes": [{ 2087 "name": "W3 Spec", 2088 "href": "http://dev.w3.org/csswg/css3-conditional/#at-supports" 2089 },{ 2090 "name": "Related Github Issue", 2091 "href": "github.com/Modernizr/Modernizr/issues/648" 2092 },{ 2093 "name": "W3 Info", 2094 "href": "http://dev.w3.org/csswg/css3-conditional/#the-csssupportsrule-interface" 2095 }] 2096 } 2097 !*/ 2098 2099 var newSyntax = 'CSS' in window && 'supports' in window.CSS; 2100 var oldSyntax = 'supportsCSS' in window; 2101 Modernizr.addTest('supports', newSyntax || oldSyntax); 2102 2103 2104 /** 2105 * Object.prototype.toString can be used with every object and allows you to 2106 * get its class easily. Abstracting it off of an object prevents situations 2107 * where the toString property has been overridden 2108 * 2109 * @access private 2110 * @function toStringFn 2111 * @returns {function} An abstracted toString function 2112 */ 2113 2114 var toStringFn = ({}).toString; 2115 2116 /*! 2117 { 2118 "name": "SVG clip paths", 2119 "property": "svgclippaths", 2120 "tags": ["svg"], 2121 "notes": [{ 2122 "name": "Demo", 2123 "href": "http://srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg" 2124 }] 2125 } 2126 !*/ 2127 /* DOC 2128 Detects support for clip paths in SVG (only, not on HTML content). 2129 2130 See [this discussion](https://github.com/Modernizr/Modernizr/issues/213) regarding applying SVG clip paths to HTML content. 2131 */ 2132 2133 Modernizr.addTest('svgclippaths', function() { 2134 return !!document.createElementNS && 2135 /SVGClipPath/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'clipPath'))); 2136 }); 2137 2138 /*! 2139 { 2140 "name": "SVG SMIL animation", 2141 "property": "smil", 2142 "caniuse": "svg-smil", 2143 "tags": ["svg"], 2144 "notes": [{ 2145 "name": "W3C Synchronised Multimedia spec", 2146 "href": "https://www.w3.org/AudioVideo/" 2147 }] 2148 } 2149 !*/ 2150 2151 // SVG SMIL animation 2152 Modernizr.addTest('smil', function() { 2153 return !!document.createElementNS && 2154 /SVGAnimate/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'animate'))); 2155 }); 2156 2157 2158 /** 2159 * getBody returns the body of a document, or an element that can stand in for 2160 * the body if a real body does not exist 2161 * 2162 * @access private 2163 * @function getBody 2164 * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an 2165 * artificially created element that stands in for the body 2166 */ 2167 2168 function getBody() { 2169 // After page load injecting a fake body doesn't work so check if body exists 2170 var body = document.body; 2171 2172 if (!body) { 2173 // Can't use the real body create a fake one. 2174 body = createElement(isSVG ? 'svg' : 'body'); 2175 body.fake = true; 2176 } 2177 2178 return body; 2179 } 2180 2181 ; 2182 2183 /** 2184 * injectElementWithStyles injects an element with style element and some CSS rules 2185 * 2186 * @access private 2187 * @function injectElementWithStyles 2188 * @param {string} rule - String representing a css rule 2189 * @param {function} callback - A function that is used to test the injected element 2190 * @param {number} [nodes] - An integer representing the number of additional nodes you want injected 2191 * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes 2192 * @returns {boolean} 2193 */ 2194 2195 function injectElementWithStyles(rule, callback, nodes, testnames) { 2196 var mod = 'modernizr'; 2197 var style; 2198 var ret; 2199 var node; 2200 var docOverflow; 2201 var div = createElement('div'); 2202 var body = getBody(); 2203 2204 if (parseInt(nodes, 10)) { 2205 // In order not to give false positives we create a node for each test
2206 // This also allows the method to scale for unspecified uses 2207 while (nodes--) { 2208 node = createElement('div'); 2209 node.id = testnames ? testnames[nodes] : mod + (nodes + 1); 2210 div.appendChild(node); 2211 } 2212 } 2213 2214 style = createElement('style'); 2215 style.type = 'text/css'; 2216 style.id = 's' + mod; 2217 2218 // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. 2219 // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 2220 (!body.fake ? div : body).appendChild(style); 2221 body.appendChild(div); 2222 2223 if (style.styleSheet) { 2224 style.styleSheet.cssText = rule; 2225 } else { 2226 style.appendChild(document.createTextNode(rule)); 2227 } 2228 div.id = mod; 2229 2230 if (body.fake) { 2231 //avoid crashing IE8, if background image is used 2232 body.style.background = ''; 2233 //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible 2234 body.style.overflow = 'hidden'; 2235 docOverflow = docElement.style.overflow; 2236 docElement.style.overflow = 'hidden'; 2237 docElement.appendChild(body); 2238 } 2239 2240 ret = callback(div, rule); 2241 // If this is done after page load we don't want to remove the body so check if body exists 2242 if (body.fake) { 2243 body.parentNode.removeChild(body); 2244 docElement.style.overflow = docOverflow; 2245 // Trigger layout so kinetic scrolling isn't disabled in iOS6+ 2246 docElement.offsetHeight; 2247 } else { 2248 div.parentNode.removeChild(div); 2249 } 2250 2251 return !!ret; 2252 2253 } 2254 2255 ; 2256 2257 /** 2258 * Modernizr.mq tests a given media query, live against the current state of the window 2259 * adapted from matchMedia polyfill by Scott Jehl and Paul Irish 2260 * gist.github.com/786768 2261 * 2262 * @memberof Modernizr 2263 * @name Modernizr.mq 2264 * @optionName Modernizr.mq() 2265 * @optionProp mq 2266 * @access public 2267 * @function mq 2268 * @param {string} mq - String of the media query we want to test 2269 * @returns {boolean} 2270 * @example 2271 * Modernizr.mq allows for you to programmatically check if the current browser 2272 * window state matches a media query. 2273 * 2274 * ```js 2275 * var query = Modernizr.mq('(min-width: 900px)'); 2276 * 2277 * if (query) { 2278 * // the browser window is larger than 900px 2279 * } 2280 * ``` 2281 * 2282 * Only valid media queries are supported, therefore you must always include values 2283 * with your media query 2284 * 2285 * ```js 2286 * // good 2287 * Modernizr.mq('(min-width: 900px)'); 2288 * 2289 * // bad 2290 * Modernizr.mq('min-width'); 2291 * ``` 2292 * 2293 * If you would just like to test that media queries are supported in general, use 2294 * 2295 * ```js 2296 * Modernizr.mq('only all'); // true if MQ are supported, false if not 2297 * ``` 2298 * 2299 * 2300 * Note that if the browser does not support media queries (e.g. old IE) mq will 2301 * always return false. 2302 */ 2303 2304 var mq = (function() { 2305 var matchMedia = window.matchMedia || window.msMatchMedia; 2306 if (matchMedia) { 2307 return function(mq) { 2308 var mql = matchMedia(mq); 2309 return mql && mql.matches || false; 2310 }; 2311 } 2312 2313 return function(mq) { 2314 var bool = false;
2315 2316 injectElementWithStyles('@media ' + mq + ' { #modernizr { position: absolute; } }', function(node) { 2317 bool = (window.getComputedStyle ? 2318 window.getComputedStyle(node, null) : 2319 node.currentStyle).position == 'absolute'; 2320 }); 2321 2322 return bool; 2323 }; 2324 })(); 2325 2326 2327 ModernizrProto.mq = mq; 2328 2329 2330 2331 /** 2332 * testStyles injects an element with style element and some CSS rules 2333 * 2334 * @memberof Modernizr 2335 * @name Modernizr.testStyles 2336 * @optionName Modernizr.testStyles() 2337 * @optionProp testStyles 2338 * @access public 2339 * @function testStyles 2340 * @param {string} rule - String representing a css rule 2341 * @param {function} callback - A function that is used to test the injected element 2342 * @param {number} [nodes] - An integer representing the number of additional nodes you want injected 2343 * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes 2344 * @returns {boolean} 2345 * @example 2346 * 2347 * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page 2348 * along with (possibly multiple) DOM elements. This lets you check for features 2349 * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules). 2350 * 2351 * ```js 2352 * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) { 2353 * // elem is the first DOM node in the page (by default #modernizr) 2354 * // rule is the first argument you supplied - the CSS rule in string form 2355 * 2356 * addTest('widthworks', elem.style.width === '9px') 2357 * }); 2358 * ``` 2359 * 2360 * If your test requires multiple nodes, you can include a third argument 2361 * indicating how many additional div elements to include on the page. The 2362 * additional nodes are injected as children of the `elem` that is returned as 2363 * the first argument to the callback. 2364 * 2365 * ```js 2366 * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) { 2367 * document.getElementById('modernizr').style.width === '1px'; // true 2368 * document.getElementById('modernizr2').style.width === '2px'; // true 2369 * elem.firstChild === document.getElementById('modernizr2'); // true 2370 * }, 1); 2371 * ``` 2372 * 2373 * By default, all of the additional elements have an ID of `modernizr[n]`, where 2374 * `n` is its index (e.g. the first additional, second overall is `#modernizr2`, 2375 * the second additional is `#modernizr3`, etc.). 2376 * If you want to have more meaningful IDs for your function, you can provide 2377 * them as the fourth argument, as an array of strings 2378 * 2379 * ```js 2380 * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) { 2381 * elem.firstChild === document.getElementById('foo'); // true 2382 * elem.lastChild === document.getElementById('bar'); // true 2383 * }, 2, ['foo', 'bar']); 2384 * ``` 2385 * 2386 */ 2387 2388 var testStyles = ModernizrProto.testStyles = injectElementWithStyles; 2389 2390 /*! 2391 { 2392 "name": "@font-face", 2393 "property": "fontface", 2394 "authors": ["Diego Perini", "Mat Marquis"], 2395 "tags": ["css"], 2396 "knownBugs": [ 2397 "False Positive: WebOS https://github.com/Modernizr/Modernizr/issues/342", 2398 "False Postive: WP7 https://github.com/Modernizr/Modernizr/issues/538" 2399 ], 2400 "notes": [{ 2401 "name": "@font-face detection routine by Diego Perini", 2402 "href": "http://javascript.nwbox.com/CSSSupport/" 2403 },{ 2404 "name": "Filament Group @font-face compatibility research", 2405 "href": "https://docs.google.com/presentation/d/1n4NyG4uPRjAA8zn_pSQ_Ket0RhcWC6QlZ6LMjKeECo0/edit#slide=id.p" 2406 },{ 2407 "name": "Filament Grunticon/@font-face device testing results", 2408 "href": "https://docs.google.com/spreadsheet/ccc?key=0Ag5_yGvxpINRdHFYeUJPNnZMWUZKR2ItMEpRTXZPdUE#gid=0" 2409 },{ 2410 "name": "CSS fonts on Android", 2411 "href": "https://stackoverflow.com/questions/3200069/css-fonts-on-android" 2412 },{ 2413 "name": "@font-face and Android", 2414 "href": "http://archivist.incutio.com/viewlist/css-discuss/115960" 2415 }] 2416 } 2417 !*/ 2418 2419 var blacklist = (function() { 2420 var ua = navigator.userAgent; 2421 var wkvers = ua.match(/applewebkit\/([0-9]+)/gi) && parseFloat(RegExp.$1); 2422 var webos = ua.match(/w(eb)?osbrowser/gi); 2423 var wppre8 = ua.match(/windows phone/gi) && ua.match(/iemobile\/([0-9])+/gi) && parseFloat(RegExp.$1) >= 9; 2424 var oldandroid = wkvers < 533 && ua.match(/android/gi); 2425 return webos || oldandroid || wppre8; 2426 }()); 2427 if (blacklist) { 2428 Modernizr.addTest('fontface', false); 2429 } else { 2430 testStyles('@font-face {font-family:"font";src:url("https://")}', function(node, rule) { 2431 var style = document.getElementById('smodernizr'); 2432 var sheet = style.sheet || style.styleSheet; 2433 var cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : ''; 2434 var bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0; 2435 Modernizr.addTest('fontface', bool); 2436 }); 2437 } 2438 ; 2439 /*! 2440 { 2441 "name": "CSS Generated Content", 2442 "property": "generatedcontent", 2443 "tags": ["css"], 2444 "warnings": ["Android won't return correct height for anything below 7px #738"],
2445 "notes": [{ 2446 "name": "W3C CSS Selectors Level 3 spec", 2447 "href": "https://www.w3.org/TR/css3-selectors/#gen-content" 2448 },{ 2449 "name": "MDN article on :before", 2450 "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/::before" 2451 },{ 2452 "name": "MDN article on :after", 2453 "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/::before" 2454 }] 2455 } 2456 !*/ 2457 2458 testStyles('#modernizr{font:0/0 a}#modernizr:after{content:":)";visibility:hidden;font:7px/1 a}', function(node) { 2459 Modernizr.addTest('generatedcontent', node.offsetHeight >= 7); 2460 }); 2461 2462 2463 var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []); 2464 ModernizrProto._cssomPrefixes = cssomPrefixes; 2465 2466 2467 /** 2468 * atRule returns a given CSS property at-rule (eg @keyframes), possibly in 2469 * some prefixed form, or false, in the case of an unsupported rule 2470 * 2471 * @memberof Modernizr 2472 * @name Modernizr.atRule 2473 * @optionName Modernizr.atRule() 2474 * @optionProp atRule 2475 * @access public 2476 * @function atRule 2477 * @param {string} prop - String name of the @-rule to test for 2478 * @returns {string|boolean} The string representing the (possibly prefixed) 2479 * valid version of the @-rule, or `false` when it is unsupported. 2480 * @example 2481 * ```js 2482 * var keyframes = Modernizr.atRule('@keyframes'); 2483 * 2484 * if (keyframes) { 2485 * // keyframes are supported 2486 * // could be `@-webkit-keyframes` or `@keyframes` 2487 * } else { 2488 * // keyframes === `false` 2489 * } 2490 * ``` 2491 * 2492 */ 2493 2494 var atRule = function(prop) { 2495 var length = prefixes.length; 2496 var cssrule = window.CSSRule; 2497 var rule; 2498 2499 if (typeof cssrule === 'undefined') { 2500 return undefined; 2501 } 2502 2503 if (!prop) { 2504 return false; 2505 } 2506 2507 // remove literal @ from beginning of provided property 2508 prop = prop.replace(/^@/, ''); 2509 2510 // CSSRules use underscores instead of dashes 2511 rule = prop.replace(/-/g, '_').toUpperCase() + '_RULE'; 2512 2513 if (rule in cssrule) { 2514 return '@' + prop; 2515 } 2516 2517 for (var i = 0; i < length; i++) { 2518 // prefixes gives us something like -o-, and we want O_ 2519 var prefix = prefixes[i]; 2520 var thisRule = prefix.toUpperCase() + '_' + rule; 2521 2522 if (thisRule in cssrule) { 2523 return '@-' + prefix.toLowerCase() + '-' + prop; 2524 } 2525 } 2526 2527 return false; 2528 }; 2529 2530 ModernizrProto.atRule = atRule; 2531 2532 2533 2534 /** 2535 * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill. 2536 * 2537 * @access private 2538 * @function fnBind 2539 * @param {function} fn - a function you want to change `this` reference to 2540 * @param {object} that - the `this` you want to call the function with 2541 * @returns {function} The wrapped version of the supplied function 2542 */ 2543 2544 function fnBind(fn, that) { 2545 return function() { 2546 return fn.apply(that, arguments); 2547 }; 2548 } 2549 2550 ; 2551 2552 /** 2553 * testDOMProps is a generic DOM property test; if a browser supports 2554 * a certain property, it won't return undefined for it. 2555 * 2556 * @access private 2557 * @function testDOMProps 2558 * @param {array.<string>} props - An array of properties to test for 2559 * @param {object} obj - An object or Element you want to use to test the parameters again 2560 * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check 2561 */ 2562 function testDOMProps(props, obj, elem) { 2563 var item; 2564 2565 for (var i in props) { 2566 if (props[i] in obj) { 2567 2568 // return the property name as a string 2569 if (elem === false) { 2570 return props[i]; 2571 } 2572 2573 item = obj[props[i]]; 2574 2575 // let's bind a function 2576 if (is(item, 'function')) { 2577 // bind to obj unless overriden 2578 return fnBind(item, elem || obj); 2579 } 2580 2581 // return the unbound function or obj or value 2582 return item; 2583 } 2584 } 2585 return false;
2586 } 2587 2588 ; 2589 2590 /** 2591 * Create our "modernizr" element that we do most feature tests on. 2592 * 2593 * @access private 2594 */ 2595 2596 var modElem = { 2597 elem: createElement('modernizr') 2598 }; 2599 2600 // Clean up this element 2601 Modernizr._q.push(function() { 2602 delete modElem.elem; 2603 }); 2604 2605 2606 2607 var mStyle = { 2608 style: modElem.elem.style 2609 }; 2610 2611 // kill ref for gc, must happen before mod.elem is removed, so we unshift on to 2612 // the front of the queue. 2613 Modernizr._q.unshift(function() { 2614 delete mStyle.style; 2615 }); 2616 2617 2618 2619 /** 2620 * domToCSS takes a camelCase string and converts it to kebab-case 2621 * e.g. boxSizing -> box-sizing 2622 * 2623 * @access private 2624 * @function domToCSS 2625 * @param {string} name - String name of camelCase prop we want to convert 2626 * @returns {string} The kebab-case version of the supplied name 2627 */ 2628 2629 function domToCSS(name) { 2630 return name.replace(/([A-Z])/g, function(str, m1) { 2631 return '-' + m1.toLowerCase(); 2632 }).replace(/^ms-/, '-ms-'); 2633 } 2634 ; 2635 2636 /** 2637 * nativeTestProps allows for us to use native feature detection functionality if available. 2638 * some prefixed form, or false, in the case of an unsupported rule 2639 * 2640 * @access private 2641 * @function nativeTestProps 2642 * @param {array} props - An array of property names 2643 * @param {string} value - A string representing the value we want to check via @supports 2644 * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise 2645 */ 2646 2647 // Accepts a list of property names and a single value 2648 // Returns `undefined` if native detection not available 2649 function nativeTestProps(props, value) { 2650 var i = props.length; 2651 // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface 2652 if ('CSS' in window && 'supports' in window.CSS) { 2653 // Try every prefixed variant of the property 2654 while (i--) { 2655 if (window.CSS.supports(domToCSS(props[i]), value)) { 2656 return true; 2657 } 2658 } 2659 return false; 2660 } 2661 // Otherwise fall back to at-rule (for Opera 12.x) 2662 else if ('CSSSupportsRule' in window) { 2663 // Build a condition string for every prefixed variant 2664 var conditionText = []; 2665 while (i--) { 2666 conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')'); 2667 } 2668 conditionText = conditionText.join(' or '); 2669 return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) { 2670 return getComputedStyle(node, null).position == 'absolute'; 2671 }); 2672 } 2673 return undefined; 2674 } 2675 ; 2676 2677 // testProps is a generic CSS / DOM property test. 2678 2679 // In testing support for a given CSS property, it's legit to test: 2680 // `elem.style[styleName] !== undefined` 2681 // If the property is supported it will return an empty string, 2682 // if unsupported it will return undefined. 2683 2684 // We'll take advantage of this quick test and skip setting a style 2685 // on our modernizr element, but instead just testing undefined vs 2686 // empty string. 2687 2688 // Property names can be provided in either camelCase or kebab-case. 2689 2690 function testProps(props, prefixed, value, skipValueTest) { 2691 skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest; 2692 2693 // Try native detect first 2694 if (!is(value, 'undefined')) { 2695 var result = nativeTestProps(props, value); 2696 if (!is(result, 'undefined')) { 2697 return result; 2698 } 2699 } 2700 2701 // Otherwise do it properly 2702 var afterInit, i, propsLength, prop, before; 2703 2704 // If we don't have a style element, that means we're running async or after 2705 // the core tests, so we'll need to create our own elements to use 2706 2707 // inside of an SVG element, in certain browsers, the `style` element is only 2708 // defined for valid tags. Therefore, if `modernizr` does not have one, we 2709 // fall back to a less used element and hope for the best. 2710 var elems = ['modernizr', 'tspan']; 2711 while (!mStyle.style) { 2712 afterInit = true; 2713 mStyle.modElem = createElement(elems.shift()); 2714 mStyle.style = mStyle.modElem.style; 2715 } 2716 2717 // Delete the objects if we created them. 2718 function cleanElems() { 2719 if (afterInit) { 2720 delete mStyle.style; 2721 delete mStyle.modElem; 2722 } 2723 } 2724 2725 propsLength = props.length; 2726 for (i = 0; i < propsLength; i++) { 2727 prop = props[i]; 2728 before = mStyle.style[prop]; 2729 2730 if (contains(prop, '-')) { 2731 prop = cssToDOM(prop); 2732 } 2733 2734 if (mStyle.style[prop] !== undefined) { 2735 2736 // If value to test has been passed in, do a set-and-check test. 2737 // 0 (integer) is a valid property value, so check that `value` isn't 2738 // undefined, rather than just checking it's truthy. 2739 if (!skipValueTest && !is(value, 'undefined')) { 2740 2741 // Needs a try catch block because of old IE. This is slow, but will 2742 // be avoided in most cases because `skipValueTest` will be used. 2743 try { 2744 mStyle.style[prop] = value; 2745 } catch (e) {} 2746 2747 // If the property value has changed, we assume the value used is 2748 // supported. If `value` is empty string, it'll fail here (because 2749 // it hasn't changed), which matches how browsers have implemented 2750 // CSS.supports() 2751 if (mStyle.style[prop] != before) { 2752 cleanElems(); 2753 return prefixed == 'pfx' ? prop : true; 2754 } 2755 } 2756 // Otherwise just return true, or the property name if this is a 2757 // `prefixed()` call 2758 else { 2759 cleanElems(); 2760 return prefixed == 'pfx' ? prop : true; 2761 } 2762 } 2763 } 2764 cleanElems(); 2765 return false;
2766 } 2767 2768 ; 2769 2770 /** 2771 * testProp() investigates whether a given style property is recognized 2772 * Property names can be provided in either camelCase or kebab-case. 2773 * 2774 * @memberof Modernizr 2775 * @name Modernizr.testProp 2776 * @access public 2777 * @optionName Modernizr.testProp() 2778 * @optionProp testProp 2779 * @function testProp 2780 * @param {string} prop - Name of the CSS property to check 2781 * @param {string} [value] - Name of the CSS value to check 2782 * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported 2783 * @returns {boolean} 2784 * @example 2785 * 2786 * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed 2787 * version of the string. 2788 * 2789 * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing) 2790 * 2791 * ```js 2792 * Modernizr.testProp('pointerEvents') // true 2793 * ``` 2794 * 2795 * You can also provide a value as an optional second argument to check if a 2796 * specific value is supported 2797 * 2798 * ```js
2799 * Modernizr.testProp('pointerEvents', 'none') // true 2800 * Modernizr.testProp('pointerEvents', 'penguin') // false 2801 * ``` 2802 */ 2803 2804 var testProp = ModernizrProto.testProp = function(prop, value, useValue) { 2805 return testProps([prop], undefined, value, useValue); 2806 }; 2807 2808 /*! 2809 { 2810 "name": "CSS textshadow", 2811 "property": "textshadow", 2812 "caniuse": "css-textshadow", 2813 "tags": ["css"], 2814 "knownBugs": ["FF3.0 will false positive on this test"] 2815 } 2816 !*/ 2817 2818 Modernizr.addTest('textshadow', testProp('textShadow', '1px 1px')); 2819 2820 2821 /** 2822 * testPropsAll tests a list of DOM properties we want to check against. 2823 * We specify literally ALL possible (known and/or likely) properties on 2824 * the element including the non-vendor prefixed one, for forward- 2825 * compatibility. 2826 * 2827 * @access private 2828 * @function testPropsAll 2829 * @param {string} prop - A string of the property to test for 2830 * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip 2831 * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against 2832 * @param {string} [value] - A string of a css value 2833 * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set 2834 */ 2835 function testPropsAll(prop, prefixed, elem, value, skipValueTest) { 2836 2837 var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), 2838 props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); 2839 2840 // did they call .prefixed('boxSizing') or are we just testing a prop? 2841 if (is(prefixed, 'string') || is(prefixed, 'undefined')) { 2842 return testProps(props, prefixed, value, skipValueTest); 2843 2844 // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) 2845 } else { 2846 props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); 2847 return testDOMProps(props, prefixed, elem); 2848 } 2849 } 2850 2851 // Modernizr.testAllProps() investigates whether a given style property, 2852 // or any of its vendor-prefixed variants, is recognized 2853 // 2854 // Note that the property names must be provided in the camelCase variant. 2855 // Modernizr.testAllProps('boxSizing') 2856 ModernizrProto.testAllProps = testPropsAll; 2857 2858 2859 2860 /** 2861 * prefixed returns the prefixed or nonprefixed property name variant of your input 2862 * 2863 * @memberof Modernizr 2864 * @name Modernizr.prefixed 2865 * @optionName Modernizr.prefixed() 2866 * @optionProp prefixed 2867 * @access public 2868 * @function prefixed 2869 * @param {string} prop - String name of the property to test for 2870 * @param {object} [obj] - An object to test for the prefixed properties on 2871 * @param {HTMLElement} [elem] - An element used to test specific properties against 2872 * @returns {string|false} The string representing the (possibly prefixed) valid 2873 * version of the property, or `false` when it is unsupported. 2874 * @example 2875 * 2876 * Modernizr.prefixed takes a string css value in the DOM style camelCase (as 2877 * opposed to the css style kebab-case) form and returns the (possibly prefixed) 2878 * version of that property that the browser actually supports. 2879 * 2880 * For example, in older Firefox... 2881 * ```js 2882 * prefixed('boxSizing') 2883 * ``` 2884 * returns 'MozBoxSizing' 2885 * 2886 * In newer Firefox, as well as any other browser that support the unprefixed 2887 * version would simply return `boxSizing`. Any browser that does not support 2888 * the property at all, it will return `false`. 2889 * 2890 * By default, prefixed is checked against a DOM element. If you want to check 2891 * for a property on another object, just pass it as a second argument 2892 * 2893 * ```js 2894 * var rAF = prefixed('requestAnimationFrame', window); 2895 * 2896 * raf(function() { 2897 * renderFunction(); 2898 * }) 2899 * ``` 2900 * 2901 * Note that this will return _the actual function_ - not the name of the function. 2902 * If you need the actual name of the property, pass in `false` as a third argument 2903 * 2904 * ```js 2905 * var rAFProp = prefixed('requestAnimationFrame', window, false); 2906 * 2907 * rafProp === 'WebkitRequestAnimationFrame' // in older webkit 2908 * ``` 2909 * 2910 * One common use case for prefixed is if you're trying to determine which transition 2911 * end event to bind to, you might do something like... 2912 * ```js 2913 * var transEndEventNames = { 2914 * 'WebkitTransition' : 'webkitTransitionEnd', * Saf 6, Android Browser 2915 * 'MozTransition' : 'transitionend', * only for FF < 15 2916 * 'transition' : 'transitionend' * IE10, Opera, Chrome, FF 15+, Saf 7+ 2917 * }; 2918 * 2919 * var transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; 2920 * ``` 2921 * 2922 * If you want a similar lookup, but in kebab-case, you can use [prefixedCSS](#modernizr-prefixedcss). 2923 */ 2924 2925 var prefixed = ModernizrProto.prefixed = function(prop, obj, elem) { 2926 if (prop.indexOf('@') === 0) { 2927 return atRule(prop); 2928 } 2929 2930 if (prop.indexOf('-') != -1) { 2931 // Convert kebab-case to camelCase 2932 prop = cssToDOM(prop); 2933 } 2934 if (!obj) { 2935 return testPropsAll(prop, 'pfx'); 2936 } else { 2937 // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame' 2938 return testPropsAll(prop, obj, elem); 2939 } 2940 }; 2941 2942 2943 /*! 2944 { 2945 "name": "IndexedDB", 2946 "property": "indexeddb", 2947 "caniuse": "indexeddb", 2948 "tags": ["storage"], 2949 "polyfills": ["indexeddb"] 2950 } 2951 !*/ 2952 /* DOC 2953 Detects support for the IndexedDB client-side storage API (final spec). 2954 */ 2955 2956 // Vendors had inconsistent prefixing with the experimental Indexed DB: 2957 // - Webkit's implementation is accessible through webkitIndexedDB 2958 // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB 2959 // For speed, we don't test the legacy (and beta-only) indexedDB 2960 2961 var indexeddb; 2962 try { 2963 indexeddb = prefixed('indexedDB', window); 2964 } catch (e) { 2965 } 2966 2967 Modernizr.addTest('indexeddb', !!indexeddb); 2968 2969 if (!!indexeddb) { 2970 Modernizr.addTest('indexeddb.deletedatabase', 'deleteDatabase' in indexeddb); 2971 } 2972 ; 2973 2974 /** 2975 * testAllProps determines whether a given CSS property is supported in the browser 2976 * 2977 * @memberof Modernizr 2978 * @name Modernizr.testAllProps 2979 * @optionName Modernizr.testAllProps() 2980 * @optionProp testAllProps 2981 * @access public 2982 * @function testAllProps 2983 * @param {string} prop - String naming the property to test (either camelCase or kebab-case) 2984 * @param {string} [value] - String of the value to test 2985 * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection 2986 * @example 2987 * 2988 * testAllProps determines whether a given CSS property, in some prefixed form, 2989 * is supported by the browser. 2990 * 2991 * ```js 2992 * testAllProps('boxSizing') // true 2993 * ``` 2994 * 2995 * It can optionally be given a CSS value in string form to test if a property 2996 * value is valid 2997 * 2998 * ```js 2999 * testAllProps('display', 'block') // true 3000 * testAllProps('display', 'penguin') // false 3001 * ``` 3002 * 3003 * A boolean can be passed as a third parameter to skip the value check when 3004 * native detection (@supports) isn't available. 3005 * 3006 * ```js 3007 * testAllProps('shapeOutside', 'content-box', true); 3008 * ``` 3009 */ 3010 3011 function testAllProps(prop, value, skipValueTest) { 3012 return testPropsAll(prop, undefined, undefined, value, skipValueTest); 3013 } 3014 ModernizrProto.testAllProps = testAllProps; 3015 3016 /*! 3017 { 3018 "name": "CSS Animations", 3019 "property": "cssanimations", 3020 "caniuse": "css-animation", 3021 "polyfills": ["transformie", "csssandpaper"], 3022 "tags": ["css"], 3023 "warnings": ["Android < 4 will pass this test, but can only animate a single property at a time"],
3024 "notes": [{ 3025 "name" : "Article: 'Dispelling the Android CSS animation myths'", 3026 "href": "https://goo.gl/OGw5Gm" 3027 }] 3028 } 3029 !*/ 3030 /* DOC 3031 Detects whether or not elements can be animated using CSS 3032 */ 3033 3034 Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true)); 3035 3036 /*! 3037 { 3038 "name": "Background Size", 3039 "property": "backgroundsize", 3040 "tags": ["css"], 3041 "knownBugs": ["This will false positive in Opera Mini - https://github.com/Modernizr/Modernizr/issues/396"], 3042 "notes": [{ 3043 "name": "Related Issue", 3044 "href": "https://github.com/Modernizr/Modernizr/issues/396" 3045 }] 3046 } 3047 !*/ 3048 3049 Modernizr.addTest('backgroundsize', testAllProps('backgroundSize', '100%', true)); 3050 3051 /*! 3052 { 3053 "name": "Border Image", 3054 "property": "borderimage", 3055 "caniuse": "border-image", 3056 "polyfills": ["css3pie"], 3057 "knownBugs": ["Android < 2.0 is true, but has a broken implementation"], 3058 "tags": ["css"] 3059 } 3060 !*/ 3061 3062 Modernizr.addTest('borderimage', testAllProps('borderImage', 'url() 1', true)); 3063 3064 /*! 3065 { 3066 "name": "Border Radius",
3067 "property": "borderradius", 3068 "caniuse": "border-radius", 3069 "polyfills": ["css3pie"], 3070 "tags": ["css"], 3071 "notes": [{ 3072 "name": "Comprehensive Compat Chart", 3073 "href": "https://muddledramblings.com/table-of-css3-border-radius-compliance" 3074 }] 3075 } 3076 !*/ 3077 3078 Modernizr.addTest('borderradius', testAllProps('borderRadius', '0px', true)); 3079 3080 /*! 3081 { 3082 "name": "Box Shadow", 3083 "property": "boxshadow", 3084 "caniuse": "css-boxshadow", 3085 "tags": ["css"], 3086 "knownBugs": [ 3087 "WebOS false positives on this test.", 3088 "The Kindle Silk browser false positives" 3089 ] 3090 } 3091 !*/ 3092 3093 Modernizr.addTest('boxshadow', testAllProps('boxShadow', '1px 1px', true)); 3094 3095 /*! 3096 { 3097 "name": "CSS Columns", 3098 "property": "csscolumns", 3099 "caniuse": "multicolumn", 3100 "polyfills": ["css3multicolumnjs"], 3101 "tags": ["css"] 3102 } 3103 !*/ 3104 3105 3106 (function() { 3107 3108 /* jshint -W053 */ 3109 Modernizr.addTest('csscolumns', function() { 3110 var bool = false; 3111 var test = testAllProps('columnCount'); 3112 try { 3113 if (bool = !!test) { 3114 bool = new Boolean(bool); 3115 } 3116 } catch (e) {} 3117 3118 return bool; 3119 }); 3120 3121 var props = ['Width', 'Span', 'Fill', 'Gap', 'Rule', 'RuleColor', 'RuleStyle', 'RuleWidth', 'BreakBefore', 'BreakAfter', 'BreakInside']; 3122 var name, test; 3123 3124 for (var i = 0; i < props.length; i++) { 3125 name = props[i].toLowerCase(); 3126 test = testAllProps('column' + props[i]); 3127 3128 // break-before, break-after & break-inside are not "column"-prefixed in spec 3129 if (name === 'breakbefore' || name === 'breakafter' || name == 'breakinside') { 3130 test = test || testAllProps(props[i]); 3131 } 3132 3133 Modernizr.addTest('csscolumns.' + name, test); 3134 } 3135 3136 3137 })(); 3138 3139 3140 /*! 3141 { 3142 "name": "Flexbox", 3143 "property": "flexbox", 3144 "caniuse": "flexbox", 3145 "tags": ["css"], 3146 "notes": [{ 3147 "name": "The _new_ flexbox", 3148 "href": "http://dev.w3.org/csswg/css3-flexbox" 3149 }], 3150 "warnings": [ 3151 "A `true` result for this detect does not imply that the `flex-wrap` property is supported; see the `flexwrap` detect." 3152 ] 3153 } 3154 !*/ 3155 /* DOC 3156 Detects support for the Flexible Box Layout model, a.k.a. Flexbox, which allows easy manipulation of layout order and sizing within a container. 3157 */ 3158 3159 Modernizr.addTest('flexbox', testAllProps('flexBasis', '1px', true)); 3160 3161 /*! 3162 { 3163 "name": "CSS Reflections", 3164 "caniuse": "css-reflections", 3165 "property": "cssreflections", 3166 "tags": ["css"] 3167 } 3168 !*/ 3169 3170 Modernizr.addTest('cssreflections', testAllProps('boxReflect', 'above', true)); 3171 3172 /*! 3173 { 3174 "name": "CSS Transforms", 3175 "property": "csstransforms", 3176 "caniuse": "transforms2d", 3177 "tags": ["css"] 3178 } 3179 !*/ 3180 3181 Modernizr.addTest('csstransforms', function() { 3182 // Android < 3.0 is buggy, so we sniff and blacklist 3183 // http://git.io/hHzL7w 3184 return navigator.userAgent.indexOf('Android 2.') === -1 && 3185 testAllProps('transform', 'scale(1)', true); 3186 }); 3187 3188 /*! 3189 { 3190 "name": "CSS Transforms 3D", 3191 "property": "csstransforms3d", 3192 "caniuse": "transforms3d", 3193 "tags": ["css"], 3194 "warnings": [ 3195 "Chrome may occassionally fail this test on some systems; more info: https://code.google.com/p/chromium/issues/detail?id=129004" 3196 ] 3197 } 3198 !*/ 3199 3200 Modernizr.addTest('csstransforms3d', function() { 3201 var ret = !!testAllProps('perspective', '1px', true); 3202 var usePrefix = Modernizr._config.usePrefixes; 3203 3204 // Webkit's 3D transforms are passed off to the browser's own graphics renderer. 3205 // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in 3206 // some conditions. As a result, Webkit typically recognizes the syntax but 3207 // will sometimes throw a false positive, thus we must do a more thorough check: 3208 if (ret && (!usePrefix || 'webkitPerspective' in docElement.style)) { 3209 var mq; 3210 var defaultStyle = '#modernizr{width:0;height:0}'; 3211 // Use CSS Conditional Rules if available 3212 if (Modernizr.supports) { 3213 mq = '@supports (perspective: 1px)'; 3214 } else { 3215 // Otherwise, Webkit allows this media query to succeed only if the feature is enabled. 3216 // `@media (transform-3d),(-webkit-transform-3d){ ... }` 3217 mq = '@media (transform-3d)'; 3218 if (usePrefix) { 3219 mq += ',(-webkit-transform-3d)'; 3220 } 3221 } 3222 3223 mq += '{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}'; 3224 3225 testStyles(defaultStyle + mq, function(elem) { 3226 ret = elem.offsetWidth === 7 && elem.offsetHeight === 18; 3227 }); 3228 } 3229 3230 return ret; 3231 }); 3232 3233 /*! 3234 { 3235 "name": "CSS Transitions", 3236 "property": "csstransitions", 3237 "caniuse": "css-transitions", 3238 "tags": ["css"] 3239 } 3240 !*/ 3241 3242 Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true)); 3243 3244 3245 // Run each test 3246 testRunner(); 3247 3248 // Remove the "no-js" class if it exists 3249 setClasses(classes); 3250 3251 delete ModernizrProto.addTest; 3252 delete ModernizrProto.addAsyncTest; 3253 3254 // Run the things that are supposed to run after the tests 3255 for (var i = 0; i < Modernizr._q.length; i++) { 3256 Modernizr._q[i](); 3257 } 3258 3259 // Leak Modernizr namespace 3260 window.Modernizr = Modernizr; 3261 3262 3263 ; 3264 3265})(window, document);; 3266/** 3267 * File skip-link-focus-fix.js. 3268 * 3269 * Helps with accessibility for keyboard only users. 3270 * 3271 * This is the source file for what is minified in the varia_skip_link_focus_fix() PHP function. 3272 * 3273 * Learn more: https://git.io/vWdr2 3274 */ 3275( function() { 3276 var isIe = /(trident|msie)/i.test( navigator.userAgent ); 3277 3278 if ( isIe && document.getElementById && window.addEventListener ) { 3279 window.addEventListener( 'hashchange', function() { 3280 var id = location.hash.substring( 1 ), 3281 element; 3282 3283 if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { 3284 return; 3285 } 3286 3287 element = document.getElementById( id ); 3288 3289 if ( element ) { 3290 if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { 3291 element.tabIndex = -1; 3292 } 3293 3294 element.focus(); 3295 } 3296 }, false ); 3297 } 3298} )(); 3299; 3300/*! This file is auto-generated */ 3301/*! 3302 * imagesLoaded PACKAGED v5.0.0 3303 * JavaScript is all like "You images are done yet or what?" 3304 * MIT License 3305 */ 3306!function(t,e){"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,(function(){function t(){}let e=t.prototype;return e.on=function(t,e){if(!t||!e)return this;let i=this._events=this._events||{},s=i[t]=i[t]||[];return s.includes(e)||s.push(e),this},e.once=function(t,e){if(!t||!e)return this;this.on(t,e);let i=this._onceEvents=this._onceEvents||{};return(i[t]=i[t]||{})[e]=!0,this},e.off=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;let s=i.indexOf(e);return-1!=s&&i.splice(s,1),this},e.emitEvent=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;i=i.slice(0),e=e||[];let s=this._onceEvents&&this._onceEvents[t];for(let n of i){s&&s[n]&&(this.off(t,n),delete s[n]),n.apply(this,e)}return this},e.allOff=function(){return delete this._events,delete this._onceEvents,this},t})), 3307/*! 3308 * imagesLoaded v5.0.0 3309 * JavaScript is all like "You images are done yet or what?" 3310 * MIT License 3311 */ 3312function(t,e){"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,(function(t,e){let i=t.jQuery,s=t.console;
3312function n(t,e,o){if(!(this instanceof n))return new n(t,e,o);let r=t;var h;("string"==typeof t&&(r=document.querySelectorAll(t)),r)?(this.elements=(h=r,Array.isArray(h)?h:"object"==typeof h&&"number"==typeof h.length?[...h]:[h]),this.options={},"function"==typeof e?o=e:Object.assign(this.options,e),o&&this.on("always",o),this.getImages(),i&&(this.jqDeferred=new i.Deferred),setTimeout(this.check.bind(this))):s.error(`Bad element for imagesLoaded ${r||t}`)}n.prototype=Object.create(e.prototype),n.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)};const o=[1,9,11];n.prototype.addElementImages=function(t){"IMG"===t.nodeName&&this.addImage(t),!0===this.options.background&&this.addElementBackgroundImages(t);let{nodeType:e}=t;if(!e||!o.includes(e))return;let i=t.querySelectorAll("img");for(let t of i)this.addImage(t);if("string"==typeof this.options.background){let e=t.querySelectorAll(this.options.background);for(let t of e)this.addElementBackgroundImages(t)}};const r=/url\((['"])?(.*?)\1\)/gi;function h(t){this.img=t}function d(t,e){this.url=t,this.element=e,this.img=new Image}return n.prototype.addElementBackgroundImages=function(t){let e=getComputedStyle(t);if(!e)return;let i=r.exec(e.backgroundImage);for(;null!==i;){let s=i&&i[2];s&&this.addBackground(s,t),i=r.exec(e.backgroundImage)}},n.prototype.addImage=function(t){let e=new h(t);this.images.push(e)},n.prototype.addBackground=function(t,e){let i=new d(t,e);this.images.push(i)},n.prototype.check=function(){if(this.progressedCount=0,this.hasAnyBroken=!1,!this.images.length)return void this.complete();let t=(t,e,i)=>{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n}));; 3313/** 3314 * jQuery plugin to make the main navigation WAI-ARIA compatible 3315 * Inspired by http://simplyaccessible.com/examples/css-menu/option-6/ 3316 * 3317 * It needs jquery.hoverIntent 3318 */ 3319(function($) { 3320 3321 $.fn.ariaNavigation = function(settings) { 3322 3323 //Map of all the alphanumeric keys so one can jump through submenus by typing the first letter 3324 //Also use the ESC key to close a submenu 3325 var keyCodeMap = { 3326 48: "0", 3327 49: "1", 3328 50: "2", 3329 51: "3", 3330 52: "4", 3331 53: "5", 3332 54: "6", 3333 55: "7", 3334 56: "8", 3335 57: "9", 3336 59: ";", 3337 65: "a", 3338 66: "b", 3339 67: "c", 3340 68: "d", 3341 69: "e", 3342 70: "f", 3343 71: "g", 3344 72: "h", 3345 73: "i", 3346 74: "j", 3347 75: "k", 3348 76: "l", 3349 77: "m", 3350 78: "n", 3351 79: "o", 3352 80: "p", 3353 81: "q", 3354 82: "r", 3355 83: "s", 3356 84: "t", 3357 85: "u", 3358 86: "v", 3359 87: "w", 3360 88: "x", 3361 89: "y", 3362 90: "z", 3363 96: "0", 3364 97: "1", 3365 98: "2", 3366 99: "3", 3367 100: "4", 3368 101: "5", 3369 102: "6", 3370 103: "7", 3371 104: "8", 3372 105: "9" 3373 }, 3374 $nav = $(this), 3375 $allLinks = $nav.find('li.menu-item > a, li.page_item > a'), 3376 $topLevelLinks = $nav.find('> li > a'), 3377 subLevelLinks = $topLevelLinks.parent('li').find('ul').find('a'); 3378 navWidth = $nav.outerWidth(); 3379 3380 //default settings 3381 settings = jQuery.extend({ 3382 menuHoverClass: 'show-menu', 3383 topMenuHoverClass: 'hover' 3384 }, settings); 3385 3386 3387 /** 3388 * First add the needed WAI-ARIA markup - supercharge the menu 3389 */ 3390 3391 // Add ARIA role to menubar and menu items 3392 //$nav.find( 'li' ).attr( 'role', 'menuitem' ); 3393 3394 $topLevelLinks.each(function() { 3395 //for regular sub-menus 3396 // Set tabIndex to -1 so that links can't receive focus until menu is open 3397 $(this).next('ul') 3398 .attr({ 3399 'aria-hidden': 'true', 3400 'role': 'menu' 3401 }) 3402 .find('a') 3403 .attr('tabIndex', -1); 3404 3405 // Add aria-haspopup for appropriate items 3406 if ($(this).next('ul').length > 0) { 3407 $(this).parent('li').attr('aria-haspopup', 'true'); 3408 } 3409 3410 // Set tabIndex to -1 so that links can't receive focus until menu is open 3411 $(this).next('.menu-item-has-children').children('ul') 3412 .attr({ 3413 'aria-hidden': 'true', 3414 'role': 'menu' 3415 }) 3416 .find('a').attr('tabIndex', -1); 3417 3418 $(this).next('.menu-item-has-children') 3419 .find('a').attr('tabIndex', -1); 3420 3421 // Add aria-haspopup for appropriate items 3422 if ($(this).next('.sub-menu').length > 0) 3423 $(this).parent('li').attr('aria-haspopup', 'true'); 3424 3425 // Set tabIndex to -1 so that links can't receive focus until menu is open 3426 $(this).next('.page_item_has_children').children('ul') 3427 .attr({ 3428 'aria-hidden': 'true', 3429 'role': 'menu' 3430 }) 3431 .find('a').attr('tabIndex', -1); 3432 3433 $(this).next('.page_item_has_children') 3434 .find('a').attr('tabIndex', -1); 3435 3436 // Add aria-haspopup for appropriate items 3437 if ($(this).next('.children').length > 0) 3438 $(this).parent('li').attr('aria-haspopup', 'true'); 3439 }); 3440 3441 3442 /** 3443 * Now let's begin binding things to their proper events 3444 */ 3445 3446 // First, bind to the hover event 3447 // use hoverIntent to make sure we avoid flicker 3448 $allLinks.closest('li').hoverIntent({ 3449 over: function() { 3450 //clean up first 3451 $(this).closest('ul') 3452 .find('ul.' + settings.menuHoverClass) 3453 .attr('aria-hidden', 'true') 3454 .removeClass(settings.menuHoverClass) 3455 .find('a') 3456 .attr('tabIndex', -1); 3457 3458 $(this).closest('ul') 3459 .find('.' + settings.topMenuHoverClass) 3460 .removeClass(settings.topMenuHoverClass); 3461 3462 //now do things 3463 showSubMenu($(this)); 3464 3465 }, 3466 out: function() { 3467 hideSubMenu($(this)); 3468 }, 3469 timeout: 10 3470 }); 3471 3472 // Secondly, bind to the focus event - very important for WAI-ARIA purposes 3473 $allLinks.focus(function() { 3474 //clean up first 3475 $(this).closest('ul') 3476 .find('ul.' + settings.menuHoverClass) 3477 .attr('aria-hidden', 'true') 3478 .removeClass(settings.menuHoverClass) 3479 .find('a') 3480 .attr('tabIndex', -1); 3481 3482 $(this).closest('ul') 3483 .find('.' + settings.topMenuHoverClass) 3484 .removeClass(settings.topMenuHoverClass); 3485 3486 //now do things 3487 showSubMenu($(this).closest('li')); 3488 3489 }); 3490 3491 3492 // Now bind arrow keys for navigating the menu 3493 3494 // First the top level links (the permanent visible links) 3495 $topLevelLinks.keydown(function(e) { 3496 var $item = $(this); 3497 3498 if (e.keyCode == 37) { //left arrow 3499 e.preventDefault(); 3500 // This is the first item 3501 if ($item.parent('li').prev('li').length == 0) { 3502 $item.parents('ul').find('> li').last().find('a').first().focus(); 3503 } else { 3504 $item.parent('li').prev('li').find('a').first().focus(); 3505 } 3506 } else if (e.keyCode == 38) { //up arrow 3507 e.preventDefault(); 3508 if ($item.parent('li').find('ul').length > 0) { 3509 $item.parent('li').find('ul') 3510 .attr('aria-hidden', 'false') 3511 .addClass(settings.menuHoverClass) 3512 .find('a').attr('tabIndex', 0) 3513 .last().focus(); 3514 } 3515 } else if (e.keyCode == 39) { //right arrow 3516 e.preventDefault(); 3517 3518 // This is the last item 3519 if ($item.parent('li').next('li').length == 0) { 3520 $item.parents('ul').find('> li').first().find('a').first().focus(); 3521 } else { 3522 $item.parent('li').next('li').find('a').first().focus(); 3523 } 3524 } else if (e.keyCode == 40) { //down arrow 3525 e.preventDefault(); 3526 if ($item.parent('li').find('ul').length > 0) { 3527 $item.parent('li').find('ul') 3528 .attr('aria-hidden', 'false') 3529 .addClass(settings.menuHoverClass) 3530 .find('a').attr('tabIndex', 0) 3531 .first().focus(); 3532 } 3533 } else if (e.keyCode == 32) { //space key 3534 // If submenu is hidden, open it 3535 e.preventDefault(); 3536 $item.parent('li').find('ul[aria-hidden=true]') 3537 .attr('aria-hidden', 'false') 3538 .addClass(settings.menuHoverClass) 3539 .find('a').attr('tabIndex', 0) 3540 .first().focus(); 3541 } else if (e.keyCode == 27) { //escape key 3542 e.preventDefault(); 3543 $('.' + settings.menuHoverClass) 3544 .attr('aria-hidden', 'true') 3545 .removeClass(settings.menuHoverClass) 3546 .find('a') 3547 .attr('tabIndex', -1); 3548 } else { //cycle through the child submenu items based on the first letter 3549 $item.parent('li').find('ul[aria-hidden=false] > li > a').each(function() { 3550 if ($(this).text().substring(0, 1).toLowerCase() == keyCodeMap[e.keyCode]) { 3551 $(this).focus(); 3552 return false;
3553 } 3554 }); 3555 } 3556 }); 3557 3558 // Now do the keys bind for the submenus links 3559 $(subLevelLinks).keydown(function(e) { 3560 var $item = $(this); 3561 3562 if (e.keyCode == 38) { //up arrow 3563 e.preventDefault(); 3564 // This is the first item 3565 if ($item.parent('li').prev('li').length == 0) { 3566 $item.parents('ul').parents('li').find('a').first().focus(); 3567 } else { 3568 $item.parent('li').prev('li').find('a').first().focus(); 3569 } 3570 } else if (e.keyCode == 39) { //right arrow 3571 e.preventDefault(); 3572 3573 //if it has sub-menus we should go into them 3574 if ($item.parent('li').hasClass('menu-item-has-children')) { 3575 $item.next('ul').find('> li').first().find('a').first().focus(); 3576 } else { 3577 // This is the last item 3578 if ($item.parent('li').next('li').length == 0) { 3579 $item.closest('ul').closest('li').children('a').first().focus(); 3580 } else { 3581 $item.parent('li').next('li').find('a').first().focus(); 3582 } 3583 } 3584 } else if (e.keyCode == 40) { //down arrow 3585 e.preventDefault(); 3586 3587 // This is the last item 3588 if ($item.parent('li').next('li').length == 0) { 3589 $item.closest('ul').closest('li').children('a').first().focus(); 3590 } else { 3591 $item.parent('li').next('li').find('a').first().focus(); 3592 } 3593 } else if (e.keyCode == 27 || e.keyCode == 37) { //escape key or left arrow => jump to the upper level links 3594 e.preventDefault(); 3595 3596 //focus on the upper level link 3597 $item.closest('ul').closest('li') 3598 .children('a').first().focus(); 3599 3600 } else if (e.keyCode == 32) { //space key 3601 e.preventDefault(); 3602 window.location = $item.attr('href'); 3603 } else { 3604 3605 //cycle through the menu items based on the first letter 3606 var found = false; 3607 $item.parent('li').nextAll('li').find('a').each(function() { 3608 if ($(this).text().substring(0, 1).toLowerCase() == keyCodeMap[e.keyCode]) { 3609 $(this).focus(); 3610 found = true; 3611 return false; 3612 } 3613 }); 3614 3615 if (!found) { 3616 $item.parent('li').prevAll('li').find('a').each(function() { 3617 if ($(this).text().substring(0, 1).toLowerCase() == keyCodeMap[e.keyCode]) { 3618 $(this).focus(); 3619 return false; 3620 } 3621 }); 3622 } 3623 } 3624 }); 3625 3626 3627 // Hide menu if click or focus occurs outside of navigation 3628 $nav.find('a').last().keydown(function(e) { 3629 if (e.keyCode == 9) { //tab key 3630 // If the user tabs out of the navigation hide all menus 3631 hideSubMenus(); 3632 } 3633 }); 3634 3635 //close all menus when pressing ESC key 3636 $(document).keydown(function(e) { 3637 if (e.keyCode == 27) { //esc key 3638 hideSubMenus(); 3639 } 3640 }); 3641 3642 //close all menus on click outside 3643 $(document).click(function() { 3644 hideSubMenus(); 3645 }); 3646 3647 $nav.on('click touchstart', function(e) { 3648 e.stopPropagation(); 3649 }); 3650 3651 function getIOSVersion(ua) { 3652 ua = ua || navigator.userAgent; 3653 return parseFloat( 3654 ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(ua) || [0, ''])[1]) 3655 .replace('undefined', '3_2').replace('_', '.').replace('_', '') 3656 ) || false; 3657 } 3658 3659 function showSubMenu($item) { 3660 3661 $item.addClass(settings.topMenuHoverClass); 3662 3663 $item.find('.sub-menu, .children').first() //affect only the first ul found - the one with the submenus, ignore the mega menu items 3664 .attr('aria-hidden', 'false') 3665 .addClass(settings.menuHoverClass); 3666 3667 $item.find('a').attr('tabIndex', 0); //set the tabIndex to 0 so we let the browser figure out the tab order 3668 3669 } 3670 3671 function hideSubMenu($item) { 3672 3673 if ($item.hasClass('menu-item-has-children')) { 3674 $item.children('.sub-menu').css('left', ''); 3675 } 3676 3677 if ($item.hasClass('page_item_has_children')) { 3678 $item.children('.children').css('left', ''); 3679 } 3680 3681 $item.children('a').first().next('ul') 3682 .attr('aria-hidden', 'true') 3683 .removeClass(settings.menuHoverClass) 3684 .find('a') 3685 .attr('tabIndex', -1); 3686 3687 //when dealing with first level submenus - they are wrapped 3688 $item.children('a').first().next('.sub-menu') 3689 .attr('aria-hidden', 'true') 3690 .removeClass(settings.menuHoverClass) 3691 .find('a') 3692 .attr('tabIndex', -1); 3693 3694 $item.children('a').first().next('.children') 3695 .attr('aria-hidden', 'true') 3696 .removeClass(settings.menuHoverClass) 3697 .find('a') 3698 .attr('tabIndex', -1); 3699 3700 $item.removeClass(settings.topMenuHoverClass); 3701 } 3702 3703 function hideSubMenus() { 3704 3705 $('.' + settings.menuHoverClass) 3706 .attr('aria-hidden', 'true') 3707 .removeClass(settings.menuHoverClass) 3708 .find('a') 3709 .attr('tabIndex', -1); 3710 3711 $('.' + settings.topMenuHoverClass).removeClass(settings.topMenuHoverClass); 3712 3713 } 3714 } 3715 3716})(jQuery); 3717 3718/*! 3719 * hoverIntent v1.8.0 // 2014.06.29 // jQuery v1.9.1+ 3720 * http://cherne.net/brian/resources/jquery.hoverIntent.html 3721 * 3722 * You may use hoverIntent under the terms of the MIT license. Basically that 3723 * means you are free to use hoverIntent as long as this header is left intact. 3724 * Copyright 2007, 2014 Brian Cherne 3725 */ 3726(function($) { 3727 $.fn.hoverIntent = function(handlerIn, handlerOut, selector) { 3728 var cfg = { 3729 interval: 100, 3730 sensitivity: 6, 3731 timeout: 0 3732 };
3733 if (typeof handlerIn === "object") { 3734 cfg = $.extend(cfg, handlerIn) 3735 } else { 3736 if ($.isFunction(handlerOut)) { 3737 cfg = $.extend(cfg, { 3738 over: handlerIn, 3739 out: handlerOut, 3740 selector: selector 3741 }) 3742 } else { 3743 cfg = $.extend(cfg, { 3744 over: handlerIn, 3745 out: handlerIn, 3746 selector: handlerOut 3747 }) 3748 } 3749 } 3750 var cX, cY, pX, pY; 3751 var track = function(ev) { 3752 cX = ev.pageX; 3753 cY = ev.pageY 3754 }; 3755 var compare = function(ev, ob) { 3756 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 3757 if (Math.sqrt((pX - cX) * (pX - cX) + (pY - cY) * (pY - cY)) < cfg.sensitivity) { 3758 $(ob).off("mousemove.hoverIntent", track); 3759 ob.hoverIntent_s = true; 3760 return cfg.over.apply(ob, [ev]) 3761 } else { 3762 pX = cX; 3763 pY = cY; 3764 ob.hoverIntent_t = setTimeout(function() { 3765 compare(ev, ob) 3766 }, cfg.interval) 3767 } 3768 }; 3769 var delay = function(ev, ob) { 3770 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 3771 ob.hoverIntent_s = false; 3772 return cfg.out.apply(ob, [ev]) 3773 }; 3774 var handleHover = function(e) { 3775 var ev = $.extend({}, e); 3776 var ob = this; 3777 if (ob.hoverIntent_t) { 3778 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t) 3779 } 3780 if (e.type === "mouseenter") { 3781 pX = ev.pageX; 3782 pY = ev.pageY; 3783 $(ob).on("mousemove.hoverIntent", track); 3784 if (!ob.hoverIntent_s) { 3785 ob.hoverIntent_t = setTimeout(function() { 3786 compare(ev, ob) 3787 }, cfg.interval) 3788 } 3789 } else { 3790 $(ob).off("mousemove.hoverIntent", track); 3791 if (ob.hoverIntent_s) { 3792 ob.hoverIntent_t = setTimeout(function() { 3793 delay(ev, ob) 3794 }, cfg.timeout) 3795 } 3796 } 3797 }; 3798 return this.on({ 3799 "mouseenter.hoverIntent": handleHover, 3800 "mouseleave.hoverIntent": handleHover 3801 }, cfg.selector) 3802 } 3803})(jQuery); 3804// /* ====== Smart Resize Logic ====== */ 3805// It's best to debounce the resize event to a void performance hiccups 3806(function($, sr) { 3807 3808 /** 3809 * debouncing function from John Hann 3810 * http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ 3811 */ 3812 var debounce = function(func, threshold, execAsap) { 3813 var timeout; 3814 3815 return function debounced() { 3816 var obj = this, 3817 args = arguments; 3818 3819 function delayed() { 3820 if (!execAsap) func.apply(obj, args); 3821 timeout = null; 3822 } 3823 3824 if (timeout) clearTimeout(timeout); 3825 else if (execAsap) func.apply(obj, args); 3826 3827 timeout = setTimeout(delayed, threshold || 200); 3828 }; 3829 } 3830 // smartresize 3831 jQuery.fn[sr] = function(fn) { 3832 return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); 3833 }; 3834 3835})(jQuery, 'smartresize'); 3836(function($, undefined) { 3837 // /* ====== SHARED VARS - jQuery ====== */ 3838 // These depend on jQuery 3839 var $window = $(window), 3840 windowHeight = $window.height(), 3841 windowWidth = $window.width(), 3842 latestKnownScrollY = window.scrollY, 3843 ticking = false, 3844 isTouchDevice = !!('ontouchstart' in window), 3845 $body = $('body'), 3846 isWekbit = ('WebkitAppearance' in document.documentElement.style) ? true : false, 3847 isIE = typeof(is_ie) !== "undefined" || (!(window.ActiveXObject) && "ActiveXObject" in window), 3848 isiele10 = navigator.userAgent.match(/msie (9|([1-9][0-9]))/i); 3849 var Grid = function() { 3850 3851 }; 3852 3853 Grid.prototype.refresh = function() { 3854 this.alignTitles(); 3855 this.addMargins(); 3856 this.adjustCardMeta(); 3857 this.offsetFirstColumn(); 3858 }; 3859 3860 Grid.prototype.alignTitles = function() { 3861 3862 $('.card-title-wrap').each(function(i, obj) { 3863 var $title = $(obj); 3864 $title.closest('.card__wrap').css('paddingBottom', $title.outerHeight() * 0.5); 3865 }); 3866 3867 }; 3868 3869 Grid.prototype.addMargins = function() { 3870 3871 var $columns = $('.column'), 3872 $compare; 3873 3874 $('.grid__item--mb').removeClass('grid__item--mb'); 3875 3876 $columns.each(function(i, column) { 3877 var $column = $(column); 3878 3879 if (i % 2 == 1) { 3880 3881 $column.children('.entry-card--portrait, .entry-card--text').each(function(j, obj) { 3882 var $obj = $(obj); 3883 3884 if ($obj.is(':nth-child(2n+1)')) { 3885 $compare = $columns.eq(i - 1); 3886 } else { 3887 $compare = $columns.eq(i + 1); 3888 } 3889 3890 if (typeof $compare == "undefined") { 3891 return; 3892 } 3893 3894 var bottom = $obj.offset().top + $obj.outerHeight(), 3895 $neighbour; 3896 3897 $compare.children().each(function(j, item) { 3898 var $item = $(item), 3899 thisBottom = $(item).offset().top + $(item).outerHeight(); 3900 3901 if (thisBottom < bottom) { 3902 $neighbour = $item; 3903 } else { 3904 return false;
3905 } 3906 }); 3907 3908 if (typeof $neighbour !== "undefined") { 3909 $neighbour.addClass('grid__item--mb'); 3910 } 3911 }); 3912 } 3913 }); 3914 }; 3915 3916 Grid.prototype.showCards = function($cards) { 3917 3918 $cards.each(function(i, obj) { 3919 var $obj = $(obj); 3920 3921 setTimeout(function() { 3922 $obj.addClass('is-visible'); 3923 }, i * 150); 3924 3925 setTimeout(function() { 3926 $obj.removeClass('ajax-loaded'); 3927 }, 400 + i * 150); 3928 3929 $obj.imagesLoaded(function() { 3930 3931 var $img = $('<img>'), 3932 $thumbnail = $obj.find('.card__image--large'); 3933 3934 $img.attr('src', $thumbnail.data('src')); 3935 3936 $img.imagesLoaded(function() { 3937 $obj.addClass('is-loaded'); 3938 }); 3939 3940 $thumbnail.replaceWith($img); 3941 }); 3942 }); 3943 3944 }; 3945 3946 Grid.prototype.adjustCardMeta = function() { 3947 3948 if ($body.is('.singular') || windowWidth < 480) { 3949 $('.card__meta').attr('style', ''); 3950 } else { 3951 $('.card--image').each(function(i, obj) { 3952 var $cardMeta = $(obj).find('.card__meta'); 3953 $cardMeta.css('marginTop', -1 * $cardMeta.height()); 3954 }); 3955 } 3956 3957 }; 3958 3959 Grid.prototype.offsetFirstColumn = function() { 3960 var $columns = $('.bricklayer-column'); 3961 if ($columns.length > 1) { 3962 var height = $('.header .site-branding').outerHeight(); 3963 $columns.css('marginTop', '').eq(1).css('marginTop', height); 3964 } 3965 }; 3966 3967 Logo = function() { 3968 3969 this.$header = $('.header'); 3970 this.$logo = $('.site-branding'); 3971 this.$clone = null; 3972 this.distance = null; 3973 this.initialized = false; 3974 3975 }; 3976 3977 Logo.prototype.adjustSiteTitle = function() { 3978 3979 $('.site-title').each(function(i, obj) { 3980 var $title = $(obj).removeAttr('style').css('fontSize', ''), 3981 $branding = $title.closest('.site-branding'), 3982 $span = $title.find('span'), 3983 titleWidth = $title.width(), 3984 brandingHeight, 3985 spanWidth = $span.width(), 3986 fontSize = parseInt($title.css('fontSize', '').css('fontSize')), 3987 scaling = spanWidth / parseFloat(titleWidth), 3988 maxLines = $body.is('.singular') ? 3 : 2; 3989 3990 /* if site title is too long use a smaller font size */ 3991 if (spanWidth > titleWidth) { 3992 fontSize = parseInt(fontSize / scaling); 3993 $title.css('fontSize', fontSize); 3994 } 3995 3996 var titleHeight = $title.outerHeight(); 3997 3998 if ($title.closest('.mobile-logo').length) { 3999 var mobileHeight = $('.mobile-logo').outerHeight(); 4000 fontSize = parseInt(fontSize * mobileHeight / titleHeight); 4001 if (mobileHeight < titleHeight) { 4002 $title.css('fontSize', fontSize); 4003 } 4004 return; 4005 } 4006 4007 brandingHeight = $branding.outerHeight(); 4008 4009 /* if site title is too long use a smaller font size */ 4010 if (brandingHeight < titleHeight) { 4011 fontSize = parseInt(fontSize * brandingHeight / t
4011itleHeight); 4012 $title.css('fontSize', fontSize); 4013 return; 4014 } 4015 4016 /* if site title is too tall, again, use a smaller font size */ 4017 var lineHeight = parseFloat($title.css('lineHeight')) / fontSize, 4018 lines = Math.round(titleHeight / fontSize / lineHeight); 4019 4020 while (lines > maxLines) { 4021 fontSize = fontSize - 1; 4022 $title.css('fontSize', fontSize); 4023 titleHeight = $title.outerHeight(); 4024 lines = titleHeight / fontSize / lineHeight; 4025 } 4026 }); 4027 }; 4028 4029 Logo.prototype.adjustArchiveTitle = function() { 4030 4031 $('.archive-title').each(function(i, obj) { 4032 var $title = $(obj).removeAttr('style').css('fontSize', ''), 4033 fontSize = parseInt($title.css('font-size')), 4034 $span = $title.find('span'), 4035 titleWidth = $title.width(), 4036 spanWidth = $span.width(), 4037 scaling = spanWidth / parseFloat(titleWidth); 4038 4039 /* if site title is too long use a smaller font size */ 4040 if (spanWidth > titleWidth) { 4041 fontSize = parseInt(fontSize / scaling); 4042 $title.css('fontSize', fontSize); 4043 } 4044 }); 4045 4046 }; 4047 4048 Logo.prototype.prepare = function(scrollY) { 4049 4050 var that = this; 4051 4052 scrollY = scrollY || (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0); 4053 4054 if (that.$logo.length) { 4055 4056 that.$logo.imagesLoaded(function() { 4057 4058 if (that.$clone === null) { 4059 that.$clone = that.$logo.clone().appendTo('.mobile-logo'); 4060 } else { 4061 that.$clone.removeAttr('style'); 4062 } 4063 4064 that.logoMid = that.$logo.offset().top + that.$logo.height() / 2; 4065 that.cloneMid = that.$clone.offset().top + that.$clone.height() / 2 - scrollY; 4066 that.distance = that.logoMid - that.cloneMid; 4067 4068 that.initialized = true; 4069 4070 that.update(scrollY); 4071 4072 that.$clone.css('opacity', 1); 4073 4074 }); 4075 } 4076 }; 4077 4078 Logo.prototype.update = function(scrollY) { 4079 4080 if (!this.initialized) { 4081 return; 4082 } 4083 4084 if (this.distance < scrollY) { 4085 this.$clone.css('transform', 'none'); 4086 return; 4087 } 4088 4089 this.$clone.css('transform', 'translateY(' + (this.distance - scrollY) + 'px)'); 4090 }; 4091 4092 /*! 4093 * pixelgradeTheme v1.0.1 4094 * Copyright (c) 2017 PixelGrade http://www.pixelgrade.com 4095 * Licensed under MIT http://www.opensource.org/licenses/mit-license.php/ 4096 */ 4097 var pixelgradeTheme = function() { 4098 4099 var _this = this, 4100 windowWidth = window.innerWidth, 4101 windowHeight = window.innerHeight, 4102 lastScrollY = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0), 4103 orientation = windowWidth > windowHeight ? 'landscape' : 'portrait'; 4104 4105 _this.ev = $({}); 4106 _this.frameRendered = false; 4107 _this.debug = false; 4108 4109 _this.log = function() { 4110 if (_this.debug) { 4111 console.log.apply(this, arguments) 4112 } 4113 }; 4114
4115 _this.getScroll = function() { 4116 return lastScrollY; 4117 }; 4118 4119 _this.getWindowWidth = function() { 4120 return windowWidth; 4121 }; 4122 4123 _this.getWindowHeight = function() { 4124 return windowHeight; 4125 }; 4126 4127 _this.getOrientation = function() { 4128 return orientation; 4129 }; 4130 4131 _this.onScroll = function() { 4132 if (_this.frameRendered === false) { 4133 return; 4134 } 4135 lastScrollY = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0); 4136 _this.frameRendered = false; 4137 }; 4138 4139 _this.onResize = function() { 4140 windowWidth = window.innerWidth; 4141 windowHeight = window.innerHeight; 4142 4143 var newOrientation = windowWidth > windowHeight ? 'landscape' : 'portrait'; 4144 4145 _this.debouncedResize(); 4146 4147 if (orientation !== newOrientation) { 4148 _this.debouncedOrientationChange(); 4149 } 4150 4151 orientation = newOrientation; 4152 }; 4153 4154 _this.debouncedResize = Util.debounce(function() { 4155 $(window).trigger('pxg:resize'); 4156 }, 300); 4157 4158 _this.debouncedOrientationChange = Util.debounce(function() { 4159 $(window).trigger('pxg:orientationchange'); 4160 }, 300); 4161 4162 _this.renderLoop = function() { 4163 if (_this.frameRendered === false) { 4164 _this.ev.trigger('render'); 4165 } 4166 requestAnimationFrame(function() { 4167 _this.renderLoop(); 4168 _this.frameRendered = true; 4169 _this.ev.trigger('afterRender'); 4170 }); 4171 }; 4172 4173 _this.eventHandlers = function() { 4174 $(document).ready(_this.onReady); 4175 $(window) 4176 .on('scroll', _this.onScroll) 4177 .on('resize', _this.onResize) 4178 .on('load', _this.onLoad); 4179 }; 4180 4181 _this.eventHandlers(); 4182 _this.renderLoop(); 4183 }; 4184 4185 pixelgradeTheme.prototype.onReady = function() { 4186 $('html').addClass('is-ready'); 4187 }; 4188 4189 pixelgradeTheme.prototype.onLoad = function() { 4190 $('html').addClass('is-loaded'); 4191 }; 4192 4193 var Util = { 4194 /** 4195 * 4196 * @returns {boolean} 4197 */ 4198 isTouch: function() { 4199 return !!( 4200 "ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch 4201 ); 4202 }, 4203 4204 handleCustomCSS: function($container) { 4205 var $elements = typeof $container !== "undefined" ? $container.find("[data-css]") : $("[data-css]"); 4206 4207 if ($elements.length) { 4208 $elements.each(function(i, obj) { 4209 var $element = $(obj), 4210 css = $element.data('css'); 4211 4212 if (typeof css !== "undefined") { 4213 $element.replaceWith('<style type="text/css">' + css + '</style>'); 4214 } 4215 }); 4216 } 4217 }, 4218 4219 4220 /** 4221 * Search every image that is alone in a p tag and wrap it 4222 * in a figure element to behave like images with captions 4223 * 4224 * @param $container 4225 */ 4226 unwrapImages: function($container) { 4227 4228 $container = typeof $container !== "undefined" ? $container : $body; 4229 4230 $container.find('p > img:first-child:last-child, p > a:first-child:last-child > img').each(function(i, obj) { 4231 var $obj = $(obj), 4232 $image = $obj.closest('img'), 4233 className = $image.attr('class'), 4234 $p = $image.closest('p'), 4235 $figure = $('<figure />').attr('class', className); 4236 4237 if ($.trim($p.text()).length) { 4238 return; 4239 } 4240 4241 $figure.append($image.removeAttr('class')); 4242 $p.replaceWith($figure); 4243 }); 4244 }, 4245 4246 wrapEmbeds: function($container) { 4247 $container = typeof $container !== "undefined" ? $container : $('body'); 4248 $container.children('iframe, embed, object').wrap('<p>'); 4249 }, 4250 4251 /** 4252 * Initialize video elements on demand from placeholders 4253 * 4254 * @param $container 4255 */ 4256 handleVideos: function($container) { 4257 $container = typeof $container !== "undefined" ? $container : $body; 4258 4259 $container.find('.video-placeholder').each(function(i, obj) { 4260 var $placeholder = $(obj), 4261 video = document.createElement('video'), 4262 $video = $(video).addClass('c-hero__video'); 4263 4264 // play as soon as possible 4265 video.onloadedmetadata = function() { 4266 video.play(); 4267 }; 4268 4269 video.src = $placeholder.data('src'); 4270 video.poster = $placeholder.data('poster'); 4271 video.muted = true; 4272 video.loop = true; 4273 4274 $placeholder.replaceWith($video); 4275 }); 4276 }, 4277 4278 smoothScrollTo: function(to, duration, easing) { 4279 to = to || 0; 4280 duration = duration || 1000; 4281 easing = easing || 'swing'; 4282 4283 $("html, body").stop().animate({ 4284 scrollTop: to 4285 }, duration, easing); 4286 4287 }, 4288 4289 // Returns a function, that, as long as it continues to be invoked, will not 4290 // be triggered. The function will be called after it stops being called for 4291 // N milliseconds. If `immediate` is passed, trigger the function on the 4292 // leading edge, instead of the trailing. 4293 debounce: function(func, wait, immediate) { 4294 var timeout; 4295 return function() { 4296 var context = this, 4297 args = arguments; 4298 var later = function() { 4299 timeout = null; 4300 if (!immediate) {
4301 func.apply(context, args); 4302 } 4303 }; 4304 var callNow = immediate && !timeout; 4305 clearTimeout(timeout); 4306 timeout = setTimeout(later, wait); 4307 if (callNow) { 4308 func.apply(context, args); 4309 } 4310 }; 4311 }, 4312 4313 // Returns a function, that, when invoked, will only be triggered at most once 4314 // during a given window of time. Normally, the throttled function will run 4315 // as much as it can, without ever going more than once per `wait` duration; 4316 // but if you'd like to disable the execution on the leading edge, pass 4317 // `{leading: false}`. To disable execution on the trailing edge, ditto. 4318 throttle: function(callback, limit) { 4319 var wait = false; 4320 return function() { 4321 if (!wait) { 4322 callback.call(); 4323 wait = true; 4324 setTimeout(function() { 4325 wait = false; 4326 }, limit); 4327 } 4328 } 4329 }, 4330 4331 mq: function(direction, string) { 4332 var $temp = $('<div class="u-mq-' + direction + '-' + string + '">').appendTo('body'), 4333 response = $temp.is(':visible'); 4334 4335 $temp.remove(); 4336 return response; 4337 }, 4338 4339 below: function(string) { 4340 return this.mq('below', string); 4341 }, 4342 4343 above: function(string) { 4344 return this.mq('above', string); 4345 }, 4346 4347 getParamFromURL: function(param, url) { 4348 var parameters = ( 4349 url.split('?') 4350 )[1]; 4351 4352 if (typeof parameters === "undefined") { 4353 return parameters; 4354 } 4355 4356 parameters = parameters.split('&'); 4357 4358 for (var i = 0; i < parameters.length; i++) { 4359 var parameter = parameters[i].split('='); 4360 if (parameter[0] === param) { 4361 return parameter[1]; 4362 } 4363 } 4364 }, 4365 4366 reloadScript: function(filename) { 4367 var $old = $('script[src*="' + filename + '"]'), 4368 $new = $('<script>'), 4369 src = $old.attr('src'); 4370 4371 if (!$old.length) { 4372 return; 4373 } 4374 4375 $old.replaceWith($new); 4376 $new.attr('src', src); 4377 }, 4378 4379 // here we change the link of the Edit button in the Admin Bar 4380 // to make sure it reflects the current page 4381 adminBarEditFix: function(id, editString, taxonomy) { 4382 // get the admin ajax url and clean it 4383 var baseEditURL = juliaStrings.ajaxurl.replace('admin-ajax.php', 'post.php'), 4384 baseEditTaxURL = juliaStrings.ajaxurl.replace('admin-ajax.php', 'edit-tags.php'), 4385 $editButton = $('#wp-admin-bar-edit a'); 4386 4387 if (!empty($editButton)) { 4388 if (id !== undefined && editString !== undefined) { //modify the current Edit button 4389 if (!empty(taxonomy)) { //it seems we need to edit a taxonomy 4390 $editButton.attr('href', baseEditTaxURL + '?tag_ID=' + id + '&taxonomy=' + taxonomy + '&action=edit'); 4391 } else { 4392 $editButton.attr('href', baseEditURL + '?post=' + id + '&action=edit'); 4393 } 4394 $editButton.html(editString); 4395 } else { // we have found an edit button but right now we don't need it anymore since we have no id 4396 $('#wp-admin-bar-edit').remove(); 4397 } 4398 } else { // upss ... no edit button 4399 // lets see if we need one 4400 if (id !== undefined && editString !== undefined) { //we do need one after all 4401 //locate the New button because we need to add stuff after it 4402 var $newButton = $('#wp-admin-bar-new-content'); 4403 4404 if (!empty($newButton)) { 4405 if (!empty(taxonomy)) { //it seems we need to generate a taxonomy edit thingy 4406 $newButton.after('<li id="wp-admin-bar-edit"><a class="ab-item dJAX_internal" href="' + baseEditTaxURL + '?tag_ID=' + id + '&taxonomy='
4406+ taxonomy + '&action=edit">' + editString + '</a></li>'); 4407 } else { //just a regular edit 4408 $newButton.after('<li id="wp-admin-bar-edit"><a class="ab-item dJAX_internal" href="' + baseEditURL + '?post=' + id + '&action=edit">' + editString + '</a></li>'); 4409 } 4410 } 4411 } 4412 } 4413 4414 //Also we need to fix the (no-)customize-support class on body by running the WordPress inline script again 4415 // The original code is generated by the wp_customize_support_script() function in wp-includes/theme.php @3007 4416 var request, b = document.body, 4417 c = 'className', 4418 cs = 'customize-support', 4419 rcs = new RegExp('(^|\\s+)(no-)?' + cs + '(\\s+|$)'); 4420 4421 // No CORS request 4422 request = true; 4423 4424 b[c] = b[c].replace(rcs, ' '); 4425 // The customizer requires postMessage and CORS (if the site is cross domain) 4426 b[c] += (window.postMessage && request ? ' ' : ' no-') + cs; 4427 4428 //Plus, we need to change the url of the Customize button to the current url 4429 var $customizeButton = $('#wp-admin-bar-customize a'), 4430 baseCustomizeURL = juliaStrings.ajaxurl.replace('admin-ajax.php', 'customize.php'); 4431 if (!empty($customizeButton)) { 4432 $customizeButton.attr('href', baseCustomizeURL + '?url=' + encodeURIComponent(window.location.href)); 4433 } 4434 4435 } 4436 4437 }; 4438 4439 var HandleSubmenusOnTouch = (function() { 4440 4441 var $theUsualSuspects, 4442 $theUsualAnchors, 4443 initialInit = false; 4444 4445 function init() { 4446 if (initialInit || !isTouchDevice) return; 4447 4448 $theUsualSuspects = $('li[class*=children]').removeClass('hover'); 4449 $theUsualAnchors = $theUsualSuspects.find('> a'); 4450 4451 unbind(); 4452 4453 $theUsualAnchors.on('click', function(e) { 4454 e.preventDefault(); 4455 e.stopPropagation(); 4456 4457 if ($(this).hasClass('active')) { 4458 window.location.href = $(this).attr('href'); 4459 } 4460 4461 $theUsualAnchors.removeClass('active'); 4462 $(this).addClass('active'); 4463 4464 // When a parent menu item is activated, 4465 // close other menu items on the same level 4466 $(this).parent().siblings().removeClass('hover'); 4467 4468 // Open the sub menu of this parent item 4469 $(this).parent().addClass('hover'); 4470 }); 4471 4472 bindOuterNavClick(); 4473 4474 initialInit = true; 4475 } 4476 4477 function unbind() { 4478 $theUsualAnchors.unbind(); 4479 isHorizontalInitiated = false; 4480 } 4481 4482 // When a sub menu is open, close it by a touch on 4483 // any other part of the viewport than navigation. 4484 // use case: normal, horizontal menu, touch events, 4485 // sub menus are not visible. 4486 function bindOuterNavClick() { 4487 $body.on('touchstart', function(e) { 4488 var container = $('.main-navigation'); 4489 4490 if (!container.is(e.target) // if the target of the click isn't the container... 4491 && 4492 container.has(e.target).length === 0) // ... nor a descendant of the container 4493 { 4494 $theUsualSuspects.removeClass('hover').removeClass('active'); 4495 } 4496 }); 4497 } 4498 4499 return { 4500 init: init 4501 } 4502 }()); 4503 4504 function checkForSmallImageOnSingle() { 4505 if (!$body.hasClass('singular') || $body.hasClass('no-featured-image')) { 4506 return; 4507 } 4508 4509 if (windowWidth > 900) { 4510 if ($('.entry-featured img').width() < 500) { 4511 $body.addClass('has--small-featured-image'); 4512 $('.post__content').css('paddingTop', $('.entry-featured').height() + 30); 4513 } 4514 } else { 4515 $('.post__content').removeAttr('style'); 4516 } 4517 } 4518 4519 var Gema = new pixelgradeTheme(), 4520 log = Gema.log, 4521 resizeEvent = 'ontouchstart' in window && 'onorientationchange' in window ? 'pxg:orientationchange' : 'pxg:resize', 4522 $html = $('html'), 4523 $body = $('body'); 4524 4525 window.bricklayer = null; 4526 4527 Gema.init = function() { 4528 $body.toggleClass('is--webkit', isWekbit); 4529 $body.toggleClass('is--ie', isIE); 4530 $body.toggleClass('is--ie-le10', isiele10); 4531 4532 Gema.Grid = new Grid(); 4533 Gema.Logo = new Logo(); 4534 4535 checkForSmallImageOnSingle(); 4536 4537 HandleSubmenusOnTouch.init(); 4538 4539 $('ul.nav-menu').ariaNavigation(); 4540 4541 $('.grid, .site-header').css('opacity', 1); 4542 4543 if ($body.is('.singular')) { 4544 prepareSingle(); 4545 } else { 4546 prepareArchive(); 4547 } 4548 4549 Gema.adjustLayout(); 4550 }; 4551 4552 Gema.onPostLoad = function(event, data) { 4553 var $elements = $(data.html).filter('.grid__item').addClass('ajax-loaded').each(function(i, obj) { 4554 if ($.fn.mediaelementplayer) { 4555 $(obj).find('audio, video').mediaelementplayer(); 4556 } 4557 }); 4558 4559 $('.infinite-loader').remove(); 4560 4561 if ($('.grid').length && bricklayer !== null) { 4562 bricklayer.append($.makeArray($elements)); 4563 } 4564 4565 // Clean up the duplicate posts that are appended 4566 // by default by Jetpack's Infinite Scroll to div#main 4567 // (and also the corresponding HTML comments) 4568 $('#main').contents().each(function() { 4569 if ($(this).is('article') || this.nodeType === Node.COMMENT_NODE) { 4570 $(this).remove(); 4571 } 4572 }); 4573 4574 Gema.adjustLayout(); 4575 4576 Gema.Grid.showCards($elements); 4577 }; 4578 4579 Gema.bindEvents = function() { 4580
4581 var $nav = $('ul.nav-menu'), 4582 $document = $(document), 4583 $window = $(window); 4584 4585 $window.on(resizeEvent, Gema.adjustLayout); 4586 $window.on('load', Gema.adjustLayout); 4587 $body.on('post-load', Gema.onPostLoad); 4588 4589 Gema.ev.on('render', Gema.update); 4590 4591 $('.overlay-toggle').on('touchstart click', toggleOverlay); 4592 $('.menu-toggle').on('touchstart click', toggleNav); 4593 $('.sidebar-toggle').on('touchstart click', toggleSidebar); 4594 4595 $document.keydown(function(e) { 4596 // ESC key 4597 if (e.keyCode === 27) { 4598 hidePanels(); 4599 } 4600 }); 4601 4602 // close all menus on click outside 4603 $('.overlay-shadow').on('touchstart', function(e) { 4604 e.preventDefault(); 4605 e.stopPropagation(); 4606 4607 hidePanels(); 4608 }); 4609 } 4610 4611 function hidePanels() { 4612 4613 if ($body.hasClass('nav-is-open')) { 4614 toggleNav(); 4615 } 4616 4617 if ($body.hasClass('overlay-is-open')) { 4618 toggleOverlay(); 4619 } 4620 4621 if ($body.hasClass('sidebar-is-open')) { 4622 toggleSidebar(); 4623 } 4624 } 4625 4626 function toggleOverlay(e) { 4627 4628 if (typeof e !== "undefined") { 4629 e.preventDefault(); 4630 e.stopPropagation(); 4631 } 4632 4633 if (!$body.hasClass('overlay-is-open')) { 4634 $body.addClass('overlay-is-open'); 4635 $body.css({ 4636 overflow: 'hidden', 4637 width: $body.width(), 4638 }); 4639 } else { 4640 $body.removeClass('overlay-is-open'); 4641 $body.css({ 4642 overflow: '', 4643 width: '', 4644 }); 4645 } 4646 4647 } 4648 4649 function toggleNav(e) { 4650 4651 if (typeof e !== "undefined") { 4652 e.preventDefault(); 4653 e.stopPropagation(); 4654 } 4655 4656 if ($body.hasClass('nav-is-open')) { 4657 // closing the menu 4658 $('.menu-toggle').attr('aria-expanded', 'false'); 4659 } else { 4660 // opening the menu 4661 $('.menu-toggle').attr('aria-expanded', 'true'); 4662 } 4663 4664 $body.toggleClass('nav-is-open'); 4665 } 4666 4667 function toggleSidebar(e) { 4668 4669 if (typeof e !== "undefined") { 4670 e.preventDefault(); 4671 e.stopPropagation(); 4672 } 4673 4674 if ($body.hasClass('sidebar-is-open')) { 4675 //closing the sidebar 4676 $('.sidebar-toggle').attr('aria-expanded', 'false'); 4677 } else { 4678 // opening the sidebar 4679 $('.sidebar-toggle').attr('aria-expanded', 'true'); 4680 } 4681 4682 $body.toggleClass('sidebar-is-open'); 4683 } 4684 4685 function prepareArchive() { 4686 4687 var $cards = $('.card'); 4688 4689 if ($('.grid').length && bricklayer === null) { 4690 bricklayer = new Bricklayer(document.querySelector('.grid')); 4691 bricklayer.redraw(); 4692 } 4693 4694 Gema.Grid.showCards($cards); 4695 4696 $body.css('opacity', 1); 4697 } 4698 4699 function prepareSingle() { 4700 4701 var $mobileHeader = $('.mobile-header-wrapper'), 4702 scrollTo; 4703 4704 if ($mobileHeader.is(':visible')) { 4705 scrollTo = $('.content-area').offset().top - $mobileHeader.outerHeight(); 4706 setTimeout(function() { 4707 window.scrollTo(0, scrollTo); 4708 $body.css('opacity', 1); 4709 }); 4710 } else { 4711 $body.css('opacity', 1); 4712 } 4713 } 4714 4715 Gema.hidePanels = function() { 4716 $body.removeClass('nav-is-open') 4717 .removeClass('sidebar-is-open') 4718 .removeClass('overlay-is-open') 4719 .css('width', '') 4720 .css('overflow', ''); 4721 }; 4722 4723 Gema.update = function() { 4724 if (typeof Gema.Logo !== "undefined") { 4725 Gema.Logo.update(Gema.getScroll()); 4726 } 4727 }; 4728 4729 Gema.alignWideBlocks = function() { 4730 var $header = $('#masthead'); 4731 var headerOffset = $header.offset(); 4732 var headerBottom = $header.length ? headerOffset.top + $header.outerHeight() : 0; 4733 var headerLeft = $header.length ? headerOffset.left : 0; 4734 4735 var $sidebar = $('#secondary'); 4736 var sidebarOffset = $sidebar.offset(); 4737 var sidebarPosition = $sidebar.css('position'); 4738 var sidebarBottom = ($sidebar.length && 'fixed' !== sidebarPosition) ? sidebarOffset.top + $
4738sidebar.outerHeight() : 0; 4739 4740 var $main = $('#main'); 4741 var mainOffset = $main.offset(); 4742 var mainLeft = mainOffset.left; 4743 var mainRight = $main.length ? mainOffset.left + $main.outerWidth() : 0; 4744 4745 var bodyWidth = $body.outerWidth(); 4746 4747 var $blocks = $('.entry-content').children('.alignfull, .alignwide'); 4748 4749 $blocks.removeClass('fill-left fill-right'); 4750 $blocks.css({ 4751 marginLeft: '', 4752 marginRight: '', 4753 }); 4754 4755 $blocks.each(function(i, obj) { 4756 var $block = $(obj); 4757 var blockOffset = $block.offset(); 4758 var blockTop = blockOffset.top; 4759 var blockLeft = blockOffset.left; 4760 var blockRight = blockLeft + $block.outerWidth(); 4761 var fillLeft = blockTop > headerBottom; 4762 var fillRight = blockTop > sidebarBottom; 4763 var wideToLeft = fillLeft ? headerLeft : mainLeft; 4764 var fullToLeft = fillLeft ? 0 : mainLeft; 4765 4766 $block.toggleClass('fill-left', fillLeft || fillRight); 4767 $block.toggleClass('fill-right', fillRight); 4768 4769 if ($block.is('.alignwide')) { 4770 4771 if (fillLeft || fillRight) { 4772 $block.css('marginLeft', wideToLeft - blockLeft); 4773 } 4774 4775 if (fillRight) { 4776 $block.css('marginRight', blockRight - mainRight); 4777 } 4778 } 4779 4780 if ($block.is('.alignfull')) { 4781 4782 if (fillLeft || fillRight) { 4783 $block.css('marginLeft', fullToLeft - blockLeft); 4784 } 4785 4786 if (fillRight) { 4787 $block.css('marginRight', blockRight - bodyWidth); 4788 } 4789 } 4790 4791 }); 4792 }; 4793 4794 Gema.adjustLayout = function() { 4795 4796 if (Gema.getWindowWidth() > 900) { 4797 Gema.hidePanels(); 4798 } 4799 4800 // Single 4801 checkForSmallImageOnSingle(); 4802 Gema.placeSidebar(); 4803 4804 if ($body.is('.singular')) { 4805 Gema.alignWideBlocks(); 4806 } 4807 4808 // Archive 4809 Gema.Logo.adjustSiteTitle(); 4810 Gema.Logo.adjustArchiveTitle(); 4811 Gema.Logo.prepare(); 4812 4813 Gema.Grid.offsetFirstColumn(); 4814 Gema.Grid.adjustCardMeta(); 4815 Gema.Grid.alignTitles(); 4816 Gema.Grid.addMargins(); 4817 }; 4818 4819 Gema.placeSidebar = function() { 4820 4821 if (!$body.hasClass('has-active-sidebar')) { 4822 return; 4823 } 4824 4825 var $sidebar = $('.widget-area'), 4826 $content = $('.content-area'); 4827 4828 if (Gema.getWindowWidth() > 900) { 4829 4830 if (!$sidebar.length) { 4831 return; 4832 } 4833 4834 if ($body.hasClass('no-featured-image')) { 4835 $sidebar.addClass('is--placed').css('top', $('.site-main').css('padding-top')); 4836 } else { 4837 // If we are past the breakpoint 4838 var $featuredImage = $('.entry-featured'), 4839 featuredImageBottom = $featuredImage.height() + parseInt($('.post__content').css('margin-top'), 10); 4840 4841 // position: absolute; on the sidebar(via ".is--placed") 4842 // below the featured image; 4843 if (!$body.hasClass('has--small-featured-image')) { 4844 $sidebar.addClass('is--placed').css('top', featuredImageBottom); 4845 } else { 4846 $sidebar.addClass('is--placed').css('top', 108); 4847 } 4848 } 4849 4850 // and set a height on the content so that everything seems in place. 4851 $content.css("minHeight", $sidebar.offset().top + $sidebar.height()); 4852 } else { 4853 // Remove the height (possibly) set above. 4854 $content.removeAttr('style'); 4855 $sidebar.css('top', ''); 4856 } 4857 }; 4858 4859 $.Gema = Gema; 4860 $.Gema.init(); 4861 Gema.bindEvents(); 4862 4863})(jQuery);; 4864!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}
4864,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.
4864info.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)}}
4864({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"}
4864function 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
4864s"))}),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.