<commit_before>/*! modernizr 3.5.0 (Custom Build) | MIT *
 * https://modernizr.com/download/?-audio-backgroundsize-boxshadow-boxsizing-classlist-cssanimations-cssgradients-csstransforms-csstransforms3d-csstransitions-flexbox-fontface-inlinesvg-opacity-svg-svgasimg-textshadow-touchevents-setclasses-testprop-teststyles !*/
!function(e,t,n){function o(e,t){return typeof e===t}function r(){var e,t,n,r,s,i,a;for(var l in T)if(T.hasOwnProperty(l)){if(e=[],t=T[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(r=o(t.fn,"function")?t.fn():t.fn,s=0;s<e.length;s++)i=e[s],a=i.split("."),1===a.length?Modernizr[a[0]]=r:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=r),x.push((r?"":"no-")+a.join("-"))}}function s(e){var t=S.className,n=Modernizr._config.classPrefix||"";if(_&&(t=t.baseVal),Modernizr._config.enableJSClass){var o=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(o,"$1"+n+"js$2")}Modernizr._config.enableClasses&&(t+=" "+n+e.join(" "+n),_?S.className.baseVal=t:S.className=t)}function i(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):_?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}function a(e,t){return!!~(""+e).indexOf(t)}function l(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function u(){var e=t.body;return e||(e=i(_?"svg":"body"),e.fake=!0),e}function f(e,n,o,r){var s,a,l,f,c="modernizr",d=i("div"),p=u();if(parseInt(o,10))for(;o--;)l=i("div"),l.id=r?r[o]:c+(o+1),d.appendChild(l);return s=i("style"),s.type="text/css",s.id="s"+c,(p.fake?p:d).appendChild(s),p.appendChild(d),s.styleSheet?s.styleSheet.cssText=e:s.appendChild(t.createTextNode(e)),d.id=c,p.fake&&(p.style.background="",p.style.overflow="hidden",f=S.style.overflow,S.style.overflow="hidden",S.appendChild(p)),a=n(d,e),p.fake?(p.parentNode.removeChild(p),S.style.overflow=f,S.offsetHeight):d.parentNode.removeChild(d),!!a}function c(e,t){if("object"==typeof e)for(var n in e)j(e,n)&&c(n,e[n]);else{e=e.toLowerCase();var o=e.split("."),r=Modernizr[o[0]];if(2==o.length&&(r=r[o[1]]),"undefined"!=typeof r)return Modernizr;t="function"==typeof t?t():t,1==o.length?Modernizr[o[0]]=t:(!Modernizr[o[0]]||Modernizr[o[0]]instanceof Boolean||(Modernizr[o[0]]=new Boolean(Modernizr[o[0]])),Modernizr[o[0]][o[1]]=t),s([(t&&0!=t?"":"no-")+o.join("-")]),Modernizr._trigger(e,t)}return Modernizr}function d(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function p(t,n,o){var r;if("getComputedStyle"in e){r=getComputedStyle.call(e,t,n);var s=e.console;if(null!==r)o&&(r=r.getPropertyValue(o));else if(s){var i=s.error?"error":"log";s[i].call(s,"getComputedStyle returning null, its possible modernizr test results are inaccurate")}}else r=!n&&t.currentStyle&&t.currentStyle[o];return r}function g(t,o){var r=t.length;if("CSS"in e&&"supports"in e.CSS){for(;r--;)if(e.CSS.supports(d(t[r]),o))return!0;return!1}if("CSSSupportsRule"in e){for(var s=[];r--;)s.push("("+d(t[r])+":"+o+")");return s=s.join(" or "),f("@supports ("+s+") { #modernizr { position: absolute; } }",function(e){return"absolute"==p(e,null,"position")})}return n}function m(e,t,r,s){function u(){c&&(delete R.style,delete R.modElem)}if(s=o(s,"undefined")?!1:s,!o(r,"undefined")){var f=g(e,r);if(!o(f,"undefined"))return f}for(var c,d,p,m,h,v=["modernizr","tspan","samp"];!R.style&&v.length;)c=!0,R.modElem=i(v.shift()),R.style=R.modElem.style;for(p=e.length,d=0;p>d;d++)if(m=e[d],h=R.style[m],a(m,"-")&&(m=l(m)),R.style[m]!==n){if(s||o(r,"undefined"))return u(),"pfx"==t?m:!0;try{R.style[m]=r}catch(y){}if(R.style[m]!=h)return u(),"pfx"==t?m:!0}return u(),!1}function h(e,t){return function(){return e.apply(t,arguments)}}function v(e,t,n){var r;for(var s in e)if(e[s]in t)return n===!1?e[s]:(r=t[e[s]],o(r,"function")?h(r,n||t):r);return!1}function y(e,t,n,r,s){var i=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+O.join(i+" ")+i).split(" ");return o(t,"string")||o(t,"undefined")?m(a,t,r,s):(a=(e+" "+L.join(i+" ")+i).split(" "),v(a,t,n))}function w(e,t,o){return y(e,n,n,t,o)}var x=[],T=[],b={_version:"3.5.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){T.push({name:e,fn:t,options:n})},addAsyncTest:function(e){T.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=b,Modernizr=new Modernizr,Modernizr.addTest("svg",!!t.createElementNS&&!!t.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect);var S=t.documentElement;Modernizr.addTest("classlist","classList"in S);var _="svg"===S.nodeName.toLowerCase();Modernizr.addTest("audio",function(){var e=i("audio"),t=!1;try{t=!!e.canPlayType,t&&(t=new Boolean(t),t.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),t.mp3=e.canPlayType('audio/mpeg; codecs="mp3"').replace(/^no$/,""),t.opus=e.canPlayType('audio/ogg; codecs="opus"')||e.canPlayType('audio/webm; codecs="opus"').replace(/^no$/,""),t.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),t.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(n){}return t}),Modernizr.addTest("inlinesvg",function(){var e=i("div");return e.innerHTML="<svg/>","http://www.w3.org/2000/svg"==("undefined"!=typeof SVGRect&&e.firstChild&&e.firstChild.namespaceURI)});var C=b._config.usePrefixes?" -webkit- -moz- -o- -ms- ".split(" "):["",""];b._prefixes=C,Modernizr.addTest("cssgradients",function(){for(var e,t="background-image:",n="gradient(linear,left top,right bottom,from(#9f9),to(white));",o="",r=0,s=C.length-1;s>r;r++)e=0===r?"to ":"",o+=t+C[r]+"linear-gradient("+e+"left top, #9f9, white);";Modernizr._config.usePrefixes&&(o+=t+"-webkit-"+n);var a=i("a"),l=a.style;return l.cssText=o,(""+l.backgroundImage).indexOf("gradient")>-1}),Modernizr.addTest("opacity",function(){var e=i("a").style;return e.cssText=C.join("opacity:.55;"),/^0.55$/.test(e.opacity)});var P="CSS"in e&&"supports"in e.CSS,z="supportsCSS"in e;Modernizr.addTest("supports",P||z);var k=b.testStyles=f;Modernizr.addTest("touchevents",function(){var n;if("ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch)n=!0;else{var o=["@media (",C.join("touch-enabled),("),"heartz",")","{#modernizr{top:9px;position:absolute}}"].join("");k(o,function(e){n=9===e.offsetTop})}return n});var E=function(){var e=navigator.userAgent,t=e.match(/w(eb)?osbrowser/gi),n=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9;return t||n}();E?Modernizr.addTest("fontface",!1):k('@font-face {font-family:"font";src:url("https://")}',function(e,n){var o=t.getElementById("smodernizr"),r=o.sheet||o.styleSheet,s=r?r.cssRules&&r.cssRules[0]?r.cssRules[0].cssText:r.cssText||"":"",i=/src/i.test(s)&&0===s.indexOf(n.split(" ")[0]);Modernizr.addTest("fontface",i)});var j;!function(){var e={}.hasOwnProperty;j=o(e,"undefined")||o(e.call,"undefined")?function(e,t){return t in e&&o(e.constructor.prototype[t],"undefined")}:function(t,n){return e.call(t,n)}}(),b._l={},b.on=function(e,t){this._l[e]||(this._l[e]=[]),this._l[e].push(t),Modernizr.hasOwnProperty(e)&&setTimeout(function(){Modernizr._trigger(e,Modernizr[e])},0)},b._trigger=function(e,t){if(this._l[e]){var n=this._l[e];setTimeout(function(){var e,o;for(e=0;e<n.length;e++)(o=n[e])(t)},0),delete this._l[e]}},Modernizr._q.push(function(){b.addTest=c}),Modernizr.addTest("svgasimg",t.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1"));var N={elem:i("modernizr")};Modernizr._q.push(function(){delete N.elem});var R={style:N.elem.style};Modernizr._q.unshift(function(){delete R.style});var $=b.testProp=function(e,t,o){return m([e],n,t,o)};Modernizr.addTest("textshadow",$("textShadow","1px 1px"));var A="Moz O ms Webkit",O=b._config.usePrefixes?A.split(" "):[];b._cssomPrefixes=O;var L=b._config.usePrefixes?A.toLowerCase().split(" "):[];b._domPrefixes=L,b.testAllProps=y,b.testAllProps=w,Modernizr.addTest("cssanimations",w("animationName","a",!0)),Modernizr.addTest("backgroundsize",w("backgroundSize","100%",!0)),Modernizr.addTest("boxshadow",w("boxShadow","1px 1px",!0)),Modernizr.addTest("boxsizing",w("boxSizing","border-box",!0)&&(t.documentMode===n||t.documentMode>7)),Modernizr.addTest("flexbox",w("flexBasis","1px",!0)),Modernizr.addTest("csstransforms",function(){return-1===navigator.userAgent.indexOf("Android 2.")&&w("transform","scale(1)",!0)}),Modernizr.addTest("csstransforms3d",function(){var e=!!w("perspective","1px",!0),t=Modernizr._config.usePrefixes;if(e&&(!t||"webkitPerspective"in S.style)){var n,o="#modernizr{width:0;height:0}";Modernizr.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",k(o+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),Modernizr.addTest("csstransitions",w("transition","all",!0)),r(),s(x),delete b.addTest,delete b.addAsyncTest;for(var B=0;B<Modernizr._q.length;B++)Modernizr._q[B]();e.Modernizr=Modernizr}(window,document);<commit_msg>Update modernizr dev pkg to more common tests and latest version.<commit_after>/*! modernizr 3.6.0 (Custom Build) | MIT *
 * https://modernizr.com/download/?-audio-backgroundsize-boxshadow-boxsizing-classlist-cssanimations-cssgradients-cssgrid_cssgridlegacy-csstransforms-csstransforms3d-csstransitions-cssvhunit-flexbox-fontface-inlinesvg-objectfit-opacity-svg-svgasimg-textshadow-touchevents-setclasses-testprop-teststyles !*/
!function(e,t,n){function r(e,t){return typeof e===t}function o(){var e,t,n,o,s,i,a;for(var l in S)if(S.hasOwnProperty(l)){if(e=[],t=S[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(o=r(t.fn,"function")?t.fn():t.fn,s=0;s<e.length;s++)i=e[s],a=i.split("."),1===a.length?Modernizr[a[0]]=o:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=o),x.push((o?"":"no-")+a.join("-"))}}function s(e){var t=C.className,n=Modernizr._config.classPrefix||"";if(_&&(t=t.baseVal),Modernizr._config.enableJSClass){var r=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(r,"$1"+n+"js$2")}Modernizr._config.enableClasses&&(t+=" "+n+e.join(" "+n),_?C.className.baseVal=t:C.className=t)}function i(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):_?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}function a(t,n,r){var o;if("getComputedStyle"in e){o=getComputedStyle.call(e,t,n);var s=e.console;if(null!==o)r&&(o=o.getPropertyValue(r));else if(s){var i=s.error?"error":"log";s[i].call(s,"getComputedStyle returning null, its possible modernizr test results are inaccurate")}}else o=!n&&t.currentStyle&&t.currentStyle[r];return o}function l(e,t){return!!~(""+e).indexOf(t)}function u(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function c(){var e=t.body;return e||(e=i(_?"svg":"body"),e.fake=!0),e}function f(e,n,r,o){var s,a,l,u,f="modernizr",d=i("div"),p=c();if(parseInt(r,10))for(;r--;)l=i("div"),l.id=o?o[r]:f+(r+1),d.appendChild(l);return s=i("style"),s.type="text/css",s.id="s"+f,(p.fake?p:d).appendChild(s),p.appendChild(d),s.styleSheet?s.styleSheet.cssText=e:s.appendChild(t.createTextNode(e)),d.id=f,p.fake&&(p.style.background="",p.style.overflow="hidden",u=C.style.overflow,C.style.overflow="hidden",C.appendChild(p)),a=n(d,e),p.fake?(p.parentNode.removeChild(p),C.style.overflow=u,C.offsetHeight):d.parentNode.removeChild(d),!!a}function d(e,t){if("object"==typeof e)for(var n in e)k(e,n)&&d(n,e[n]);else{e=e.toLowerCase();var r=e.split("."),o=Modernizr[r[0]];if(2==r.length&&(o=o[r[1]]),"undefined"!=typeof o)return Modernizr;t="function"==typeof t?t():t,1==r.length?Modernizr[r[0]]=t:(!Modernizr[r[0]]||Modernizr[r[0]]instanceof Boolean||(Modernizr[r[0]]=new Boolean(Modernizr[r[0]])),Modernizr[r[0]][r[1]]=t),s([(t&&0!=t?"":"no-")+r.join("-")]),Modernizr._trigger(e,t)}return Modernizr}function p(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function g(t,r){var o=t.length;if("CSS"in e&&"supports"in e.CSS){for(;o--;)if(e.CSS.supports(p(t[o]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var s=[];o--;)s.push("("+p(t[o])+":"+r+")");return s=s.join(" or "),f("@supports ("+s+") { #modernizr { position: absolute; } }",function(e){return"absolute"==a(e,null,"position")})}return n}function m(e,t,o,s){function a(){f&&(delete O.style,delete O.modElem)}if(s=r(s,"undefined")?!1:s,!r(o,"undefined")){var c=g(e,o);if(!r(c,"undefined"))return c}for(var f,d,p,m,h,v=["modernizr","tspan","samp"];!O.style&&v.length;)f=!0,O.modElem=i(v.shift()),O.style=O.modElem.style;for(p=e.length,d=0;p>d;d++)if(m=e[d],h=O.style[m],l(m,"-")&&(m=u(m)),O.style[m]!==n){if(s||r(o,"undefined"))return a(),"pfx"==t?m:!0;try{O.style[m]=o}catch(y){}if(O.style[m]!=h)return a(),"pfx"==t?m:!0}return a(),!1}function h(e,t){return function(){return e.apply(t,arguments)}}function v(e,t,n){var o;for(var s in e)if(e[s]in t)return n===!1?e[s]:(o=t[e[s]],r(o,"function")?h(o,n||t):o);return!1}function y(e,t,n,o,s){var i=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+A.join(i+" ")+i).split(" ");return r(t,"string")||r(t,"undefined")?m(a,t,o,s):(a=(e+" "+B.join(i+" ")+i).split(" "),v(a,t,n))}function w(e,t,r){return y(e,n,n,t,r)}function T(e,t){return e-1===t||e===t||e+1===t}var x=[],S=[],b={_version:"3.6.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){S.push({name:e,fn:t,options:n})},addAsyncTest:function(e){S.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=b,Modernizr=new Modernizr,Modernizr.addTest("svg",!!t.createElementNS&&!!t.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect);var C=t.documentElement;Modernizr.addTest("classlist","classList"in C);var _="svg"===C.nodeName.toLowerCase();Modernizr.addTest("audio",function(){var e=i("audio"),t=!1;try{t=!!e.canPlayType,t&&(t=new Boolean(t),t.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),t.mp3=e.canPlayType('audio/mpeg; codecs="mp3"').replace(/^no$/,""),t.opus=e.canPlayType('audio/ogg; codecs="opus"')||e.canPlayType('audio/webm; codecs="opus"').replace(/^no$/,""),t.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),t.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(n){}return t}),Modernizr.addTest("inlinesvg",function(){var e=i("div");return e.innerHTML="<svg/>","http://www.w3.org/2000/svg"==("undefined"!=typeof SVGRect&&e.firstChild&&e.firstChild.namespaceURI)});var P=b._config.usePrefixes?" -webkit- -moz- -o- -ms- ".split(" "):["",""];b._prefixes=P,Modernizr.addTest("cssgradients",function(){for(var e,t="background-image:",n="gradient(linear,left top,right bottom,from(#9f9),to(white));",r="",o=0,s=P.length-1;s>o;o++)e=0===o?"to ":"",r+=t+P[o]+"linear-gradient("+e+"left top, #9f9, white);";Modernizr._config.usePrefixes&&(r+=t+"-webkit-"+n);var a=i("a"),l=a.style;return l.cssText=r,(""+l.backgroundImage).indexOf("gradient")>-1}),Modernizr.addTest("opacity",function(){var e=i("a").style;return e.cssText=P.join("opacity:.55;"),/^0.55$/.test(e.opacity)});var z="CSS"in e&&"supports"in e.CSS,j="supportsCSS"in e;Modernizr.addTest("supports",z||j);var E=b.testStyles=f;Modernizr.addTest("touchevents",function(){var n;if("ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch)n=!0;else{var r=["@media (",P.join("touch-enabled),("),"heartz",")","{#modernizr{top:9px;position:absolute}}"].join("");E(r,function(e){n=9===e.offsetTop})}return n});var R=function(){var e=navigator.userAgent,t=e.match(/w(eb)?osbrowser/gi),n=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9;return t||n}();R?Modernizr.addTest("fontface",!1):E('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),o=r.sheet||r.styleSheet,s=o?o.cssRules&&o.cssRules[0]?o.cssRules[0].cssText:o.cssText||"":"",i=/src/i.test(s)&&0===s.indexOf(n.split(" ")[0]);Modernizr.addTest("fontface",i)});var k;!function(){var e={}.hasOwnProperty;k=r(e,"undefined")||r(e.call,"undefined")?function(e,t){return t in e&&r(e.constructor.prototype[t],"undefined")}:function(t,n){return e.call(t,n)}}(),b._l={},b.on=function(e,t){this._l[e]||(this._l[e]=[]),this._l[e].push(t),Modernizr.hasOwnProperty(e)&&setTimeout(function(){Modernizr._trigger(e,Modernizr[e])},0)},b._trigger=function(e,t){if(this._l[e]){var n=this._l[e];setTimeout(function(){var e,r;for(e=0;e<n.length;e++)(r=n[e])(t)},0),delete this._l[e]}},Modernizr._q.push(function(){b.addTest=d}),Modernizr.addTest("svgasimg",t.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1"));var N={elem:i("modernizr")};Modernizr._q.push(function(){delete N.elem});var O={style:N.elem.style};Modernizr._q.unshift(function(){delete O.style});var L=b.testProp=function(e,t,r){return m([e],n,t,r)};Modernizr.addTest("textshadow",L("textShadow","1px 1px"));var $="Moz O ms Webkit",A=b._config.usePrefixes?$.split(" "):[];b._cssomPrefixes=A;var I=function(t){var r,o=P.length,s=e.CSSRule;if("undefined"==typeof s)return n;if(!t)return!1;if(t=t.replace(/^@/,""),r=t.replace(/-/g,"_").toUpperCase()+"_RULE",r in s)return"@"+t;for(var i=0;o>i;i++){var a=P[i],l=a.toUpperCase()+"_"+r;if(l in s)return"@-"+a.toLowerCase()+"-"+t}return!1};b.atRule=I;var B=b._config.usePrefixes?$.toLowerCase().split(" "):[];b._domPrefixes=B,b.testAllProps=y,b.testAllProps=w,Modernizr.addTest("cssanimations",w("animationName","a",!0)),Modernizr.addTest("backgroundsize",w("backgroundSize","100%",!0)),Modernizr.addTest("boxshadow",w("boxShadow","1px 1px",!0)),Modernizr.addTest("boxsizing",w("boxSizing","border-box",!0)&&(t.documentMode===n||t.documentMode>7)),Modernizr.addTest("cssgridlegacy",w("grid-columns","10px",!0)),Modernizr.addTest("cssgrid",w("grid-template-rows","none",!0)),Modernizr.addTest("flexbox",w("flexBasis","1px",!0)),Modernizr.addTest("csstransforms",function(){return-1===navigator.userAgent.indexOf("Android 2.")&&w("transform","scale(1)",!0)}),Modernizr.addTest("csstransforms3d",function(){return!!w("perspective","1px",!0)}),Modernizr.addTest("csstransitions",w("transition","all",!0));var V=b.prefixed=function(e,t,n){return 0===e.indexOf("@")?I(e):(-1!=e.indexOf("-")&&(e=u(e)),t?y(e,t,n):y(e,"pfx"))};Modernizr.addTest("objectfit",!!V("objectFit"),{aliases:["object-fit"]}),E("#modernizr { height: 50vh; }",function(t){var n=parseInt(e.innerHeight/2,10),r=parseInt(a(t,null,"height"),10);Modernizr.addTest("cssvhunit",T(r,n))}),o(),s(x),delete b.addTest,delete b.addAsyncTest;for(var q=0;q<Modernizr._q.length;q++)Modernizr._q[q]();e.Modernizr=Modernizr}(window,document);
<|endoftext|>


<commit_before>var sampleElement = document.createElement('context');
var createMenu = function (event, items) {
    var menulist = sampleElement.cloneNode();
    menulist.setAttribute("mode", "v");
    menulist.tabIndex = 0;
    items = items.filter(item => {
        if (!item.when) return true;
        if (!item.when(event)) return false;
        return true;
    });
    var elem = menuList(menulist, items, function (item) {
        action.call(this, item, event.target).then(function (e) {
            if (e !== false) remove(elem);
        });
        return false;
    });

    return elem;
}
function contextmenu(target, menuItems) {
    var showContext = function (event) {
        var menu;
        if (menuItems instanceof Function) {
            menu = menuItems.call(this, event);
        }
        if (menuItems instanceof Array) {
            menu = createMenu.call(this, event, menuItems);
        }
        if (!menu) return;
        css(menu, {
            position: "absolute",
        });
        popup(menu, event);
        onmousedown(menu, e => e.preventDefault());
        return menu;
    };
    var menuHandle = 0;
    var tm;
    moveupon(target, {
        start(event) {
            if (event.defaultPrevented) return;
            clearTimeout(menuHandle);
            menuHandle = setTimeout(function () {
                var e = createEvent("contextmenu", true);
                e.clientX = event.clientX;
                e.clientY = event.clientY;
                Object.defineProperty(e, "target", { value: event.target });
                Object.defineProperty(e, "srcElement", { value: event.srcElement });
                dispatch(event.target, e);
            }, 600);
        },
        move() {
            if (onclick.preventClick) {
                if (tm) remove(tm);
                return clearTimeout(menuHandle);
            }
        },
        end(event) {
            clearTimeout(menuHandle);
            event.preventDefault();
            _remove = function () { };
            setTimeout(function () {
                _remove = remove;
                if (tm) tm.focus();
            });
        }
    });
    var _remove = remove;
    var blur = lazy(function () {
        if (document.activeElement === this) return;
        _remove(this);
    }, 60);
    on("contextmenu")(target, function (event) {
        if (event.defaultPrevented) return;
        event.preventDefault();
        if (tm) remove(tm), tm = null;
        tm = showContext(event);
        if (!tm) return;
        tm.focus();
        onblur(tm, blur);
    });
    return sampleElement;
}<commit_msg>长按鼠标键不再弹出菜单<commit_after>var sampleElement = document.createElement('context');
var createMenu = function (event, items) {
    var menulist = sampleElement.cloneNode();
    menulist.setAttribute("mode", "v");
    menulist.tabIndex = 0;
    items = items.filter(item => {
        if (!item.when) return true;
        if (!item.when(event)) return false;
        return true;
    });
    var elem = menuList(menulist, items, function (item) {
        action.call(this, item, event.target).then(function (e) {
            if (e !== false) remove(elem);
        });
        return false;
    });

    return elem;
}
function contextmenu(target, menuItems) {
    var showContext = function (event) {
        var menu;
        if (menuItems instanceof Function) {
            menu = menuItems.call(this, event);
        }
        if (menuItems instanceof Array) {
            menu = createMenu.call(this, event, menuItems);
        }
        if (!menu) return;
        css(menu, {
            position: "absolute",
        });
        popup(menu, event);
        onmousedown(menu, e => e.preventDefault());
        return menu;
    };
    var menuHandle = 0;
    var tm;
    moveupon(target, {
        start(event) {
            if (event.defaultPrevented || event.type === 'mousedown') return;
            clearTimeout(menuHandle);
            menuHandle = setTimeout(function () {
                var e = createEvent("contextmenu", true);
                e.clientX = event.clientX;
                e.clientY = event.clientY;
                Object.defineProperty(e, "target", { value: event.target });
                Object.defineProperty(e, "srcElement", { value: event.srcElement });
                dispatch(event.target, e);
            }, 600);
        },
        move() {
            if (onclick.preventClick) {
                if (tm) remove(tm);
                return clearTimeout(menuHandle);
            }
        },
        end(event) {
            clearTimeout(menuHandle);
            event.preventDefault();
            _remove = function () { };
            setTimeout(function () {
                _remove = remove;
                if (tm) tm.focus();
            });
        }
    });
    var _remove = remove;
    var blur = lazy(function () {
        if (document.activeElement === this) return;
        _remove(this);
    }, 60);
    on("contextmenu")(target, function (event) {
        if (event.defaultPrevented) return;
        event.preventDefault();
        if (tm) remove(tm), tm = null;
        tm = showContext(event);
        if (!tm) return;
        tm.focus();
        onblur(tm, blur);
    });
    return sampleElement;
}<|endoftext|>


<commit_before>/**
 * Copyright 2019 The AMP HTML Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const argv = require('minimist')(process.argv.slice(2));
const babelify = require('babelify');
const karmaConfig = require('../karma.conf');
const log = require('fancy-log');
const testConfig = require('../../config');
const {
  createKarmaServer,
  getAdTypes,
  runTestInBatches,
  startTestServer,
} = require('./helpers');
const {createCtrlcHandler, exitCtrlcHandler} = require('../../ctrlcHandler');
const {green, yellow, cyan, red} = require('ansi-colors');
const {isTravisBuild} = require('../../travis');
const {reportTestStarted} = require('.././report-test-status');
const {unitTestsToRun} = require('./helpers-unit');

/**
 * Updates the browsers based off of the test type
 * being run (unit, integration, a4a) and test settings.
 * Keeps the default spec as is if no matching settings are found.
 * @param {!RuntimeTestConfig} config
 */
function updateBrowsers(config) {
  if (argv.saucelabs) {
    if (config.testType == 'unit') {
      Object.assign(config, {browsers: ['SL_Safari_12', 'SL_Firefox']});
      return;
    }

    if (config.testType == 'integration') {
      Object.assign(config, {
        browsers: [
          'SL_Chrome',
          'SL_Firefox',
          'SL_Edge_17',
          'SL_Safari_12',
          'SL_IE_11',
          // TODO(amp-infra): Evaluate and add more platforms here.
          //'SL_Chrome_Android_7',
          //'SL_iOS_11',
          //'SL_iOS_12',
          'SL_Chrome_Beta',
          'SL_Firefox_Beta',
        ],
      });
      return;
    }

    throw new Error(
      'The --saucelabs flag is valid only for `gulp unit` and `gulp integration`.'
    );
  }

  const chromeFlags = [];
  if (argv.chrome_flags) {
    argv.chrome_flags.split(',').forEach(flag => {
      chromeFlags.push('--'.concat(flag));
    });
  }

  const options = new Map();
  options
    .set('chrome_canary', {browsers: ['ChromeCanary']})
    .set('chrome_flags', {
      browsers: ['Chrome_flags'],
      customLaunchers: {
        // eslint-disable-next-line
        Chrome_flags: {
          base: 'Chrome',
          flags: chromeFlags,
        },
      },
    })
    .set('edge', {browsers: ['Edge']})
    .set('firefox', {browsers: ['Firefox']})
    .set('headless', {browsers: ['Chrome_no_extensions_headless']})
    .set('ie', {
      browsers: ['IE'],
      customLaunchers: {
        IeNoAddOns: {
          base: 'IE',
          flags: ['-extoff'],
        },
      },
    })
    .set('safari', {browsers: ['Safari']});

  for (const [key, value] of options) {
    if (argv.hasOwnProperty(key)) {
      Object.assign(config, value);
      return;
    }
  }
}

/**
 * Get the appropriate files based off of the test type
 * being run (unit, integration, a4a) and test settings.
 * @param {string} testType
 * @return {!Array<string>}
 */
function getFiles(testType) {
  let files;

  switch (testType) {
    case 'unit':
      files = testConfig.commonUnitTestPaths.concat(testConfig.chaiAsPromised);
      if (argv.files) {
        return files.concat(argv.files);
      }
      if (argv.saucelabs) {
        return files.concat(testConfig.unitTestOnSaucePaths);
      }
      if (argv.local_changes) {
        return files.concat(unitTestsToRun(testConfig.unitTestPaths));
      }
      return files.concat(testConfig.unitTestPaths);

    case 'integration':
      files = testConfig.commonIntegrationTestPaths;
      if (argv.files) {
        return files.concat(argv.files);
      }
      return files.concat(testConfig.integrationTestPaths);

    case 'a4a':
      return testConfig.chaiAsPromised.concat(testConfig.a4aTestPaths);

    default:
      throw new Error(`Test type ${testType} was not recognized`);
  }
}

/**
 * Adds reporters to the default karma spec per test settings.
 * Overrides default reporters for verbose settings.
 * @param {!RuntimeTestConfig} config
 */
function updateReporters(config) {
  if (
    (argv.testnames || argv.local_changes || argv.files) &&
    !isTravisBuild()
  ) {
    config.reporters = ['mocha'];
  }

  if (argv.coverage) {
    config.reporters.push('coverage-istanbul');
  }

  if (argv.saucelabs) {
    config.reporters.push('saucelabs');
  }
}

class RuntimeTestConfig {
  constructor(testType) {
    this.testType = testType;

    Object.assign(this, karmaConfig);
    updateBrowsers(this);
    updateReporters(this);
    this.files = getFiles(this.testType);
    this.singleRun = !argv.watch && !argv.w;
    this.client.mocha.grep = !!argv.grep;
    this.client.verboseLogging = !!argv.verbose || !!argv.v;
    this.client.captureConsole = !!argv.verbose || !!argv.v || !!argv.files;
    this.browserify.configure = function(bundle) {
      bundle.on('prebundle', function() {
        log(
          green('Transforming tests with'),
          cyan('browserify') + green('...')
        );
      });
      bundle.on('transform', function(tr) {
        if (tr instanceof babelify) {
          tr.once('babelify', function() {
            process.stdout.write('.');
          });
        }
      });
    };

    // c.client is available in test browser via window.parent.karma.config
    this.client.amp = {
      useCompiledJs: !!argv.compiled,
      saucelabs: !!argv.saucelabs,
      singlePass: !!argv.single_pass,
      adTypes: getAdTypes(),
      mochaTimeout: this.client.mocha.timeout,
      propertiesObfuscated: !!argv.single_pass,
      testServerPort: this.client.testServerPort,
      testOnIe:
        this.browsers.includes('IE') || this.browsers.includes('SL_IE_11'),
    };

    if (argv.coverage && this.testType != 'a4a') {
      this.plugins.push('karma-coverage-istanbul-reporter');
      this.coverageIstanbulReporter = {
        dir: 'test/coverage',
        reports: isTravisBuild()
          ? ['lcovonly']
          : ['html', 'text', 'text-summary'],
        'report-config': {lcovonly: {file: `lcov-${testType}.info`}},
      };

      const instanbulPlugin = [
        'istanbul',
        {
          exclude: [
            'ads/**/*.js',
            'build-system/**/*.js',
            'extensions/**/test/**/*.js',
            'third_party/**/*.js',
            'test/**/*.js',
            'testing/**/*.js',
          ],
        },
      ];
      // don't overwrite existing plugins
      const plugins = [instanbulPlugin].concat(this.babelifyConfig.plugins);

      this.browserify.transform = [
        ['babelify', Object.assign({}, this.babelifyConfig, {plugins})],
      ];
    }
  }
}

class RuntimeTestRunner {
  constructor(config) {
    this.config = config;
    this.env = null;
    this.exitCode = 0;
  }

  async maybeBuild() {
    throw new Error('maybeBuild method must be overridden');
  }

  async setup() {
    // TODO(alanorozco): Come up with a more elegant check?
    global.AMP_TESTING = true;

    // Run tests against compiled code when explicitly specified via --compiled,
    // or when the minified runtime is automatically built.
    process.env.SERVE_MODE =
      argv.compiled || !argv.nobuild ? 'compiled' : 'default';

    await this.maybeBuild();

    const testServer = startTestServer(this.config.client.testServerPort);
    const handlerProcess = createCtrlcHandler(`gulp ${this.config.testType}`);

    this.env = new Map()
      .set('handlerProcess', handlerProcess)
      .set('testServer', testServer);
  }

  async run() {
    reportTestStarted();

    if (argv.saucelabs) {
      this.exitCode = await runTestInBatches(this.config);
    } else {
      this.exitCode = await createKarmaServer(this.config);
    }
  }

  async teardown() {
    this.env.get('testServer').emit('kill');
    exitCtrlcHandler(this.env.get('handlerProcess'));

    if (this.exitCode != 0) {
      log(
        red('ERROR:'),
        yellow(`Karma test failed with exit code ${this.exitCode}`)
      );
      process.exitCode = this.exitCode;
    }
  }
}

module.exports = {
  RuntimeTestRunner,
  RuntimeTestConfig,
};
<commit_msg>Use mocha reporter when --verbose flag is specified (#23503)<commit_after>/**
 * Copyright 2019 The AMP HTML Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const argv = require('minimist')(process.argv.slice(2));
const babelify = require('babelify');
const karmaConfig = require('../karma.conf');
const log = require('fancy-log');
const testConfig = require('../../config');
const {
  createKarmaServer,
  getAdTypes,
  runTestInBatches,
  startTestServer,
} = require('./helpers');
const {createCtrlcHandler, exitCtrlcHandler} = require('../../ctrlcHandler');
const {green, yellow, cyan, red} = require('ansi-colors');
const {isTravisBuild} = require('../../travis');
const {reportTestStarted} = require('.././report-test-status');
const {unitTestsToRun} = require('./helpers-unit');

/**
 * Updates the browsers based off of the test type
 * being run (unit, integration, a4a) and test settings.
 * Keeps the default spec as is if no matching settings are found.
 * @param {!RuntimeTestConfig} config
 */
function updateBrowsers(config) {
  if (argv.saucelabs) {
    if (config.testType == 'unit') {
      Object.assign(config, {browsers: ['SL_Safari_12', 'SL_Firefox']});
      return;
    }

    if (config.testType == 'integration') {
      Object.assign(config, {
        browsers: [
          'SL_Chrome',
          'SL_Firefox',
          'SL_Edge_17',
          'SL_Safari_12',
          'SL_IE_11',
          // TODO(amp-infra): Evaluate and add more platforms here.
          //'SL_Chrome_Android_7',
          //'SL_iOS_11',
          //'SL_iOS_12',
          'SL_Chrome_Beta',
          'SL_Firefox_Beta',
        ],
      });
      return;
    }

    throw new Error(
      'The --saucelabs flag is valid only for `gulp unit` and `gulp integration`.'
    );
  }

  const chromeFlags = [];
  if (argv.chrome_flags) {
    argv.chrome_flags.split(',').forEach(flag => {
      chromeFlags.push('--'.concat(flag));
    });
  }

  const options = new Map();
  options
    .set('chrome_canary', {browsers: ['ChromeCanary']})
    .set('chrome_flags', {
      browsers: ['Chrome_flags'],
      customLaunchers: {
        // eslint-disable-next-line
        Chrome_flags: {
          base: 'Chrome',
          flags: chromeFlags,
        },
      },
    })
    .set('edge', {browsers: ['Edge']})
    .set('firefox', {browsers: ['Firefox']})
    .set('headless', {browsers: ['Chrome_no_extensions_headless']})
    .set('ie', {
      browsers: ['IE'],
      customLaunchers: {
        IeNoAddOns: {
          base: 'IE',
          flags: ['-extoff'],
        },
      },
    })
    .set('safari', {browsers: ['Safari']});

  for (const [key, value] of options) {
    if (argv.hasOwnProperty(key)) {
      Object.assign(config, value);
      return;
    }
  }
}

/**
 * Get the appropriate files based off of the test type
 * being run (unit, integration, a4a) and test settings.
 * @param {string} testType
 * @return {!Array<string>}
 */
function getFiles(testType) {
  let files;

  switch (testType) {
    case 'unit':
      files = testConfig.commonUnitTestPaths.concat(testConfig.chaiAsPromised);
      if (argv.files) {
        return files.concat(argv.files);
      }
      if (argv.saucelabs) {
        return files.concat(testConfig.unitTestOnSaucePaths);
      }
      if (argv.local_changes) {
        return files.concat(unitTestsToRun(testConfig.unitTestPaths));
      }
      return files.concat(testConfig.unitTestPaths);

    case 'integration':
      files = testConfig.commonIntegrationTestPaths;
      if (argv.files) {
        return files.concat(argv.files);
      }
      return files.concat(testConfig.integrationTestPaths);

    case 'a4a':
      return testConfig.chaiAsPromised.concat(testConfig.a4aTestPaths);

    default:
      throw new Error(`Test type ${testType} was not recognized`);
  }
}

/**
 * Adds reporters to the default karma spec per test settings.
 * Overrides default reporters for verbose settings.
 * @param {!RuntimeTestConfig} config
 */
function updateReporters(config) {
  if (
    (argv.testnames || argv.local_changes || argv.files || argv.verbose) &&
    !isTravisBuild()
  ) {
    config.reporters = ['mocha'];
  }

  if (argv.coverage) {
    config.reporters.push('coverage-istanbul');
  }

  if (argv.saucelabs) {
    config.reporters.push('saucelabs');
  }
}

class RuntimeTestConfig {
  constructor(testType) {
    this.testType = testType;

    Object.assign(this, karmaConfig);
    updateBrowsers(this);
    updateReporters(this);
    this.files = getFiles(this.testType);
    this.singleRun = !argv.watch && !argv.w;
    this.client.mocha.grep = !!argv.grep;
    this.client.verboseLogging = !!argv.verbose || !!argv.v;
    this.client.captureConsole = !!argv.verbose || !!argv.v || !!argv.files;
    this.browserify.configure = function(bundle) {
      bundle.on('prebundle', function() {
        log(
          green('Transforming tests with'),
          cyan('browserify') + green('...')
        );
      });
      bundle.on('transform', function(tr) {
        if (tr instanceof babelify) {
          tr.once('babelify', function() {
            process.stdout.write('.');
          });
        }
      });
    };

    // c.client is available in test browser via window.parent.karma.config
    this.client.amp = {
      useCompiledJs: !!argv.compiled,
      saucelabs: !!argv.saucelabs,
      singlePass: !!argv.single_pass,
      adTypes: getAdTypes(),
      mochaTimeout: this.client.mocha.timeout,
      propertiesObfuscated: !!argv.single_pass,
      testServerPort: this.client.testServerPort,
      testOnIe:
        this.browsers.includes('IE') || this.browsers.includes('SL_IE_11'),
    };

    if (argv.coverage && this.testType != 'a4a') {
      this.plugins.push('karma-coverage-istanbul-reporter');
      this.coverageIstanbulReporter = {
        dir: 'test/coverage',
        reports: isTravisBuild()
          ? ['lcovonly']
          : ['html', 'text', 'text-summary'],
        'report-config': {lcovonly: {file: `lcov-${testType}.info`}},
      };

      const instanbulPlugin = [
        'istanbul',
        {
          exclude: [
            'ads/**/*.js',
            'build-system/**/*.js',
            'extensions/**/test/**/*.js',
            'third_party/**/*.js',
            'test/**/*.js',
            'testing/**/*.js',
          ],
        },
      ];
      // don't overwrite existing plugins
      const plugins = [instanbulPlugin].concat(this.babelifyConfig.plugins);

      this.browserify.transform = [
        ['babelify', Object.assign({}, this.babelifyConfig, {plugins})],
      ];
    }
  }
}

class RuntimeTestRunner {
  constructor(config) {
    this.config = config;
    this.env = null;
    this.exitCode = 0;
  }

  async maybeBuild() {
    throw new Error('maybeBuild method must be overridden');
  }

  async setup() {
    // TODO(alanorozco): Come up with a more elegant check?
    global.AMP_TESTING = true;

    // Run tests against compiled code when explicitly specified via --compiled,
    // or when the minified runtime is automatically built.
    process.env.SERVE_MODE =
      argv.compiled || !argv.nobuild ? 'compiled' : 'default';

    await this.maybeBuild();

    const testServer = startTestServer(this.config.client.testServerPort);
    const handlerProcess = createCtrlcHandler(`gulp ${this.config.testType}`);

    this.env = new Map()
      .set('handlerProcess', handlerProcess)
      .set('testServer', testServer);
  }

  async run() {
    reportTestStarted();

    if (argv.saucelabs) {
      this.exitCode = await runTestInBatches(this.config);
    } else {
      this.exitCode = await createKarmaServer(this.config);
    }
  }

  async teardown() {
    this.env.get('testServer').emit('kill');
    exitCtrlcHandler(this.env.get('handlerProcess'));

    if (this.exitCode != 0) {
      log(
        red('ERROR:'),
        yellow(`Karma test failed with exit code ${this.exitCode}`)
      );
      process.exitCode = this.exitCode;
    }
  }
}

module.exports = {
  RuntimeTestRunner,
  RuntimeTestConfig,
};
<|endoftext|>


<commit_before>// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')

module.exports = {
  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },
  dev: {
    env: require('./dev.env'),
    port: 8080,
    autoOpenBrowser: true,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},
    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false
  }
}
<commit_msg>quash startup warning from dev-server<commit_after>// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')

module.exports = {
  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },
  dev: {
    env: require('./dev.env'),
    port: 8080,
    autoOpenBrowser: false,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},
    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false
  }
}
<|endoftext|>


<commit_before>(function (enyo, source) {
	/**
	 * An [object]{@glossary Object} describing the the last known coordinates of the cursor or
	 * user-interaction point in touch environments.
	 *
	 * @typedef {Object} enyo.dispatcher~CursorCoordinates
	 * @property {Number} clientX - The horizontal coordinate within the application's client area.
	 * @property {Number} clientY - The vertical coordinate within the application's client area.
	 * @property {Number} pageX - The X coordinate of the cursor relative to the viewport, including any
	 *   scroll offset.
	 * @property {Number} pageY - The Y coordinate of the cursor relative to the viewport, including any
	 *   scroll offset.
	 * @property {Number} screenX - The X coordinate of the cursor relative to the screen, not including
	 *   any scroll offset.
	 * @property {Number} screenY - The Y coordinate of the cursor relative to the screen, not including
	 *   any scroll offset.
	 */

	/**
	* @private
	*/
	enyo.$ = {};

	/**
	* @private
	*/
	enyo.dispatcher =
		/** @lends enyo.dispatcher.prototype */ {

		/**
		* These events come from document
		*
		* @private
		*/
		events: ["mousedown", "mouseup", "mouseover", "mouseout", "mousemove", "mousewheel",
			"click", "dblclick", "change", "keydown", "keyup", "keypress", "input",
			"paste", "copy", "cut", "webkitTransitionEnd", "transitionend", "webkitAnimationEnd", "animationend",
			"webkitAnimationStart", "animationstart", "webkitAnimationIteration", "animationiteration"],

		/**
		* These events come from window
		*
		* @private
		*/
		windowEvents: ["resize", "load", "unload", "message", "hashchange", "popstate", "focus", "blur"],

		/**
		* Feature plugins (aka filters)
		*
		* @private
		*/
		features: [],

		/**
		* @private
		*/
		connect: function() {
			var d = enyo.dispatcher, i, n;
			for (i=0; (n=d.events[i]); i++) {
				d.listen(document, n);
			}
			for (i=0; (n=d.windowEvents[i]); i++) {
				// Chrome Packaged Apps don't like "unload"
				if(n === "unload" &&
					(typeof window.chrome === "object") &&
					window.chrome.app) {
					continue;
				}

				d.listen(window, n);
			}
		},

		/**
		* @private
		*/
		listen: function(inListener, inEventName, inHandler) {
			var d = enyo.dispatch;
			if (inListener.addEventListener) {
				this.listen = function(inListener, inEventName, inHandler) {
					inListener.addEventListener(inEventName, inHandler || d, false);
				};
			} else {
				//enyo.log("IE8 COMPAT: using 'attachEvent'");
				this.listen = function(inListener, inEvent, inHandler) {
					inListener.attachEvent("on" + inEvent, function(e) {
						e.target = e.srcElement;
						if (!e.preventDefault) {
							e.preventDefault = enyo.iePreventDefault;
						}
						return (inHandler || d)(e);
					});
				};
			}
			this.listen(inListener, inEventName, inHandler);
		},

		/**
		* @private
		*/
		stopListening: function(inListener, inEventName, inHandler) {
			var d = enyo.dispatch;
			if (inListener.addEventListener) {
				this.stopListening = function(inListener, inEventName, inHandler) {
					inListener.removeEventListener(inEventName, inHandler || d, false);
				};
			} else {
				//enyo.log("IE8 COMPAT: using 'detachEvent'");
				this.stopListening = function(inListener, inEvent, inHandler) {
					inListener.detachEvent("on" + inEvent, inHandler || d);
				};
			}
			this.stopListening(inListener, inEventName, inHandler);
		},

		/**
		* Fires an event for Enyo to listen for.
		*
		* @private
		*/
		dispatch: function(e) {
			// Find the control who maps to e.target, or the first control that maps to an ancestor of e.target.
			var c = this.findDispatchTarget(e.target) || this.findDefaultTarget();
			// Cache the original target
			e.dispatchTarget = c;
			// support pluggable features return true to abort immediately or set e.preventDispatch to avoid processing.
			for (var i=0, fn; (fn=this.features[i]); i++) {
				if (fn.call(this, e) === true) {
					return;
				}
			}
			if (c && !e.preventDispatch) {
				return this.dispatchBubble(e, c);
			}
		},

		/**
		* Takes an event target and finds the corresponding Enyo control.
		*
		* @private
		*/
		findDispatchTarget: function(inNode) {
			var t, n = inNode;
			// FIXME: Mozilla: try/catch is here to squelch "Permission denied to access property xxx from a non-chrome context"
			// which appears to happen for scrollbar nodes in particular. It's unclear why those nodes are valid targets if
			// it is illegal to interrogate them. Would like to trap the bad nodes explicitly rather than using an exception block.
			try {
				while (n) {
					if ((t = enyo.$[n.id])) {
						// there could be multiple nodes with this id, the relevant node for this event is n
						// we don't push this directly to t.node because sometimes we are just asking what
						// the target 'would be' (aka, calling findDispatchTarget from handleMouseOverOut)
						t.eventNode = n;
						break;
					}
					n = n.parentNode;
				}
			} catch(x) {
				enyo.log(x, n);
			}
			return t;
		},

		/**
		* Returns the default Enyo control for events.
		*
		* @private
		*/
		findDefaultTarget: function() {
			return enyo.master;
		},

		/**
		* @private
		*/
		dispatchBubble: function(e, c) {
			var type = e.type;
			type = e.customEvent ? type : "on" + type;
			return c.bubble(type, e, c);
		}
	};

	/**
	* Called in the context of an event.
	*
	* @private
	*/
	enyo.iePreventDefault = function() {
		try {
			this.returnValue = false;
		}
		catch(e) {
			// do nothing
		}
	};

	/**
	* @private
	*/
	enyo.dispatch = function(inEvent) {
		return enyo.dispatcher.dispatch(inEvent);
	};

	/**
	* @private
	*/
	enyo.bubble = function(inEvent) {
		// '|| window.event' clause needed for IE8
		var e = inEvent || window.event;
		if (e) {
			// We depend on e.target existing for event tracking and dispatching.
			if (!e.target) {
				e.target = e.srcElement;
			}
			enyo.dispatch(e);
		}
	};

	// This string is set on event handlers attributes for DOM elements that
	// don't normally bubble (like onscroll) so that they can participate in the
	// Enyo event system.
	enyo.bubbler = "enyo.bubble(arguments[0])";

	// The code below helps make Enyo compatible with Google Packaged Apps
	// Content Security Policy(http://developer.chrome.com/extensions/contentSecurityPolicy.html),
	// which, among other things, forbids the use of inline scripts.
	// We replace online scripting with equivalent means, leaving enyo.bubbler
	// for backward compatibility.
	(function() {
		var bubbleUp = function() {
			enyo.bubble(arguments[0]);
		};

		/**
		* Makes given events bubble on a specified Enyo control.
		*
		* @private
		*/
		enyo.makeBubble = function() {
			var args = Array.prototype.slice.call(arguments, 0),
				control = args.shift();

			if((typeof control === "object") && (typeof control.hasNode === "function")) {
				enyo.forEach(args, function(event) {
					if(this.hasNode()) {
						enyo.dispatcher.listen(this.node, event, bubbleUp);
					}
				}, control);
			}
		};

		/**
		* Removes the event listening and bubbling initiated by
		* [enyo.makeBubble()]{@link enyo.makeBubble} on a specific control.
		*
		* @private
		*/
		enyo.unmakeBubble = function() {
			var args = Array.prototype.slice.call(arguments, 0),
				control = args.shift();

			if((typeof control === "object") && (typeof control.hasNode === "function")) {
				enyo.forEach(args, function(event) {
					if(this.hasNode()) {
						enyo.dispatcher.stopListening(this.node, event, bubbleUp);
					}
				}, control);
			}
		};
	})();

	/**
	* @private
	*/
	// FIXME: we need to create and initialize dispatcher someplace else to allow overrides
	enyo.requiresWindow(enyo.dispatcher.connect);

	/**
	* Generates a tapped event for a raw-click event.
	*
	* @private
	*/
	enyo.dispatcher.features.push(
		function (e) {
			if ("click" === e.type) {
				if (e.clientX === 0 && e.clientY === 0) {
					// this allows the click to dispatch as well
					// but note the tap event will fire first
					var cp = enyo.clone(e);
					cp.type = "tap";
					cp.preventDefault = enyo.nop;
					enyo.dispatch(cp);
				}
			}
		}
	);

	/**
	* Instead of having multiple `features` pushed and handled in separate methods
	* for these events, we handle them uniformly here to expose the last known
	* interaction coordinates as accurately as possible.
	*
	* @private
	*/
	var _xy = {};
	enyo.dispatcher.features.push(
		function (e) {
			if (
				(e.type == "mousemove")  ||
				(e.type == "tap")        ||
				(e.type == "click")      ||
				(e.type == "touchmove")
			) {
				_xy.clientX = e.clientX;
				_xy.clientY = e.clientY;
				// note only ie8 does not support pageX/pageY
				_xy.pageX   = e.pageX;
				_xy.pageY   = e.pageY;
				// note ie8 and opera report these values incorrectly
				_xy.screenX = e.screenX;
				_xy.screenY = e.screenY;
			}
		}
	);

	/**
	* Retrieves the last known coordinates of the cursor or user-interaction point
	* in touch environments. Returns an immutable object with the `clientX`,
	* `clientY`, `pageX`, `pageY`, `screenX`, and `screenY` properties. It is
	* important to note that IE8 and Opera have improper reporting for the
	* `screenX` and `screenY` properties (they both use CSS pixels as opposed to
	* device pixels) and IE8 has no support for the `pageX` and `pageY` properties,
	* so they are facaded.
	*
	* @returns {enyo.dispatcher~CursorCoordinates} An [object]{@glossary Object} describing the
	*	the last known coordinates of the cursor or user-interaction point in touch environments.
	* @public
	*/
	enyo.getPosition = function () {
		var p = enyo.clone(_xy);
		// if we are in ie8 we facade the _pageX, pageY_ properties
		if (enyo.platform.ie < 9) {
			var d = (document.documentElement || document.body.parentNode || document.body);
			p.pageX = (p.clientX + d.scrollLeft);
			p.pageY = (p.clientY + d.scrollTop);
		}
		return p;
	};

})(enyo, this);
<commit_msg>ENYO-923: Listen focus, blur window events only when webos version > 4<commit_after>(function (enyo, source) {
	/**
	 * An [object]{@glossary Object} describing the the last known coordinates of the cursor or
	 * user-interaction point in touch environments.
	 *
	 * @typedef {Object} enyo.dispatcher~CursorCoordinates
	 * @property {Number} clientX - The horizontal coordinate within the application's client area.
	 * @property {Number} clientY - The vertical coordinate within the application's client area.
	 * @property {Number} pageX - The X coordinate of the cursor relative to the viewport, including any
	 *   scroll offset.
	 * @property {Number} pageY - The Y coordinate of the cursor relative to the viewport, including any
	 *   scroll offset.
	 * @property {Number} screenX - The X coordinate of the cursor relative to the screen, not including
	 *   any scroll offset.
	 * @property {Number} screenY - The Y coordinate of the cursor relative to the screen, not including
	 *   any scroll offset.
	 */

	/**
	* @private
	*/
	enyo.$ = {};

	/**
	* @private
	*/
	enyo.dispatcher =
		/** @lends enyo.dispatcher.prototype */ {

		/**
		* These events come from document
		*
		* @private
		*/
		events: ["mousedown", "mouseup", "mouseover", "mouseout", "mousemove", "mousewheel",
			"click", "dblclick", "change", "keydown", "keyup", "keypress", "input",
			"paste", "copy", "cut", "webkitTransitionEnd", "transitionend", "webkitAnimationEnd", "animationend",
			"webkitAnimationStart", "animationstart", "webkitAnimationIteration", "animationiteration"],

		/**
		* These events come from window
		*
		* @private
		*/
		windowEvents: ["resize", "load", "unload", "message", "hashchange", "popstate"],

		/**
		* Feature plugins (aka filters)
		*
		* @private
		*/
		features: [],

		/**
		* @private
		*/
		platformSpecific: function() {
			var d = enyo.dispatcher,
				webosWindowEvents = ["focus", "blur"];
			if (enyo.platform.webos >= 4) {
				d.windowEvents.concat(webosWindowEvents);
			}
		},

		/**
		* @private
		*/
		connect: function() {
			var d = enyo.dispatcher, i, n;
			d.platformSpecific();
			for (i=0; (n=d.events[i]); i++) {
				d.listen(document, n);
			}
			for (i=0; (n=d.windowEvents[i]); i++) {
				// Chrome Packaged Apps don't like "unload"
				if(n === "unload" &&
					(typeof window.chrome === "object") &&
					window.chrome.app) {
					continue;
				}

				d.listen(window, n);
			}
		},

		/**
		* @private
		*/
		listen: function(inListener, inEventName, inHandler) {
			var d = enyo.dispatch;
			if (inListener.addEventListener) {
				this.listen = function(inListener, inEventName, inHandler) {
					inListener.addEventListener(inEventName, inHandler || d, false);
				};
			} else {
				//enyo.log("IE8 COMPAT: using 'attachEvent'");
				this.listen = function(inListener, inEvent, inHandler) {
					inListener.attachEvent("on" + inEvent, function(e) {
						e.target = e.srcElement;
						if (!e.preventDefault) {
							e.preventDefault = enyo.iePreventDefault;
						}
						return (inHandler || d)(e);
					});
				};
			}
			this.listen(inListener, inEventName, inHandler);
		},

		/**
		* @private
		*/
		stopListening: function(inListener, inEventName, inHandler) {
			var d = enyo.dispatch;
			if (inListener.addEventListener) {
				this.stopListening = function(inListener, inEventName, inHandler) {
					inListener.removeEventListener(inEventName, inHandler || d, false);
				};
			} else {
				//enyo.log("IE8 COMPAT: using 'detachEvent'");
				this.stopListening = function(inListener, inEvent, inHandler) {
					inListener.detachEvent("on" + inEvent, inHandler || d);
				};
			}
			this.stopListening(inListener, inEventName, inHandler);
		},

		/**
		* Fires an event for Enyo to listen for.
		*
		* @private
		*/
		dispatch: function(e) {
			// Find the control who maps to e.target, or the first control that maps to an ancestor of e.target.
			var c = this.findDispatchTarget(e.target) || this.findDefaultTarget();
			// Cache the original target
			e.dispatchTarget = c;
			// support pluggable features return true to abort immediately or set e.preventDispatch to avoid processing.
			for (var i=0, fn; (fn=this.features[i]); i++) {
				if (fn.call(this, e) === true) {
					return;
				}
			}
			if (c && !e.preventDispatch) {
				return this.dispatchBubble(e, c);
			}
		},

		/**
		* Takes an event target and finds the corresponding Enyo control.
		*
		* @private
		*/
		findDispatchTarget: function(inNode) {
			var t, n = inNode;
			// FIXME: Mozilla: try/catch is here to squelch "Permission denied to access property xxx from a non-chrome context"
			// which appears to happen for scrollbar nodes in particular. It's unclear why those nodes are valid targets if
			// it is illegal to interrogate them. Would like to trap the bad nodes explicitly rather than using an exception block.
			try {
				while (n) {
					if ((t = enyo.$[n.id])) {
						// there could be multiple nodes with this id, the relevant node for this event is n
						// we don't push this directly to t.node because sometimes we are just asking what
						// the target 'would be' (aka, calling findDispatchTarget from handleMouseOverOut)
						t.eventNode = n;
						break;
					}
					n = n.parentNode;
				}
			} catch(x) {
				enyo.log(x, n);
			}
			return t;
		},

		/**
		* Returns the default Enyo control for events.
		*
		* @private
		*/
		findDefaultTarget: function() {
			return enyo.master;
		},

		/**
		* @private
		*/
		dispatchBubble: function(e, c) {
			var type = e.type;
			type = e.customEvent ? type : "on" + type;
			return c.bubble(type, e, c);
		}
	};

	/**
	* Called in the context of an event.
	*
	* @private
	*/
	enyo.iePreventDefault = function() {
		try {
			this.returnValue = false;
		}
		catch(e) {
			// do nothing
		}
	};

	/**
	* @private
	*/
	enyo.dispatch = function(inEvent) {
		return enyo.dispatcher.dispatch(inEvent);
	};

	/**
	* @private
	*/
	enyo.bubble = function(inEvent) {
		// '|| window.event' clause needed for IE8
		var e = inEvent || window.event;
		if (e) {
			// We depend on e.target existing for event tracking and dispatching.
			if (!e.target) {
				e.target = e.srcElement;
			}
			enyo.dispatch(e);
		}
	};

	// This string is set on event handlers attributes for DOM elements that
	// don't normally bubble (like onscroll) so that they can participate in the
	// Enyo event system.
	enyo.bubbler = "enyo.bubble(arguments[0])";

	// The code below helps make Enyo compatible with Google Packaged Apps
	// Content Security Policy(http://developer.chrome.com/extensions/contentSecurityPolicy.html),
	// which, among other things, forbids the use of inline scripts.
	// We replace online scripting with equivalent means, leaving enyo.bubbler
	// for backward compatibility.
	(function() {
		var bubbleUp = function() {
			enyo.bubble(arguments[0]);
		};

		/**
		* Makes given events bubble on a specified Enyo control.
		*
		* @private
		*/
		enyo.makeBubble = function() {
			var args = Array.prototype.slice.call(arguments, 0),
				control = args.shift();

			if((typeof control === "object") && (typeof control.hasNode === "function")) {
				enyo.forEach(args, function(event) {
					if(this.hasNode()) {
						enyo.dispatcher.listen(this.node, event, bubbleUp);
					}
				}, control);
			}
		};

		/**
		* Removes the event listening and bubbling initiated by
		* [enyo.makeBubble()]{@link enyo.makeBubble} on a specific control.
		*
		* @private
		*/
		enyo.unmakeBubble = function() {
			var args = Array.prototype.slice.call(arguments, 0),
				control = args.shift();

			if((typeof control === "object") && (typeof control.hasNode === "function")) {
				enyo.forEach(args, function(event) {
					if(this.hasNode()) {
						enyo.dispatcher.stopListening(this.node, event, bubbleUp);
					}
				}, control);
			}
		};
	})();

	/**
	* @private
	*/
	// FIXME: we need to create and initialize dispatcher someplace else to allow overrides
	enyo.requiresWindow(enyo.dispatcher.connect);

	/**
	* Generates a tapped event for a raw-click event.
	*
	* @private
	*/
	enyo.dispatcher.features.push(
		function (e) {
			if ("click" === e.type) {
				if (e.clientX === 0 && e.clientY === 0) {
					// this allows the click to dispatch as well
					// but note the tap event will fire first
					var cp = enyo.clone(e);
					cp.type = "tap";
					cp.preventDefault = enyo.nop;
					enyo.dispatch(cp);
				}
			}
		}
	);

	/**
	* Instead of having multiple `features` pushed and handled in separate methods
	* for these events, we handle them uniformly here to expose the last known
	* interaction coordinates as accurately as possible.
	*
	* @private
	*/
	var _xy = {};
	enyo.dispatcher.features.push(
		function (e) {
			if (
				(e.type == "mousemove")  ||
				(e.type == "tap")        ||
				(e.type == "click")      ||
				(e.type == "touchmove")
			) {
				_xy.clientX = e.clientX;
				_xy.clientY = e.clientY;
				// note only ie8 does not support pageX/pageY
				_xy.pageX   = e.pageX;
				_xy.pageY   = e.pageY;
				// note ie8 and opera report these values incorrectly
				_xy.screenX = e.screenX;
				_xy.screenY = e.screenY;
			}
		}
	);

	/**
	* Retrieves the last known coordinates of the cursor or user-interaction point
	* in touch environments. Returns an immutable object with the `clientX`,
	* `clientY`, `pageX`, `pageY`, `screenX`, and `screenY` properties. It is
	* important to note that IE8 and Opera have improper reporting for the
	* `screenX` and `screenY` properties (they both use CSS pixels as opposed to
	* device pixels) and IE8 has no support for the `pageX` and `pageY` properties,
	* so they are facaded.
	*
	* @returns {enyo.dispatcher~CursorCoordinates} An [object]{@glossary Object} describing the
	*	the last known coordinates of the cursor or user-interaction point in touch environments.
	* @public
	*/
	enyo.getPosition = function () {
		var p = enyo.clone(_xy);
		// if we are in ie8 we facade the _pageX, pageY_ properties
		if (enyo.platform.ie < 9) {
			var d = (document.documentElement || document.body.parentNode || document.body);
			p.pageX = (p.clientX + d.scrollLeft);
			p.pageY = (p.clientY + d.scrollTop);
		}
		return p;
	};

})(enyo, this);
<|endoftext|>


<commit_before>/**
 * Sub-View to render the Application tree.
 * @type {*}
 */
define([
    "underscore", "jquery", "backbone",
    "model/app-tree", "./entity-details", "model/entity-summary", "model/application",
    "text!tpl/apps/tree-item.html", "text!tpl/apps/details.html", "text!tpl/apps/entity-not-found.html"
], function (_, $, Backbone,
             AppTree, EntityDetailsView, EntitySummary, Application,
             TreeItemHtml, EntityDetailsEmptyHtml, EntityNotFoundHtml) {

    var treeViewTemplate = _.template(TreeItemHtml),
        notFoundTemplate = _.template(EntityNotFoundHtml);

    var ApplicationTreeView = Backbone.View.extend({
        tagName: "ol",
        className: "tree applications",
        template: treeViewTemplate,

        events:{
            'click .name.entity':'displayEntity'
        },

        initialize:function () {
            this.collection.on('reset', this.render, this)
            _.bindAll(this);
        },

        beforeClose:function () {
            this.collection.off("reset", this.render)
            if (this.detailsView) this.detailsView.close()
        },

        render:function () {
            var that = this
            this.$el.empty()

            // Display tree and highlight the selected entity.
            if (this.collection.isEmpty()) {
                this.$el.append("
No applications
")
            } else {
                this.collection.each(function (app) {
                    that.$el.append(that.buildTree(app))
                })
            }
            this.highlightEntity();

            // Render the details for the selected entity.
            if (this.detailsView) {
            	this.detailsView.render()
            } else {
            	// if nothing selected, select the first application
            	if (!this.collection.isEmpty()) {
            		var app0 = this.collection.first().id;
            		_.defer(function () {
            			if (!that.selectedEntityId)
            				that.displayEntityId(app0, app0)
        			});
            	} else {
            	    _.defer(function() {
            	        $("div#details").html(_.template(EntityDetailsEmptyHtml));
            	        $("div#details").find("a[href='#summary']").tab('show')
            	    })
            	}
            }
            return this
        },

        buildTree:function (application) {
            var that = this,
                $template = $(this.template({
                    id:application.get("id"),
                    type:"application",
                    parentApp:application.get("id"),
                    displayName:application.get("name")
                })),
                treeFromEntity = function (entity) {
                    var $entityTpl

                    if (entity.hasChildren()) {
                        $entityTpl = $(that.template({
                            id:entity.get("id"),
                            type:"entity",
                            parentApp:application.get("id"),
                            displayName:entity.getDisplayName()
                        }))
                        var $parentTpl = $entityTpl.find("ol.tree")
                        _.each(entity.get("children"), function (childEntity) {
                            $parentTpl.append(treeFromEntity(new AppTree.Model(childEntity)))
                        })
                    } else {
                        $entityTpl = $(that.template({
                            id:entity.get("id"),
                            type:"leaf",
                            parentApp:application.get("id"),
                            displayName:entity.getDisplayName()
                        }))
                    }
                    return $entityTpl
                }

            // start rendering from initial children of the application
            var $tree = $template.find("ol.tree")
            _.each(application.get("children"), function (entity) {
                $tree.append(treeFromEntity(new AppTree.Model(entity)))
            })
            $('a', $tree).click(function(e) { e.preventDefault(); })

            return $template
        },

        displayEntity: function(event) {
            event.preventDefault();
            var entityId = $(event.currentTarget).attr("id"),
                stateId = entityId,
                href = event.target.getAttribute('href'),
                tab = (this.detailsView)
                    ? this.detailsView.$el.find(".tab-pane.active").attr("id")
                    : undefined;
            if (tab) {
                href = href+"/"+tab
                stateId = entityId+"/"+tab
                this.preselectTab(tab)
            }
            window.history.pushState(stateId, "", href)
        	this.displayEntityId(entityId, $(event.currentTarget).data("parent-app"));
        },

        displayEntityId:function (id, appName) {
            var entitySummary = new EntitySummary.Model,
                that = this;
            console.debug("Displaying entity: " + id);
            this.highlightEntity(id)

            if (appName === undefined) {
                appName = $("span.entity_tree_node#"+id).data("parent-app")
            }
            if (appName === undefined) {
                // no such app
                console.error("Couldn't find a parent application for entity: " + id);
                return this.displayEntityNotFound(id);
            }

            var app = new Application.Model()
            app.url = "/v1/applications/" + appName
            app.fetch({async:false})

            entitySummary.url = "/v1/applications/" + appName + "/entities/" + id
            entitySummary.fetch({
                success: function() {
                    that.showDetails(app, entitySummary);
                }});
        },

        displayEntityNotFound: function(id) {
            $("div#details").html(notFoundTemplate({"id": id}));
        },

        /**
         * Causes the tab with the given name to be selected automatically when
         * the view is next rendered.
         */
        preselectTab: function(tab) {
            this.currentTab = tab
        },

        showDetails: function(app, entitySummary) {
            var whichTab = this.currentTab
            if (whichTab === undefined) {
                whichTab = "summary";
                if (this.detailsView) {
                    whichTab = this.detailsView.$el.find(".tab-pane.active").attr("id");
                    this.detailsView.close()
                }
            }
            if (this.detailsView)
                this.detailsView.close()
            this.detailsView = new EntityDetailsView({
                model:entitySummary,
                application:app
            })
            $("div#details").html(this.detailsView.render().el)
            // preserve the tab selected before
            $("div#details").find('a[href="#'+whichTab+'"]').tab('show');
        },

        highlightEntity:function (id) {
        	if (id) this.selectedEntityId = id
        	else id = this.selectedEntityId
        	$("span.entity_tree_node").removeClass("active")
        	if (id) {
        		$("span.entity_tree_node#"+id).addClass("active")
        	}
        }
    })

    return ApplicationTreeView
})
<commit_msg>Display 'unknown entity' message when loading details fails.<commit_after>/**
 * Sub-View to render the Application tree.
 * @type {*}
 */
define([
    "underscore", "jquery", "backbone",
    "model/app-tree", "./entity-details", "model/entity-summary", "model/application",
    "text!tpl/apps/tree-item.html", "text!tpl/apps/details.html", "text!tpl/apps/entity-not-found.html"
], function (_, $, Backbone,
             AppTree, EntityDetailsView, EntitySummary, Application,
             TreeItemHtml, EntityDetailsEmptyHtml, EntityNotFoundHtml) {

    var treeViewTemplate = _.template(TreeItemHtml),
        notFoundTemplate = _.template(EntityNotFoundHtml);

    var ApplicationTreeView = Backbone.View.extend({
        tagName: "ol",
        className: "tree applications",
        template: treeViewTemplate,

        events:{
            'click .name.entity':'displayEntity'
        },

        initialize:function () {
            this.collection.on('reset', this.render, this)
            _.bindAll(this);
        },

        beforeClose:function () {
            this.collection.off("reset", this.render)
            if (this.detailsView) this.detailsView.close()
        },

        render:function () {
            var that = this
            this.$el.empty()

            // Display tree and highlight the selected entity.
            if (this.collection.isEmpty()) {
                this.$el.append("
No applications
")
            } else {
                this.collection.each(function (app) {
                    that.$el.append(that.buildTree(app))
                })
            }
            this.highlightEntity();

            // Render the details for the selected entity.
            if (this.detailsView) {
            	this.detailsView.render()
            } else {
            	// if nothing selected, select the first application
            	if (!this.collection.isEmpty()) {
            		var app0 = this.collection.first().id;
            		_.defer(function () {
            			if (!that.selectedEntityId)
            				that.displayEntityId(app0, app0)
        			});
            	} else {
            	    _.defer(function() {
            	        $("div#details").html(_.template(EntityDetailsEmptyHtml));
            	        $("div#details").find("a[href='#summary']").tab('show')
            	    })
            	}
            }
            return this
        },

        buildTree:function (application) {
            var that = this,
                $template = $(this.template({
                    id:application.get("id"),
                    type:"application",
                    parentApp:application.get("id"),
                    displayName:application.get("name")
                })),
                treeFromEntity = function (entity) {
                    var $entityTpl

                    if (entity.hasChildren()) {
                        $entityTpl = $(that.template({
                            id:entity.get("id"),
                            type:"entity",
                            parentApp:application.get("id"),
                            displayName:entity.getDisplayName()
                        }))
                        var $parentTpl = $entityTpl.find("ol.tree")
                        _.each(entity.get("children"), function (childEntity) {
                            $parentTpl.append(treeFromEntity(new AppTree.Model(childEntity)))
                        })
                    } else {
                        $entityTpl = $(that.template({
                            id:entity.get("id"),
                            type:"leaf",
                            parentApp:application.get("id"),
                            displayName:entity.getDisplayName()
                        }))
                    }
                    return $entityTpl
                }

            // start rendering from initial children of the application
            var $tree = $template.find("ol.tree")
            _.each(application.get("children"), function (entity) {
                $tree.append(treeFromEntity(new AppTree.Model(entity)))
            })
            $('a', $tree).click(function(e) { e.preventDefault(); })

            return $template
        },

        displayEntity: function(event) {
            event.preventDefault();
            var entityId = $(event.currentTarget).attr("id"),
                stateId = entityId,
                href = event.target.getAttribute('href'),
                tab = (this.detailsView)
                    ? this.detailsView.$el.find(".tab-pane.active").attr("id")
                    : undefined;
            if (tab) {
                href = href+"/"+tab
                stateId = entityId+"/"+tab
                this.preselectTab(tab)
            }
            window.history.pushState(stateId, "", href)
        	this.displayEntityId(entityId, $(event.currentTarget).data("parent-app"));
        },

        displayEntityId:function (id, appName) {
            var that = this;
            console.debug("Displaying entity: " + id);
            this.highlightEntity(id)

            var entityLoadFailed = function() {
                return that.displayEntityNotFound(id);
            };

            if (appName === undefined) {
                appName = $("span.entity_tree_node#"+id).data("parent-app")
            }
            if (appName === undefined) {
                // no such app
                console.error("Couldn't find a parent application for entity: " + id);
                return entityLoadFailed();
            }

            var app = new Application.Model(),
                entitySummary = new EntitySummary.Model;

            app.url = "/v1/applications/" + appName
            entitySummary.url = "/v1/applications/" + appName + "/entities/" + id;

            $.when(app.fetch(), entitySummary.fetch())
                .done(function() {
                    that.showDetails(app, entitySummary);
                })
                .fail(entityLoadFailed);
        },

        displayEntityNotFound: function(id) {
            $("div#details").html(notFoundTemplate({"id": id}));
        },

        /**
         * Causes the tab with the given name to be selected automatically when
         * the view is next rendered.
         */
        preselectTab: function(tab) {
            this.currentTab = tab
        },

        showDetails: function(app, entitySummary) {
            var whichTab = this.currentTab
            if (whichTab === undefined) {
                whichTab = "summary";
                if (this.detailsView) {
                    whichTab = this.detailsView.$el.find(".tab-pane.active").attr("id");
                    this.detailsView.close()
                }
            }
            if (this.detailsView)
                this.detailsView.close()
            this.detailsView = new EntityDetailsView({
                model:entitySummary,
                application:app
            })
            $("div#details").html(this.detailsView.render().el)
            // preserve the tab selected before
            $("div#details").find('a[href="#'+whichTab+'"]').tab('show');
        },

        highlightEntity:function (id) {
        	if (id) this.selectedEntityId = id
        	else id = this.selectedEntityId
        	$("span.entity_tree_node").removeClass("active")
        	if (id) {
        		$("span.entity_tree_node#"+id).addClass("active")
        	}
        }
    })

    return ApplicationTreeView
})
<|endoftext|>


<commit_before>var test = require('tap').test;
var detective = require('../');
var fs = require('fs');
var src = fs.readFileSync(__dirname + '/files/skip.js');

test('skip', function (t) {
    t.deepEqual(detective(src), [ 'a', 'b', 'c' ]);
    t.end();
});
<commit_msg>update skip test, these things should not be skipped<commit_after>var test = require('tap').test;
var detective = require('../');
var fs = require('fs');
var src = fs.readFileSync(__dirname + '/files/skip.js');

test('skip', function (t) {
    t.deepEqual(detective(src), [ 'a', 'x', 'b', 'y', 'c', 'z']);
    t.end();
});
<|endoftext|>


<commit_before>import ZoneId from './zone_id';

// Ordered as per duty finder.  This is intended to be used as ordering for
// any ui that is dealing with multiple zones / triggers.
//
// These are not things that cactbot necessarily supports, but things that it
// theoretically could be supporting in the future with raidboss and oopsy.

export default [
  // General (cactbot custom zone id)
  ZoneId.MatchAll,

  // Dungeons (A Realm Reborn)
  ZoneId.Sastasha,
  ZoneId.TheTamTaraDeepcroft,
  ZoneId.CopperbellMines,
  ZoneId.Halatali,
  ZoneId.TheThousandMawsOfTotoRak,
  ZoneId.HaukkeManor,
  ZoneId.BrayfloxsLongstop,
  ZoneId.TheSunkenTempleOfQarn,
  ZoneId.CuttersCry,
  ZoneId.TheStoneVigil,
  ZoneId.DzemaelDarkhold,
  ZoneId.TheAurumVale,
  ZoneId.TheWanderersPalace,
  ZoneId.CastrumMeridianum,
  ZoneId.ThePraetorium,
  ZoneId.AmdaporKeep,
  ZoneId.PharosSirius,
  ZoneId.CopperbellMinesHard,
  ZoneId.HaukkeManorHard,
  ZoneId.TheLostCityOfAmdapor,
  ZoneId.HalataliHard,
  ZoneId.BrayfloxsLongstopHard,
  ZoneId.HullbreakerIsle,
  ZoneId.TheTamTaraDeepcroftHard,
  ZoneId.TheStoneVigilHard,
  ZoneId.Snowcloak,
  ZoneId.SastashaHard,
  ZoneId.TheSunkenTempleOfQarnHard,
  ZoneId.TheKeeperOfTheLake,
  ZoneId.TheWanderersPalaceHard,
  ZoneId.AmdaporKeepHard,

  // Dungeons (Heavensward)
  ZoneId.TheDuskVigil,
  ZoneId.SohmAl,
  ZoneId.TheAery,
  ZoneId.TheVault,
  ZoneId.TheGreatGubalLibrary,
  ZoneId.TheAetherochemicalResearchFacility,
  ZoneId.Neverreap,
  ZoneId.TheFractalContinuum,
  ZoneId.SaintMociannesArboretum,
  ZoneId.PharosSiriusHard,
  ZoneId.TheAntitower,
  ZoneId.TheLostCityOfAmdaporHard,
  ZoneId.SohrKhai,
  ZoneId.HullbreakerIsleHard,
  ZoneId.Xelphatol,
  ZoneId.TheGreatGubalLibraryHard,
  ZoneId.BaelsarsWall,
  ZoneId.SohmAlHard,

  // Dungeons (Stormblood)
  ZoneId.TheSirensongSea,
  ZoneId.ShisuiOfTheVioletTides,
  ZoneId.BardamsMettle,
  ZoneId.DomaCastle,
  ZoneId.CastrumAbania,
  ZoneId.AlaMhigo,
  ZoneId.KuganeCastle,
  ZoneId.TheTempleOfTheFist,
  ZoneId.TheDrownedCityOfSkalla,
  ZoneId.HellsLid,
  ZoneId.TheFractalContinuumHard,
  ZoneId.TheSwallowsCompass,
  ZoneId.TheBurn,
  ZoneId.SaintMociannesArboretumHard,
  ZoneId.TheGhimlytDark,

  // Dungeons (Shadowbringers)
  ZoneId.HolminsterSwitch,
  ZoneId.DohnMheg,
  ZoneId.TheQitanaRavel,
  ZoneId.MalikahsWell,
  ZoneId.MtGulg,
  ZoneId.Amaurot,
  ZoneId.TheTwinning,
  ZoneId.AkadaemiaAnyder,
  ZoneId.TheGrandCosmos,
  ZoneId.AnamnesisAnyder,
  ZoneId.TheHeroesGauntlet,
  ZoneId.MatoyasRelict,

  // Guildhests
  ZoneId.BasicTrainingEnemyParties,
  ZoneId.UnderTheArmor,
  ZoneId.BasicTrainingEnemyStrongholds,
  ZoneId.HeroOnTheHalfShell,
  ZoneId.PullingPoisonPosies,
  ZoneId.StingingBack,
  ZoneId.AllsWellThatEndsInTheWell,
  ZoneId.FlickingSticksAndTakingNames,
  ZoneId.MoreThanAFeeler,
  ZoneId.AnnoyTheVoid,
  ZoneId.ShadowAndClaw,
  ZoneId.LongLiveTheQueen,
  ZoneId.WardUp,
  ZoneId.SolemnTrinity,

  // Trials (A Realm Reborn)
  ZoneId.TheBowlOfEmbers,
  ZoneId.TheNavel,
  ZoneId.TheHowlingEye,
  ZoneId.CapeWestwind,
  ZoneId.TheChrysalis,
  ZoneId.TheStepsOfFaith,
  ZoneId.ARelicRebornTheChimera,
  ZoneId.ARelicRebornTheHydra,
  ZoneId.BattleOnTheBigBridge,
  ZoneId.TheDragonsNeck,
  ZoneId.BattleInTheBigKeep,
  ZoneId.TheBowlOfEmbersHard,
  ZoneId.TheHowlingEyeHard,
  ZoneId.TheNavelHard,
  ZoneId.ThornmarchHard,
  ZoneId.TheWhorleaterHard,
  ZoneId.TheStrikingTreeHard,
  ZoneId.TheAkhAfahAmphitheatreHard,
  ZoneId.UrthsFount,

  // High-end Trials (A Realm Reborn)
  ZoneId.TheMinstrelsBalladUltimasBane,
  ZoneId.TheHowlingEyeExtreme,
  ZoneId.TheNavelExtreme,
  ZoneId.TheBowlOfEmbersExtreme,
  ZoneId.ThornmarchExtreme,
  ZoneId.TheWhorleaterExtreme,
  ZoneId.TheStrikingTreeExtreme,
  ZoneId.TheAkhAfahAmphitheatreExtreme,

  // Trials (Heavensward)
  ZoneId.ThokAstThokHard,
  ZoneId.TheLimitlessBlueHard,
  ZoneId.TheSingularityReactor,
  ZoneId.TheFinalStepsOfFaith,
  ZoneId.ContainmentBayS1T7,
  ZoneId.ContainmentBayP1T6,
  ZoneId.ContainmentBayZ1T9,

  // High-end Trials (Heavensward)
  ZoneId.TheLimitlessBlueExtreme,
  ZoneId.ThokAstThokExtreme,
  ZoneId.TheMinstrelsBalladThordansReign,
  ZoneId.TheMinstrelsBalladNidhoggsRage,
  ZoneId.ContainmentBayS1T7Extreme,
  ZoneId.ContainmentBayP1T6Extreme,
  ZoneId.ContainmentBayZ1T9Extreme,

  // Trials (Stormblood)
  ZoneId.ThePoolOfTribute,
  ZoneId.Emanation,
  ZoneId.TheRoyalMenagerie,
  ZoneId.CastrumFluminis,
  ZoneId.KuganeOhashi,
  ZoneId.TheGreatHunt,
  ZoneId.TheJadeStoa,
  ZoneId.HellsKier,
  ZoneId.TheWreathOfSnakes,

  // High-end Trials (Stormblood)
  ZoneId.ThePoolOfTributeExtreme,
  ZoneId.EmanationExtreme,
  ZoneId.TheMinstrelsBalladShinryusDomain,
  ZoneId.TheMinstrelsBalladTsukuyomisPain,
  ZoneId.TheGreatHuntExtreme,
  ZoneId.TheJadeStoaExtreme,
  ZoneId.HellsKierExtreme,
  ZoneId.TheWreathOfSnakesExtreme,

  // Trials (Shadowbringers)
  ZoneId.TheDancingPlague,
  ZoneId.TheCrownOfTheImmaculate,
  ZoneId.TheDyingGasp,
  ZoneId.CinderDrift,
  ZoneId.TheSeatOfSacrifice,
  ZoneId.CastrumMarinum,

  // High-end Trials (Shadowbringers)
  ZoneId.TheDancingPlagueExtreme,
  ZoneId.TheCrownOfTheImmaculateExtreme,
  ZoneId.TheMinstrelsBalladHadessElegy,
  ZoneId.CinderDriftExtreme,
  ZoneId.MemoriaMiseraExtreme,
  ZoneId.TheSeatOfSacrificeExtreme,
  ZoneId.CastrumMarinumExtreme,
  ZoneId.TheAkhAfahAmphitheatreUnreal,
  ZoneId.TheNavelUnreal,

  // Alliance Raids (A Realm Reborn)
  ZoneId.TheLabyrinthOfTheAncients,
  ZoneId.SyrcusTower,
  ZoneId.TheWorldOfDarkness,

  // Raids (A Realm Reborn)
  ZoneId.TheBindingCoilOfBahamutTurn1,
  ZoneId.TheBindingCoilOfBahamutTurn2,
  ZoneId.TheBindingCoilOfBahamutTurn3,
  ZoneId.TheBindingCoilOfBahamutTurn4,
  ZoneId.TheBindingCoilOfBahamutTurn5,
  ZoneId.TheSecondCoilOfBahamutTurn1,
  ZoneId.TheSecondCoilOfBahamutTurn2,
  ZoneId.TheSecondCoilOfBahamutTurn3,
  ZoneId.TheSecondCoilOfBahamutTurn4,
  ZoneId.TheFinalCoilOfBahamutTurn1,
  ZoneId.TheFinalCoilOfBahamutTurn2,
  ZoneId.TheFinalCoilOfBahamutTurn3,
  ZoneId.TheFinalCoilOfBahamutTurn4,

  // Savage Raids (A Realm Reborn)
  ZoneId.TheSecondCoilOfBahamutSavageTurn1,
  ZoneId.TheSecondCoilOfBahamutSavageTurn2,
  ZoneId.TheSecondCoilOfBahamutSavageTurn3,
  ZoneId.TheSecondCoilOfBahamutSavageTurn4,

  // Alliance Raids (Heavensward)
  ZoneId.TheVoidArk,
  ZoneId.TheWeepingCityOfMhach,
  ZoneId.DunScaith,

  // Normal Raids (Heavensward)
  ZoneId.AlexanderTheFistOfTheFather,
  ZoneId.AlexanderTheCuffOfTheFather,
  ZoneId.AlexanderTheArmOfTheFather,
  ZoneId.AlexanderTheBurdenOfTheFather,
  ZoneId.AlexanderTheFistOfTheSon,
  ZoneId.AlexanderTheCuffOfTheSon,
  ZoneId.AlexanderTheArmOfTheSon,
  ZoneId.AlexanderTheBurdenOfTheSon,
  ZoneId.AlexanderTheEyesOfTheCreator,
  ZoneId.AlexanderTheBreathOfTheCreator,
  ZoneId.AlexanderTheHeartOfTheCreator,
  ZoneId.AlexanderTheSoulOfTheCreator,

  // Savage Raids (Heavensward)
  ZoneId.AlexanderTheFistOfTheFatherSavage,
  ZoneId.AlexanderTheCuffOfTheFatherSavage,
  ZoneId.AlexanderTheArmOfTheFatherSavage,
  ZoneId.AlexanderTheBurdenOfTheFatherSavage,
  ZoneId.AlexanderTheFistOfTheSonSavage,
  ZoneId.AlexanderTheCuffOfTheSonSavage,
  ZoneId.AlexanderTheArmOfTheSonSavage,
  ZoneId.AlexanderTheBurdenOfTheSonSavage,
  ZoneId.AlexanderTheEyesOfTheCreatorSavage,
  ZoneId.AlexanderTheBreathOfTheCreatorSavage,
  ZoneId.AlexanderTheHeartOfTheCreatorSavage,
  ZoneId.AlexanderTheSoulOfTheCreatorSavage,

  // Alliance Raids (Stormblood)
  ZoneId.TheRoyalCityOfRabanastre,
  ZoneId.TheRidoranaLighthouse,
  ZoneId.TheOrbonneMonastery,

  // Normal Raids (Stormblood)
  ZoneId.DeltascapeV10,
  ZoneId.DeltascapeV20,
  ZoneId.DeltascapeV30,
  ZoneId.DeltascapeV40,
  ZoneId.SigmascapeV10,
  ZoneId.SigmascapeV20,
  ZoneId.SigmascapeV30,
  ZoneId.SigmascapeV40,
  ZoneId.AlphascapeV10,
  ZoneId.AlphascapeV20,
  ZoneId.AlphascapeV30,
  ZoneId.AlphascapeV40,

  // Savage Raids (Stormblood)
  ZoneId.DeltascapeV10Savage,
  ZoneId.DeltascapeV20Savage,
  ZoneId.DeltascapeV30Savage,
  ZoneId.DeltascapeV40Savage,
  ZoneId.SigmascapeV10Savage,
  ZoneId.SigmascapeV20Savage,
  ZoneId.SigmascapeV30Savage,
  ZoneId.SigmascapeV40Savage,
  ZoneId.AlphascapeV10Savage,
  ZoneId.AlphascapeV20Savage,
  ZoneId.AlphascapeV30Savage,
  ZoneId.AlphascapeV40Savage,

  // Alliance Raids (Shadowbringers)
  ZoneId.TheCopiedFactory,
  ZoneId.ThePuppetsBunker,

  // Normal Raids (Shadowbringers)
  ZoneId.EdensGateResurrection,
  ZoneId.EdensGateDescent,
  ZoneId.EdensGateInundation,
  ZoneId.EdensGateSepulture,
  ZoneId.EdensVerseFulmination,
  ZoneId.EdensVerseFuror,
  ZoneId.EdensVerseIconoclasm,
  ZoneId.EdensVerseRefulgence,
  ZoneId.EdensPromiseUmbra,
  ZoneId.EdensPromiseLitany,
  ZoneId.EdensPromiseAnamorphosis,
  ZoneId.EdensPromiseEternity,

  // Savage Raids (Shadowbringers)
  ZoneId.EdensGateResurrectionSavage,
  ZoneId.EdensGateDescentSavage,
  ZoneId.EdensGateInundationSavage,
  ZoneId.EdensGateSepultureSavage,
  ZoneId.EdensVerseFulminationSavage,
  ZoneId.EdensVerseFurorSavage,
  ZoneId.EdensVerseIconoclasmSavage,
  ZoneId.EdensVerseRefulgenceSavage,
  ZoneId.EdensPromiseUmbraSavage,
  ZoneId.EdensPromiseLitanySavage,
  ZoneId.EdensPromiseAnamorphosisSavage,
  ZoneId.EdensPromiseEternitySavage,

  // Ultimate Raids
  ZoneId.TheUnendingCoilOfBahamutUltimate,
  ZoneId.TheWeaponsRefrainUltimate,
  ZoneId.TheEpicOfAlexanderUltimate,
];
<commit_msg>resources: manually update content list order for 5.5<commit_after>import ZoneId from './zone_id';

// Ordered as per duty finder.  This is intended to be used as ordering for
// any ui that is dealing with multiple zones / triggers.
//
// These are not things that cactbot necessarily supports, but things that it
// theoretically could be supporting in the future with raidboss and oopsy.

export default [
  // General (cactbot custom zone id)
  ZoneId.MatchAll,

  // Dungeons (A Realm Reborn)
  ZoneId.Sastasha,
  ZoneId.TheTamTaraDeepcroft,
  ZoneId.CopperbellMines,
  ZoneId.Halatali,
  ZoneId.TheThousandMawsOfTotoRak,
  ZoneId.HaukkeManor,
  ZoneId.BrayfloxsLongstop,
  ZoneId.TheSunkenTempleOfQarn,
  ZoneId.CuttersCry,
  ZoneId.TheStoneVigil,
  ZoneId.DzemaelDarkhold,
  ZoneId.TheAurumVale,
  ZoneId.TheWanderersPalace,
  ZoneId.CastrumMeridianum,
  ZoneId.ThePraetorium,
  ZoneId.AmdaporKeep,
  ZoneId.PharosSirius,
  ZoneId.CopperbellMinesHard,
  ZoneId.HaukkeManorHard,
  ZoneId.TheLostCityOfAmdapor,
  ZoneId.HalataliHard,
  ZoneId.BrayfloxsLongstopHard,
  ZoneId.HullbreakerIsle,
  ZoneId.TheTamTaraDeepcroftHard,
  ZoneId.TheStoneVigilHard,
  ZoneId.Snowcloak,
  ZoneId.SastashaHard,
  ZoneId.TheSunkenTempleOfQarnHard,
  ZoneId.TheKeeperOfTheLake,
  ZoneId.TheWanderersPalaceHard,
  ZoneId.AmdaporKeepHard,

  // Dungeons (Heavensward)
  ZoneId.TheDuskVigil,
  ZoneId.SohmAl,
  ZoneId.TheAery,
  ZoneId.TheVault,
  ZoneId.TheGreatGubalLibrary,
  ZoneId.TheAetherochemicalResearchFacility,
  ZoneId.Neverreap,
  ZoneId.TheFractalContinuum,
  ZoneId.SaintMociannesArboretum,
  ZoneId.PharosSiriusHard,
  ZoneId.TheAntitower,
  ZoneId.TheLostCityOfAmdaporHard,
  ZoneId.SohrKhai,
  ZoneId.HullbreakerIsleHard,
  ZoneId.Xelphatol,
  ZoneId.TheGreatGubalLibraryHard,
  ZoneId.BaelsarsWall,
  ZoneId.SohmAlHard,

  // Dungeons (Stormblood)
  ZoneId.TheSirensongSea,
  ZoneId.ShisuiOfTheVioletTides,
  ZoneId.BardamsMettle,
  ZoneId.DomaCastle,
  ZoneId.CastrumAbania,
  ZoneId.AlaMhigo,
  ZoneId.KuganeCastle,
  ZoneId.TheTempleOfTheFist,
  ZoneId.TheDrownedCityOfSkalla,
  ZoneId.HellsLid,
  ZoneId.TheFractalContinuumHard,
  ZoneId.TheSwallowsCompass,
  ZoneId.TheBurn,
  ZoneId.SaintMociannesArboretumHard,
  ZoneId.TheGhimlytDark,

  // Dungeons (Shadowbringers)
  ZoneId.HolminsterSwitch,
  ZoneId.DohnMheg,
  ZoneId.TheQitanaRavel,
  ZoneId.MalikahsWell,
  ZoneId.MtGulg,
  ZoneId.Amaurot,
  ZoneId.TheTwinning,
  ZoneId.AkadaemiaAnyder,
  ZoneId.TheGrandCosmos,
  ZoneId.AnamnesisAnyder,
  ZoneId.TheHeroesGauntlet,
  ZoneId.MatoyasRelict,
  ZoneId.Paglthan,

  // Guildhests
  ZoneId.BasicTrainingEnemyParties,
  ZoneId.UnderTheArmor,
  ZoneId.BasicTrainingEnemyStrongholds,
  ZoneId.HeroOnTheHalfShell,
  ZoneId.PullingPoisonPosies,
  ZoneId.StingingBack,
  ZoneId.AllsWellThatEndsInTheWell,
  ZoneId.FlickingSticksAndTakingNames,
  ZoneId.MoreThanAFeeler,
  ZoneId.AnnoyTheVoid,
  ZoneId.ShadowAndClaw,
  ZoneId.LongLiveTheQueen,
  ZoneId.WardUp,
  ZoneId.SolemnTrinity,

  // Trials (A Realm Reborn)
  ZoneId.TheBowlOfEmbers,
  ZoneId.TheNavel,
  ZoneId.TheHowlingEye,
  ZoneId.CapeWestwind,
  ZoneId.TheChrysalis,
  ZoneId.TheStepsOfFaith,
  ZoneId.ARelicRebornTheChimera,
  ZoneId.ARelicRebornTheHydra,
  ZoneId.BattleOnTheBigBridge,
  ZoneId.TheDragonsNeck,
  ZoneId.BattleInTheBigKeep,
  ZoneId.TheBowlOfEmbersHard,
  ZoneId.TheHowlingEyeHard,
  ZoneId.TheNavelHard,
  ZoneId.ThornmarchHard,
  ZoneId.TheWhorleaterHard,
  ZoneId.TheStrikingTreeHard,
  ZoneId.TheAkhAfahAmphitheatreHard,
  ZoneId.UrthsFount,

  // High-end Trials (A Realm Reborn)
  ZoneId.TheMinstrelsBalladUltimasBane,
  ZoneId.TheHowlingEyeExtreme,
  ZoneId.TheNavelExtreme,
  ZoneId.TheBowlOfEmbersExtreme,
  ZoneId.ThornmarchExtreme,
  ZoneId.TheWhorleaterExtreme,
  ZoneId.TheStrikingTreeExtreme,
  ZoneId.TheAkhAfahAmphitheatreExtreme,

  // Trials (Heavensward)
  ZoneId.ThokAstThokHard,
  ZoneId.TheLimitlessBlueHard,
  ZoneId.TheSingularityReactor,
  ZoneId.TheFinalStepsOfFaith,
  ZoneId.ContainmentBayS1T7,
  ZoneId.ContainmentBayP1T6,
  ZoneId.ContainmentBayZ1T9,

  // High-end Trials (Heavensward)
  ZoneId.TheLimitlessBlueExtreme,
  ZoneId.ThokAstThokExtreme,
  ZoneId.TheMinstrelsBalladThordansReign,
  ZoneId.TheMinstrelsBalladNidhoggsRage,
  ZoneId.ContainmentBayS1T7Extreme,
  ZoneId.ContainmentBayP1T6Extreme,
  ZoneId.ContainmentBayZ1T9Extreme,

  // Trials (Stormblood)
  ZoneId.ThePoolOfTribute,
  ZoneId.Emanation,
  ZoneId.TheRoyalMenagerie,
  ZoneId.CastrumFluminis,
  ZoneId.KuganeOhashi,
  ZoneId.TheGreatHunt,
  ZoneId.TheJadeStoa,
  ZoneId.HellsKier,
  ZoneId.TheWreathOfSnakes,

  // High-end Trials (Stormblood)
  ZoneId.ThePoolOfTributeExtreme,
  ZoneId.EmanationExtreme,
  ZoneId.TheMinstrelsBalladShinryusDomain,
  ZoneId.TheMinstrelsBalladTsukuyomisPain,
  ZoneId.TheGreatHuntExtreme,
  ZoneId.TheJadeStoaExtreme,
  ZoneId.HellsKierExtreme,
  ZoneId.TheWreathOfSnakesExtreme,

  // Trials (Shadowbringers)
  ZoneId.TheDancingPlague,
  ZoneId.TheCrownOfTheImmaculate,
  ZoneId.TheDyingGasp,
  ZoneId.CinderDrift,
  ZoneId.TheSeatOfSacrifice,
  ZoneId.CastrumMarinum,
  ZoneId.TheCloudDeck,

  // High-end Trials (Shadowbringers)
  ZoneId.TheDancingPlagueExtreme,
  ZoneId.TheCrownOfTheImmaculateExtreme,
  ZoneId.TheMinstrelsBalladHadessElegy,
  ZoneId.CinderDriftExtreme,
  ZoneId.MemoriaMiseraExtreme,
  ZoneId.TheSeatOfSacrificeExtreme,
  ZoneId.CastrumMarinumExtreme,
  ZoneId.TheCloudDeckExtreme,
  ZoneId.TheAkhAfahAmphitheatreUnreal,
  ZoneId.TheNavelUnreal,
  ZoneId.TheWhorleaterUnreal,

  // Alliance Raids (A Realm Reborn)
  ZoneId.TheLabyrinthOfTheAncients,
  ZoneId.SyrcusTower,
  ZoneId.TheWorldOfDarkness,

  // Raids (A Realm Reborn)
  ZoneId.TheBindingCoilOfBahamutTurn1,
  ZoneId.TheBindingCoilOfBahamutTurn2,
  ZoneId.TheBindingCoilOfBahamutTurn3,
  ZoneId.TheBindingCoilOfBahamutTurn4,
  ZoneId.TheBindingCoilOfBahamutTurn5,
  ZoneId.TheSecondCoilOfBahamutTurn1,
  ZoneId.TheSecondCoilOfBahamutTurn2,
  ZoneId.TheSecondCoilOfBahamutTurn3,
  ZoneId.TheSecondCoilOfBahamutTurn4,
  ZoneId.TheFinalCoilOfBahamutTurn1,
  ZoneId.TheFinalCoilOfBahamutTurn2,
  ZoneId.TheFinalCoilOfBahamutTurn3,
  ZoneId.TheFinalCoilOfBahamutTurn4,

  // Savage Raids (A Realm Reborn)
  ZoneId.TheSecondCoilOfBahamutSavageTurn1,
  ZoneId.TheSecondCoilOfBahamutSavageTurn2,
  ZoneId.TheSecondCoilOfBahamutSavageTurn3,
  ZoneId.TheSecondCoilOfBahamutSavageTurn4,

  // Alliance Raids (Heavensward)
  ZoneId.TheVoidArk,
  ZoneId.TheWeepingCityOfMhach,
  ZoneId.DunScaith,

  // Normal Raids (Heavensward)
  ZoneId.AlexanderTheFistOfTheFather,
  ZoneId.AlexanderTheCuffOfTheFather,
  ZoneId.AlexanderTheArmOfTheFather,
  ZoneId.AlexanderTheBurdenOfTheFather,
  ZoneId.AlexanderTheFistOfTheSon,
  ZoneId.AlexanderTheCuffOfTheSon,
  ZoneId.AlexanderTheArmOfTheSon,
  ZoneId.AlexanderTheBurdenOfTheSon,
  ZoneId.AlexanderTheEyesOfTheCreator,
  ZoneId.AlexanderTheBreathOfTheCreator,
  ZoneId.AlexanderTheHeartOfTheCreator,
  ZoneId.AlexanderTheSoulOfTheCreator,

  // Savage Raids (Heavensward)
  ZoneId.AlexanderTheFistOfTheFatherSavage,
  ZoneId.AlexanderTheCuffOfTheFatherSavage,
  ZoneId.AlexanderTheArmOfTheFatherSavage,
  ZoneId.AlexanderTheBurdenOfTheFatherSavage,
  ZoneId.AlexanderTheFistOfTheSonSavage,
  ZoneId.AlexanderTheCuffOfTheSonSavage,
  ZoneId.AlexanderTheArmOfTheSonSavage,
  ZoneId.AlexanderTheBurdenOfTheSonSavage,
  ZoneId.AlexanderTheEyesOfTheCreatorSavage,
  ZoneId.AlexanderTheBreathOfTheCreatorSavage,
  ZoneId.AlexanderTheHeartOfTheCreatorSavage,
  ZoneId.AlexanderTheSoulOfTheCreatorSavage,

  // Alliance Raids (Stormblood)
  ZoneId.TheRoyalCityOfRabanastre,
  ZoneId.TheRidoranaLighthouse,
  ZoneId.TheOrbonneMonastery,

  // Normal Raids (Stormblood)
  ZoneId.DeltascapeV10,
  ZoneId.DeltascapeV20,
  ZoneId.DeltascapeV30,
  ZoneId.DeltascapeV40,
  ZoneId.SigmascapeV10,
  ZoneId.SigmascapeV20,
  ZoneId.SigmascapeV30,
  ZoneId.SigmascapeV40,
  ZoneId.AlphascapeV10,
  ZoneId.AlphascapeV20,
  ZoneId.AlphascapeV30,
  ZoneId.AlphascapeV40,

  // Savage Raids (Stormblood)
  ZoneId.DeltascapeV10Savage,
  ZoneId.DeltascapeV20Savage,
  ZoneId.DeltascapeV30Savage,
  ZoneId.DeltascapeV40Savage,
  ZoneId.SigmascapeV10Savage,
  ZoneId.SigmascapeV20Savage,
  ZoneId.SigmascapeV30Savage,
  ZoneId.SigmascapeV40Savage,
  ZoneId.AlphascapeV10Savage,
  ZoneId.AlphascapeV20Savage,
  ZoneId.AlphascapeV30Savage,
  ZoneId.AlphascapeV40Savage,

  // Alliance Raids (Shadowbringers)
  ZoneId.TheCopiedFactory,
  ZoneId.ThePuppetsBunker,
  ZoneId.TheTowerAtParadigmsBreach,

  // Normal Raids (Shadowbringers)
  ZoneId.EdensGateResurrection,
  ZoneId.EdensGateDescent,
  ZoneId.EdensGateInundation,
  ZoneId.EdensGateSepulture,
  ZoneId.EdensVerseFulmination,
  ZoneId.EdensVerseFuror,
  ZoneId.EdensVerseIconoclasm,
  ZoneId.EdensVerseRefulgence,
  ZoneId.EdensPromiseUmbra,
  ZoneId.EdensPromiseLitany,
  ZoneId.EdensPromiseAnamorphosis,
  ZoneId.EdensPromiseEternity,

  // Savage Raids (Shadowbringers)
  ZoneId.EdensGateResurrectionSavage,
  ZoneId.EdensGateDescentSavage,
  ZoneId.EdensGateInundationSavage,
  ZoneId.EdensGateSepultureSavage,
  ZoneId.EdensVerseFulminationSavage,
  ZoneId.EdensVerseFurorSavage,
  ZoneId.EdensVerseIconoclasmSavage,
  ZoneId.EdensVerseRefulgenceSavage,
  ZoneId.EdensPromiseUmbraSavage,
  ZoneId.EdensPromiseLitanySavage,
  ZoneId.EdensPromiseAnamorphosisSavage,
  ZoneId.EdensPromiseEternitySavage,

  // Ultimate Raids
  ZoneId.TheUnendingCoilOfBahamutUltimate,
  ZoneId.TheWeaponsRefrainUltimate,
  ZoneId.TheEpicOfAlexanderUltimate,
];
<|endoftext|>